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 }