github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/worker/uniter/operation/factory.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/errors" 8 corecharm "gopkg.in/juju/charm.v6" 9 "gopkg.in/juju/names.v2" 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 // FactoryParams holds all the necessary parameters for a new operation factory. 17 type FactoryParams struct { 18 Deployer charm.Deployer 19 RunnerFactory runner.Factory 20 Callbacks Callbacks 21 Abort <-chan struct{} 22 MetricSpoolDir string 23 } 24 25 // NewFactory returns a Factory that creates Operations backed by the supplied 26 // parameters. 27 func NewFactory(params FactoryParams) Factory { 28 return &factory{ 29 config: params, 30 } 31 } 32 33 type factory struct { 34 config FactoryParams 35 } 36 37 // newDeploy is the common code for creating arbitrary deploy operations. 38 func (f *factory) newDeploy(kind Kind, charmURL *corecharm.URL, revert, resolved bool) (Operation, error) { 39 if charmURL == nil { 40 return nil, errors.New("charm url required") 41 } else if kind != Install && kind != Upgrade { 42 return nil, errors.Errorf("unknown deploy kind: %s", kind) 43 } 44 return &deploy{ 45 kind: kind, 46 charmURL: charmURL, 47 revert: revert, 48 resolved: resolved, 49 callbacks: f.config.Callbacks, 50 deployer: f.config.Deployer, 51 abort: f.config.Abort, 52 }, nil 53 } 54 55 // NewInstall is part of the Factory interface. 56 func (f *factory) NewInstall(charmURL *corecharm.URL) (Operation, error) { 57 return f.newDeploy(Install, charmURL, false, false) 58 } 59 60 // NewUpgrade is part of the Factory interface. 61 func (f *factory) NewUpgrade(charmURL *corecharm.URL) (Operation, error) { 62 return f.newDeploy(Upgrade, charmURL, false, false) 63 } 64 65 // NewNoOpUpgrade is part of the Factory interface. 66 func (f *factory) NewNoOpUpgrade(charmURL *corecharm.URL) (Operation, error) { 67 return &skipOperation{&noOpUpgrade{charmURL: charmURL}}, nil 68 } 69 70 func (f *factory) NewNoOpFinishUpgradeSeries() (Operation, error) { 71 return &noOpFinishUpgradeSeries{&skipOperation{}}, nil 72 } 73 74 func (f *factory) NewFinishUpgradeCharmProfile(charmURL *corecharm.URL) (Operation, error) { 75 return &finishUpgradeCharmProfile{ 76 kind: Upgrade, 77 charmURL: charmURL, 78 callbacks: f.config.Callbacks, 79 }, nil 80 } 81 82 // NewRevertUpgrade is part of the Factory interface. 83 func (f *factory) NewRevertUpgrade(charmURL *corecharm.URL) (Operation, error) { 84 return f.newDeploy(Upgrade, charmURL, true, false) 85 } 86 87 // NewResolvedUpgrade is part of the Factory interface. 88 func (f *factory) NewResolvedUpgrade(charmURL *corecharm.URL) (Operation, error) { 89 return f.newDeploy(Upgrade, charmURL, false, true) 90 } 91 92 // NewRunHook is part of the Factory interface. 93 func (f *factory) NewRunHook(hookInfo hook.Info) (Operation, error) { 94 if err := hookInfo.Validate(); err != nil { 95 return nil, err 96 } 97 return &runHook{ 98 info: hookInfo, 99 callbacks: f.config.Callbacks, 100 runnerFactory: f.config.RunnerFactory, 101 }, nil 102 } 103 104 // NewSkipHook is part of the Factory interface. 105 func (f *factory) NewSkipHook(hookInfo hook.Info) (Operation, error) { 106 hookOp, err := f.NewRunHook(hookInfo) 107 if err != nil { 108 return nil, err 109 } 110 return &skipOperation{hookOp}, nil 111 } 112 113 // NewAction is part of the Factory interface. 114 func (f *factory) NewAction(actionId string) (Operation, error) { 115 if !names.IsValidAction(actionId) { 116 return nil, errors.Errorf("invalid action id %q", actionId) 117 } 118 return &runAction{ 119 actionId: actionId, 120 callbacks: f.config.Callbacks, 121 runnerFactory: f.config.RunnerFactory, 122 }, nil 123 } 124 125 // NewFailAction is part of the factory interface. 126 func (f *factory) NewFailAction(actionId string) (Operation, error) { 127 if !names.IsValidAction(actionId) { 128 return nil, errors.Errorf("invalid action id %q", actionId) 129 } 130 return &failAction{ 131 actionId: actionId, 132 callbacks: f.config.Callbacks, 133 }, nil 134 } 135 136 // NewCommands is part of the Factory interface. 137 func (f *factory) NewCommands(args CommandArgs, sendResponse CommandResponseFunc) (Operation, error) { 138 if args.Commands == "" { 139 return nil, errors.New("commands required") 140 } else if sendResponse == nil { 141 return nil, errors.New("response sender required") 142 } 143 if args.RemoteUnitName != "" { 144 if args.RelationId == -1 { 145 return nil, errors.New("remote unit not valid without relation") 146 } else if !names.IsValidUnit(args.RemoteUnitName) { 147 return nil, errors.Errorf("invalid remote unit name %q", args.RemoteUnitName) 148 } 149 } 150 return &runCommands{ 151 args: args, 152 sendResponse: sendResponse, 153 callbacks: f.config.Callbacks, 154 runnerFactory: f.config.RunnerFactory, 155 }, nil 156 } 157 158 // NewResignLeadership is part of the Factory interface. 159 func (f *factory) NewResignLeadership() (Operation, error) { 160 return &resignLeadership{}, nil 161 } 162 163 // NewAcceptLeadership is part of the Factory interface. 164 func (f *factory) NewAcceptLeadership() (Operation, error) { 165 return &acceptLeadership{}, nil 166 }