github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/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  	"github.com/juju/loggo"
     9  	"github.com/juju/names"
    10  
    11  	apimachiner "github.com/juju/juju/api/machiner"
    12  	"github.com/juju/juju/api/watcher"
    13  	"github.com/juju/juju/apiserver/params"
    14  	"github.com/juju/juju/state/multiwatcher"
    15  	"github.com/juju/juju/worker"
    16  )
    17  
    18  var logger = loggo.GetLogger("juju.worker.conv2state")
    19  
    20  // New returns a new notify watch handler that will convert the given machine &
    21  // agent to a state server.
    22  func New(m *apimachiner.State, agent Agent) worker.NotifyWatchHandler {
    23  	return &converter{machiner: wrapper{m}, agent: agent}
    24  }
    25  
    26  // converter is a NotifyWatchHandler that converts a unit hosting machine to a
    27  // state machine.
    28  type converter struct {
    29  	agent    Agent
    30  	machiner machiner
    31  	machine  machine
    32  }
    33  
    34  // Agent is an interface that can have its password set and be told to restart.
    35  type Agent interface {
    36  	Restart() error
    37  	Tag() names.Tag
    38  }
    39  
    40  // machiner is a type that creates machines from a tag.
    41  type machiner interface {
    42  	Machine(tag names.MachineTag) (machine, error)
    43  }
    44  
    45  // machine is a type that has a list of jobs and can be watched.
    46  type machine interface {
    47  	Jobs() (*params.JobsResult, error)
    48  	Watch() (watcher.NotifyWatcher, error)
    49  }
    50  
    51  // wrapper is a wrapper around api/machiner.State to match the (local) machiner
    52  // interface.
    53  type wrapper struct {
    54  	m *apimachiner.State
    55  }
    56  
    57  // Machines implements machiner.Machine and returns a machine from the wrapper
    58  // api/machiner.
    59  func (w wrapper) Machine(tag names.MachineTag) (machine, error) {
    60  	m, err := w.m.Machine(tag)
    61  	if err != nil {
    62  		return nil, err
    63  	}
    64  	return m, nil
    65  }
    66  
    67  // SetUp implements NotifyWatchHandler's SetUp method. It returns a watcher that
    68  // checks for changes to the current machine.
    69  func (c *converter) SetUp() (watcher.NotifyWatcher, error) {
    70  	m, err := c.machiner.Machine(c.agent.Tag().(names.MachineTag))
    71  	if err != nil {
    72  		return nil, errors.Trace(err)
    73  	}
    74  	c.machine = m
    75  	return m.Watch()
    76  }
    77  
    78  // Handle implements NotifyWatchHandler's Handle method.  If the change means
    79  // that the machine is now expected to manage the environment, we change its
    80  // password (to set its password in mongo) and restart the agent.
    81  func (c *converter) Handle(_ <-chan struct{}) error {
    82  	results, err := c.machine.Jobs()
    83  	if err != nil {
    84  		return errors.Annotate(err, "can't get jobs for machine")
    85  	}
    86  	if !multiwatcher.AnyJobNeedsState(results.Jobs...) {
    87  		return nil
    88  	}
    89  
    90  	return errors.Trace(c.agent.Restart())
    91  }
    92  
    93  // TearDown implements NotifyWatchHandler's TearDown method.
    94  func (c *converter) TearDown() error {
    95  	return nil
    96  }