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  }