github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/worker/machiner/manifold.go (about)

     1  // Copyright 2016 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package machiner
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  	"gopkg.in/juju/names.v2"
     9  	"gopkg.in/juju/worker.v1"
    10  	"gopkg.in/juju/worker.v1/dependency"
    11  
    12  	"github.com/juju/juju/agent"
    13  	apiagent "github.com/juju/juju/api/agent"
    14  	"github.com/juju/juju/api/base"
    15  	apimachiner "github.com/juju/juju/api/machiner"
    16  )
    17  
    18  // ManifoldConfig defines the names of the manifolds on which a
    19  // Manifold will depend.
    20  type ManifoldConfig struct {
    21  	AgentName         string
    22  	APICallerName     string
    23  	FanConfigurerName string
    24  }
    25  
    26  // Manifold returns a dependency manifold that runs a machiner worker, using
    27  // the resource names defined in the supplied config.
    28  func Manifold(config ManifoldConfig) dependency.Manifold {
    29  	return dependency.Manifold{
    30  		Inputs: []string{
    31  			config.AgentName,
    32  			config.APICallerName,
    33  			config.FanConfigurerName,
    34  		},
    35  		Start: func(context dependency.Context) (worker.Worker, error) {
    36  			var agent agent.Agent
    37  			if err := context.Get(config.AgentName, &agent); err != nil {
    38  				return nil, err
    39  			}
    40  			var apiCaller base.APICaller
    41  			if err := context.Get(config.APICallerName, &apiCaller); err != nil {
    42  				return nil, err
    43  			}
    44  			var fanConfigurerReady bool
    45  			if err := context.Get(config.FanConfigurerName, &fanConfigurerReady); err != nil {
    46  				return nil, err
    47  			}
    48  			if !fanConfigurerReady {
    49  				return nil, dependency.ErrMissing
    50  			}
    51  			return newWorker(agent, apiCaller)
    52  		},
    53  	}
    54  }
    55  
    56  // newWorker non-trivially wraps NewMachiner to specialise a engine.AgentAPIManifold.
    57  //
    58  // TODO(waigani) This function is currently covered by functional tests
    59  // under the machine agent. Add unit tests once infrastructure to do so is
    60  // in place.
    61  func newWorker(a agent.Agent, apiCaller base.APICaller) (worker.Worker, error) {
    62  	currentConfig := a.CurrentConfig()
    63  
    64  	// TODO(fwereade): this functionality should be on the
    65  	// machiner facade instead -- or, better yet, separate
    66  	// the networking concerns from the lifecycle ones and
    67  	// have completely separate workers.
    68  	//
    69  	// (With their own facades.)
    70  	agentFacade, err := apiagent.NewState(apiCaller)
    71  	if err != nil {
    72  		return nil, errors.Trace(err)
    73  	}
    74  	modelConfig, err := agentFacade.ModelConfig()
    75  	if err != nil {
    76  		return nil, errors.Errorf("cannot read environment config: %v", err)
    77  	}
    78  
    79  	ignoreMachineAddresses, _ := modelConfig.IgnoreMachineAddresses()
    80  	// Containers only have machine addresses, so we can't ignore them.
    81  	tag := currentConfig.Tag()
    82  	if names.IsContainerMachine(tag.Id()) {
    83  		ignoreMachineAddresses = false
    84  	}
    85  	if ignoreMachineAddresses {
    86  		logger.Infof("machine addresses not used, only addresses from provider")
    87  	}
    88  	accessor := APIMachineAccessor{apimachiner.NewState(apiCaller)}
    89  	w, err := NewMachiner(Config{
    90  		MachineAccessor:              accessor,
    91  		Tag:                          tag.(names.MachineTag),
    92  		ClearMachineAddressesOnStart: ignoreMachineAddresses,
    93  		NotifyMachineDead: func() error {
    94  			return agent.SetCanUninstall(a)
    95  		},
    96  	})
    97  	if err != nil {
    98  		return nil, errors.Annotate(err, "cannot start machiner worker")
    99  	}
   100  	return w, err
   101  }