github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/cmd/jujud/agent/unit/manifolds.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package unit
     5  
     6  import (
     7  	"time"
     8  
     9  	coreagent "github.com/juju/juju/agent"
    10  	"github.com/juju/juju/worker/agent"
    11  	"github.com/juju/juju/worker/apiaddressupdater"
    12  	"github.com/juju/juju/worker/apicaller"
    13  	"github.com/juju/juju/worker/charmdir"
    14  	"github.com/juju/juju/worker/dependency"
    15  	"github.com/juju/juju/worker/gate"
    16  	"github.com/juju/juju/worker/leadership"
    17  	"github.com/juju/juju/worker/logger"
    18  	"github.com/juju/juju/worker/logsender"
    19  	"github.com/juju/juju/worker/machinelock"
    20  	"github.com/juju/juju/worker/metrics/collect"
    21  	"github.com/juju/juju/worker/metrics/sender"
    22  	"github.com/juju/juju/worker/metrics/spool"
    23  	"github.com/juju/juju/worker/proxyupdater"
    24  	"github.com/juju/juju/worker/rsyslog"
    25  	"github.com/juju/juju/worker/uniter"
    26  	"github.com/juju/juju/worker/upgrader"
    27  )
    28  
    29  // ManifoldsConfig allows specialisation of the result of Manifolds.
    30  type ManifoldsConfig struct {
    31  
    32  	// Agent contains the agent that will be wrapped and made available to
    33  	// its dependencies via a dependency.Engine.
    34  	Agent coreagent.Agent
    35  
    36  	// LogSource will be read from by the logsender component.
    37  	LogSource logsender.LogRecordCh
    38  
    39  	// LeadershipGuarantee controls the behaviour of the leadership tracker.
    40  	LeadershipGuarantee time.Duration
    41  }
    42  
    43  // Manifolds returns a set of co-configured manifolds covering the various
    44  // responsibilities of a standalone unit agent. It also accepts the logSource
    45  // argument because we haven't figured out how to thread all the logging bits
    46  // through a dependency engine yet.
    47  //
    48  // Thou Shalt Not Use String Literals In This Function. Or Else.
    49  func Manifolds(config ManifoldsConfig) dependency.Manifolds {
    50  	return dependency.Manifolds{
    51  
    52  		// The agent manifold references the enclosing agent, and is the
    53  		// foundation stone on which most other manifolds ultimately depend.
    54  		// (Currently, that is "all manifolds", but consider a shared clock.)
    55  		AgentName: agent.Manifold(config.Agent),
    56  
    57  		// The machine lock manifold is a thin concurrent wrapper around an
    58  		// FSLock in an agreed location. We expect it to be replaced with an
    59  		// in-memory lock when the unit agent moves into the machine agent.
    60  		MachineLockName: machinelock.Manifold(machinelock.ManifoldConfig{
    61  			AgentName: AgentName,
    62  		}),
    63  
    64  		// The api caller is a thin concurrent wrapper around a connection
    65  		// to some API server. It's used by many other manifolds, which all
    66  		// select their own desired facades. It will be interesting to see
    67  		// how this works when we consolidate the agents; might be best to
    68  		// handle the auth changes server-side..?
    69  		APICallerName: apicaller.Manifold(apicaller.ManifoldConfig{
    70  			AgentName:       AgentName,
    71  			APIInfoGateName: APIInfoGateName,
    72  		}),
    73  
    74  		// This manifold is used to coordinate between the api caller and the
    75  		// log sender, which share the API credentials that the API caller may
    76  		// update. To avoid surprising races, the log sender waits for the api
    77  		// caller to unblock this, indicating that any password dance has been
    78  		// completed and the log-sender can now connect without confusion.
    79  		APIInfoGateName: gate.Manifold(),
    80  
    81  		// The log sender is a leaf worker that sends log messages to some
    82  		// API server, when configured so to do. We should only need one of
    83  		// these in a consolidated agent.
    84  		LogSenderName: logsender.Manifold(logsender.ManifoldConfig{
    85  			AgentName:       AgentName,
    86  			APIInfoGateName: APIInfoGateName,
    87  			LogSource:       config.LogSource,
    88  		}),
    89  
    90  		// The rsyslog config updater is a leaf worker that causes rsyslog
    91  		// to send messages to the state servers. We should only need one
    92  		// of these in a consolidated agent.
    93  		RsyslogConfigUpdaterName: rsyslog.Manifold(rsyslog.ManifoldConfig{
    94  			AgentName:     AgentName,
    95  			APICallerName: APICallerName,
    96  		}),
    97  
    98  		// The logging config updater is a leaf worker that indirectly
    99  		// controls the messages sent via the log sender or rsyslog,
   100  		// according to changes in environment config. We should only need
   101  		// one of these in a consolidated agent.
   102  		LoggingConfigUpdaterName: logger.Manifold(logger.ManifoldConfig{
   103  			AgentName:     AgentName,
   104  			APICallerName: APICallerName,
   105  		}),
   106  
   107  		// The api address updater is a leaf worker that rewrites agent config
   108  		// as the state server addresses change. We should only need one of
   109  		// these in a consolidated agent.
   110  		APIAdddressUpdaterName: apiaddressupdater.Manifold(apiaddressupdater.ManifoldConfig{
   111  			AgentName:     AgentName,
   112  			APICallerName: APICallerName,
   113  		}),
   114  
   115  		// The proxy config updater is a leaf worker that sets http/https/apt/etc
   116  		// proxy settings.
   117  		// TODO(fwereade): timing of this is suspicious. There was superstitious
   118  		// code trying to run this early; if that ever helped, it was only by
   119  		// coincidence. Probably we ought to be making components that might
   120  		// need proxy config into explicit dependencies of the proxy updater...
   121  		ProxyConfigUpdaterName: proxyupdater.Manifold(proxyupdater.ManifoldConfig{
   122  			APICallerName: APICallerName,
   123  		}),
   124  
   125  		// The upgrader is a leaf worker that returns a specific error type
   126  		// recognised by the unit agent, causing other workers to be stopped
   127  		// and the agent to be restarted running the new tools. We should only
   128  		// need one of these in a consolidated agent, but we'll need to be
   129  		// careful about behavioural differences, and interactions with the
   130  		// upgrade-steps worker.
   131  		UpgraderName: upgrader.Manifold(upgrader.ManifoldConfig{
   132  			AgentName:     AgentName,
   133  			APICallerName: APICallerName,
   134  		}),
   135  
   136  		// The leadership tracker attempts to secure and retain leadership of
   137  		// the unit's service, and is consulted on such matters by the
   138  		// uniter. As it stannds today, we'll need one per unit in a
   139  		// consolidated agent.
   140  		LeadershipTrackerName: leadership.Manifold(leadership.ManifoldConfig{
   141  			AgentName:           AgentName,
   142  			APICallerName:       APICallerName,
   143  			LeadershipGuarantee: config.LeadershipGuarantee,
   144  		}),
   145  
   146  		// The uniter installs charms; manages the unit's presence in its
   147  		// relations; creates suboordinate units; runs all the hooks; sends
   148  		// metrics; etc etc etc. We expect to break it up further in the
   149  		// coming weeks, and to need one per unit in a consolidated agent
   150  		// (and probably one for each component broken out).
   151  		UniterName: uniter.Manifold(uniter.ManifoldConfig{
   152  			AgentName:             AgentName,
   153  			APICallerName:         APICallerName,
   154  			LeadershipTrackerName: LeadershipTrackerName,
   155  			MachineLockName:       MachineLockName,
   156  			CharmDirName:          CharmDirName,
   157  		}),
   158  
   159  		// TODO (mattyw) should be added to machine agent.
   160  		MetricSpoolName: spool.Manifold(spool.ManifoldConfig{
   161  			AgentName: AgentName,
   162  		}),
   163  
   164  		// The charmdir resource tracks whether the charm directory is available or
   165  		// not; after 'start' hook and before 'stop' hook executes, and not during
   166  		// upgrades.
   167  		CharmDirName: charmdir.Manifold(),
   168  
   169  		// The metric collect worker executes the collect-metrics hook in a
   170  		// restricted context that can safely run concurrently with other hooks.
   171  		MetricCollectName: collect.Manifold(collect.ManifoldConfig{
   172  			AgentName:       AgentName,
   173  			APICallerName:   APICallerName,
   174  			MetricSpoolName: MetricSpoolName,
   175  			CharmDirName:    CharmDirName,
   176  		}),
   177  
   178  		MetricSenderName: sender.Manifold(sender.ManifoldConfig{
   179  			APICallerName:   APICallerName,
   180  			MetricSpoolName: MetricSpoolName,
   181  		}),
   182  	}
   183  }
   184  
   185  const (
   186  	AgentName                = "agent"
   187  	APIAdddressUpdaterName   = "api-address-updater"
   188  	APICallerName            = "api-caller"
   189  	APIInfoGateName          = "api-info-gate"
   190  	LeadershipTrackerName    = "leadership-tracker"
   191  	LoggingConfigUpdaterName = "logging-config-updater"
   192  	LogSenderName            = "log-sender"
   193  	MachineLockName          = "machine-lock"
   194  	ProxyConfigUpdaterName   = "proxy-config-updater"
   195  	RsyslogConfigUpdaterName = "rsyslog-config-updater"
   196  	UniterName               = "uniter"
   197  	UpgraderName             = "upgrader"
   198  	MetricSpoolName          = "metric-spool"
   199  	CharmDirName             = "charm-dir"
   200  	MetricCollectName        = "metric-collect"
   201  	MetricSenderName         = "metric-sender"
   202  )