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