github.com/Pankov404/juju@v0.0.0-20150703034450-be266991dceb/worker/apicaller/manifold.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package apicaller
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  
     9  	coreagent "github.com/juju/juju/agent"
    10  	"github.com/juju/juju/api/base"
    11  	"github.com/juju/juju/worker"
    12  	"github.com/juju/juju/worker/agent"
    13  	"github.com/juju/juju/worker/dependency"
    14  	"github.com/juju/juju/worker/util"
    15  )
    16  
    17  // ManifoldConfig defines the names of the manifolds on which a Manifold will depend.
    18  type ManifoldConfig util.AgentManifoldConfig
    19  
    20  // Manifold returns a manifold whose worker wraps an API connection made on behalf of
    21  // the dependency identified by AgentName.
    22  func Manifold(config ManifoldConfig) dependency.Manifold {
    23  	return dependency.Manifold{
    24  		Inputs: []string{
    25  			config.AgentName,
    26  		},
    27  		Output: outputFunc,
    28  		Start:  startFunc(config),
    29  	}
    30  }
    31  
    32  // startFunc returns a StartFunc that creates a worker based on the manifolds
    33  // named in the supplied config.
    34  func startFunc(config ManifoldConfig) dependency.StartFunc {
    35  	return func(getResource dependency.GetResourceFunc) (worker.Worker, error) {
    36  
    37  		// Get dependencies and open a connection.
    38  		var agent agent.Agent
    39  		if err := getResource(config.AgentName, &agent); err != nil {
    40  			return nil, err
    41  		}
    42  		conn, err := openConnection(agent)
    43  		if err != nil {
    44  			return nil, errors.Annotate(err, "cannot open api")
    45  		}
    46  
    47  		// Add the environment uuid to agent config if not present.
    48  		currentConfig := agent.CurrentConfig()
    49  		if currentConfig.Environment().Id() == "" {
    50  			err := agent.ChangeConfig(func(setter coreagent.ConfigSetter) error {
    51  				environTag, err := conn.EnvironTag()
    52  				if err != nil {
    53  					return errors.Annotate(err, "no environment uuid set on api")
    54  				}
    55  				return setter.Migrate(coreagent.MigrateParams{
    56  					Environment: environTag,
    57  				})
    58  			})
    59  			if err != nil {
    60  				logger.Warningf("unable to save environment uuid: %v", err)
    61  				// Not really fatal, just annoying.
    62  			}
    63  		}
    64  
    65  		// Return the worker.
    66  		return newApiConnWorker(conn)
    67  	}
    68  }
    69  
    70  // outputFunc extracts a base.APICaller from a *apiConnWorker.
    71  func outputFunc(in worker.Worker, out interface{}) error {
    72  	inWorker, _ := in.(*apiConnWorker)
    73  	outPointer, _ := out.(*base.APICaller)
    74  	if inWorker == nil || outPointer == nil {
    75  		return errors.Errorf("expected %T->%T; got %T->%T", inWorker, outPointer, in, out)
    76  	}
    77  	*outPointer = inWorker.conn
    78  	return nil
    79  }