github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/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/cmd/jujud/util"
    13  	"github.com/juju/juju/core/watcher"
    14  	"github.com/juju/juju/state/multiwatcher"
    15  )
    16  
    17  // New returns a new notify watch handler that will convert the given machine &
    18  // agent to a controller.
    19  func New(m *machiner.State, agent Agent) watcher.NotifyHandler {
    20  	return &converter{machiner: wrapper{m}, agent: agent}
    21  }
    22  
    23  // converter is a NotifyWatchHandler that converts a unit hosting machine to a
    24  // state machine.
    25  type converter struct {
    26  	agent    Agent
    27  	machiner interface {
    28  		Machine(tag names.MachineTag) (machine, error)
    29  	}
    30  	machine machine
    31  }
    32  
    33  // Agent is an interface that exposes machine agent methods required for the
    34  // conversion worker.
    35  type Agent interface {
    36  	Tag() names.Tag
    37  }
    38  
    39  // machine is a type that has a list of jobs and can be watched.
    40  type machine interface {
    41  	Jobs() (*params.JobsResult, error)
    42  	Watch() (watcher.NotifyWatcher, error)
    43  }
    44  
    45  // wrapper is a wrapper around api/machiner.State to match the (local) machiner
    46  // interface.
    47  type wrapper struct {
    48  	m *machiner.State
    49  }
    50  
    51  // Machines implements machiner.Machine and returns a machine from the wrapper
    52  // api/machiner.
    53  func (w wrapper) Machine(tag names.MachineTag) (machine, error) {
    54  	m, err := w.m.Machine(tag)
    55  	if err != nil {
    56  		return nil, err
    57  	}
    58  	return m, nil
    59  }
    60  
    61  // SetUp implements NotifyWatchHandler's SetUp method. It returns a watcher that
    62  // checks for changes to the current machine.
    63  func (c *converter) SetUp() (watcher.NotifyWatcher, error) {
    64  	m, err := c.machiner.Machine(c.agent.Tag().(names.MachineTag))
    65  	if err != nil {
    66  		return nil, errors.Trace(err)
    67  	}
    68  	c.machine = m
    69  	return m.Watch()
    70  }
    71  
    72  // Handle implements NotifyWatchHandler's Handle method.  If the change means
    73  // that the machine is now expected to manage the environment,
    74  // we throw a fatal error to instigate agent restart.
    75  func (c *converter) Handle(_ <-chan struct{}) error {
    76  	results, err := c.machine.Jobs()
    77  	if err != nil {
    78  		return errors.Annotate(err, "can't get jobs for machine")
    79  	}
    80  	if !multiwatcher.AnyJobNeedsState(results.Jobs...) {
    81  		return nil
    82  	}
    83  
    84  	return &util.FatalError{"bounce agent to pick up new jobs"}
    85  }
    86  
    87  // TearDown implements NotifyWatchHandler's TearDown method.
    88  func (c *converter) TearDown() error {
    89  	return nil
    90  }