github.com/mhilton/juju-juju@v0.0.0-20150901100907-a94dd2c73455/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.v5" 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 // NewRetryHook creates an operation to clear the unit's resolved flag, and 87 // re-execute the supplied hook. 88 NewRetryHook(hookInfo hook.Info) (Operation, error) 89 90 // NewSkipHook creates an operation to clear the unit's resolved flag, and 91 // mark the supplied hook as completed successfully. 92 NewSkipHook(hookInfo hook.Info) (Operation, error) 93 94 // NewAction creates an operation to execute the supplied action. 95 NewAction(actionId string) (Operation, error) 96 97 // NewCommands creates an operation to execute the supplied script in the 98 // indicated relation context, and pass the results back over the supplied 99 // func. 100 NewCommands(args CommandArgs, sendResponse CommandResponseFunc) (Operation, error) 101 102 // NewUpdateRelations creates an operation to ensure the supplied relation 103 // ids are known and tracked. 104 NewUpdateRelations(ids []int) (Operation, error) 105 106 // NewUpdateStorage creates an operation to ensure the supplied storage 107 // tags are known and tracked. 108 NewUpdateStorage(tags []names.StorageTag) (Operation, error) 109 110 // NewAcceptLeadership creates an operation to ensure the uniter acts as 111 // service leader. 112 NewAcceptLeadership() (Operation, error) 113 114 // NewResignLeadership creates an operation to ensure the uniter does not 115 // act as service leader. 116 NewResignLeadership() (Operation, error) 117 118 // NewSendMetrics creates an operation that sends all metrics collected 119 // by the unit. 120 NewSendMetrics() (Operation, error) 121 } 122 123 // CommandArgs stores the arguments for a Command operation. 124 type CommandArgs struct { 125 // Commands is the arbitrary commands to execute on the unit 126 Commands string 127 // RelationId is the relation context to execute the commands in. 128 RelationId int 129 // RemoteUnitName is the remote unit for the relation context. 130 RemoteUnitName string 131 // ForceRemoteUnit skips unit inference and existence validation. 132 ForceRemoteUnit bool 133 } 134 135 // CommandResponseFunc is for marshalling command responses back to the source 136 // of the original request. 137 type CommandResponseFunc func(*utilexec.ExecResponse, error) 138 139 // Callbacks exposes all the uniter code that's required by the various operations. 140 // It's far from cohesive, and fundamentally represents inappropriate coupling, so 141 // it's a prime candidate for future refactoring. 142 type Callbacks interface { 143 // PrepareHook and CommitHook exist so that we can defer worrying about how 144 // to untangle Uniter.relationers from everything else. They're only used by 145 // RunHook operations. 146 PrepareHook(info hook.Info) (name string, err error) 147 CommitHook(info hook.Info) error 148 149 // SetExecutingStatus sets the agent state to "Executing" with a message. 150 SetExecutingStatus(string) error 151 152 // UpdateRelations exists so that we can encapsulate it in an operation. 153 UpdateRelations(ids []int) error 154 155 // NotifyHook* exist so that we can defer worrying about how to untangle the 156 // callbacks inserted for uniter_test. They're only used by RunHook operations. 157 NotifyHookCompleted(string, runner.Context) 158 NotifyHookFailed(string, runner.Context) 159 160 // InitializeMetricsTimers ensures that the collect-metrics hook timer is 161 // up to date given the current deployed charm. It's only used in deploy 162 // operations. 163 InitializeMetricsTimers() error 164 165 // The following methods exist primarily to allow us to test operation code 166 // without using a live api connection. 167 168 // FailAction marks the supplied action failed. It's only used by 169 // RunActions operations. 170 FailAction(actionId, message string) error 171 172 // GetArchiveInfo is used to find out how to download a charm archive. It's 173 // only used by Deploy operations. 174 GetArchiveInfo(charmURL *corecharm.URL) (charm.BundleInfo, error) 175 176 // SetCurrentCharm records intent to deploy a given charm. It must be called 177 // *before* recording local state referencing that charm, to ensure there's 178 // no path by which the state server can legitimately garbage collect that 179 // charm or the service's settings for it. It's only used by Deploy operations. 180 SetCurrentCharm(charmURL *corecharm.URL) error 181 182 // ClearResolvedFlag notifies the state server that the uniter has accepted 183 // the resolved attempt and is trying to progress. It's only used by Resolved 184 // operations (which we generally expect to wrap other operations). 185 ClearResolvedFlag() error 186 } 187 188 // StorageUpdater is an interface used for updating local knowledge of storage 189 // attachments. 190 type StorageUpdater interface { 191 // UpdateStorage updates local knowledge of the storage attachments 192 // with the specified tags. 193 UpdateStorage([]names.StorageTag) error 194 }