// NextOp implements the resolver.Resolver interface. func (r *actionsResolver) NextOp( localState resolver.LocalState, remoteState remotestate.Snapshot, opFactory operation.Factory, ) (operation.Operation, error) { nextAction, err := nextAction(remoteState.Actions, localState.CompletedActions) if err != nil { return nil, err } switch localState.Kind { case operation.RunHook: // We can still run actions if the unit is in a hook error state. if localState.Step == operation.Pending { return opFactory.NewAction(nextAction) } case operation.RunAction: if localState.Hook != nil { logger.Infof("found incomplete action %q; ignoring", localState.ActionId) logger.Infof("recommitting prior %q hook", localState.Hook.Kind) return opFactory.NewSkipHook(*localState.Hook) } else { logger.Infof("%q hook is nil", operation.RunAction) return opFactory.NewFailAction(*localState.ActionId) } case operation.Continue: return opFactory.NewAction(nextAction) } return nil, resolver.ErrNoOperation }
// NextOp implements the resolver.Resolver interface. func (r *actionsResolver) NextOp( localState resolver.LocalState, remoteState remotestate.Snapshot, opFactory operation.Factory, ) (operation.Operation, error) { nextAction, err := nextAction(remoteState.Actions, localState.CompletedActions) if err != nil { return nil, err } switch localState.Kind { case operation.RunHook: // We can still run actions if the unit is in a hook error state. if localState.Step == operation.Pending { return opFactory.NewAction(nextAction) } case operation.RunAction: // TODO(fwereade): we *should* handle interrupted actions, and make sure // they're marked as failed, but that's not for now. if localState.Hook != nil { logger.Infof("found incomplete action %q; ignoring", localState.ActionId) logger.Infof("recommitting prior %q hook", localState.Hook.Kind) return opFactory.NewSkipHook(*localState.Hook) } else { logger.Infof("%q hook is nil", operation.RunAction) } case operation.Continue: return opFactory.NewAction(nextAction) } return nil, resolver.ErrNoOperation }