github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/worker/uniter/actions/resolver.go (about) 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 func NewResolver() resolver.Resolver { 21 return &actionsResolver{} 22 } 23 24 func nextAction(pendingActions []string, completedActions map[string]struct{}) (string, error) { 25 for _, action := range pendingActions { 26 if _, ok := completedActions[action]; !ok { 27 return action, nil 28 } 29 } 30 return "", resolver.ErrNoOperation 31 } 32 33 // NextOp implements the resolver.Resolver interface. 34 func (r *actionsResolver) NextOp( 35 localState resolver.LocalState, 36 remoteState remotestate.Snapshot, 37 opFactory operation.Factory, 38 ) (operation.Operation, error) { 39 nextAction, err := nextAction(remoteState.Actions, localState.CompletedActions) 40 if err != nil { 41 return nil, err 42 } 43 switch localState.Kind { 44 case operation.RunHook: 45 // We can still run actions if the unit is in a hook error state. 46 if localState.Step == operation.Pending { 47 return opFactory.NewAction(nextAction) 48 } 49 case operation.RunAction: 50 // TODO(fwereade): we *should* handle interrupted actions, and make sure 51 // they're marked as failed, but that's not for now. 52 if localState.Hook != nil { 53 logger.Infof("found incomplete action %q; ignoring", localState.ActionId) 54 logger.Infof("recommitting prior %q hook", localState.Hook.Kind) 55 return opFactory.NewSkipHook(*localState.Hook) 56 } else { 57 logger.Infof("%q hook is nil", operation.RunAction) 58 } 59 case operation.Continue: 60 return opFactory.NewAction(nextAction) 61 } 62 return nil, resolver.ErrNoOperation 63 }