github.com/juju/juju@v0.0.0-20240327075706-a90865de2538/worker/stateconverter/converter.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package stateconverter 5 6 import ( 7 "fmt" 8 9 "github.com/juju/errors" 10 "github.com/juju/names/v5" 11 12 "github.com/juju/juju/api/agent/machiner" 13 agenterrors "github.com/juju/juju/cmd/jujud/agent/errors" 14 "github.com/juju/juju/core/model" 15 "github.com/juju/juju/core/watcher" 16 ) 17 18 type config struct { 19 machineTag names.MachineTag 20 machiner Machiner 21 logger Logger 22 } 23 24 // NewConverter returns a new notify watch handler that will convert the given machine & 25 // agent to a controller. 26 func NewConverter(cfg config) watcher.NotifyHandler { 27 return &converter{ 28 machiner: cfg.machiner, 29 machineTag: cfg.machineTag, 30 logger: cfg.logger, 31 } 32 } 33 34 // converter is a NotifyWatchHandler that converts a unit hosting machine to a 35 // state machine. 36 type converter struct { 37 machineTag names.MachineTag 38 machiner Machiner 39 machine Machine 40 logger Logger 41 } 42 43 // wrapper is a wrapper around api/machiner.State to match the (local) machiner 44 // interface. 45 type wrapper struct { 46 m *machiner.State 47 } 48 49 // Machine implements machiner.Machine and returns a machine from the wrapper 50 // api/machiner. 51 func (w wrapper) Machine(tag names.MachineTag) (Machine, error) { 52 m, err := w.m.Machine(tag) 53 if err != nil { 54 return nil, err 55 } 56 return m, nil 57 } 58 59 // SetUp implements NotifyWatchHandler's SetUp method. It returns a watcher that 60 // checks for changes to the current machine. 61 func (c *converter) SetUp() (watcher.NotifyWatcher, error) { 62 c.logger.Tracef("Calling SetUp for %s", c.machineTag) 63 m, err := c.machiner.Machine(c.machineTag) 64 if err != nil { 65 return nil, errors.Trace(err) 66 } 67 c.machine = m 68 return m.Watch() 69 } 70 71 // Handle implements NotifyWatchHandler's Handle method. If the change means 72 // that the machine is now expected to manage the environment, 73 // we throw a fatal error to instigate agent restart. 74 func (c *converter) Handle(_ <-chan struct{}) error { 75 c.logger.Tracef("Calling Handle for %s", c.machineTag) 76 results, err := c.machine.Jobs() 77 if err != nil { 78 return errors.Annotate(err, "can't get jobs for machine") 79 } 80 if !model.AnyJobNeedsState(results.Jobs...) { 81 return nil 82 } 83 84 return fmt.Errorf("bounce agent to pick up new jobs%w", errors.Hide(agenterrors.FatalError)) 85 } 86 87 // TearDown implements NotifyWatchHandler's TearDown method. 88 func (c *converter) TearDown() error { 89 return nil 90 }