github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/worker/uniter/leadership/resolver.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package leadership 5 6 import ( 7 "github.com/juju/loggo" 8 9 "github.com/juju/juju/apiserver/params" 10 "github.com/juju/juju/worker/uniter/hook" 11 "github.com/juju/juju/worker/uniter/operation" 12 "github.com/juju/juju/worker/uniter/remotestate" 13 "github.com/juju/juju/worker/uniter/resolver" 14 ) 15 16 var logger = loggo.GetLogger("juju.worker.uniter.leadership") 17 18 type leadershipResolver struct { 19 } 20 21 // NewResolver returns a new leadership resolver. 22 func NewResolver() resolver.Resolver { 23 return &leadershipResolver{} 24 } 25 26 // NextOp is defined on the Resolver interface. 27 func (l *leadershipResolver) NextOp( 28 localState resolver.LocalState, 29 remoteState remotestate.Snapshot, 30 opFactory operation.Factory, 31 ) (operation.Operation, error) { 32 33 // TODO(wallyworld) - maybe this can occur before install 34 if !localState.Installed { 35 return nil, resolver.ErrNoOperation 36 } 37 38 // Check for any leadership change, and enact it if possible. 39 logger.Tracef("checking leadership status") 40 41 // If we've already accepted leadership, we don't need to do it again. 42 canAcceptLeader := !localState.Leader 43 if remoteState.Life == params.Dying { 44 canAcceptLeader = false 45 } else { 46 // If we're in an unexpected mode (eg pending hook) we shouldn't try either. 47 if localState.Kind != operation.Continue { 48 canAcceptLeader = false 49 } 50 } 51 52 switch { 53 case remoteState.Leader && canAcceptLeader: 54 return opFactory.NewAcceptLeadership() 55 56 // If we're the leader but should not be any longer, or 57 // if the unit is dying, we should resign leadership. 58 case localState.Leader && (!remoteState.Leader || remoteState.Life == params.Dying): 59 return opFactory.NewResignLeadership() 60 } 61 62 if localState.Kind == operation.Continue { 63 // We want to run the leader settings hook if we're 64 // not the leader and the settings have changed. 65 if !localState.Leader && localState.LeaderSettingsVersion != remoteState.LeaderSettingsVersion { 66 return opFactory.NewRunHook(hook.Info{Kind: hook.LeaderSettingsChanged}) 67 } 68 } 69 70 logger.Tracef("leadership status is up-to-date") 71 return nil, resolver.ErrNoOperation 72 }