github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/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/state/multiwatcher" 13 "github.com/juju/juju/watcher" 14 ) 15 16 // New returns a new notify watch handler that will convert the given machine & 17 // agent to a controller. 18 func New(m *machiner.State, agent Agent) watcher.NotifyHandler { 19 return &converter{machiner: wrapper{m}, agent: agent} 20 } 21 22 // converter is a NotifyWatchHandler that converts a unit hosting machine to a 23 // state machine. 24 type converter struct { 25 agent Agent 26 machiner interface { 27 Machine(tag names.MachineTag) (machine, error) 28 } 29 machine machine 30 } 31 32 // Agent is an interface that can have its password set and be told to restart. 33 type Agent interface { 34 Restart() error 35 Tag() names.Tag 36 } 37 38 // machine is a type that has a list of jobs and can be watched. 39 type machine interface { 40 Jobs() (*params.JobsResult, error) 41 Watch() (watcher.NotifyWatcher, error) 42 } 43 44 // wrapper is a wrapper around api/machiner.State to match the (local) machiner 45 // interface. 46 type wrapper struct { 47 m *machiner.State 48 } 49 50 // Machines implements machiner.Machine and returns a machine from the wrapper 51 // api/machiner. 52 func (w wrapper) Machine(tag names.MachineTag) (machine, error) { 53 m, err := w.m.Machine(tag) 54 if err != nil { 55 return nil, err 56 } 57 return m, nil 58 } 59 60 // SetUp implements NotifyWatchHandler's SetUp method. It returns a watcher that 61 // checks for changes to the current machine. 62 func (c *converter) SetUp() (watcher.NotifyWatcher, error) { 63 m, err := c.machiner.Machine(c.agent.Tag().(names.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, we change its 73 // password (to set its password in mongo) and restart the agent. 74 func (c *converter) Handle(_ <-chan struct{}) error { 75 results, err := c.machine.Jobs() 76 if err != nil { 77 return errors.Annotate(err, "can't get jobs for machine") 78 } 79 if !multiwatcher.AnyJobNeedsState(results.Jobs...) { 80 return nil 81 } 82 83 return errors.Trace(c.agent.Restart()) 84 } 85 86 // TearDown implements NotifyWatchHandler's TearDown method. 87 func (c *converter) TearDown() error { 88 return nil 89 }