github.com/juju/juju@v0.0.0-20240327075706-a90865de2538/worker/upgrader/manifold.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package upgrader 5 6 import ( 7 "time" 8 9 "github.com/juju/errors" 10 "github.com/juju/version/v2" 11 "github.com/juju/worker/v3" 12 "github.com/juju/worker/v3/dependency" 13 14 "github.com/juju/juju/agent" 15 "github.com/juju/juju/api/agent/upgrader" 16 "github.com/juju/juju/api/base" 17 "github.com/juju/juju/upgrades" 18 "github.com/juju/juju/worker/gate" 19 ) 20 21 // Clock represents the clock methods this worker uses. 22 type Clock interface { 23 After(time.Duration) <-chan time.Time 24 } 25 26 // Logger represents the logging methods used by this package. 27 type Logger interface { 28 Debugf(string, ...interface{}) 29 Infof(string, ...interface{}) 30 Errorf(string, ...interface{}) 31 } 32 33 // ManifoldConfig defines the names of the manifolds on which a 34 // Manifold will depend. 35 type ManifoldConfig struct { 36 AgentName string 37 APICallerName string 38 UpgradeStepsGateName string 39 UpgradeCheckGateName string 40 PreviousAgentVersion version.Number 41 Logger Logger 42 Clock Clock 43 } 44 45 // Manifold returns a dependency manifold that runs an upgrader 46 // worker, using the resource names defined in the supplied config. 47 func Manifold(config ManifoldConfig) dependency.Manifold { 48 inputs := []string{ 49 config.AgentName, 50 config.APICallerName, 51 } 52 // The machine agent uses these but the unit agent doesn't. 53 if config.UpgradeStepsGateName != "" { 54 inputs = append(inputs, config.UpgradeStepsGateName) 55 } 56 if config.UpgradeCheckGateName != "" { 57 inputs = append(inputs, config.UpgradeCheckGateName) 58 } 59 60 return dependency.Manifold{ 61 Inputs: inputs, 62 Start: func(context dependency.Context) (worker.Worker, error) { 63 64 var agent agent.Agent 65 if err := context.Get(config.AgentName, &agent); err != nil { 66 return nil, err 67 } 68 currentConfig := agent.CurrentConfig() 69 70 var apiCaller base.APICaller 71 if err := context.Get(config.APICallerName, &apiCaller); err != nil { 72 return nil, err 73 } 74 upgraderFacade := upgrader.NewState(apiCaller) 75 76 // If there is no UpgradeStepsGateName, the worker should 77 // report the running version and exit. 78 var upgradeStepsWaiter gate.Waiter 79 if config.UpgradeStepsGateName != "" { 80 if config.PreviousAgentVersion == version.Zero { 81 return nil, errors.New("previous agent version not specified") 82 } 83 if err := context.Get(config.UpgradeStepsGateName, &upgradeStepsWaiter); err != nil { 84 return nil, err 85 } 86 } 87 88 var initialCheckUnlocker gate.Unlocker 89 if config.UpgradeCheckGateName != "" { 90 if err := context.Get(config.UpgradeCheckGateName, &initialCheckUnlocker); err != nil { 91 return nil, err 92 } 93 } 94 95 return NewAgentUpgrader(Config{ 96 Clock: config.Clock, 97 Logger: config.Logger, 98 State: upgraderFacade, 99 AgentConfig: currentConfig, 100 OrigAgentVersion: config.PreviousAgentVersion, 101 UpgradeStepsWaiter: upgradeStepsWaiter, 102 InitialUpgradeCheckComplete: initialCheckUnlocker, 103 CheckDiskSpace: upgrades.CheckFreeDiskSpace, 104 }) 105 }, 106 } 107 }