github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/worker/uniter/upgradeseries/resolver.go (about)

     1  // Copyright 2018 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package upgradeseries
     5  
     6  import (
     7  	"gopkg.in/juju/charm.v6/hooks"
     8  
     9  	"github.com/juju/juju/core/model"
    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  type upgradeSeriesResolver struct{}
    17  
    18  // NewResolver returns a new upgrade-series resolver.
    19  func NewResolver() resolver.Resolver {
    20  	return &upgradeSeriesResolver{}
    21  }
    22  
    23  // NextOp is defined on the Resolver interface.
    24  func (l *upgradeSeriesResolver) NextOp(
    25  	localState resolver.LocalState, remoteState remotestate.Snapshot, opFactory operation.Factory,
    26  ) (operation.Operation, error) {
    27  	// If the unit has completed a pre-series-upgrade hook
    28  	// (as noted by its state) then the uniter should idle in the face of all
    29  	// remote state changes.
    30  	if remoteState.UpgradeSeriesStatus == model.UpgradeSeriesPrepareCompleted {
    31  		return nil, resolver.ErrDoNotProceed
    32  	}
    33  
    34  	if localState.Kind == operation.Continue {
    35  		if localState.UpgradeSeriesStatus == model.UpgradeSeriesNotStarted &&
    36  			remoteState.UpgradeSeriesStatus == model.UpgradeSeriesPrepareStarted {
    37  			return opFactory.NewRunHook(hook.Info{Kind: hooks.PreSeriesUpgrade})
    38  		}
    39  
    40  		// The uniter's local state will be in the "not started" state if the
    41  		// uniter was stopped for any reason, while performing a series upgrade.
    42  		// If the uniter was not stopped then it will be in the "prepare completed"
    43  		// state and likewise run the post upgrade hook.
    44  		if (localState.UpgradeSeriesStatus == model.UpgradeSeriesNotStarted ||
    45  			localState.UpgradeSeriesStatus == model.UpgradeSeriesPrepareCompleted) &&
    46  			remoteState.UpgradeSeriesStatus == model.UpgradeSeriesCompleteStarted {
    47  			return opFactory.NewRunHook(hook.Info{Kind: hooks.PostSeriesUpgrade})
    48  		}
    49  
    50  		// If the local state is completed but the remote state is not started,
    51  		// then this means that the lock has been removed and the local uniter
    52  		// state should be reset.
    53  		if localState.UpgradeSeriesStatus == model.UpgradeSeriesCompleted &&
    54  			remoteState.UpgradeSeriesStatus == model.UpgradeSeriesNotStarted {
    55  			return opFactory.NewNoOpFinishUpgradeSeries()
    56  		}
    57  	}
    58  
    59  	return nil, resolver.ErrNoOperation
    60  }