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

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package upgradesteps
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  	"gopkg.in/juju/worker.v1"
     9  	"gopkg.in/juju/worker.v1/dependency"
    10  
    11  	"github.com/juju/juju/agent"
    12  	"github.com/juju/juju/api"
    13  	apiagent "github.com/juju/juju/api/agent"
    14  	"github.com/juju/juju/environs"
    15  	"github.com/juju/juju/state"
    16  	"github.com/juju/juju/worker/gate"
    17  )
    18  
    19  // ManifoldConfig defines the names of the manifolds on which a
    20  // Manifold will depend.
    21  type ManifoldConfig struct {
    22  	AgentName            string
    23  	APICallerName        string
    24  	UpgradeStepsGateName string
    25  	OpenStateForUpgrade  func() (*state.StatePool, error)
    26  	PreUpgradeSteps      func(*state.StatePool, agent.Config, bool, bool) error
    27  	NewEnvironFunc       environs.NewEnvironFunc
    28  	NewAgentStatusSetter func(apiConn api.Connection) (StatusSetter, error)
    29  }
    30  
    31  // Manifold returns a dependency manifold that runs an upgrader
    32  // worker, using the resource names defined in the supplied config.
    33  func Manifold(config ManifoldConfig) dependency.Manifold {
    34  	return dependency.Manifold{
    35  		Inputs: []string{
    36  			config.AgentName,
    37  			config.APICallerName,
    38  			config.UpgradeStepsGateName,
    39  		},
    40  		Start: func(context dependency.Context) (worker.Worker, error) {
    41  			// Sanity checks
    42  			if config.OpenStateForUpgrade == nil {
    43  				return nil, errors.New("missing OpenStateForUpgrade in config")
    44  			}
    45  			if config.PreUpgradeSteps == nil {
    46  				return nil, errors.New("missing PreUpgradeSteps in config")
    47  			}
    48  
    49  			// Get machine agent.
    50  			var agent agent.Agent
    51  			if err := context.Get(config.AgentName, &agent); err != nil {
    52  				return nil, err
    53  			}
    54  
    55  			// Get API connection.
    56  			// TODO(fwereade): can we make the worker use an
    57  			// APICaller instead? should be able to depend on
    58  			// the Engine to abort us when conn is closed...
    59  			var apiConn api.Connection
    60  			if err := context.Get(config.APICallerName, &apiConn); err != nil {
    61  				return nil, err
    62  			}
    63  
    64  			// Get upgradesteps completed lock.
    65  			var upgradeStepsLock gate.Lock
    66  			if err := context.Get(config.UpgradeStepsGateName, &upgradeStepsLock); err != nil {
    67  				return nil, err
    68  			}
    69  
    70  			// Get the agent's jobs.
    71  			// TODO(fwereade): use appropriate facade!
    72  			agentFacade, err := apiagent.NewState(apiConn)
    73  			if err != nil {
    74  				return nil, err
    75  			}
    76  			entity, err := agentFacade.Entity(agent.CurrentConfig().Tag())
    77  			if err != nil {
    78  				return nil, err
    79  			}
    80  			jobs := entity.Jobs()
    81  
    82  			// Get a component capable of setting machine status
    83  			// to indicate progress to the user.
    84  			statusSetter, err := config.NewAgentStatusSetter(apiConn)
    85  			if err != nil {
    86  				return nil, err
    87  			}
    88  			return NewWorker(
    89  				upgradeStepsLock,
    90  				agent,
    91  				apiConn,
    92  				jobs,
    93  				config.OpenStateForUpgrade,
    94  				config.PreUpgradeSteps,
    95  				statusSetter,
    96  				config.NewEnvironFunc,
    97  			)
    98  		},
    99  	}
   100  }