github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/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.Infof("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.Infof("leadership status is up-to-date")
    71  	return nil, resolver.ErrNoOperation
    72  }