github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/worker/deployer/manifold.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package deployer
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  	"gopkg.in/juju/names.v2"
     9  
    10  	"github.com/juju/juju/agent"
    11  	apiagent "github.com/juju/juju/api/agent"
    12  	"github.com/juju/juju/api/base"
    13  	apideployer "github.com/juju/juju/api/deployer"
    14  	"github.com/juju/juju/cmd/jujud/agent/engine"
    15  	"github.com/juju/juju/state/multiwatcher"
    16  	"github.com/juju/juju/worker"
    17  	"github.com/juju/juju/worker/dependency"
    18  )
    19  
    20  // ManifoldConfig defines the names of the manifolds on which a Manifold will depend.
    21  type ManifoldConfig struct {
    22  	AgentName        string
    23  	APICallerName    string
    24  	NewDeployContext func(st *apideployer.State, agentConfig agent.Config) Context
    25  }
    26  
    27  // Manifold returns a dependency manifold that runs a deployer worker,
    28  // using the resource names defined in the supplied config.
    29  func Manifold(config ManifoldConfig) dependency.Manifold {
    30  	typedConfig := engine.AgentAPIManifoldConfig{
    31  		AgentName:     config.AgentName,
    32  		APICallerName: config.APICallerName,
    33  	}
    34  	return engine.AgentAPIManifold(typedConfig, config.newWorker)
    35  }
    36  
    37  // newWorker trivially wraps NewDeployer for use in a engine.AgentAPIManifold.
    38  //
    39  // It's not tested at the moment, because the scaffolding
    40  // necessary is too unwieldy/distracting to introduce at this point.
    41  func (config ManifoldConfig) newWorker(a agent.Agent, apiCaller base.APICaller) (worker.Worker, error) {
    42  	cfg := a.CurrentConfig()
    43  	// Grab the tag and ensure that it's for a machine.
    44  	tag, ok := cfg.Tag().(names.MachineTag)
    45  	if !ok {
    46  		return nil, errors.New("agent's tag is not a machine tag")
    47  	}
    48  
    49  	// Get the machine agent's jobs.
    50  	// TODO(fwereade): this functionality should be on the
    51  	// deployer facade instead.
    52  	agentFacade := apiagent.NewState(apiCaller)
    53  	entity, err := agentFacade.Entity(tag)
    54  	if err != nil {
    55  		return nil, err
    56  	}
    57  
    58  	var isUnitHoster bool
    59  	for _, job := range entity.Jobs() {
    60  		if job == multiwatcher.JobHostUnits {
    61  			isUnitHoster = true
    62  			break
    63  		}
    64  	}
    65  
    66  	if !isUnitHoster {
    67  		return nil, dependency.ErrUninstall
    68  	}
    69  
    70  	deployerFacade := apideployer.NewState(apiCaller)
    71  	context := config.NewDeployContext(deployerFacade, cfg)
    72  	w, err := NewDeployer(deployerFacade, context)
    73  	if err != nil {
    74  		return nil, errors.Annotate(err, "cannot start unit agent deployer worker")
    75  	}
    76  	return w, nil
    77  }