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