github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/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/api/watcher" 13 "github.com/juju/juju/apiserver/params" 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 var _ worker.NotifyWatchHandler = (*Reboot)(nil) 22 23 // The reboot worker listens for changes to the reboot flag and 24 // exists with worker.ErrRebootMachine if the machine should reboot or 25 // with worker.ErrShutdownMachine if it should shutdown. This will be picked 26 // up by the machine agent as a fatal error and will do the 27 // right thing (reboot or shutdown) 28 type Reboot struct { 29 tomb tomb.Tomb 30 st *reboot.State 31 tag names.MachineTag 32 machineLock *fslock.Lock 33 } 34 35 func NewReboot(st *reboot.State, agentConfig agent.Config, machineLock *fslock.Lock) (worker.Worker, error) { 36 tag, ok := agentConfig.Tag().(names.MachineTag) 37 if !ok { 38 return nil, errors.Errorf("Expected names.MachineTag, got %T: %v", agentConfig.Tag(), agentConfig.Tag()) 39 } 40 r := &Reboot{ 41 st: st, 42 tag: tag, 43 machineLock: machineLock, 44 } 45 return worker.NewNotifyWorker(r), nil 46 } 47 48 func (r *Reboot) checkForRebootState() error { 49 var err 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 err = r.machineLock.BreakLock() 57 if err != nil { 58 return errors.Trace(err) 59 } 60 } 61 return nil 62 } 63 64 func (r *Reboot) SetUp() (watcher.NotifyWatcher, error) { 65 logger.Debugf("Reboot worker setup") 66 err := r.checkForRebootState() 67 if err != nil { 68 return nil, errors.Trace(err) 69 } 70 watcher, err := r.st.WatchForRebootEvent() 71 if err != nil { 72 return nil, errors.Trace(err) 73 } 74 return watcher, nil 75 } 76 77 func (r *Reboot) Handle(_ <-chan struct{}) error { 78 rAction, err := r.st.GetRebootAction() 79 if err != nil { 80 return errors.Trace(err) 81 } 82 logger.Debugf("Reboot worker got action: %v", rAction) 83 switch rAction { 84 case params.ShouldReboot: 85 r.machineLock.Lock(RebootMessage) 86 return worker.ErrRebootMachine 87 case params.ShouldShutdown: 88 r.machineLock.Lock(RebootMessage) 89 return worker.ErrShutdownMachine 90 } 91 return nil 92 } 93 94 func (r *Reboot) TearDown() error { 95 // nothing to teardown. 96 return nil 97 }