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  }