github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/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  	// NewUpdateStorage creates an operation to ensure the supplied storage
    99  	// tags are known and tracked.
   100  	NewUpdateStorage(tags []names.StorageTag) (Operation, error)
   101  
   102  	// NewAcceptLeadership creates an operation to ensure the uniter acts as
   103  	// service leader.
   104  	NewAcceptLeadership() (Operation, error)
   105  
   106  	// NewResignLeadership creates an operation to ensure the uniter does not
   107  	// act as service leader.
   108  	NewResignLeadership() (Operation, error)
   109  }
   110  
   111  // CommandArgs stores the arguments for a Command operation.
   112  type CommandArgs struct {
   113  	// Commands is the arbitrary commands to execute on the unit
   114  	Commands string
   115  	// RelationId is the relation context to execute the commands in.
   116  	RelationId int
   117  	// RemoteUnitName is the remote unit for the relation context.
   118  	RemoteUnitName string
   119  	// ForceRemoteUnit skips unit inference and existence validation.
   120  	ForceRemoteUnit bool
   121  }
   122  
   123  // CommandResponseFunc is for marshalling command responses back to the source
   124  // of the original request.
   125  type CommandResponseFunc func(*utilexec.ExecResponse, error)
   126  
   127  // Callbacks exposes all the uniter code that's required by the various operations.
   128  // It's far from cohesive, and fundamentally represents inappropriate coupling, so
   129  // it's a prime candidate for future refactoring.
   130  type Callbacks interface {
   131  	// PrepareHook and CommitHook exist so that we can defer worrying about how
   132  	// to untangle Uniter.relationers from everything else. They're only used by
   133  	// RunHook operations.
   134  	PrepareHook(info hook.Info) (name string, err error)
   135  	CommitHook(info hook.Info) error
   136  
   137  	// SetExecutingStatus sets the agent state to "Executing" with a message.
   138  	SetExecutingStatus(string) error
   139  
   140  	// NotifyHook* exist so that we can defer worrying about how to untangle the
   141  	// callbacks inserted for uniter_test. They're only used by RunHook operations.
   142  	NotifyHookCompleted(string, runner.Context)
   143  	NotifyHookFailed(string, runner.Context)
   144  
   145  	// The following methods exist primarily to allow us to test operation code
   146  	// without using a live api connection.
   147  
   148  	// FailAction marks the supplied action failed. It's only used by
   149  	// RunActions operations.
   150  	FailAction(actionId, message string) error
   151  
   152  	// GetArchiveInfo is used to find out how to download a charm archive. It's
   153  	// only used by Deploy operations.
   154  	GetArchiveInfo(charmURL *corecharm.URL) (charm.BundleInfo, error)
   155  
   156  	// SetCurrentCharm records intent to deploy a given charm. It must be called
   157  	// *before* recording local state referencing that charm, to ensure there's
   158  	// no path by which the state server can legitimately garbage collect that
   159  	// charm or the service's settings for it. It's only used by Deploy operations.
   160  	SetCurrentCharm(charmURL *corecharm.URL) error
   161  }
   162  
   163  // StorageUpdater is an interface used for updating local knowledge of storage
   164  // attachments.
   165  type StorageUpdater interface {
   166  	// UpdateStorage updates local knowledge of the storage attachments
   167  	// with the specified tags.
   168  	UpdateStorage([]names.StorageTag) error
   169  }