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 }