github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/worker/modelupgrader/manifold.go (about) 1 // Copyright 2017 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package modelupgrader 5 6 import ( 7 "github.com/juju/errors" 8 "gopkg.in/juju/names.v2" 9 "gopkg.in/juju/worker.v1" 10 "gopkg.in/juju/worker.v1/dependency" 11 12 "github.com/juju/juju/api/base" 13 "github.com/juju/juju/environs" 14 "github.com/juju/juju/worker/common" 15 "github.com/juju/juju/worker/gate" 16 ) 17 18 // ManifoldConfig describes how to configure and construct a Worker, 19 // and what registered resources it may depend upon. 20 type ManifoldConfig struct { 21 APICallerName string 22 EnvironName string 23 GateName string 24 ControllerTag names.ControllerTag 25 ModelTag names.ModelTag 26 27 NewFacade func(base.APICaller) (Facade, error) 28 NewWorker func(Config) (worker.Worker, error) 29 NewCredentialValidatorFacade func(base.APICaller) (common.CredentialAPI, error) 30 } 31 32 func (config ManifoldConfig) start(context dependency.Context) (worker.Worker, error) { 33 34 var environ environs.Environ 35 if err := context.Get(config.EnvironName, &environ); err != nil { 36 if errors.Cause(err) != dependency.ErrMissing { 37 return nil, errors.Trace(err) 38 } 39 // Only the controller's leader is given an Environ; the 40 // other controller units will watch the model and wait 41 // for its environ version to be updated. 42 environ = nil 43 } 44 45 var apiCaller base.APICaller 46 if err := context.Get(config.APICallerName, &apiCaller); err != nil { 47 return nil, errors.Trace(err) 48 } 49 50 var gate gate.Unlocker 51 if err := context.Get(config.GateName, &gate); err != nil { 52 return nil, errors.Trace(err) 53 } 54 55 facade, err := config.NewFacade(apiCaller) 56 if err != nil { 57 return nil, errors.Trace(err) 58 } 59 60 credentialAPI, err := config.NewCredentialValidatorFacade(apiCaller) 61 if err != nil { 62 return nil, errors.Trace(err) 63 } 64 65 worker, err := config.NewWorker(Config{ 66 Facade: facade, 67 Environ: environ, 68 GateUnlocker: gate, 69 ControllerTag: config.ControllerTag, 70 ModelTag: config.ModelTag, 71 CredentialAPI: credentialAPI, 72 }) 73 if err != nil { 74 return nil, errors.Trace(err) 75 } 76 return worker, nil 77 } 78 79 // Manifold returns a dependency.Manifold that will run a Worker as 80 // configured. 81 func Manifold(config ManifoldConfig) dependency.Manifold { 82 return dependency.Manifold{ 83 Inputs: []string{ 84 config.APICallerName, 85 config.EnvironName, 86 config.GateName, 87 }, 88 Start: config.start, 89 Filter: bounceErrChanged, 90 } 91 } 92 93 // bounceErrChanged converts ErrModelRemoved to dependency.ErrUninstall. 94 func bounceErrChanged(err error) error { 95 if errors.Cause(err) == ErrModelRemoved { 96 return dependency.ErrUninstall 97 } 98 return err 99 }