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

     1  // Copyright 2017 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package modelupgrader
     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/api/base"
    13  	"github.com/juju/juju/environs"
    14  	"github.com/juju/juju/worker/common"
    15  	"github.com/juju/juju/worker/gate"
    16  )
    17  
    18  // ManifoldConfig describes how to configure and construct a Worker,
    19  // and what registered resources it may depend upon.
    20  type ManifoldConfig struct {
    21  	APICallerName string
    22  	EnvironName   string
    23  	GateName      string
    24  	ControllerTag names.ControllerTag
    25  	ModelTag      names.ModelTag
    26  
    27  	NewFacade                    func(base.APICaller) (Facade, error)
    28  	NewWorker                    func(Config) (worker.Worker, error)
    29  	NewCredentialValidatorFacade func(base.APICaller) (common.CredentialAPI, error)
    30  }
    31  
    32  func (config ManifoldConfig) start(context dependency.Context) (worker.Worker, error) {
    33  
    34  	var environ environs.Environ
    35  	if err := context.Get(config.EnvironName, &environ); err != nil {
    36  		if errors.Cause(err) != dependency.ErrMissing {
    37  			return nil, errors.Trace(err)
    38  		}
    39  		// Only the controller's leader is given an Environ; the
    40  		// other controller units will watch the model and wait
    41  		// for its environ version to be updated.
    42  		environ = nil
    43  	}
    44  
    45  	var apiCaller base.APICaller
    46  	if err := context.Get(config.APICallerName, &apiCaller); err != nil {
    47  		return nil, errors.Trace(err)
    48  	}
    49  
    50  	var gate gate.Unlocker
    51  	if err := context.Get(config.GateName, &gate); err != nil {
    52  		return nil, errors.Trace(err)
    53  	}
    54  
    55  	facade, err := config.NewFacade(apiCaller)
    56  	if err != nil {
    57  		return nil, errors.Trace(err)
    58  	}
    59  
    60  	credentialAPI, err := config.NewCredentialValidatorFacade(apiCaller)
    61  	if err != nil {
    62  		return nil, errors.Trace(err)
    63  	}
    64  
    65  	worker, err := config.NewWorker(Config{
    66  		Facade:        facade,
    67  		Environ:       environ,
    68  		GateUnlocker:  gate,
    69  		ControllerTag: config.ControllerTag,
    70  		ModelTag:      config.ModelTag,
    71  		CredentialAPI: credentialAPI,
    72  	})
    73  	if err != nil {
    74  		return nil, errors.Trace(err)
    75  	}
    76  	return worker, nil
    77  }
    78  
    79  // Manifold returns a dependency.Manifold that will run a Worker as
    80  // configured.
    81  func Manifold(config ManifoldConfig) dependency.Manifold {
    82  	return dependency.Manifold{
    83  		Inputs: []string{
    84  			config.APICallerName,
    85  			config.EnvironName,
    86  			config.GateName,
    87  		},
    88  		Start:  config.start,
    89  		Filter: bounceErrChanged,
    90  	}
    91  }
    92  
    93  // bounceErrChanged converts ErrModelRemoved to dependency.ErrUninstall.
    94  func bounceErrChanged(err error) error {
    95  	if errors.Cause(err) == ErrModelRemoved {
    96  		return dependency.ErrUninstall
    97  	}
    98  	return err
    99  }