Merge lp:~axwalk/juju-core/refactor-environs-manual into lp:~go-bot/juju-core/trunk
- refactor-environs-manual
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Andrew Wilkins |
Approved revision: | no longer in the source branch. |
Merged at revision: | 2065 |
Proposed branch: | lp:~axwalk/juju-core/refactor-environs-manual |
Merge into: | lp:~go-bot/juju-core/trunk |
Diff against target: |
473 lines (+89/-130) 8 files modified
container/userdata.go (+3/-1) environs/cloudinit.go (+3/-2) environs/cloudinit/cloudinit.go (+16/-21) environs/cloudinit/cloudinit_test.go (+8/-9) environs/manual/agent.go (+10/-54) environs/manual/agent_test.go (+19/-15) environs/manual/bootstrap.go (+14/-12) environs/manual/provisioner.go (+16/-16) |
To merge this branch: | bzr merge lp:~axwalk/juju-core/refactor-environs-manual |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Juju Engineering | Pending | ||
Review via email: mp+195342@code.launchpad.net |
Commit message
Refactor environs/
environs/cloudinit has been modified to
have two sub-Configure methods:
ConfigureBase and ConfigureJuju. The
former initialises a cloud-init config
to setup a base OS with SSH keys; the
latter does the rest.
environs/manual has been modified to
expose provisionMachin
a capital P), which now just takes a
hostname and *cloudinit.
We will use this later to install
machine agents into cloud images.
Description of the change
Refactor environs/
environs/cloudinit has been modified to
have two sub-Configure methods:
ConfigureBase and ConfigureJuju. The
former initialises a cloud-init config
to setup a base OS with SSH keys; the
latter does the rest.
environs/manual has been modified to
expose provisionMachin
a capital P), which now just takes a
hostname and *cloudinit.
We will use this later to install
machine agents into cloud images.
Andrew Wilkins (axwalk) wrote : | # |
Roger Peppe (rogpeppe) wrote : | # |
LGTM with one thought below.
https:/
File environs/
https:/
environs/
string, c *cloudinit.Config) error {
Passing thought: I wonder if this function and the above might work
better with the cloudinit.Config as the first argument, as if it was the
receiver.
Also I'm not entirely sure that "Base" is quite right as a name - with
that name, it sounds as if it's a necessary base that others must build
on, but since the cloudinit config is passed in, that's not necessarily
the case.
As an alternative, we could make it return the new config:
func BaseConfig(
(no need to return an error, I think). Then it really would be a base,
because everything would start with it.
Or alternatively rename it to something else; ConfigureBasic perhaps?
I think my preference is for the above though.
https:/
File environs/
https:/
environs/
It's great to see all this go.
Andrew Wilkins (axwalk) wrote : | # |
https:/
File environs/
https:/
environs/
string, c *cloudinit.Config) error {
On 2013/11/15 08:36:09, rog wrote:
> Passing thought: I wonder if this function and the above might work
better with
> the cloudinit.Config as the first argument, as if it was the receiver.
Making it a receiver seems wrong to me, as that would suggest to me that
it's the cloudinit.Config configuring something else.
As for the order here: I don't have a strong preference, I was just
keeping it consistent with Configure (input first, output second).
> Also I'm not entirely sure that "Base" is quite right as a name - with
that
> name, it sounds as if it's a necessary base that others must build on,
but since
> the cloudinit config is passed in, that's not necessarily the case.
I think it may just be confusing, given how generic the word "base" is.
ConfigureBase produces cloud-init that configures a "base OS image".
That is then built on by adding the juju bits (via ConfigureJuju).
> As an alternative, we could make it return the new config:
> func BaseConfig(
> (no need to return an error, I think). Then it really would be a base,
because
> everything would start with it.
The thing is, not *everything* starts with it. Manual
bootstrap/
"base".
> Or alternatively rename it to something else; ConfigureBasic perhaps?
> I think my preference is for the above though.
To me, Basic and Base have more or less the same connotations (except
Basic has an additional meaning of not-complex). I want to say
ConfigurePristine, but it isn't exactly (it adds SSH keys...).
Andrew Wilkins (axwalk) wrote : | # |
On 2013/11/15 09:10:42, axw wrote:
https:/
> File environs/
https:/
> environs/
string, c
> *cloudinit.Config) error {
> On 2013/11/15 08:36:09, rog wrote:
> > Passing thought: I wonder if this function and the above might work
better
> with
> > the cloudinit.Config as the first argument, as if it was the
receiver.
> Making it a receiver seems wrong to me, as that would suggest to me
that it's
> the cloudinit.Config configuring something else.
> As for the order here: I don't have a strong preference, I was just
keeping it
> consistent with Configure (input first, output second).
> > Also I'm not entirely sure that "Base" is quite right as a name -
with that
> > name, it sounds as if it's a necessary base that others must build
on, but
> since
> > the cloudinit config is passed in, that's not necessarily the case.
> I think it may just be confusing, given how generic the word "base"
is.
> ConfigureBase produces cloud-init that configures a "base OS image".
That is
> then built on by adding the juju bits (via ConfigureJuju).
> > As an alternative, we could make it return the new config:
> >
> > func BaseConfig(
> >
> > (no need to return an error, I think). Then it really would be a
base, because
> > everything would start with it.
> The thing is, not *everything* starts with it. Manual
bootstrap/
> doesn't use ConfigureBase, as they already have a "base".
> > Or alternatively rename it to something else; ConfigureBasic
perhaps?
> > I think my preference is for the above though.
> To me, Basic and Base have more or less the same connotations (except
Basic has
> an additional meaning of not-complex). I want to say
ConfigurePristine, but it
> isn't exactly (it adds SSH keys...).
As per discussion on IRC, ConfigureBase and ConfigureJuju can be
rejoined. I had thought I would need to split them, but as it turns out
I won't.
Andrew Wilkins (axwalk) wrote : | # |
Please take a look.
Roger Peppe (rogpeppe) wrote : | # |
LGTM with a couple of trivial thoughts below.
https:/
File environs/
https:/
environs/
We should probably document that the scripts run before anything else.
https:/
File environs/
https:/
environs/
Juju machine agent.
s/initialise/
might as well use the usual american spelling everywhere.
https:/
environs/
tee -a /var/log/
Much nicer having this at the start, thanks.
Andrew Wilkins (axwalk) wrote : | # |
Please take a look.
https:/
File environs/
https:/
environs/
On 2013/11/15 10:01:44, rog wrote:
> We should probably document that the scripts run before anything else.
Done. Not quite before *everything* else, just the runcmds.
https:/
File environs/
https:/
environs/
Juju machine agent.
On 2013/11/15 10:01:44, rog wrote:
> s/initialise/
> might as well use the usual american spelling everywhere.
Done.
Andrew Wilkins (axwalk) wrote : | # |
On 2013/11/15 10:12:35, axw wrote:
> Please take a look.
I'm an idiot. We *do* need separate Configure methods: for (non-manual)
synchronous bootstrap. There we only want a base OS image with SSH keys
and cloud-init output logs configured. For manual bootstrap we don't
care, but for non-manual we do care.
I'll have to reinstate the two methods, but I'll try to come up with a
better name.
Preview Diff
1 | === modified file 'container/userdata.go' |
2 | --- container/userdata.go 2013-11-11 21:54:29 +0000 |
3 | +++ container/userdata.go 2013-11-15 10:10:33 +0000 |
4 | @@ -11,6 +11,7 @@ |
5 | |
6 | "launchpad.net/loggo" |
7 | |
8 | + coreCloudinit "launchpad.net/juju-core/cloudinit" |
9 | "launchpad.net/juju-core/environs/cloudinit" |
10 | "launchpad.net/juju-core/utils" |
11 | ) |
12 | @@ -37,7 +38,8 @@ |
13 | func cloudInitUserData(machineConfig *cloudinit.MachineConfig) ([]byte, error) { |
14 | // consider not having this line hardcoded... |
15 | machineConfig.DataDir = "/var/lib/juju" |
16 | - cloudConfig, err := cloudinit.New(machineConfig) |
17 | + cloudConfig := coreCloudinit.New() |
18 | + err := cloudinit.Configure(machineConfig, cloudConfig) |
19 | if err != nil { |
20 | return nil, err |
21 | } |
22 | |
23 | === modified file 'environs/cloudinit.go' |
24 | --- environs/cloudinit.go 2013-11-07 09:09:55 +0000 |
25 | +++ environs/cloudinit.go 2013-11-15 10:10:33 +0000 |
26 | @@ -124,13 +124,14 @@ |
27 | |
28 | // ComposeUserData puts together a binary (gzipped) blob of user data. |
29 | // The additionalScripts are additional command lines that you need cloudinit |
30 | -// to run on the instance. Use with care. |
31 | +// to run on the instance; they are executed before all other cloud-init |
32 | +// runcmds. Use with care. |
33 | func ComposeUserData(cfg *cloudinit.MachineConfig, additionalScripts ...string) ([]byte, error) { |
34 | cloudcfg := coreCloudinit.New() |
35 | for _, script := range additionalScripts { |
36 | cloudcfg.AddRunCmd(script) |
37 | } |
38 | - cloudcfg, err := cloudinit.Configure(cfg, cloudcfg) |
39 | + err := cloudinit.Configure(cfg, cloudcfg) |
40 | if err != nil { |
41 | return nil, err |
42 | } |
43 | |
44 | === modified file 'environs/cloudinit/cloudinit.go' |
45 | --- environs/cloudinit/cloudinit.go 2013-11-01 04:00:55 +0000 |
46 | +++ environs/cloudinit/cloudinit.go 2013-11-15 10:10:33 +0000 |
47 | @@ -125,16 +125,19 @@ |
48 | return base64.StdEncoding.EncodeToString(data) |
49 | } |
50 | |
51 | -func New(cfg *MachineConfig) (*cloudinit.Config, error) { |
52 | - c := cloudinit.New() |
53 | - return Configure(cfg, c) |
54 | -} |
55 | - |
56 | -func Configure(cfg *MachineConfig, c *cloudinit.Config) (*cloudinit.Config, error) { |
57 | +// Configure updates the provided cloudinit.Config with |
58 | +// configuration to initialize a Juju machine agent. |
59 | +func Configure(cfg *MachineConfig, c *cloudinit.Config) error { |
60 | if err := verifyConfig(cfg); err != nil { |
61 | - return nil, err |
62 | + return err |
63 | } |
64 | + |
65 | + // General options. |
66 | + c.SetAptUpgrade(true) |
67 | + c.SetAptUpdate(true) |
68 | + c.SetOutput(cloudinit.OutAll, "| tee -a /var/log/cloud-init-output.log", "") |
69 | c.AddSSHAuthorizedKeys(cfg.AuthorizedKeys) |
70 | + |
71 | c.AddPackage("git") |
72 | // Perfectly reasonable to install lxc on environment instances and kvm |
73 | // containers. |
74 | @@ -161,7 +164,7 @@ |
75 | } |
76 | toolsJson, err := json.Marshal(cfg.Tools) |
77 | if err != nil { |
78 | - return nil, err |
79 | + return err |
80 | } |
81 | c.AddScripts( |
82 | "bin="+shquote(cfg.jujuTools()), |
83 | @@ -176,7 +179,7 @@ |
84 | ) |
85 | |
86 | if err := cfg.addLogging(c); err != nil { |
87 | - return nil, err |
88 | + return err |
89 | } |
90 | |
91 | // We add the machine agent's configuration info |
92 | @@ -188,7 +191,7 @@ |
93 | machineTag := names.MachineTag(cfg.MachineId) |
94 | _, err = cfg.addAgentInfo(c, machineTag) |
95 | if err != nil { |
96 | - return nil, err |
97 | + return err |
98 | } |
99 | |
100 | // Add the cloud archive cloud-tools pocket to apt sources |
101 | @@ -212,7 +215,7 @@ |
102 | certKey := string(cfg.StateServerCert) + string(cfg.StateServerKey) |
103 | c.AddFile(cfg.dataFile("server.pem"), certKey, 0600) |
104 | if err := cfg.addMongoToBoot(c); err != nil { |
105 | - return nil, err |
106 | + return err |
107 | } |
108 | // We temporarily give bootstrap-state a directory |
109 | // of its own so that it can get the state info via the |
110 | @@ -223,7 +226,7 @@ |
111 | // We leave it for the time being for backward compatibility. |
112 | acfg, err := cfg.addAgentInfo(c, "bootstrap") |
113 | if err != nil { |
114 | - return nil, err |
115 | + return err |
116 | } |
117 | cons := cfg.Constraints.String() |
118 | if cons != "" { |
119 | @@ -241,15 +244,7 @@ |
120 | ) |
121 | } |
122 | |
123 | - if err := cfg.addMachineAgentToBoot(c, machineTag, cfg.MachineId); err != nil { |
124 | - return nil, err |
125 | - } |
126 | - |
127 | - // general options |
128 | - c.SetAptUpgrade(true) |
129 | - c.SetAptUpdate(true) |
130 | - c.SetOutput(cloudinit.OutAll, "| tee -a /var/log/cloud-init-output.log", "") |
131 | - return c, nil |
132 | + return cfg.addMachineAgentToBoot(c, machineTag, cfg.MachineId) |
133 | } |
134 | |
135 | func (cfg *MachineConfig) addLogging(c *cloudinit.Config) error { |
136 | |
137 | === modified file 'environs/cloudinit/cloudinit_test.go' |
138 | --- environs/cloudinit/cloudinit_test.go 2013-10-23 23:54:55 +0000 |
139 | +++ environs/cloudinit/cloudinit_test.go 2013-11-15 10:10:33 +0000 |
140 | @@ -352,7 +352,8 @@ |
141 | if test.setEnvConfig { |
142 | test.cfg.Config = minimalConfig(c) |
143 | } |
144 | - ci, err := cloudinit.New(&test.cfg) |
145 | + ci := coreCloudinit.New() |
146 | + err := cloudinit.Configure(&test.cfg, ci) |
147 | c.Assert(err, gc.IsNil) |
148 | c.Check(ci, gc.NotNil) |
149 | // render the cloudinit config to bytes, and then |
150 | @@ -394,9 +395,8 @@ |
151 | test.cfg.Config = minimalConfig(c) |
152 | c.Logf("test %d (Configure)", i) |
153 | cloudcfg := coreCloudinit.New() |
154 | - ci, err := cloudinit.Configure(&test.cfg, cloudcfg) |
155 | + err := cloudinit.Configure(&test.cfg, cloudcfg) |
156 | c.Assert(err, gc.IsNil) |
157 | - c.Check(ci, gc.NotNil) |
158 | } |
159 | } |
160 | |
161 | @@ -406,10 +406,9 @@ |
162 | script := "test script" |
163 | cloudcfg.AddRunCmd(script) |
164 | cloudinitTests[0].cfg.Config = minimalConfig(c) |
165 | - ci, err := cloudinit.Configure(&cloudinitTests[0].cfg, cloudcfg) |
166 | + err := cloudinit.Configure(&cloudinitTests[0].cfg, cloudcfg) |
167 | c.Assert(err, gc.IsNil) |
168 | - c.Check(ci, gc.NotNil) |
169 | - data, err := ci.Render() |
170 | + data, err := cloudcfg.Render() |
171 | c.Assert(err, gc.IsNil) |
172 | |
173 | ciContent := make(map[interface{}]interface{}) |
174 | @@ -683,16 +682,16 @@ |
175 | MachineNonce: "FAKE_NONCE", |
176 | } |
177 | // check that the base configuration does not give an error |
178 | - _, err := cloudinit.New(cfg) |
179 | + ci := coreCloudinit.New() |
180 | + err := cloudinit.Configure(cfg, ci) |
181 | c.Assert(err, gc.IsNil) |
182 | |
183 | for i, test := range verifyTests { |
184 | c.Logf("test %d. %s", i, test.err) |
185 | cfg1 := *cfg |
186 | test.mutate(&cfg1) |
187 | - t, err := cloudinit.New(&cfg1) |
188 | + err = cloudinit.Configure(&cfg1, ci) |
189 | c.Assert(err, gc.ErrorMatches, "invalid machine configuration: "+test.err) |
190 | - c.Assert(t, gc.IsNil) |
191 | } |
192 | } |
193 | |
194 | |
195 | === modified file 'environs/manual/agent.go' |
196 | --- environs/manual/agent.go 2013-11-01 04:06:00 +0000 |
197 | +++ environs/manual/agent.go 2013-11-15 10:10:33 +0000 |
198 | @@ -9,49 +9,23 @@ |
199 | "os" |
200 | "strings" |
201 | |
202 | - "launchpad.net/juju-core/agent" |
203 | corecloudinit "launchpad.net/juju-core/cloudinit" |
204 | - "launchpad.net/juju-core/constraints" |
205 | - "launchpad.net/juju-core/environs" |
206 | "launchpad.net/juju-core/environs/cloudinit" |
207 | - "launchpad.net/juju-core/environs/config" |
208 | - "launchpad.net/juju-core/provider" |
209 | - "launchpad.net/juju-core/state" |
210 | - "launchpad.net/juju-core/state/api" |
211 | - "launchpad.net/juju-core/tools" |
212 | "launchpad.net/juju-core/utils" |
213 | ) |
214 | |
215 | -type provisionMachineAgentArgs struct { |
216 | - host string |
217 | - dataDir string |
218 | - bootstrap bool |
219 | - environConfig *config.Config |
220 | - machineId string |
221 | - nonce string |
222 | - stateFileURL string |
223 | - stateInfo *state.Info |
224 | - apiInfo *api.Info |
225 | - tools *tools.Tools |
226 | - |
227 | - // agentEnv is an optional map of |
228 | - // arbitrary key/value pairs to pass |
229 | - // into the machine agent. |
230 | - agentEnv map[string]string |
231 | -} |
232 | - |
233 | -// provisionMachineAgent connects to a machine over SSH, |
234 | -// copies across the tools, and installs a machine agent. |
235 | -func provisionMachineAgent(args provisionMachineAgentArgs) error { |
236 | - logger.Infof("Provisioning machine agent on %s", args.host) |
237 | - script, err := provisionMachineAgentScript(args) |
238 | +// ProvisionMachineAgent connects to a machine over SSH, |
239 | +// and installs a machine agent. |
240 | +func ProvisionMachineAgent(host string, mcfg *cloudinit.MachineConfig) error { |
241 | + logger.Infof("Provisioning machine agent on %s", host) |
242 | + script, err := provisionMachineAgentScript(mcfg) |
243 | if err != nil { |
244 | return err |
245 | } |
246 | scriptBase64 := base64.StdEncoding.EncodeToString([]byte(script)) |
247 | script = fmt.Sprintf(`F=$(mktemp); echo %s | base64 -d > $F; . $F`, scriptBase64) |
248 | cmd := sshCommand( |
249 | - args.host, |
250 | + host, |
251 | fmt.Sprintf("sudo bash -c '%s'", script), |
252 | allocateTTY, |
253 | ) |
254 | @@ -62,31 +36,13 @@ |
255 | } |
256 | |
257 | // provisionMachineAgentScript generates the script necessary |
258 | -// to install a machine agent on the specified host. |
259 | -func provisionMachineAgentScript(args provisionMachineAgentArgs) (string, error) { |
260 | +// to install a machine agent with the provided MachineConfig. |
261 | +func provisionMachineAgentScript(mcfg *cloudinit.MachineConfig) (string, error) { |
262 | // We generate a cloud-init config, which we'll then pull the runcmds |
263 | // and prerequisite packages out of. Rather than generating a cloud-config, |
264 | // we'll just generate a shell script. |
265 | - var mcfg *cloudinit.MachineConfig |
266 | - if args.bootstrap { |
267 | - mcfg = environs.NewBootstrapMachineConfig(args.stateFileURL) |
268 | - } else { |
269 | - mcfg = environs.NewMachineConfig(args.machineId, args.nonce, args.stateInfo, args.apiInfo) |
270 | - } |
271 | - if args.dataDir != "" { |
272 | - mcfg.DataDir = args.dataDir |
273 | - } |
274 | - mcfg.Tools = args.tools |
275 | - err := environs.FinishMachineConfig(mcfg, args.environConfig, constraints.Value{}) |
276 | - if err != nil { |
277 | - return "", err |
278 | - } |
279 | - mcfg.AgentEnvironment[agent.ProviderType] = provider.Null |
280 | - for k, v := range args.agentEnv { |
281 | - mcfg.AgentEnvironment[k] = v |
282 | - } |
283 | cloudcfg := corecloudinit.New() |
284 | - if cloudcfg, err = cloudinit.Configure(mcfg, cloudcfg); err != nil { |
285 | + if err := cloudinit.Configure(mcfg, cloudcfg); err != nil { |
286 | return "", err |
287 | } |
288 | |
289 | @@ -148,7 +104,7 @@ |
290 | } |
291 | cmds = append(cmds, "apt-add-repository -y "+utils.ShQuote(src.Source)) |
292 | } |
293 | - if cfg.AptUpdate() { |
294 | + if len(cfg.AptSources()) > 0 { |
295 | cmds = append(cmds, "apt-get -y update") |
296 | } |
297 | // Note: explicitly ignoring apt_upgrade, so as not to trample the target |
298 | |
299 | === modified file 'environs/manual/agent_test.go' |
300 | --- environs/manual/agent_test.go 2013-11-01 04:06:00 +0000 |
301 | +++ environs/manual/agent_test.go 2013-11-15 10:10:33 +0000 |
302 | @@ -6,6 +6,9 @@ |
303 | import ( |
304 | gc "launchpad.net/gocheck" |
305 | |
306 | + "launchpad.net/juju-core/constraints" |
307 | + "launchpad.net/juju-core/environs" |
308 | + "launchpad.net/juju-core/environs/cloudinit" |
309 | "launchpad.net/juju-core/environs/config" |
310 | envtools "launchpad.net/juju-core/environs/tools" |
311 | _ "launchpad.net/juju-core/provider/dummy" |
312 | @@ -34,20 +37,21 @@ |
313 | return testConfig |
314 | } |
315 | |
316 | -func (s *agentSuite) getArgs(c *gc.C, stateServer bool, vers version.Binary) provisionMachineAgentArgs { |
317 | - tools := &tools.Tools{Version: vers} |
318 | - tools.URL = "file:///var/lib/juju/storage/" + envtools.StorageName(vers) |
319 | - return provisionMachineAgentArgs{ |
320 | - bootstrap: stateServer, |
321 | - environConfig: dummyConfig(c, stateServer, vers), |
322 | - machineId: "0", |
323 | - nonce: "ya", |
324 | - stateFileURL: "http://whatever/dotcom", |
325 | - tools: tools, |
326 | - // stateInfo *state.Info |
327 | - // apiInfo *api.Info |
328 | - agentEnv: make(map[string]string), |
329 | - } |
330 | +func (s *agentSuite) getMachineConfig(c *gc.C, stateServer bool, vers version.Binary) *cloudinit.MachineConfig { |
331 | + var mcfg *cloudinit.MachineConfig |
332 | + if stateServer { |
333 | + mcfg = environs.NewBootstrapMachineConfig("http://whatever/dotcom") |
334 | + } else { |
335 | + mcfg = environs.NewMachineConfig("0", "ya", nil, nil) |
336 | + } |
337 | + mcfg.Tools = &tools.Tools{ |
338 | + Version: vers, |
339 | + URL: "file:///var/lib/juju/storage/" + envtools.StorageName(vers), |
340 | + } |
341 | + environConfig := dummyConfig(c, stateServer, vers) |
342 | + err := environs.FinishMachineConfig(mcfg, environConfig, constraints.Value{}) |
343 | + c.Assert(err, gc.IsNil) |
344 | + return mcfg |
345 | } |
346 | |
347 | var allSeries = [...]string{"precise", "quantal", "raring", "saucy"} |
348 | @@ -62,7 +66,7 @@ |
349 | func (s *agentSuite) TestAptSources(c *gc.C) { |
350 | for _, series := range allSeries { |
351 | vers := version.MustParseBinary("1.16.0-" + series + "-amd64") |
352 | - script, err := provisionMachineAgentScript(s.getArgs(c, true, vers)) |
353 | + script, err := provisionMachineAgentScript(s.getMachineConfig(c, true, vers)) |
354 | c.Assert(err, gc.IsNil) |
355 | |
356 | // Only Precise requires the cloud-tools pocket. |
357 | |
358 | === modified file 'environs/manual/bootstrap.go' |
359 | --- environs/manual/bootstrap.go 2013-10-02 10:38:04 +0000 |
360 | +++ environs/manual/bootstrap.go 2013-11-15 10:10:33 +0000 |
361 | @@ -7,11 +7,11 @@ |
362 | "errors" |
363 | "fmt" |
364 | |
365 | + "launchpad.net/juju-core/constraints" |
366 | "launchpad.net/juju-core/environs" |
367 | envtools "launchpad.net/juju-core/environs/tools" |
368 | "launchpad.net/juju-core/instance" |
369 | "launchpad.net/juju-core/provider/common" |
370 | - "launchpad.net/juju-core/state" |
371 | "launchpad.net/juju-core/tools" |
372 | "launchpad.net/juju-core/worker/localstorage" |
373 | ) |
374 | @@ -108,15 +108,17 @@ |
375 | |
376 | // Finally, provision the machine agent. |
377 | stateFileURL := fmt.Sprintf("file://%s/%s", storageDir, common.StateFile) |
378 | - err = provisionMachineAgent(provisionMachineAgentArgs{ |
379 | - host: args.Host, |
380 | - dataDir: args.DataDir, |
381 | - environConfig: args.Environ.Config(), |
382 | - stateFileURL: stateFileURL, |
383 | - bootstrap: true, |
384 | - nonce: state.BootstrapNonce, |
385 | - tools: &tools, |
386 | - agentEnv: agentEnv, |
387 | - }) |
388 | - return err |
389 | + mcfg := environs.NewBootstrapMachineConfig(stateFileURL) |
390 | + if args.DataDir != "" { |
391 | + mcfg.DataDir = args.DataDir |
392 | + } |
393 | + mcfg.Tools = &tools |
394 | + err = environs.FinishMachineConfig(mcfg, args.Environ.Config(), constraints.Value{}) |
395 | + if err != nil { |
396 | + return err |
397 | + } |
398 | + for k, v := range agentEnv { |
399 | + mcfg.AgentEnvironment[k] = v |
400 | + } |
401 | + return ProvisionMachineAgent(args.Host, mcfg) |
402 | } |
403 | |
404 | === modified file 'environs/manual/provisioner.go' |
405 | --- environs/manual/provisioner.go 2013-11-08 02:52:25 +0000 |
406 | +++ environs/manual/provisioner.go 2013-11-15 10:10:33 +0000 |
407 | @@ -11,6 +11,9 @@ |
408 | |
409 | "launchpad.net/loggo" |
410 | |
411 | + "launchpad.net/juju-core/constraints" |
412 | + "launchpad.net/juju-core/environs" |
413 | + "launchpad.net/juju-core/environs/cloudinit" |
414 | "launchpad.net/juju-core/environs/config" |
415 | "launchpad.net/juju-core/instance" |
416 | "launchpad.net/juju-core/juju" |
417 | @@ -80,16 +83,13 @@ |
418 | } |
419 | |
420 | // Gather the information needed by the machine agent to run the provisioning script. |
421 | - provisioningArgs, err := createProvisioningArgs(client, machineId, series, arch) |
422 | + mcfg, err := createMachineConfig(client, machineId, series, arch, nonce, args.DataDir) |
423 | if err != nil { |
424 | return machineId, err |
425 | } |
426 | - provisioningArgs.host = args.Host |
427 | - provisioningArgs.dataDir = args.DataDir |
428 | - provisioningArgs.nonce = nonce |
429 | |
430 | // Finally, provision the machine agent. |
431 | - err = provisionMachineAgent(*provisioningArgs) |
432 | + err = ProvisionMachineAgent(args.Host, mcfg) |
433 | if err != nil { |
434 | return machineId, err |
435 | } |
436 | @@ -170,12 +170,11 @@ |
437 | return machineInfo.Machine, series, *hc.Arch, nil |
438 | } |
439 | |
440 | -func createProvisioningArgs(client *api.Client, machineId, series, arch string) (*provisionMachineAgentArgs, error) { |
441 | +func createMachineConfig(client *api.Client, machineId, series, arch, nonce, dataDir string) (*cloudinit.MachineConfig, error) { |
442 | configParameters, err := client.MachineConfig(machineId, series, arch) |
443 | if err != nil { |
444 | return nil, err |
445 | } |
446 | - |
447 | stateInfo := &state.Info{ |
448 | Addrs: configParameters.StateAddrs, |
449 | Password: configParameters.Password, |
450 | @@ -192,13 +191,14 @@ |
451 | if err != nil { |
452 | return nil, err |
453 | } |
454 | - |
455 | - return &provisionMachineAgentArgs{ |
456 | - environConfig: environConfig, |
457 | - machineId: machineId, |
458 | - bootstrap: false, |
459 | - stateInfo: stateInfo, |
460 | - apiInfo: apiInfo, |
461 | - tools: configParameters.Tools, |
462 | - }, nil |
463 | + mcfg := environs.NewMachineConfig(machineId, nonce, stateInfo, apiInfo) |
464 | + if dataDir != "" { |
465 | + mcfg.DataDir = dataDir |
466 | + } |
467 | + mcfg.Tools = configParameters.Tools |
468 | + err = environs.FinishMachineConfig(mcfg, environConfig, constraints.Value{}) |
469 | + if err != nil { |
470 | + return nil, err |
471 | + } |
472 | + return mcfg, nil |
473 | } |
Reviewers: mp+195342_ code.launchpad. net,
Message:
Please take a look.
Description: {cloudinit, manual}
Refactor environs/
environs/cloudinit has been modified to
have two sub-Configure methods:
ConfigureBase and ConfigureJuju. The
former initialises a cloud-init config
to setup a base OS with SSH keys; the
latter does the rest.
environs/manual has been modified to eAgent (now with MachineConfig.
expose provisionMachin
a capital P), which now just takes a
hostname and *cloudinit.
We will use this later to install
machine agents into cloud images.
https:/ /code.launchpad .net/~axwalk/ juju-core/ refactor- environs- manual/ +merge/ 195342
(do not edit description out of merge proposal)
Please review this at https:/ /codereview. appspot. com/26570047/
Affected files (+108, -130 lines): userdata. go cloudinit. go cloudinit/ cloudinit. go cloudinit/ cloudinit_ test.go manual/ agent.go manual/ agent_test. go manual/ bootstrap. go manual/ provisioner. go
A [revision details]
M container/
M environs/
M environs/
M environs/
M environs/
M environs/
M environs/
M environs/