github.com/juju/juju@v0.0.0-20240327075706-a90865de2538/worker/containerbroker/manifold.go (about) 1 // Copyright 2019 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package containerbroker 5 6 import ( 7 "github.com/juju/errors" 8 "github.com/juju/worker/v3" 9 "github.com/juju/worker/v3/dependency" 10 11 "github.com/juju/juju/agent" 12 "github.com/juju/juju/api/agent/provisioner" 13 "github.com/juju/juju/api/base" 14 "github.com/juju/juju/container/broker" 15 "github.com/juju/juju/core/machinelock" 16 "github.com/juju/juju/environs" 17 ) 18 19 // ManifoldConfig describes the resources used by a Tracker. 20 type ManifoldConfig struct { 21 AgentName string 22 APICallerName string 23 MachineLock machinelock.Lock 24 NewBrokerFunc func(broker.Config) (environs.InstanceBroker, error) 25 NewTracker func(Config) (worker.Worker, error) 26 } 27 28 // Validate validates the manifold configuration. 29 func (config ManifoldConfig) Validate() error { 30 if config.AgentName == "" { 31 return errors.NotValidf("empty AgentName") 32 } 33 if config.APICallerName == "" { 34 return errors.NotValidf("empty APICallerName") 35 } 36 if config.MachineLock == nil { 37 return errors.NotValidf("nil MachineLock") 38 } 39 if config.NewBrokerFunc == nil { 40 return errors.NotValidf("nil NewBrokerFunc") 41 } 42 if config.NewTracker == nil { 43 return errors.NotValidf("nil NewTracker") 44 } 45 return nil 46 } 47 48 // Manifold returns a Manifold that encapsulates a *Tracker and exposes it as 49 // an Broker resource. 50 func Manifold(config ManifoldConfig) dependency.Manifold { 51 return dependency.Manifold{ 52 Inputs: []string{ 53 config.AgentName, 54 config.APICallerName, 55 }, 56 Output: manifoldOutput, 57 Start: func(context dependency.Context) (worker.Worker, error) { 58 if err := config.Validate(); err != nil { 59 return nil, errors.Trace(err) 60 } 61 62 var agent agent.Agent 63 if err := context.Get(config.AgentName, &agent); err != nil { 64 return nil, errors.Trace(err) 65 } 66 var apiCaller base.APICaller 67 if err := context.Get(config.APICallerName, &apiCaller); err != nil { 68 return nil, errors.Trace(err) 69 } 70 w, err := config.NewTracker(Config{ 71 APICaller: apiCaller, 72 AgentConfig: agent.CurrentConfig(), 73 MachineLock: config.MachineLock, 74 NewBrokerFunc: config.NewBrokerFunc, 75 NewStateFunc: func(apiCaller base.APICaller) State { 76 return provisioner.NewState(apiCaller) 77 }, 78 }) 79 if err != nil { 80 return nil, errors.Trace(err) 81 } 82 return w, nil 83 }, 84 } 85 } 86 87 // manifoldOutput extracts an environs.Environ resource from a *Tracker. 88 func manifoldOutput(in worker.Worker, out interface{}) error { 89 inTracker, ok := in.(*Tracker) 90 if !ok { 91 return errors.Errorf("expected *broker.Tracker, got %T", in) 92 } 93 switch result := out.(type) { 94 case *environs.InstanceBroker: 95 *result = inTracker.Broker() 96 default: 97 return errors.Errorf("expected *environs.InstanceBroker got %T", out) 98 } 99 return nil 100 }