github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/worker/deployer/manifold.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package deployer 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/agent" 13 apiagent "github.com/juju/juju/api/agent" 14 "github.com/juju/juju/api/base" 15 apideployer "github.com/juju/juju/api/deployer" 16 "github.com/juju/juju/cmd/jujud/agent/engine" 17 "github.com/juju/juju/state/multiwatcher" 18 ) 19 20 // ManifoldConfig defines the names of the manifolds on which a Manifold will depend. 21 type ManifoldConfig struct { 22 AgentName string 23 APICallerName string 24 NewDeployContext func(st *apideployer.State, agentConfig agent.Config) Context 25 } 26 27 // Manifold returns a dependency manifold that runs a deployer worker, 28 // using the resource names defined in the supplied config. 29 func Manifold(config ManifoldConfig) dependency.Manifold { 30 typedConfig := engine.AgentAPIManifoldConfig{ 31 AgentName: config.AgentName, 32 APICallerName: config.APICallerName, 33 } 34 return engine.AgentAPIManifold(typedConfig, config.newWorker) 35 } 36 37 // newWorker trivially wraps NewDeployer for use in a engine.AgentAPIManifold. 38 // 39 // It's not tested at the moment, because the scaffolding 40 // necessary is too unwieldy/distracting to introduce at this point. 41 func (config ManifoldConfig) newWorker(a agent.Agent, apiCaller base.APICaller) (worker.Worker, error) { 42 cfg := a.CurrentConfig() 43 // Grab the tag and ensure that it's for a machine. 44 tag, ok := cfg.Tag().(names.MachineTag) 45 if !ok { 46 return nil, errors.New("agent's tag is not a machine tag") 47 } 48 49 // Get the machine agent's jobs. 50 // TODO(fwereade): this functionality should be on the 51 // deployer facade instead. 52 agentFacade, err := apiagent.NewState(apiCaller) 53 if err != nil { 54 return nil, errors.Trace(err) 55 } 56 entity, err := agentFacade.Entity(tag) 57 if err != nil { 58 return nil, errors.Trace(err) 59 } 60 61 var isUnitHoster bool 62 for _, job := range entity.Jobs() { 63 if job == multiwatcher.JobHostUnits { 64 isUnitHoster = true 65 break 66 } 67 } 68 69 if !isUnitHoster { 70 return nil, dependency.ErrUninstall 71 } 72 73 deployerFacade := apideployer.NewState(apiCaller) 74 context := config.NewDeployContext(deployerFacade, cfg) 75 w, err := NewDeployer(deployerFacade, context) 76 if err != nil { 77 return nil, errors.Annotate(err, "cannot start unit agent deployer worker") 78 } 79 return w, nil 80 }