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  }