1
// Copyright 2015 Canonical Ltd.
2
// Licensed under the AGPLv3, see LICENCE file for details.
7
"github.com/juju/errors"
9
"github.com/juju/juju/agent"
10
"github.com/juju/juju/api"
11
"github.com/juju/juju/api/base"
12
"github.com/juju/juju/worker"
13
"github.com/juju/juju/worker/dependency"
16
// ManifoldConfig defines the names of the manifolds on which a Manifold will depend.
17
type ManifoldConfig struct {
21
// Manifold returns a manifold whose worker wraps an API connection made on behalf of
22
// the dependency identified by AgentName.
23
func Manifold(config ManifoldConfig) dependency.Manifold {
24
return dependency.Manifold{
29
Start: startFunc(config),
33
// startFunc returns a StartFunc that creates a worker based on the manifolds
34
// named in the supplied config.
35
func startFunc(config ManifoldConfig) dependency.StartFunc {
36
return func(getResource dependency.GetResourceFunc) (worker.Worker, error) {
38
// Get dependencies and open a connection.
40
if err := getResource(config.AgentName, &a); err != nil {
43
conn, err := openConnection(a)
45
return nil, errors.Annotate(err, "cannot open api")
48
// Add the environment uuid to agent config if not present.
49
currentConfig := a.CurrentConfig()
50
if currentConfig.Model().Id() == "" {
51
err := a.ChangeConfig(func(setter agent.ConfigSetter) error {
52
modelTag, err := conn.ModelTag()
54
return errors.Annotate(err, "no model uuid set on api")
56
return setter.Migrate(agent.MigrateParams{
61
logger.Warningf("unable to save model uuid: %v", err)
62
// Not really fatal, just annoying.
67
return newApiConnWorker(conn)
71
// outputFunc extracts an API connection from a *apiConnWorker.
72
func outputFunc(in worker.Worker, out interface{}) error {
73
inWorker, _ := in.(*apiConnWorker)
75
return errors.Errorf("in should be a %T; got %T", inWorker, in)
78
switch outPointer := out.(type) {
80
*outPointer = inWorker.conn
82
// Using api.Connection is strongly discouraged as consumers
83
// of this API connection should not be able to close it. This
84
// option is only available to support legacy upgrade steps.
85
*outPointer = inWorker.conn
87
return errors.Errorf("out should be *base.APICaller or *api.Connection; got %T", out)