github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/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 "github.com/juju/juju/agent" 10 "github.com/juju/juju/api/base" 11 "github.com/juju/juju/worker" 12 "github.com/juju/juju/worker/dependency" 13 "github.com/juju/juju/worker/gate" 14 ) 15 16 // ManifoldConfig defines the names of the manifolds on which a Manifold will depend. 17 type ManifoldConfig struct { 18 AgentName string 19 APIInfoGateName string 20 } 21 22 // Manifold returns a manifold whose worker wraps an API connection made on behalf of 23 // the dependency identified by AgentName. 24 func Manifold(config ManifoldConfig) dependency.Manifold { 25 return dependency.Manifold{ 26 Inputs: []string{ 27 config.AgentName, 28 config.APIInfoGateName, 29 }, 30 Output: outputFunc, 31 Start: startFunc(config), 32 } 33 } 34 35 // startFunc returns a StartFunc that creates a worker based on the manifolds 36 // named in the supplied config. 37 func startFunc(config ManifoldConfig) dependency.StartFunc { 38 return func(getResource dependency.GetResourceFunc) (worker.Worker, error) { 39 40 // Get dependencies and open a connection. 41 var gate gate.Unlocker 42 if err := getResource(config.APIInfoGateName, &gate); err != nil { 43 return nil, err 44 } 45 var a agent.Agent 46 if err := getResource(config.AgentName, &a); err != nil { 47 return nil, err 48 } 49 conn, err := openConnection(a) 50 if err != nil { 51 return nil, errors.Annotate(err, "cannot open api") 52 } 53 54 // Add the environment uuid to agent config if not present. 55 currentConfig := a.CurrentConfig() 56 if currentConfig.Environment().Id() == "" { 57 err := a.ChangeConfig(func(setter agent.ConfigSetter) error { 58 environTag, err := conn.EnvironTag() 59 if err != nil { 60 return errors.Annotate(err, "no environment uuid set on api") 61 } 62 return setter.Migrate(agent.MigrateParams{ 63 Environment: environTag, 64 }) 65 }) 66 if err != nil { 67 logger.Warningf("unable to save environment uuid: %v", err) 68 // Not really fatal, just annoying. 69 } 70 } 71 72 // Now we know the agent config has been fixed up, notify everyone 73 // else who might depend upon its stability/correctness. 74 gate.Unlock() 75 76 // Return the worker. 77 return newApiConnWorker(conn) 78 } 79 } 80 81 // outputFunc extracts a base.APICaller from a *apiConnWorker. 82 func outputFunc(in worker.Worker, out interface{}) error { 83 inWorker, _ := in.(*apiConnWorker) 84 outPointer, _ := out.(*base.APICaller) 85 if inWorker == nil || outPointer == nil { 86 return errors.Errorf("expected %T->%T; got %T->%T", inWorker, outPointer, in, out) 87 } 88 *outPointer = inWorker.conn 89 return nil 90 }