~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/github.com/juju/juju/worker/uniter/actions/resolver.go

  • Committer: Nicholas Skaggs
  • Date: 2016-10-24 20:56:05 UTC
  • Revision ID: nicholas.skaggs@canonical.com-20161024205605-z8lta0uvuhtxwzwl
Initi with beta15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2015 Canonical Ltd.
 
2
// Licensed under the AGPLv3, see LICENCE file for details.
 
3
 
 
4
package actions
 
5
 
 
6
import (
 
7
        "github.com/juju/loggo"
 
8
 
 
9
        "github.com/juju/juju/worker/uniter/operation"
 
10
        "github.com/juju/juju/worker/uniter/remotestate"
 
11
        "github.com/juju/juju/worker/uniter/resolver"
 
12
)
 
13
 
 
14
var logger = loggo.GetLogger("juju.worker.uniter.actions")
 
15
 
 
16
type actionsResolver struct{}
 
17
 
 
18
// NewResolver returns a new resolver with determines which action related operation
 
19
// should be run based on local and remote uniter states.
 
20
//
 
21
// TODO(axw) 2015-10-27 #1510333
 
22
// Use the same method as in the runcommands resolver
 
23
// for updating the remote state snapshot when an
 
24
// action is completed.
 
25
func NewResolver() resolver.Resolver {
 
26
        return &actionsResolver{}
 
27
}
 
28
 
 
29
func nextAction(pendingActions []string, completedActions map[string]struct{}) (string, error) {
 
30
        for _, action := range pendingActions {
 
31
                if _, ok := completedActions[action]; !ok {
 
32
                        return action, nil
 
33
                }
 
34
        }
 
35
        return "", resolver.ErrNoOperation
 
36
}
 
37
 
 
38
// NextOp implements the resolver.Resolver interface.
 
39
func (r *actionsResolver) NextOp(
 
40
        localState resolver.LocalState,
 
41
        remoteState remotestate.Snapshot,
 
42
        opFactory operation.Factory,
 
43
) (operation.Operation, error) {
 
44
        nextAction, err := nextAction(remoteState.Actions, localState.CompletedActions)
 
45
        if err != nil {
 
46
                return nil, err
 
47
        }
 
48
        switch localState.Kind {
 
49
        case operation.RunHook:
 
50
                // We can still run actions if the unit is in a hook error state.
 
51
                if localState.Step == operation.Pending {
 
52
                        return opFactory.NewAction(nextAction)
 
53
                }
 
54
        case operation.RunAction:
 
55
                // TODO(fwereade): we *should* handle interrupted actions, and make sure
 
56
                // they're marked as failed, but that's not for now.
 
57
                if localState.Hook != nil {
 
58
                        logger.Infof("found incomplete action %q; ignoring", localState.ActionId)
 
59
                        logger.Infof("recommitting prior %q hook", localState.Hook.Kind)
 
60
                        return opFactory.NewSkipHook(*localState.Hook)
 
61
                } else {
 
62
                        logger.Infof("%q hook is nil", operation.RunAction)
 
63
                }
 
64
        case operation.Continue:
 
65
                return opFactory.NewAction(nextAction)
 
66
        }
 
67
        return nil, resolver.ErrNoOperation
 
68
}