github.com/juju/juju@v0.0.0-20240327075706-a90865de2538/worker/peergrouper/manifold.go (about) 1 // Copyright 2017 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package peergrouper 5 6 import ( 7 "github.com/juju/clock" 8 "github.com/juju/errors" 9 "github.com/juju/worker/v3" 10 "github.com/juju/worker/v3/dependency" 11 "github.com/prometheus/client_golang/prometheus" 12 13 "github.com/juju/juju/agent" 14 "github.com/juju/juju/state" 15 "github.com/juju/juju/worker/common" 16 workerstate "github.com/juju/juju/worker/state" 17 ) 18 19 // ManifoldConfig holds the information necessary to run a peergrouper 20 // in a dependency.Engine. 21 type ManifoldConfig struct { 22 AgentName string 23 ClockName string 24 ControllerPortName string 25 StateName string 26 Hub Hub 27 28 PrometheusRegisterer prometheus.Registerer 29 NewWorker func(Config) (worker.Worker, error) 30 } 31 32 // Validate validates the manifold configuration. 33 func (config ManifoldConfig) Validate() error { 34 if config.AgentName == "" { 35 return errors.NotValidf("empty AgentName") 36 } 37 if config.ClockName == "" { 38 return errors.NotValidf("empty ClockName") 39 } 40 if config.ControllerPortName == "" { 41 return errors.NotValidf("empty ControllerPortName") 42 } 43 if config.StateName == "" { 44 return errors.NotValidf("empty StateName") 45 } 46 if config.Hub == nil { 47 return errors.NotValidf("nil Hub") 48 } 49 if config.PrometheusRegisterer == nil { 50 return errors.NotValidf("nil PrometheusRegisterer") 51 } 52 if config.NewWorker == nil { 53 return errors.NotValidf("nil NewWorker") 54 } 55 return nil 56 } 57 58 // Manifold returns a dependency.Manifold that will run a peergrouper. 59 func Manifold(config ManifoldConfig) dependency.Manifold { 60 return dependency.Manifold{ 61 Inputs: []string{ 62 config.AgentName, 63 config.ClockName, 64 config.ControllerPortName, 65 config.StateName, 66 }, 67 Start: config.start, 68 } 69 } 70 71 // start is a method on ManifoldConfig because it's more readable than a closure. 72 func (config ManifoldConfig) start(context dependency.Context) (worker.Worker, error) { 73 if err := config.Validate(); err != nil { 74 return nil, errors.Trace(err) 75 } 76 77 var agent agent.Agent 78 if err := context.Get(config.AgentName, &agent); err != nil { 79 return nil, errors.Trace(err) 80 } 81 82 var clock clock.Clock 83 if err := context.Get(config.ClockName, &clock); err != nil { 84 return nil, errors.Trace(err) 85 } 86 87 // Ensure that the controller-port worker is running. 88 if err := context.Get(config.ControllerPortName, nil); err != nil { 89 return nil, errors.Trace(err) 90 } 91 92 var stTracker workerstate.StateTracker 93 if err := context.Get(config.StateName, &stTracker); err != nil { 94 return nil, errors.Trace(err) 95 } 96 statePool, err := stTracker.Use() 97 if err != nil { 98 return nil, errors.Trace(err) 99 } 100 101 st, err := statePool.SystemState() 102 if err != nil { 103 return nil, errors.Trace(err) 104 } 105 mongoSession := st.MongoSession() 106 agentConfig := agent.CurrentConfig() 107 stateServingInfo, ok := agentConfig.StateServingInfo() 108 if !ok { 109 _ = stTracker.Done() 110 return nil, errors.New("state serving info missing from agent config") 111 } 112 model, err := st.Model() 113 if err != nil { 114 _ = stTracker.Done() 115 return nil, errors.Trace(err) 116 } 117 supportsHA := model.Type() != state.ModelTypeCAAS 118 119 w, err := config.NewWorker(Config{ 120 State: StateShim{st}, 121 MongoSession: MongoSessionShim{mongoSession}, 122 APIHostPortsSetter: &CachingAPIHostPortsSetter{APIHostPortsSetter: st}, 123 Clock: clock, 124 Hub: config.Hub, 125 MongoPort: stateServingInfo.StatePort, 126 APIPort: stateServingInfo.APIPort, 127 ControllerAPIPort: stateServingInfo.ControllerAPIPort, 128 SupportsHA: supportsHA, 129 PrometheusRegisterer: config.PrometheusRegisterer, 130 // On machine models, the controller id is the same as the machine/agent id. 131 // TODO(wallyworld) - revisit when we add HA to k8s. 132 ControllerId: agentConfig.Tag().Id, 133 }) 134 if err != nil { 135 _ = stTracker.Done() 136 return nil, errors.Trace(err) 137 } 138 return common.NewCleanupWorker(w, func() { _ = stTracker.Done() }), nil 139 }