github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/worker/reboot/reboot.go (about) 1 package reboot 2 3 import ( 4 "github.com/juju/errors" 5 "github.com/juju/loggo" 6 "github.com/juju/names" 7 "github.com/juju/utils/fslock" 8 "launchpad.net/tomb" 9 10 "github.com/juju/juju/agent" 11 "github.com/juju/juju/api/reboot" 12 "github.com/juju/juju/apiserver/params" 13 "github.com/juju/juju/watcher" 14 "github.com/juju/juju/worker" 15 ) 16 17 var logger = loggo.GetLogger("juju.worker.reboot") 18 19 const RebootMessage = "preparing for reboot" 20 21 // The reboot worker listens for changes to the reboot flag and 22 // exists with worker.ErrRebootMachine if the machine should reboot or 23 // with worker.ErrShutdownMachine if it should shutdown. This will be picked 24 // up by the machine agent as a fatal error and will do the 25 // right thing (reboot or shutdown) 26 type Reboot struct { 27 tomb tomb.Tomb 28 st reboot.State 29 tag names.MachineTag 30 machineLock *fslock.Lock 31 } 32 33 func NewReboot(st reboot.State, agentConfig agent.Config, machineLock *fslock.Lock) (worker.Worker, error) { 34 tag, ok := agentConfig.Tag().(names.MachineTag) 35 if !ok { 36 return nil, errors.Errorf("Expected names.MachineTag, got %T: %v", agentConfig.Tag(), agentConfig.Tag()) 37 } 38 r := &Reboot{ 39 st: st, 40 tag: tag, 41 machineLock: machineLock, 42 } 43 w, err := watcher.NewNotifyWorker(watcher.NotifyConfig{ 44 Handler: r, 45 }) 46 return w, errors.Trace(err) 47 } 48 49 func (r *Reboot) checkForRebootState() error { 50 if r.machineLock.IsLocked() == false { 51 return nil 52 } 53 54 if r.machineLock.Message() == RebootMessage { 55 // Not a lock held by the machne agent in order to reboot 56 if err := r.machineLock.BreakLock(); err != nil { 57 return errors.Trace(err) 58 } 59 } 60 return nil 61 } 62 63 func (r *Reboot) SetUp() (watcher.NotifyWatcher, error) { 64 if err := r.checkForRebootState(); err != nil { 65 return nil, errors.Trace(err) 66 } 67 watcher, err := r.st.WatchForRebootEvent() 68 return watcher, errors.Trace(err) 69 } 70 71 func (r *Reboot) Handle(_ <-chan struct{}) error { 72 rAction, err := r.st.GetRebootAction() 73 if err != nil { 74 return errors.Trace(err) 75 } 76 logger.Debugf("Reboot worker got action: %v", rAction) 77 switch rAction { 78 case params.ShouldReboot: 79 r.machineLock.Lock(RebootMessage) 80 return worker.ErrRebootMachine 81 case params.ShouldShutdown: 82 r.machineLock.Lock(RebootMessage) 83 return worker.ErrShutdownMachine 84 } 85 return nil 86 } 87 88 func (r *Reboot) TearDown() error { 89 // nothing to teardown. 90 return nil 91 }