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