github.com/altoros/juju-vmware@v0.0.0-20150312064031-f19ae857ccca/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  	utilexec "github.com/juju/utils/exec"
     9  	corecharm "gopkg.in/juju/charm.v4"
    10  
    11  	"github.com/juju/juju/worker/uniter/charm"
    12  	"github.com/juju/juju/worker/uniter/hook"
    13  	"github.com/juju/juju/worker/uniter/runner"
    14  )
    15  
    16  var logger = loggo.GetLogger("juju.worker.uniter.operation")
    17  
    18  // Operation encapsulates the stages of the various things the uniter can do,
    19  // and the state changes that need to be recorded as they happen. Operations
    20  // are designed to be Run (or Skipped) by an Executor, which supplies starting
    21  // state and records the changes returned.
    22  type Operation interface {
    23  
    24  	// String returns a short representation of the operation.
    25  	String() string
    26  
    27  	// Prepare ensures that the operation is valid and ready to be executed.
    28  	// If it returns a non-nil state, that state will be validated and recorded.
    29  	// If it returns ErrSkipExecute, it indicates that the operation can be
    30  	// committed directly.
    31  	Prepare(state State) (*State, error)
    32  
    33  	// Execute carries out the operation. It must not be called without having
    34  	// called Prepare first. If it returns a non-nil state, that state will be
    35  	// validated and recorded.
    36  	Execute(state State) (*State, error)
    37  
    38  	// Commit ensures that the operation's completion is recorded. If it returns
    39  	// a non-nil state, that state will be validated and recorded.
    40  	Commit(state State) (*State, error)
    41  }
    42  
    43  // Executor records and exposes uniter state, and applies suitable changes as
    44  // operations are run or skipped.
    45  type Executor interface {
    46  
    47  	// State returns a copy of the executor's current operation state.
    48  	State() State
    49  
    50  	// Run will Prepare, Execute, and Commit the supplied operation, writing
    51  	// indicated state changes between steps. If any step returns an unknown
    52  	// error, the run will be aborted and an error will be returned.
    53  	Run(Operation) error
    54  
    55  	// Skip will Commit the supplied operation, and write any state change
    56  	// indicated. If Commit returns an error, so will Skip.
    57  	Skip(Operation) error
    58  }
    59  
    60  // Factory creates operations.
    61  type Factory interface {
    62  
    63  	// NewInstall creates an install operation for the supplied charm.
    64  	NewInstall(charmURL *corecharm.URL) (Operation, error)
    65  
    66  	// NewUpgrade creates an upgrade operation for the supplied charm.
    67  	NewUpgrade(charmURL *corecharm.URL) (Operation, error)
    68  
    69  	// NewRevertUpgrade creates an operation to clear the unit's resolved flag,
    70  	// and execute an upgrade to the supplied charm that is careful to excise
    71  	// remnants of a previously failed upgrade to a different charm.
    72  	NewRevertUpgrade(charmURL *corecharm.URL) (Operation, error)
    73  
    74  	// NewResolvedUpgrade creates an operation to clear the unit's resolved flag,
    75  	// and execute an upgrade to the supplied charm that is careful to preserve
    76  	// non-overlapping remnants of a previously failed upgrade to the same charm.
    77  	NewResolvedUpgrade(charmURL *corecharm.URL) (Operation, error)
    78  
    79  	// NewRunHook creates an operation to execute the supplied hook.
    80  	NewRunHook(hookInfo hook.Info) (Operation, error)
    81  
    82  	// NewRetryHook creates an operation to clear the unit's resolved flag, and
    83  	// re-execute the supplied hook.
    84  	NewRetryHook(hookInfo hook.Info) (Operation, error)
    85  
    86  	// NewSkipHook creates an operation to clear the unit's resolved flag, and
    87  	// mark the supplied hook as completed successfully.
    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  	// NewUpdateRelations creates an operation to ensure the supplied relation
    99  	// ids are known and tracked.
   100  	NewUpdateRelations(ids []int) (Operation, error)
   101  }
   102  
   103  // CommandArgs stores the arguments for a Command operation.
   104  type CommandArgs struct {
   105  	// Commands is the arbitrary commands to execute on the unit
   106  	Commands string
   107  	// RelationId is the relation context to execute the commands in.
   108  	RelationId int
   109  	// RemoteUnitName is the remote unit for the relation context.
   110  	RemoteUnitName string
   111  	// ForceRemoteUnit skips unit inference and existence validation.
   112  	ForceRemoteUnit bool
   113  }
   114  
   115  // CommandResponseFunc is for marshalling command responses back to the source
   116  // of the original request.
   117  type CommandResponseFunc func(*utilexec.ExecResponse, error)
   118  
   119  // Callbacks exposes all the uniter code that's required by the various operations.
   120  // It's far from cohesive, and fundamentally represents inappropriate coupling, so
   121  // it's a prime candidate for future refactoring.
   122  type Callbacks interface {
   123  
   124  	// AcquireExecutionLock acquires the machine-level execution lock, and
   125  	// returns a func that must be called to unlock it. It's used by all the
   126  	// operations that execute external code.
   127  	AcquireExecutionLock(message string) (unlock func(), err error)
   128  
   129  	// PrepareHook and CommitHook exist so that we can defer worrying about how
   130  	// to untangle Uniter.relationers from everything else. They're only used by
   131  	// RunHook operations.
   132  	PrepareHook(info hook.Info) (name string, err error)
   133  	CommitHook(info hook.Info) error
   134  
   135  	// UpdateRelations exists so that we can encapsulate it in an operation.
   136  	UpdateRelations(ids []int) error
   137  
   138  	// NotifyHook* exist so that we can defer worrying about how to untangle the
   139  	// callbacks inserted for uniter_test. They're only used by RunHook operations.
   140  	NotifyHookCompleted(string, runner.Context)
   141  	NotifyHookFailed(string, runner.Context)
   142  
   143  	// InitializeMetricsCollector ensures that the collect-metrics hook timer is
   144  	// up to date given the current deployed charm. It's only used in deploy
   145  	// operations.
   146  	InitializeMetricsCollector() error
   147  
   148  	// The following methods exist primarily to allow us to test operation code
   149  	// without using a live api connection.
   150  
   151  	// FailAction marks the supplied action failed. It's only used by
   152  	// RunActions operations.
   153  	FailAction(actionId, message string) error
   154  
   155  	// GetArchiveInfo is used to find out how to download a charm archive. It's
   156  	// only used by Deploy operations.
   157  	GetArchiveInfo(charmURL *corecharm.URL) (charm.BundleInfo, error)
   158  
   159  	// SetCurrentCharm records intent to deploy a given charm. It must be called
   160  	// *before* recording local state referencing that charm, to ensure there's
   161  	// no path by which the state server can legitimately garbage collect that
   162  	// charm or the service's settings for it. It's only used by Deploy operations.
   163  	SetCurrentCharm(charmURL *corecharm.URL) error
   164  
   165  	// ClearResolvedFlag notifies the state server that the uniter has accepted
   166  	// the resolved attempt and is trying to progress. It's only used by Resolved
   167  	// operations (which we generally expect to wrap other operations).
   168  	ClearResolvedFlag() error
   169  }