github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/worker/uniter/operation/interface.go (about)

     1  // Copyright 2014-2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package operation
     5  
     6  import (
     7  	"github.com/juju/loggo"
     8  	"github.com/juju/names"
     9  	utilexec "github.com/juju/utils/exec"
    10  	corecharm "gopkg.in/juju/charm.v6-unstable"
    11  
    12  	"github.com/juju/juju/worker/uniter/charm"
    13  	"github.com/juju/juju/worker/uniter/hook"
    14  	"github.com/juju/juju/worker/uniter/runner"
    15  )
    16  
    17  var logger = loggo.GetLogger("juju.worker.uniter.operation")
    18  
    19  // Operation encapsulates the stages of the various things the uniter can do,
    20  // and the state changes that need to be recorded as they happen. Operations
    21  // are designed to be Run (or Skipped) by an Executor, which supplies starting
    22  // state and records the changes returned.
    23  type Operation interface {
    24  
    25  	// String returns a short representation of the operation.
    26  	String() string
    27  
    28  	// NeedsGlobalMachineLock returns a bool expressing whether we need to lock the machine.
    29  	NeedsGlobalMachineLock() bool
    30  
    31  	// Prepare ensures that the operation is valid and ready to be executed.
    32  	// If it returns a non-nil state, that state will be validated and recorded.
    33  	// If it returns ErrSkipExecute, it indicates that the operation can be
    34  	// committed directly.
    35  	Prepare(state State) (*State, error)
    36  
    37  	// Execute carries out the operation. It must not be called without having
    38  	// called Prepare first. If it returns a non-nil state, that state will be
    39  	// validated and recorded.
    40  	Execute(state State) (*State, error)
    41  
    42  	// Commit ensures that the operation's completion is recorded. If it returns
    43  	// a non-nil state, that state will be validated and recorded.
    44  	Commit(state State) (*State, error)
    45  }
    46  
    47  // Executor records and exposes uniter state, and applies suitable changes as
    48  // operations are run or skipped.
    49  type Executor interface {
    50  
    51  	// State returns a copy of the executor's current operation state.
    52  	State() State
    53  
    54  	// Run will Prepare, Execute, and Commit the supplied operation, writing
    55  	// indicated state changes between steps. If any step returns an unknown
    56  	// error, the run will be aborted and an error will be returned.
    57  	Run(Operation) error
    58  
    59  	// Skip will Commit the supplied operation, and write any state change
    60  	// indicated. If Commit returns an error, so will Skip.
    61  	Skip(Operation) error
    62  }
    63  
    64  // Factory creates operations.
    65  type Factory interface {
    66  
    67  	// NewInstall creates an install operation for the supplied charm.
    68  	NewInstall(charmURL *corecharm.URL) (Operation, error)
    69  
    70  	// NewUpgrade creates an upgrade operation for the supplied charm.
    71  	NewUpgrade(charmURL *corecharm.URL) (Operation, error)
    72  
    73  	// NewRevertUpgrade creates an operation to clear the unit's resolved flag,
    74  	// and execute an upgrade to the supplied charm that is careful to excise
    75  	// remnants of a previously failed upgrade to a different charm.
    76  	NewRevertUpgrade(charmURL *corecharm.URL) (Operation, error)
    77  
    78  	// NewResolvedUpgrade creates an operation to clear the unit's resolved flag,
    79  	// and execute an upgrade to the supplied charm that is careful to preserve
    80  	// non-overlapping remnants of a previously failed upgrade to the same charm.
    81  	NewResolvedUpgrade(charmURL *corecharm.URL) (Operation, error)
    82  
    83  	// NewRunHook creates an operation to execute the supplied hook.
    84  	NewRunHook(hookInfo hook.Info) (Operation, error)
    85  
    86  	// NewSkipHook creates an operation to mark the supplied hook as
    87  	// completed successfully, without executing the hook.
    88  	NewSkipHook(hookInfo hook.Info) (Operation, error)
    89  
    90  	// NewAction creates an operation to execute the supplied action.
    91  	NewAction(actionId string) (Operation, error)
    92  
    93  	// NewCommands creates an operation to execute the supplied script in the
    94  	// indicated relation context, and pass the results back over the supplied
    95  	// func.
    96  	NewCommands(args CommandArgs, sendResponse CommandResponseFunc) (Operation, error)
    97  
    98  	// NewAcceptLeadership creates an operation to ensure the uniter acts as
    99  	// service leader.
   100  	NewAcceptLeadership() (Operation, error)
   101  
   102  	// NewResignLeadership creates an operation to ensure the uniter does not
   103  	// act as service leader.
   104  	NewResignLeadership() (Operation, error)
   105  }
   106  
   107  // CommandArgs stores the arguments for a Command operation.
   108  type CommandArgs struct {
   109  	// Commands is the arbitrary commands to execute on the unit
   110  	Commands string
   111  	// RelationId is the relation context to execute the commands in.
   112  	RelationId int
   113  	// RemoteUnitName is the remote unit for the relation context.
   114  	RemoteUnitName string
   115  	// ForceRemoteUnit skips unit inference and existence validation.
   116  	ForceRemoteUnit bool
   117  }
   118  
   119  // CommandResponseFunc is for marshalling command responses back to the source
   120  // of the original request.
   121  type CommandResponseFunc func(*utilexec.ExecResponse, error)
   122  
   123  // Callbacks exposes all the uniter code that's required by the various operations.
   124  // It's far from cohesive, and fundamentally represents inappropriate coupling, so
   125  // it's a prime candidate for future refactoring.
   126  type Callbacks interface {
   127  	// PrepareHook and CommitHook exist so that we can defer worrying about how
   128  	// to untangle Uniter.relationers from everything else. They're only used by
   129  	// RunHook operations.
   130  	PrepareHook(info hook.Info) (name string, err error)
   131  	CommitHook(info hook.Info) error
   132  
   133  	// SetExecutingStatus sets the agent state to "Executing" with a message.
   134  	SetExecutingStatus(string) error
   135  
   136  	// NotifyHook* exist so that we can defer worrying about how to untangle the
   137  	// callbacks inserted for uniter_test. They're only used by RunHook operations.
   138  	NotifyHookCompleted(string, runner.Context)
   139  	NotifyHookFailed(string, runner.Context)
   140  
   141  	// The following methods exist primarily to allow us to test operation code
   142  	// without using a live api connection.
   143  
   144  	// FailAction marks the supplied action failed. It's only used by
   145  	// RunActions operations.
   146  	FailAction(actionId, message string) error
   147  
   148  	// GetArchiveInfo is used to find out how to download a charm archive. It's
   149  	// only used by Deploy operations.
   150  	GetArchiveInfo(charmURL *corecharm.URL) (charm.BundleInfo, error)
   151  
   152  	// SetCurrentCharm records intent to deploy a given charm. It must be called
   153  	// *before* recording local state referencing that charm, to ensure there's
   154  	// no path by which the controller can legitimately garbage collect that
   155  	// charm or the service's settings for it. It's only used by Deploy operations.
   156  	SetCurrentCharm(charmURL *corecharm.URL) error
   157  }
   158  
   159  // StorageUpdater is an interface used for updating local knowledge of storage
   160  // attachments.
   161  type StorageUpdater interface {
   162  	// UpdateStorage updates local knowledge of the storage attachments
   163  	// with the specified tags.
   164  	UpdateStorage([]names.StorageTag) error
   165  }