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