Merge lp:~fwereade/juju-core/bootstrap-constraints-2 into lp:~juju/juju-core/trunk
- bootstrap-constraints-2
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 1021 |
Proposed branch: | lp:~fwereade/juju-core/bootstrap-constraints-2 |
Merge into: | lp:~juju/juju-core/trunk |
Prerequisite: | lp:~fwereade/juju-core/bootstrap-constraints-1 |
Diff against target: |
581 lines (+103/-56) 16 files modified
cmd/juju/bootstrap.go (+4/-2) cmd/juju/bootstrap_test.go (+26/-10) environs/bootstrap.go (+8/-11) environs/bootstrap_test.go (+24/-5) environs/dummy/environs.go (+9/-3) environs/ec2/ec2.go (+2/-1) environs/ec2/local_test.go (+1/-1) environs/interface.go (+4/-1) environs/jujutest/livetests.go (+3/-3) environs/jujutest/tests.go (+6/-6) environs/open_test.go (+2/-1) environs/openstack/local_test.go (+3/-3) environs/openstack/provider.go (+2/-1) juju/apiconn_test.go (+2/-1) juju/conn_test.go (+6/-6) juju/testing/conn.go (+1/-1) |
To merge this branch: | bzr merge lp:~fwereade/juju-core/bootstrap-constraints-2 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Juju Engineering | Pending | ||
Review via email: mp+153600@code.launchpad.net |
Commit message
Description of the change
cmd/juju: bootstrap accepts --constraints
...and passes them on to environs.Bootstrap, which passes them on to
Environ.Bootstrap. Only the dummy provider actually handles constraints
at the moment -- so we can test the bootstrap command -- all the others
will be implemented in followups.
William Reade (fwereade) wrote : | # |
Dimiter Naydenov (dimitern) wrote : | # |
LGTM, with some suggestions/
https:/
File cmd/juju/
https:/
cmd/juju/
"constraints", "set environment constraints")
This was included in the prereq CL with a slightly different wording -
won't it result in a merge conflict?
https:/
File cmd/juju/
https:/
cmd/juju/
"brokenenv"
this is iffy and kinda confusing - what's broken about it?
https:/
File environs/
https:/
environs/
Environ.Bootstrap.
please, update the comment to include the constraints arg.
https:/
File environs/
https:/
environs/
state.Constrain
couldn't this be *state.Constraints instead, so we can pass nil?
(elsewhere as well)
https:/
environs/
Bootstrap(cons state.Constraints, uploadTools bool, certPEM, keyPEM
[]byte) error {
see above
https:/
File environs/
https:/
environs/
bool, stateServerCert, stateServerKey []byte) error
please update the comment as well.
John A Meinel (jameinel) wrote : | # |
LGTM
https:/
File environs/
https:/
environs/
state.Constrain
+1, as it also means the struct doesn't get copied when it doesn't need
to. Though I suppose we want to avoid the side-effect of passing in
constraints and then changing the in-memory struct later?
But that could just be the final e.constraints = *cons (so it does do an
explicit copy at that point).
Tim Penhey (thumper) wrote : | # |
On 2013/03/18 22:54:54, dfc wrote:
> LGTM.
https:/
> File environs/
https:/
> environs/
> state.Constrain
> On 2013/03/18 18:04:58, jameinel wrote:
> > +1, as it also means the struct doesn't get copied when it doesn't
need to.
> > Though I suppose we want to avoid the side-effect of passing in
constraints
> and
> > then changing the in-memory struct later?
> > But that could just be the final e.constraints = *cons (so it does
do an
> > explicit copy at that point).
> I've pondered on this as well, passing a struct is less common than a
pointer to
> a struct, but in this case I think it is correct, if a little
unorthodox.
> By creating a new empty (zero value) constraint set here we guarantee
that it
> can't be mutated afterwards by the caller. This is a useful property
for
> something as contentious as constraints.
This is about to conflict wonderfully with the branch I'm about to
merge.
William Reade (fwereade) wrote : | # |
*** Submitted:
cmd/juju: bootstrap accepts --constraints
...and passes them on to environs.Bootstrap, which passes them on to
Environ.Bootstrap. Only the dummy provider actually handles constraints
at the moment -- so we can test the bootstrap command -- all the others
will be implemented in followups.
R=dimitern, jameinel, dfc, thumper
CC=
https:/
https:/
File cmd/juju/
https:/
cmd/juju/
"constraints", "set environment constraints")
On 2013/03/15 17:33:20, dimitern wrote:
> This was included in the prereq CL with a slightly different wording -
won't it
> result in a merge conflict?
That was jujud, not juju
https:/
File cmd/juju/
https:/
cmd/juju/
"brokenenv"
On 2013/03/15 17:33:20, dimitern wrote:
> this is iffy and kinda confusing - what's broken about it?
Dropped.
https:/
File environs/
https:/
environs/
Environ.Bootstrap.
On 2013/03/15 17:33:20, dimitern wrote:
> please, update the comment to include the constraints arg.
Done.
https:/
File environs/
https:/
environs/
state.Constrain
On 2013/03/18 22:54:54, dfc wrote:
> On 2013/03/18 18:04:58, jameinel wrote:
> > +1, as it also means the struct doesn't get copied when it doesn't
need to.
> > Though I suppose we want to avoid the side-effect of passing in
constraints
> and
> > then changing the in-memory struct later?
> > But that could just be the final e.constraints = *cons (so it does
do an
> > explicit copy at that point).
> I've pondered on this as well, passing a struct is less common than a
pointer to
> a struct, but in this case I think it is correct, if a little
unorthodox.
> By creating a new empty (zero value) constraint set here we guarantee
that it
> can't be mutated afterwards by the caller. This is a useful property
for
> something as contentious as constraints.
Value semantics are useful; there's no reason to use nil when there's a
perfectly good zero value; and I don't believe the overhead of copying
these structs around a bit is going to hurt us.
https:/
File environs/
https:/
environs/
bool, stateServerCert, stateServerKey []byte) error
On 20...
Preview Diff
1 | === modified file 'cmd/juju/bootstrap.go' |
2 | --- cmd/juju/bootstrap.go 2013-03-18 22:33:50 +0000 |
3 | +++ cmd/juju/bootstrap.go 2013-03-19 10:29:25 +0000 |
4 | @@ -5,6 +5,7 @@ |
5 | "launchpad.net/gnuflag" |
6 | "launchpad.net/juju-core/cmd" |
7 | "launchpad.net/juju-core/environs" |
8 | + "launchpad.net/juju-core/state" |
9 | "os" |
10 | ) |
11 | |
12 | @@ -12,6 +13,7 @@ |
13 | // environment, and setting up everything necessary to continue working. |
14 | type BootstrapCommand struct { |
15 | EnvCommandBase |
16 | + Constraints state.Constraints |
17 | UploadTools bool |
18 | } |
19 | |
20 | @@ -24,6 +26,7 @@ |
21 | |
22 | func (c *BootstrapCommand) SetFlags(f *gnuflag.FlagSet) { |
23 | c.EnvCommandBase.SetFlags(f) |
24 | + f.Var(state.ConstraintsValue{&c.Constraints}, "constraints", "set environment constraints") |
25 | f.BoolVar(&c.UploadTools, "upload-tools", false, "upload local version of tools before bootstrapping") |
26 | } |
27 | |
28 | @@ -43,11 +46,10 @@ |
29 | } |
30 | return err |
31 | } |
32 | - |
33 | // TODO: if in verbose mode, write out to Stdout if a new cert was created. |
34 | _, err = environs.EnsureCertificate(environ, environs.WriteCertAndKeyToHome) |
35 | if err != nil { |
36 | return err |
37 | } |
38 | - return environs.Bootstrap(environ, c.UploadTools) |
39 | + return environs.Bootstrap(environ, c.Constraints, c.UploadTools) |
40 | } |
41 | |
42 | === modified file 'cmd/juju/bootstrap_test.go' |
43 | --- cmd/juju/bootstrap_test.go 2013-03-18 22:45:01 +0000 |
44 | +++ cmd/juju/bootstrap_test.go 2013-03-19 10:29:25 +0000 |
45 | @@ -7,6 +7,7 @@ |
46 | "launchpad.net/juju-core/environs" |
47 | "launchpad.net/juju-core/environs/agent" |
48 | "launchpad.net/juju-core/environs/dummy" |
49 | + "launchpad.net/juju-core/state" |
50 | "launchpad.net/juju-core/testing" |
51 | "launchpad.net/juju-core/version" |
52 | "net/http" |
53 | @@ -42,6 +43,15 @@ |
54 | dummy.Reset() |
55 | } |
56 | |
57 | +func (*BootstrapSuite) TestBasic(c *C) { |
58 | + defer testing.MakeFakeHome(c, envConfig).Restore() |
59 | + opc, errc := runCommand(new(BootstrapCommand)) |
60 | + c.Check(<-errc, IsNil) |
61 | + opBootstrap := (<-opc).(dummy.OpBootstrap) |
62 | + c.Check(opBootstrap.Env, Equals, "peckham") |
63 | + c.Check(opBootstrap.Constraints, DeepEquals, state.Constraints{}) |
64 | +} |
65 | + |
66 | func (*BootstrapSuite) TestRunGeneratesCertificate(c *C) { |
67 | defer testing.MakeFakeHome(c, envConfig).Restore() |
68 | envName := "peckham" |
69 | @@ -62,14 +72,19 @@ |
70 | c.Assert(err, IsNil) |
71 | } |
72 | |
73 | -func (*BootstrapSuite) TestBootstrapCommandNoParams(c *C) { |
74 | - defer testing.MakeFakeHome(c, envConfig).Restore() |
75 | - opc, errc := runCommand(new(BootstrapCommand)) |
76 | +func (*BootstrapSuite) TestConstraints(c *C) { |
77 | + defer testing.MakeFakeHome(c, envConfig, "brokenenv").Restore() |
78 | + scons := " cpu-cores=2 mem=4G" |
79 | + cons, err := state.ParseConstraints(scons) |
80 | + c.Assert(err, IsNil) |
81 | + opc, errc := runCommand(new(BootstrapCommand), "--constraints", scons) |
82 | c.Check(<-errc, IsNil) |
83 | - c.Check((<-opc).(dummy.OpBootstrap).Env, Equals, "peckham") |
84 | + opBootstrap := (<-opc).(dummy.OpBootstrap) |
85 | + c.Check(opBootstrap.Env, Equals, "peckham") |
86 | + c.Check(opBootstrap.Constraints, DeepEquals, cons) |
87 | } |
88 | |
89 | -func (*BootstrapSuite) TestBootstrapCommandUploadTools(c *C) { |
90 | +func (*BootstrapSuite) TestUploadTools(c *C) { |
91 | defer testing.MakeFakeHome(c, envConfig).Restore() |
92 | // bootstrap with tool uploading - checking that a file |
93 | // is uploaded should be sufficient, as the detailed semantics |
94 | @@ -77,24 +92,26 @@ |
95 | opc, errc := runCommand(new(BootstrapCommand), "--upload-tools") |
96 | c.Check(<-errc, IsNil) |
97 | c.Check((<-opc).(dummy.OpPutFile).Env, Equals, "peckham") |
98 | - c.Check((<-opc).(dummy.OpBootstrap).Env, Equals, "peckham") |
99 | + opBootstrap := (<-opc).(dummy.OpBootstrap) |
100 | + c.Check(opBootstrap.Env, Equals, "peckham") |
101 | + c.Check(opBootstrap.Constraints, DeepEquals, state.Constraints{}) |
102 | |
103 | + // Check that some file was uploaded and can be unpacked; detailed |
104 | + // semantics tested elsewhere. |
105 | envs, err := environs.ReadEnvirons("") |
106 | c.Assert(err, IsNil) |
107 | env, err := envs.Open("peckham") |
108 | c.Assert(err, IsNil) |
109 | - |
110 | tools, err := environs.FindTools(env, version.Current, environs.CompatVersion) |
111 | c.Assert(err, IsNil) |
112 | resp, err := http.Get(tools.URL) |
113 | c.Assert(err, IsNil) |
114 | defer resp.Body.Close() |
115 | - |
116 | err = agent.UnpackTools(c.MkDir(), tools, resp.Body) |
117 | c.Assert(err, IsNil) |
118 | } |
119 | |
120 | -func (*BootstrapSuite) TestBootstrapCommandBrokenEnvironment(c *C) { |
121 | +func (*BootstrapSuite) TestBrokenEnvironment(c *C) { |
122 | defer testing.MakeFakeHome(c, envConfig).Restore() |
123 | opc, errc := runCommand(new(BootstrapCommand), "-e", "brokenenv") |
124 | c.Check(<-errc, ErrorMatches, "dummy.Bootstrap is broken") |
125 | @@ -103,7 +120,6 @@ |
126 | |
127 | func (*BootstrapSuite) TestMissingEnvironment(c *C) { |
128 | defer testing.MakeFakeHomeNoEnvironments(c, "empty").Restore() |
129 | - // bootstrap without an environments.yaml |
130 | ctx := testing.Context(c) |
131 | code := cmd.Main(&BootstrapCommand{}, ctx, nil) |
132 | c.Check(code, Equals, 1) |
133 | |
134 | === modified file 'environs/bootstrap.go' |
135 | --- environs/bootstrap.go 2013-03-15 01:31:54 +0000 |
136 | +++ environs/bootstrap.go 2013-03-19 10:29:25 +0000 |
137 | @@ -3,19 +3,16 @@ |
138 | import ( |
139 | "fmt" |
140 | "launchpad.net/juju-core/cert" |
141 | + "launchpad.net/juju-core/state" |
142 | "time" |
143 | ) |
144 | |
145 | -// Bootstrap bootstraps the given environment. If the environment does |
146 | -// not contain a CA certificate, a new certificate and key pair are |
147 | -// generated, added to the environment configuration, and writeCertAndKey |
148 | -// will be called to save them. If writeCertFile is nil, the generated |
149 | -// certificate and key will be saved to ~/.juju/<environ-name>-cert.pem |
150 | -// and ~/.juju/<environ-name>-private-key.pem. |
151 | -// |
152 | -// If uploadTools is true, the current version of the juju tools will be |
153 | -// uploaded, as documented in Environ.Bootstrap. |
154 | -func Bootstrap(environ Environ, uploadTools bool) error { |
155 | +// Bootstrap bootstraps the given environment. The supplied constraints are |
156 | +// used to provision the instance, and are also set within the bootstrapped |
157 | +// environment. The uploadTools parameter requires that the juju-core source |
158 | +// code be available within $GOPATH; if that is the case, that code will be |
159 | +// built locally and made available to the environment. |
160 | +func Bootstrap(environ Environ, cons state.Constraints, uploadTools bool) error { |
161 | cfg := environ.Config() |
162 | caCert, hasCACert := cfg.CACert() |
163 | caKey, hasCAKey := cfg.CAPrivateKey() |
164 | @@ -31,5 +28,5 @@ |
165 | if err != nil { |
166 | return fmt.Errorf("cannot generate bootstrap certificate: %v", err) |
167 | } |
168 | - return environ.Bootstrap(uploadTools, cert, key) |
169 | + return environ.Bootstrap(cons, uploadTools, cert, key) |
170 | } |
171 | |
172 | === modified file 'environs/bootstrap_test.go' |
173 | --- environs/bootstrap_test.go 2013-03-15 00:23:00 +0000 |
174 | +++ environs/bootstrap_test.go 2013-03-19 10:29:25 +0000 |
175 | @@ -7,6 +7,7 @@ |
176 | "launchpad.net/juju-core/cert" |
177 | "launchpad.net/juju-core/environs" |
178 | "launchpad.net/juju-core/environs/config" |
179 | + "launchpad.net/juju-core/state" |
180 | "launchpad.net/juju-core/testing" |
181 | "time" |
182 | ) |
183 | @@ -34,13 +35,13 @@ |
184 | |
185 | func (s *bootstrapSuite) TestBootstrapNeedsConfigCert(c *C) { |
186 | env := newEnviron("bar", noKeysDefined) |
187 | - err := environs.Bootstrap(env, false) |
188 | + err := environs.Bootstrap(env, state.Constraints{}, false) |
189 | c.Assert(err, ErrorMatches, "environment configuration missing CA certificate") |
190 | } |
191 | |
192 | func (s *bootstrapSuite) TestBootstrapKeyGeneration(c *C) { |
193 | env := newEnviron("foo", useDefaultKeys) |
194 | - err := environs.Bootstrap(env, false) |
195 | + err := environs.Bootstrap(env, state.Constraints{}, false) |
196 | c.Assert(err, IsNil) |
197 | c.Assert(env.bootstrapCount, Equals, 1) |
198 | |
199 | @@ -55,18 +56,34 @@ |
200 | |
201 | func (s *bootstrapSuite) TestBootstrapUploadTools(c *C) { |
202 | env := newEnviron("foo", useDefaultKeys) |
203 | - err := environs.Bootstrap(env, false) |
204 | + err := environs.Bootstrap(env, state.Constraints{}, false) |
205 | c.Assert(err, IsNil) |
206 | c.Assert(env.bootstrapCount, Equals, 1) |
207 | c.Assert(env.uploadTools, Equals, false) |
208 | |
209 | env = newEnviron("foo", useDefaultKeys) |
210 | - err = environs.Bootstrap(env, true) |
211 | + err = environs.Bootstrap(env, state.Constraints{}, true) |
212 | c.Assert(err, IsNil) |
213 | c.Assert(env.bootstrapCount, Equals, 1) |
214 | c.Assert(env.uploadTools, Equals, true) |
215 | } |
216 | |
217 | +func (s *bootstrapSuite) TestBootstrapConstraints(c *C) { |
218 | + env := newEnviron("foo", useDefaultKeys) |
219 | + err := environs.Bootstrap(env, state.Constraints{}, false) |
220 | + c.Assert(err, IsNil) |
221 | + c.Assert(env.bootstrapCount, Equals, 1) |
222 | + c.Assert(env.constraints, DeepEquals, state.Constraints{}) |
223 | + |
224 | + env = newEnviron("foo", useDefaultKeys) |
225 | + cons, err := state.ParseConstraints("cpu-cores=2 mem=4G") |
226 | + c.Assert(err, IsNil) |
227 | + err = environs.Bootstrap(env, cons, false) |
228 | + c.Assert(err, IsNil) |
229 | + c.Assert(env.bootstrapCount, Equals, 1) |
230 | + c.Assert(env.constraints, DeepEquals, cons) |
231 | +} |
232 | + |
233 | type bootstrapEnviron struct { |
234 | name string |
235 | cfg *config.Config |
236 | @@ -74,6 +91,7 @@ |
237 | |
238 | // The following fields are filled in when Bootstrap is called. |
239 | bootstrapCount int |
240 | + constraints state.Constraints |
241 | uploadTools bool |
242 | certPEM []byte |
243 | keyPEM []byte |
244 | @@ -105,8 +123,9 @@ |
245 | return e.name |
246 | } |
247 | |
248 | -func (e *bootstrapEnviron) Bootstrap(uploadTools bool, certPEM, keyPEM []byte) error { |
249 | +func (e *bootstrapEnviron) Bootstrap(cons state.Constraints, uploadTools bool, certPEM, keyPEM []byte) error { |
250 | e.bootstrapCount++ |
251 | + e.constraints = cons |
252 | e.uploadTools = uploadTools |
253 | e.certPEM = certPEM |
254 | e.keyPEM = keyPEM |
255 | |
256 | === modified file 'environs/dummy/environs.go' |
257 | --- environs/dummy/environs.go 2013-03-14 02:38:14 +0000 |
258 | +++ environs/dummy/environs.go 2013-03-19 10:29:25 +0000 |
259 | @@ -59,7 +59,10 @@ |
260 | Env string |
261 | } |
262 | |
263 | -type OpBootstrap GenericOperation |
264 | +type OpBootstrap struct { |
265 | + Env string |
266 | + Constraints state.Constraints |
267 | +} |
268 | |
269 | type OpDestroy GenericOperation |
270 | |
271 | @@ -425,7 +428,7 @@ |
272 | return e.state.name |
273 | } |
274 | |
275 | -func (e *environ) Bootstrap(uploadTools bool, cert, key []byte) error { |
276 | +func (e *environ) Bootstrap(cons state.Constraints, uploadTools bool, cert, key []byte) error { |
277 | defer delay() |
278 | if err := e.checkBroken("Bootstrap"); err != nil { |
279 | return err |
280 | @@ -453,7 +456,7 @@ |
281 | } |
282 | e.state.mu.Lock() |
283 | defer e.state.mu.Unlock() |
284 | - e.state.ops <- OpBootstrap{Env: e.state.name} |
285 | + e.state.ops <- OpBootstrap{Env: e.state.name, Constraints: cons} |
286 | if e.state.bootstrapped { |
287 | return fmt.Errorf("environment is already bootstrapped") |
288 | } |
289 | @@ -467,6 +470,9 @@ |
290 | if err != nil { |
291 | panic(err) |
292 | } |
293 | + if err := st.SetEnvironConstraints(cons); err != nil { |
294 | + panic(err) |
295 | + } |
296 | if err := st.SetAdminMongoPassword(trivial.PasswordHash(password)); err != nil { |
297 | panic(err) |
298 | } |
299 | |
300 | === modified file 'environs/ec2/ec2.go' |
301 | --- environs/ec2/ec2.go 2013-03-14 02:38:14 +0000 |
302 | +++ environs/ec2/ec2.go 2013-03-19 10:29:25 +0000 |
303 | @@ -236,7 +236,8 @@ |
304 | return e.publicStorageUnlocked |
305 | } |
306 | |
307 | -func (e *environ) Bootstrap(uploadTools bool, cert, key []byte) error { |
308 | +func (e *environ) Bootstrap(cons state.Constraints, uploadTools bool, cert, key []byte) error { |
309 | + // TODO(fwereade): handle bootstrap constraints |
310 | password := e.Config().AdminSecret() |
311 | if password == "" { |
312 | return fmt.Errorf("admin-secret is required for bootstrap") |
313 | |
314 | === modified file 'environs/ec2/local_test.go' |
315 | --- environs/ec2/local_test.go 2013-03-13 05:03:32 +0000 |
316 | +++ environs/ec2/local_test.go 2013-03-19 10:29:25 +0000 |
317 | @@ -237,7 +237,7 @@ |
318 | policy := t.env.AssignmentPolicy() |
319 | c.Assert(policy, Equals, state.AssignUnused) |
320 | |
321 | - err := environs.Bootstrap(t.env, true) |
322 | + err := environs.Bootstrap(t.env, state.Constraints{}, true) |
323 | c.Assert(err, IsNil) |
324 | |
325 | // check that the state holds the id of the bootstrap machine. |
326 | |
327 | === modified file 'environs/interface.go' |
328 | --- environs/interface.go 2013-02-27 13:28:43 +0000 |
329 | +++ environs/interface.go 2013-03-19 10:29:25 +0000 |
330 | @@ -145,10 +145,13 @@ |
331 | // environment via the juju package, the password hash will be |
332 | // automatically replaced by the real password. |
333 | // |
334 | + // The supplied constraints are used to choose the initial instance |
335 | + // specification, and will be stored in the new environment's state. |
336 | + // |
337 | // The stateServerCertand stateServerKey parameters hold |
338 | // both the certificate and the respective private key to be |
339 | // used by the initial state server, in PEM format. |
340 | - Bootstrap(uploadTools bool, stateServerCert, stateServerKey []byte) error |
341 | + Bootstrap(cons state.Constraints, uploadTools bool, stateServerCert, stateServerKey []byte) error |
342 | |
343 | // StateInfo returns information on the state initialized |
344 | // by Bootstrap. |
345 | |
346 | === modified file 'environs/jujutest/livetests.go' |
347 | --- environs/jujutest/livetests.go 2013-03-13 05:03:32 +0000 |
348 | +++ environs/jujutest/livetests.go 2013-03-19 10:29:25 +0000 |
349 | @@ -81,7 +81,7 @@ |
350 | } |
351 | // We only build and upload tools if there will be a state agent that |
352 | // we could connect to (actual live tests, rather than local-only) |
353 | - err := environs.Bootstrap(t.Env, t.CanOpenState) |
354 | + err := environs.Bootstrap(t.Env, state.Constraints{}, t.CanOpenState) |
355 | c.Assert(err, IsNil) |
356 | t.bootstrapped = true |
357 | } |
358 | @@ -301,7 +301,7 @@ |
359 | func (t *LiveTests) TestBootstrapMultiple(c *C) { |
360 | t.BootstrapOnce(c) |
361 | |
362 | - err := environs.Bootstrap(t.Env, false) |
363 | + err := environs.Bootstrap(t.Env, state.Constraints{}, false) |
364 | c.Assert(err, ErrorMatches, "environment is already bootstrapped") |
365 | |
366 | c.Logf("destroy env") |
367 | @@ -731,7 +731,7 @@ |
368 | err = storageCopy(dummyStorage, currentPath, envStorage, otherPath) |
369 | c.Assert(err, IsNil) |
370 | |
371 | - err = environs.Bootstrap(env, false) |
372 | + err = environs.Bootstrap(env, state.Constraints{}, false) |
373 | c.Assert(err, IsNil) |
374 | defer env.Destroy(nil) |
375 | |
376 | |
377 | === modified file 'environs/jujutest/tests.go' |
378 | --- environs/jujutest/tests.go 2013-03-13 05:03:32 +0000 |
379 | +++ environs/jujutest/tests.go 2013-03-19 10:29:25 +0000 |
380 | @@ -52,7 +52,7 @@ |
381 | delete(m, "admin-secret") |
382 | env, err := environs.NewFromAttrs(m) |
383 | c.Assert(err, IsNil) |
384 | - err = environs.Bootstrap(env, false) |
385 | + err = environs.Bootstrap(env, state.Constraints{}, false) |
386 | c.Assert(err, ErrorMatches, ".*admin-secret is required for bootstrap") |
387 | } |
388 | |
389 | @@ -107,18 +107,18 @@ |
390 | func (t *Tests) TestBootstrap(c *C) { |
391 | // TODO tests for Bootstrap(true) |
392 | e := t.Open(c) |
393 | - err := environs.Bootstrap(e, false) |
394 | + err := environs.Bootstrap(e, state.Constraints{}, false) |
395 | c.Assert(err, IsNil) |
396 | |
397 | info, apiInfo, err := e.StateInfo() |
398 | c.Check(info.Addrs, Not(HasLen), 0) |
399 | c.Check(apiInfo.Addrs, Not(HasLen), 0) |
400 | |
401 | - err = environs.Bootstrap(e, false) |
402 | + err = environs.Bootstrap(e, state.Constraints{}, false) |
403 | c.Assert(err, ErrorMatches, "environment is already bootstrapped") |
404 | |
405 | e2 := t.Open(c) |
406 | - err = environs.Bootstrap(e2, false) |
407 | + err = environs.Bootstrap(e2, state.Constraints{}, false) |
408 | c.Assert(err, ErrorMatches, "environment is already bootstrapped") |
409 | |
410 | info2, apiInfo2, err := e2.StateInfo() |
411 | @@ -131,10 +131,10 @@ |
412 | // Open again because Destroy invalidates old environments. |
413 | e3 := t.Open(c) |
414 | |
415 | - err = environs.Bootstrap(e3, false) |
416 | + err = environs.Bootstrap(e3, state.Constraints{}, false) |
417 | c.Assert(err, IsNil) |
418 | |
419 | - err = environs.Bootstrap(e3, false) |
420 | + err = environs.Bootstrap(e3, state.Constraints{}, false) |
421 | c.Assert(err, NotNil) |
422 | } |
423 | |
424 | |
425 | === modified file 'environs/open_test.go' |
426 | --- environs/open_test.go 2013-03-06 20:21:43 +0000 |
427 | +++ environs/open_test.go 2013-03-19 10:29:25 +0000 |
428 | @@ -4,6 +4,7 @@ |
429 | . "launchpad.net/gocheck" |
430 | "launchpad.net/juju-core/environs" |
431 | "launchpad.net/juju-core/environs/dummy" |
432 | + "launchpad.net/juju-core/state" |
433 | "launchpad.net/juju-core/testing" |
434 | ) |
435 | |
436 | @@ -28,7 +29,7 @@ |
437 | } |
438 | env, err := environs.NewFromAttrs(config) |
439 | c.Assert(err, IsNil) |
440 | - c.Assert(env.Bootstrap(false, nil, nil), IsNil) |
441 | + c.Assert(env.Bootstrap(state.Constraints{}, false, nil, nil), IsNil) |
442 | } |
443 | |
444 | func (OpenSuite) TestNewUnknownEnviron(c *C) { |
445 | |
446 | === modified file 'environs/openstack/local_test.go' |
447 | --- environs/openstack/local_test.go 2013-03-13 05:03:32 +0000 |
448 | +++ environs/openstack/local_test.go 2013-03-19 10:29:25 +0000 |
449 | @@ -232,7 +232,7 @@ |
450 | newconfig["use-floating-ip"] = true |
451 | env, err := environs.NewFromAttrs(newconfig) |
452 | c.Assert(err, IsNil) |
453 | - err = environs.Bootstrap(env, s.CanOpenState) |
454 | + err = environs.Bootstrap(env, state.Constraints{}, s.CanOpenState) |
455 | c.Assert(err, ErrorMatches, ".*cannot allocate a public IP as needed.*") |
456 | } |
457 | |
458 | @@ -254,7 +254,7 @@ |
459 | }, |
460 | ) |
461 | defer cleanup() |
462 | - err := environs.Bootstrap(s.Env, false) |
463 | + err := environs.Bootstrap(s.Env, state.Constraints{}, false) |
464 | c.Assert(err, IsNil) |
465 | inst, err := s.Env.StartInstance("100", testing.InvalidStateInfo("100"), testing.InvalidAPIInfo("100"), nil) |
466 | c.Assert(err, IsNil) |
467 | @@ -355,7 +355,7 @@ |
468 | policy := t.env.AssignmentPolicy() |
469 | c.Assert(policy, Equals, state.AssignUnused) |
470 | |
471 | - err := environs.Bootstrap(t.env, false) |
472 | + err := environs.Bootstrap(t.env, state.Constraints{}, false) |
473 | c.Assert(err, IsNil) |
474 | |
475 | // check that the state holds the id of the bootstrap machine. |
476 | |
477 | === modified file 'environs/openstack/provider.go' |
478 | --- environs/openstack/provider.go 2013-03-14 02:38:14 +0000 |
479 | +++ environs/openstack/provider.go 2013-03-19 10:29:25 +0000 |
480 | @@ -416,7 +416,8 @@ |
481 | return e.publicStorageUnlocked |
482 | } |
483 | |
484 | -func (e *environ) Bootstrap(uploadTools bool, cert, key []byte) error { |
485 | +func (e *environ) Bootstrap(cons state.Constraints, uploadTools bool, cert, key []byte) error { |
486 | + // TODO(fwereade): handle bootstrap constraints |
487 | password := e.Config().AdminSecret() |
488 | if password == "" { |
489 | return fmt.Errorf("admin-secret is required for bootstrap") |
490 | |
491 | === modified file 'juju/apiconn_test.go' |
492 | --- juju/apiconn_test.go 2013-03-13 05:03:32 +0000 |
493 | +++ juju/apiconn_test.go 2013-03-19 10:29:25 +0000 |
494 | @@ -5,6 +5,7 @@ |
495 | "launchpad.net/juju-core/environs" |
496 | "launchpad.net/juju-core/environs/dummy" |
497 | "launchpad.net/juju-core/juju" |
498 | + "launchpad.net/juju-core/state" |
499 | coretesting "launchpad.net/juju-core/testing" |
500 | ) |
501 | |
502 | @@ -32,7 +33,7 @@ |
503 | } |
504 | env, err := environs.NewFromAttrs(attrs) |
505 | c.Assert(err, IsNil) |
506 | - err = environs.Bootstrap(env, false) |
507 | + err = environs.Bootstrap(env, state.Constraints{}, false) |
508 | c.Assert(err, IsNil) |
509 | |
510 | conn, err := juju.NewConn(env) |
511 | |
512 | === modified file 'juju/conn_test.go' |
513 | --- juju/conn_test.go 2013-03-13 05:03:32 +0000 |
514 | +++ juju/conn_test.go 2013-03-19 10:29:25 +0000 |
515 | @@ -44,7 +44,7 @@ |
516 | } |
517 | env, err := environs.NewFromAttrs(attrs) |
518 | c.Assert(err, IsNil) |
519 | - err = environs.Bootstrap(env, false) |
520 | + err = environs.Bootstrap(env, state.Constraints{}, false) |
521 | c.Assert(err, IsNil) |
522 | |
523 | delete(attrs, "admin-secret") |
524 | @@ -65,7 +65,7 @@ |
525 | func bootstrapEnv(c *C, envName string) { |
526 | environ, err := environs.NewFromName(envName) |
527 | c.Assert(err, IsNil) |
528 | - err = environs.Bootstrap(environ, false) |
529 | + err = environs.Bootstrap(environ, state.Constraints{}, false) |
530 | c.Assert(err, IsNil) |
531 | } |
532 | |
533 | @@ -112,7 +112,7 @@ |
534 | } |
535 | env, err := environs.NewFromAttrs(attrs) |
536 | c.Assert(err, IsNil) |
537 | - err = environs.Bootstrap(env, false) |
538 | + err = environs.Bootstrap(env, state.Constraints{}, false) |
539 | c.Assert(err, IsNil) |
540 | info, _, err := env.StateInfo() |
541 | c.Assert(err, IsNil) |
542 | @@ -152,7 +152,7 @@ |
543 | } |
544 | env, err := environs.NewFromAttrs(attrs) |
545 | c.Assert(err, IsNil) |
546 | - err = environs.Bootstrap(env, false) |
547 | + err = environs.Bootstrap(env, state.Constraints{}, false) |
548 | c.Assert(err, IsNil) |
549 | |
550 | // Make a new Conn, which will push the secrets. |
551 | @@ -190,7 +190,7 @@ |
552 | "ca-private-key": coretesting.CAKey, |
553 | }) |
554 | c.Assert(err, IsNil) |
555 | - err = environs.Bootstrap(env, false) |
556 | + err = environs.Bootstrap(env, state.Constraints{}, false) |
557 | c.Assert(err, IsNil) |
558 | |
559 | // Check that Bootstrap has correctly used a hash |
560 | @@ -248,7 +248,7 @@ |
561 | } |
562 | environ, err := environs.NewFromAttrs(attrs) |
563 | c.Assert(err, IsNil) |
564 | - err = environs.Bootstrap(environ, false) |
565 | + err = environs.Bootstrap(environ, state.Constraints{}, false) |
566 | c.Assert(err, IsNil) |
567 | s.conn, err = juju.NewConn(environ) |
568 | c.Assert(err, IsNil) |
569 | |
570 | === modified file 'juju/testing/conn.go' |
571 | --- juju/testing/conn.go 2013-03-18 23:15:14 +0000 |
572 | +++ juju/testing/conn.go 2013-03-19 10:29:25 +0000 |
573 | @@ -150,7 +150,7 @@ |
574 | c.Assert(err, IsNil) |
575 | // sanity check we've got the correct environment. |
576 | c.Assert(environ.Name(), Equals, "dummyenv") |
577 | - c.Assert(environs.Bootstrap(environ, false), IsNil) |
578 | + c.Assert(environs.Bootstrap(environ, state.Constraints{}, false), IsNil) |
579 | |
580 | conn, err := juju.NewConn(environ) |
581 | c.Assert(err, IsNil) |
Reviewers: mp+153600_ code.launchpad. net,
Message:
Please take a look.
Description:
cmd/juju: bootstrap accepts --constraints
...and passes them on to environs.Bootstrap, which passes them on to
Environ.Bootstrap. Only the dummy provider actually handles constraints
at the moment -- so we can test the bootstrap command -- all the others
will be implemented in followups.
https:/ /code.launchpad .net/~fwereade/ juju-core/ bootstrap- constraints- 2/+merge/ 153600
Requires: /code.launchpad .net/~fwereade/ juju-core/ bootstrap- constraints- 1/+merge/ 153523
https:/
(do not edit description out of merge proposal)
Please review this at https:/ /codereview. appspot. com/7610048/
Affected files: bootstrap. go bootstrap_ test.go bootstrap. go bootstrap_ test.go dummy/environs. go ec2/local_ test.go interface. go jujutest/ livetests. go jujutest/ tests.go open_test. go openstack/ local_test. go openstack/ provider. go test.go conn.go
A [revision details]
M cmd/builddb/main.go
M cmd/juju/
M cmd/juju/
M environs/
M environs/
M environs/
M environs/ec2/ec2.go
M environs/
M environs/
M environs/
M environs/
M environs/
M environs/
M environs/
M juju/apiconn_
M juju/conn_test.go
M juju/testing/