github.com/juju/juju@v0.0.0-20240327075706-a90865de2538/worker/stateconverter/converter.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package stateconverter
     5  
     6  import (
     7  	"fmt"
     8  
     9  	"github.com/juju/errors"
    10  	"github.com/juju/names/v5"
    11  
    12  	"github.com/juju/juju/api/agent/machiner"
    13  	agenterrors "github.com/juju/juju/cmd/jujud/agent/errors"
    14  	"github.com/juju/juju/core/model"
    15  	"github.com/juju/juju/core/watcher"
    16  )
    17  
    18  type config struct {
    19  	machineTag names.MachineTag
    20  	machiner   Machiner
    21  	logger     Logger
    22  }
    23  
    24  // NewConverter returns a new notify watch handler that will convert the given machine &
    25  // agent to a controller.
    26  func NewConverter(cfg config) watcher.NotifyHandler {
    27  	return &converter{
    28  		machiner:   cfg.machiner,
    29  		machineTag: cfg.machineTag,
    30  		logger:     cfg.logger,
    31  	}
    32  }
    33  
    34  // converter is a NotifyWatchHandler that converts a unit hosting machine to a
    35  // state machine.
    36  type converter struct {
    37  	machineTag names.MachineTag
    38  	machiner   Machiner
    39  	machine    Machine
    40  	logger     Logger
    41  }
    42  
    43  // wrapper is a wrapper around api/machiner.State to match the (local) machiner
    44  // interface.
    45  type wrapper struct {
    46  	m *machiner.State
    47  }
    48  
    49  // Machine implements machiner.Machine and returns a machine from the wrapper
    50  // api/machiner.
    51  func (w wrapper) Machine(tag names.MachineTag) (Machine, error) {
    52  	m, err := w.m.Machine(tag)
    53  	if err != nil {
    54  		return nil, err
    55  	}
    56  	return m, nil
    57  }
    58  
    59  // SetUp implements NotifyWatchHandler's SetUp method. It returns a watcher that
    60  // checks for changes to the current machine.
    61  func (c *converter) SetUp() (watcher.NotifyWatcher, error) {
    62  	c.logger.Tracef("Calling SetUp for %s", c.machineTag)
    63  	m, err := c.machiner.Machine(c.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,
    73  // we throw a fatal error to instigate agent restart.
    74  func (c *converter) Handle(_ <-chan struct{}) error {
    75  	c.logger.Tracef("Calling Handle for %s", c.machineTag)
    76  	results, err := c.machine.Jobs()
    77  	if err != nil {
    78  		return errors.Annotate(err, "can't get jobs for machine")
    79  	}
    80  	if !model.AnyJobNeedsState(results.Jobs...) {
    81  		return nil
    82  	}
    83  
    84  	return fmt.Errorf("bounce agent to pick up new jobs%w", errors.Hide(agenterrors.FatalError))
    85  }
    86  
    87  // TearDown implements NotifyWatchHandler's TearDown method.
    88  func (c *converter) TearDown() error {
    89  	return nil
    90  }