github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/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-unstable" 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 // NewRevertUpgrade is part of the Factory interface. 66 func (f *factory) NewRevertUpgrade(charmURL *corecharm.URL) (Operation, error) { 67 return f.newDeploy(Upgrade, charmURL, true, false) 68 } 69 70 // NewResolvedUpgrade is part of the Factory interface. 71 func (f *factory) NewResolvedUpgrade(charmURL *corecharm.URL) (Operation, error) { 72 return f.newDeploy(Upgrade, charmURL, false, true) 73 } 74 75 // NewRunHook is part of the Factory interface. 76 func (f *factory) NewRunHook(hookInfo hook.Info) (Operation, error) { 77 if err := hookInfo.Validate(); err != nil { 78 return nil, err 79 } 80 return &runHook{ 81 info: hookInfo, 82 callbacks: f.config.Callbacks, 83 runnerFactory: f.config.RunnerFactory, 84 }, nil 85 } 86 87 // NewSkipHook is part of the Factory interface. 88 func (f *factory) NewSkipHook(hookInfo hook.Info) (Operation, error) { 89 hookOp, err := f.NewRunHook(hookInfo) 90 if err != nil { 91 return nil, err 92 } 93 return &skipOperation{hookOp}, nil 94 } 95 96 // NewAction is part of the Factory interface. 97 func (f *factory) NewAction(actionId string) (Operation, error) { 98 if !names.IsValidAction(actionId) { 99 return nil, errors.Errorf("invalid action id %q", actionId) 100 } 101 return &runAction{ 102 actionId: actionId, 103 callbacks: f.config.Callbacks, 104 runnerFactory: f.config.RunnerFactory, 105 }, nil 106 } 107 108 // NewFailAction is part of the factory interface. 109 func (f *factory) NewFailAction(actionId string) (Operation, error) { 110 if !names.IsValidAction(actionId) { 111 return nil, errors.Errorf("invalid action id %q", actionId) 112 } 113 return &failAction{ 114 actionId: actionId, 115 callbacks: f.config.Callbacks, 116 }, nil 117 } 118 119 // NewCommands is part of the Factory interface. 120 func (f *factory) NewCommands(args CommandArgs, sendResponse CommandResponseFunc) (Operation, error) { 121 if args.Commands == "" { 122 return nil, errors.New("commands required") 123 } else if sendResponse == nil { 124 return nil, errors.New("response sender required") 125 } 126 if args.RemoteUnitName != "" { 127 if args.RelationId == -1 { 128 return nil, errors.New("remote unit not valid without relation") 129 } else if !names.IsValidUnit(args.RemoteUnitName) { 130 return nil, errors.Errorf("invalid remote unit name %q", args.RemoteUnitName) 131 } 132 } 133 return &runCommands{ 134 args: args, 135 sendResponse: sendResponse, 136 callbacks: f.config.Callbacks, 137 runnerFactory: f.config.RunnerFactory, 138 }, nil 139 } 140 141 // NewResignLeadership is part of the Factory interface. 142 func (f *factory) NewResignLeadership() (Operation, error) { 143 return &resignLeadership{}, nil 144 } 145 146 // NewAcceptLeadership is part of the Factory interface. 147 func (f *factory) NewAcceptLeadership() (Operation, error) { 148 return &acceptLeadership{}, nil 149 }