Merge lp:~axwalk/juju-core/lp1237709-bootstrap-placement into lp:~go-bot/juju-core/trunk

Proposed by Andrew Wilkins
Status: Merged
Approved by: Andrew Wilkins
Approved revision: no longer in the source branch.
Merged at revision: 2674
Proposed branch: lp:~axwalk/juju-core/lp1237709-bootstrap-placement
Merge into: lp:~go-bot/juju-core/trunk
Diff against target: 1076 lines (+155/-109)
33 files modified
cmd/juju/bootstrap.go (+24/-2)
cmd/juju/bootstrap_test.go (+11/-5)
cmd/juju/cmd_test.go (+0/-5)
cmd/juju/deploy_test.go (+3/-0)
cmd/plugins/juju-restore/restore.go (+2/-1)
environs/bootstrap/bootstrap.go (+2/-3)
environs/bootstrap/bootstrap_test.go (+25/-15)
environs/interface.go (+12/-4)
environs/jujutest/livetests.go (+2/-2)
environs/jujutest/tests.go (+2/-3)
environs/open_test.go (+1/-2)
instance/placement.go (+1/-1)
juju/apiconn_test.go (+2/-3)
juju/conn_test.go (+6/-6)
juju/testing/conn.go (+1/-2)
provider/azure/environ.go (+2/-2)
provider/common/bootstrap.go (+4/-4)
provider/common/bootstrap_test.go (+13/-8)
provider/common/mock_test.go (+2/-1)
provider/dummy/environs.go (+7/-7)
provider/ec2/ec2.go (+2/-2)
provider/ec2/local_test.go (+4/-4)
provider/joyent/environ.go (+2/-2)
provider/joyent/local_test.go (+3/-3)
provider/local/config_test.go (+2/-2)
provider/local/environ.go (+2/-2)
provider/local/environ_test.go (+1/-1)
provider/maas/environ.go (+2/-2)
provider/maas/environ_whitebox_test.go (+4/-4)
provider/manual/environ.go (+2/-1)
provider/openstack/live_test.go (+1/-2)
provider/openstack/local_test.go (+6/-6)
provider/openstack/provider.go (+2/-2)
To merge this branch: bzr merge lp:~axwalk/juju-core/lp1237709-bootstrap-placement
Reviewer Review Type Date Requested Status
Juju Engineering Pending
Review via email: mp+216971@code.launchpad.net

Commit message

Support placement directives on bootstrap

juju bootstrap will accept a single, optional
positional argument that will be parsed as a
placement directive. We currently only allow
unscoped placement directives at bootstrap.

https://codereview.appspot.com/91740043/

Description of the change

Support placement directives on bootstrap

juju bootstrap will accept a single, optional
positional argument that will be parsed as a
placement directive. We currently only allow
unscoped placement directives at bootstrap.

https://codereview.appspot.com/91740043/

To post a comment you must log in.
Revision history for this message
Andrew Wilkins (axwalk) wrote :

Reviewers: mp+216971_code.launchpad.net,

Message:
Please take a look.

Description:
Support placement directives on bootstrap

juju bootstrap will accept a single, optional
positional argument that will be parsed as a
placement directive. We currently only allow
unscoped placement directives at bootstrap.

https://code.launchpad.net/~axwalk/juju-core/lp1237709-bootstrap-placement/+merge/216971

(do not edit description out of merge proposal)

Please review this at https://codereview.appspot.com/91740043/

Affected files (+156, -108 lines):
   A [revision details]
   M cmd/juju/bootstrap.go
   M cmd/juju/bootstrap_test.go
   M cmd/juju/cmd_test.go
   M cmd/juju/deploy_test.go
   M cmd/plugins/juju-restore/restore.go
   M environs/bootstrap/bootstrap.go
   M environs/bootstrap/bootstrap_test.go
   M environs/interface.go
   M environs/jujutest/livetests.go
   M environs/jujutest/tests.go
   M environs/open_test.go
   M juju/apiconn_test.go
   M juju/conn_test.go
   M juju/testing/conn.go
   M provider/azure/environ.go
   M provider/common/bootstrap.go
   M provider/common/bootstrap_test.go
   M provider/common/mock_test.go
   M provider/dummy/environs.go
   M provider/ec2/ec2.go
   M provider/ec2/local_test.go
   M provider/joyent/environ.go
   M provider/joyent/local_test.go
   M provider/local/config_test.go
   M provider/local/environ.go
   M provider/local/environ_test.go
   M provider/maas/environ.go
   M provider/maas/environ_whitebox_test.go
   M provider/manual/environ.go
   M provider/openstack/live_test.go
   M provider/openstack/local_test.go
   M provider/openstack/provider.go

Revision history for this message
Ian Booth (wallyworld) wrote :

LGTM with a suggestion.
Also a drive by fix for
// Directive is a scope-specific placement idrective

would be great.

https://codereview.appspot.com/91740043/diff/1/cmd/juju/bootstrap.go
File cmd/juju/bootstrap.go (right):

https://codereview.appspot.com/91740043/diff/1/cmd/juju/bootstrap.go#newcode107
cmd/juju/bootstrap.go:107: if err != instance.ErrPlacementScopeMissing {
What happens if there's a different error other than
ErrPlacementScopeMissing?
In that case we should just return that other error shouldn't we? ie
there's a difference between an unsupported placement directive and a
placement directive that doesn't parse due to some other error. Even if
there's no other error that can be returned (yet), reworking the
conditional would make it explicit that we are only interested in a
specific case.

https://codereview.appspot.com/91740043/

Revision history for this message
Andrew Wilkins (axwalk) wrote :

Please take a look.

https://codereview.appspot.com/91740043/diff/1/cmd/juju/bootstrap.go
File cmd/juju/bootstrap.go (right):

https://codereview.appspot.com/91740043/diff/1/cmd/juju/bootstrap.go#newcode107
cmd/juju/bootstrap.go:107: if err != instance.ErrPlacementScopeMissing {
On 2014/04/24 03:10:01, wallyworld wrote:
> What happens if there's a different error other than
ErrPlacementScopeMissing?
> In that case we should just return that other error shouldn't we? ie
there's a
> difference between an unsupported placement directive and a placement
directive
> that doesn't parse due to some other error. Even if there's no other
error that
> can be returned (yet), reworking the conditional would make it
explicit that we
> are only interested in a specific case.

There are other errors, but they're not meaningful to us if we don't
support scoped placements. For example, lxc:non-numeric will fail to
parse, but we bootstrap doesn't care about why; it only cares that
"lxc:anything" is not supported by bootstrap.

https://codereview.appspot.com/91740043/

Revision history for this message
Go Bot (go-bot) wrote :
Download full text (10.6 KiB)

The attempt to merge lp:~axwalk/juju-core/lp1237709-bootstrap-placement into lp:juju-core failed. Below is the output from the failed tests.

ok launchpad.net/juju-core 0.014s
ok launchpad.net/juju-core/agent 1.907s
ok launchpad.net/juju-core/agent/mongo 1.310s
ok launchpad.net/juju-core/agent/tools 0.173s
ok launchpad.net/juju-core/bzr 5.220s
ok launchpad.net/juju-core/cert 2.368s
ok launchpad.net/juju-core/charm 0.366s
? launchpad.net/juju-core/charm/hooks [no test files]
? launchpad.net/juju-core/charm/testing [no test files]
ok launchpad.net/juju-core/cloudinit 0.029s
ok launchpad.net/juju-core/cloudinit/sshinit 0.805s
ok launchpad.net/juju-core/cmd 0.178s
ok launchpad.net/juju-core/cmd/charm-admin 0.707s
? launchpad.net/juju-core/cmd/charmd [no test files]
? launchpad.net/juju-core/cmd/charmload [no test files]
ok launchpad.net/juju-core/cmd/envcmd 0.216s
ok launchpad.net/juju-core/cmd/juju 226.670s
ok launchpad.net/juju-core/cmd/jujud 77.888s
ok launchpad.net/juju-core/cmd/plugins/juju-metadata 10.731s
? launchpad.net/juju-core/cmd/plugins/juju-restore [no test files]
ok launchpad.net/juju-core/cmd/plugins/local 0.199s
? launchpad.net/juju-core/cmd/plugins/local/juju-local [no test files]
ok launchpad.net/juju-core/constraints 0.027s
ok launchpad.net/juju-core/container 0.045s
ok launchpad.net/juju-core/container/factory 0.049s
ok launchpad.net/juju-core/container/kvm 0.195s
ok launchpad.net/juju-core/container/kvm/mock 0.034s
? launchpad.net/juju-core/container/kvm/testing [no test files]
ok launchpad.net/juju-core/container/lxc 3.221s
? launchpad.net/juju-core/container/lxc/mock [no test files]
? launchpad.net/juju-core/container/lxc/testing [no test files]
? launchpad.net/juju-core/container/testing [no test files]
ok launchpad.net/juju-core/downloader 5.243s
ok launchpad.net/juju-core/environs 2.623s
ok launchpad.net/juju-core/environs/bootstrap 11.317s
ok launchpad.net/juju-core/environs/cloudinit 0.415s
ok launchpad.net/juju-core/environs/config 1.846s
ok launchpad.net/juju-core/environs/configstore 0.030s
ok launchpad.net/juju-core/environs/filestorage 0.026s
ok launchpad.net/juju-core/environs/httpstorage 0.771s
ok launchpad.net/juju-core/environs/imagemetadata 0.413s
? launchpad.net/juju-core/environs/imagemetadata/testing [no test files]
ok launchpad.net/juju-core/environs/instances 0.043s
ok launchpad.net/juju-core/environs/jujutest 0.165s
ok launchpad.net/juju-core/environs/manual 12.387s
? launchpad.net/juju-core/environs/network [no test files]
ok launchpad.net/juju-core/environs/simplestreams 0.274s
? launchpad.net/juju-core/environs/simplestreams/testing [no test files]
ok launchpad.net/juju-core/environs/sshstorage 0.876s
ok launchpad.net/juju-core/environs/storage 1.011s
ok launchpad.net/juju-core/environs/sync 50.343s
ok launchpad.net/juju-core/environs/testing 0.143s
ok launchpad.net/juju-core/environs/tools 4.910s
? launchpad.net/juju-core/environs/tools/testing [no test files]
ok launchpad.net/juju-core/errors 0.017s
ok launchpad.net/juju-core/instance 0.017s
? launchpad.net/juju-core/ins...

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'cmd/juju/bootstrap.go'
--- cmd/juju/bootstrap.go 2014-04-18 13:49:33 +0000
+++ cmd/juju/bootstrap.go 2014-04-24 03:34:13 +0000
@@ -14,9 +14,11 @@
14 "launchpad.net/juju-core/cmd"14 "launchpad.net/juju-core/cmd"
15 "launchpad.net/juju-core/cmd/envcmd"15 "launchpad.net/juju-core/cmd/envcmd"
16 "launchpad.net/juju-core/constraints"16 "launchpad.net/juju-core/constraints"
17 "launchpad.net/juju-core/environs"
17 "launchpad.net/juju-core/environs/bootstrap"18 "launchpad.net/juju-core/environs/bootstrap"
18 "launchpad.net/juju-core/environs/imagemetadata"19 "launchpad.net/juju-core/environs/imagemetadata"
19 "launchpad.net/juju-core/environs/tools"20 "launchpad.net/juju-core/environs/tools"
21 "launchpad.net/juju-core/instance"
20 "launchpad.net/juju-core/provider"22 "launchpad.net/juju-core/provider"
21)23)
2224
@@ -64,11 +66,13 @@
64 UploadTools bool66 UploadTools bool
65 Series []string67 Series []string
66 MetadataSource string68 MetadataSource string
69 Placement string
67}70}
6871
69func (c *BootstrapCommand) Info() *cmd.Info {72func (c *BootstrapCommand) Info() *cmd.Info {
70 return &cmd.Info{73 return &cmd.Info{
71 Name: "bootstrap",74 Name: "bootstrap",
75 Args: "[placement]",
72 Purpose: "start up an environment from scratch",76 Purpose: "start up an environment from scratch",
73 Doc: bootstrapDoc,77 Doc: bootstrapDoc,
74 }78 }
@@ -90,7 +94,22 @@
90 if len(c.Series) > 0 && !c.UploadTools {94 if len(c.Series) > 0 && !c.UploadTools {
91 return fmt.Errorf("--series requires --upload-tools")95 return fmt.Errorf("--series requires --upload-tools")
92 }96 }
93 return cmd.CheckEmpty(args)97 // Parse the placement directive. Bootstrap currently only
98 // supports provider-specific placement directives.
99 placement, err := cmd.ZeroOrOneArgs(args)
100 if err != nil {
101 return err
102 }
103 if placement == "" {
104 return nil
105 }
106 _, err = instance.ParsePlacement(placement)
107 if err != instance.ErrPlacementScopeMissing {
108 // We only support unscoped placement directives for bootstrap.
109 return fmt.Errorf("unsupported bootstrap placement directive %q", placement)
110 }
111 c.Placement = placement
112 return nil
94}113}
95114
96// Run connects to the environment specified on the command line and bootstraps115// Run connects to the environment specified on the command line and bootstraps
@@ -153,7 +172,10 @@
153 return err172 return err
154 }173 }
155 }174 }
156 return bootstrap.Bootstrap(ctx, environ, c.Constraints)175 return bootstrap.Bootstrap(ctx, environ, environs.BootstrapParams{
176 Constraints: c.Constraints,
177 Placement: c.Placement,
178 })
157}179}
158180
159type seriesVar struct {181type seriesVar struct {
160182
=== modified file 'cmd/juju/bootstrap_test.go'
--- cmd/juju/bootstrap_test.go 2014-04-21 23:10:05 +0000
+++ cmd/juju/bootstrap_test.go 2014-04-24 03:34:13 +0000
@@ -193,6 +193,7 @@
193 // will be uploaded before running the test.193 // will be uploaded before running the test.
194 uploads []string194 uploads []string
195 constraints constraints.Value195 constraints constraints.Value
196 placement string
196 hostArch string197 hostArch string
197}198}
198199
@@ -271,7 +272,8 @@
271272
272 opBootstrap := (<-opc).(dummy.OpBootstrap)273 opBootstrap := (<-opc).(dummy.OpBootstrap)
273 c.Check(opBootstrap.Env, gc.Equals, "peckham")274 c.Check(opBootstrap.Env, gc.Equals, "peckham")
274 c.Check(opBootstrap.Constraints, gc.DeepEquals, test.constraints)275 c.Check(opBootstrap.Args.Constraints, gc.DeepEquals, test.constraints)
276 c.Check(opBootstrap.Args.Placement, gc.Equals, test.placement)
275277
276 store, err := configstore.Default()278 store, err := configstore.Default()
277 c.Assert(err, gc.IsNil)279 c.Assert(err, gc.IsNil)
@@ -287,10 +289,6 @@
287var bootstrapTests = []bootstrapTest{{289var bootstrapTests = []bootstrapTest{{
288 info: "no args, no error, no uploads, no constraints",290 info: "no args, no error, no uploads, no constraints",
289}, {291}, {
290 info: "bad arg",
291 args: []string{"twiddle"},
292 err: `unrecognized args: \["twiddle"\]`,
293}, {
294 info: "bad --constraints",292 info: "bad --constraints",
295 args: []string{"--constraints", "bad=wrong"},293 args: []string{"--constraints", "bad=wrong"},
296 err: `invalid value "bad=wrong" for flag --constraints: unknown constraint "bad"`,294 err: `invalid value "bad=wrong" for flag --constraints: unknown constraint "bad"`,
@@ -372,6 +370,14 @@
372 "1.2.3.5-raring-amd64",370 "1.2.3.5-raring-amd64",
373 "1.2.3.5-%LTS%-amd64",371 "1.2.3.5-%LTS%-amd64",
374 },372 },
373}, {
374 info: "placement",
375 args: []string{"something"},
376 placement: "something",
377}, {
378 info: "invalid placement: ssh",
379 args: []string{"ssh:someplace"},
380 err: `unsupported bootstrap placement directive "ssh:someplace"`,
375}}381}}
376382
377func (s *BootstrapSuite) TestBootstrapTwice(c *gc.C) {383func (s *BootstrapSuite) TestBootstrapTwice(c *gc.C) {
378384
=== modified file 'cmd/juju/cmd_test.go'
--- cmd/juju/cmd_test.go 2014-03-28 12:28:30 +0000
+++ cmd/juju/cmd_test.go 2014-04-24 03:34:13 +0000
@@ -114,11 +114,6 @@
114 testInit(c, com, args, "")114 testInit(c, com, args, "")
115 os.Setenv(osenv.JujuEnvEnvKey, oldenv)115 os.Setenv(osenv.JujuEnvEnvKey, oldenv)
116 assertConnName(c, com, "walthamstow")116 assertConnName(c, com, "walthamstow")
117
118 com, args = cmdFunc()
119 if _, ok := com.(*StatusCommand); !ok {
120 testInit(c, com, append(args, "hotdog"), "unrecognized args.*")
121 }
122 }117 }
123}118}
124119
125120
=== modified file 'cmd/juju/deploy_test.go'
--- cmd/juju/deploy_test.go 2014-04-14 12:36:13 +0000
+++ cmd/juju/deploy_test.go 2014-04-24 03:34:13 +0000
@@ -37,6 +37,9 @@
37 args: nil,37 args: nil,
38 err: `no charm specified`,38 err: `no charm specified`,
39 }, {39 }, {
40 args: []string{"charm-name", "service-name", "hotdog"},
41 err: `unrecognized args: \["hotdog"\]`,
42 }, {
40 args: []string{"craz~ness"},43 args: []string{"craz~ness"},
41 err: `invalid charm name "craz~ness"`,44 err: `invalid charm name "craz~ness"`,
42 }, {45 }, {
4346
=== modified file 'cmd/plugins/juju-restore/restore.go'
--- cmd/plugins/juju-restore/restore.go 2014-04-12 05:53:58 +0000
+++ cmd/plugins/juju-restore/restore.go 2014-04-24 03:34:13 +0000
@@ -254,7 +254,8 @@
254 // error-prone) or we could provide a --no-check flag to make254 // error-prone) or we could provide a --no-check flag to make
255 // it go ahead anyway without the check.255 // it go ahead anyway without the check.
256256
257 if err := bootstrap.Bootstrap(ctx, env, cons); err != nil {257 args := environs.BootstrapParams{Constraints: cons}
258 if err := bootstrap.Bootstrap(ctx, env, args); err != nil {
258 return nil, fmt.Errorf("cannot bootstrap new instance: %v", err)259 return nil, fmt.Errorf("cannot bootstrap new instance: %v", err)
259 }260 }
260 return env, nil261 return env, nil
261262
=== modified file 'environs/bootstrap/bootstrap.go'
--- environs/bootstrap/bootstrap.go 2014-04-17 10:09:39 +0000
+++ environs/bootstrap/bootstrap.go 2014-04-24 03:34:13 +0000
@@ -8,7 +8,6 @@
88
9 "github.com/juju/loggo"9 "github.com/juju/loggo"
1010
11 "launchpad.net/juju-core/constraints"
12 "launchpad.net/juju-core/environs"11 "launchpad.net/juju-core/environs"
13 coretools "launchpad.net/juju-core/tools"12 coretools "launchpad.net/juju-core/tools"
14 "launchpad.net/juju-core/utils/ssh"13 "launchpad.net/juju-core/utils/ssh"
@@ -20,7 +19,7 @@
20// Bootstrap bootstraps the given environment. The supplied constraints are19// Bootstrap bootstraps the given environment. The supplied constraints are
21// used to provision the instance, and are also set within the bootstrapped20// used to provision the instance, and are also set within the bootstrapped
22// environment.21// environment.
23func Bootstrap(ctx environs.BootstrapContext, environ environs.Environ, cons constraints.Value) error {22func Bootstrap(ctx environs.BootstrapContext, environ environs.Environ, args environs.BootstrapParams) error {
24 cfg := environ.Config()23 cfg := environ.Config()
25 if secret := cfg.AdminSecret(); secret == "" {24 if secret := cfg.AdminSecret(); secret == "" {
26 return fmt.Errorf("environment configuration has no admin-secret")25 return fmt.Errorf("environment configuration has no admin-secret")
@@ -45,7 +44,7 @@
45 }44 }
46 logger.Debugf("environment %q supports service/machine networks: %v", environ.Name(), environ.SupportNetworks())45 logger.Debugf("environment %q supports service/machine networks: %v", environ.Name(), environ.SupportNetworks())
47 logger.Infof("bootstrapping environment %q", environ.Name())46 logger.Infof("bootstrapping environment %q", environ.Name())
48 return environ.Bootstrap(ctx, cons)47 return environ.Bootstrap(ctx, args)
49}48}
5049
51// SetBootstrapTools returns the newest tools from the given tools list,50// SetBootstrapTools returns the newest tools from the given tools list,
5251
=== modified file 'environs/bootstrap/bootstrap_test.go'
--- environs/bootstrap/bootstrap_test.go 2014-04-17 09:42:34 +0000
+++ environs/bootstrap/bootstrap_test.go 2014-04-24 03:34:13 +0000
@@ -70,20 +70,20 @@
70 env.cfg = cfg70 env.cfg = cfg
71 }71 }
7272
73 err := bootstrap.Bootstrap(coretesting.Context(c), env, constraints.Value{})73 err := bootstrap.Bootstrap(coretesting.Context(c), env, environs.BootstrapParams{})
74 c.Assert(err, gc.ErrorMatches, "environment configuration has no admin-secret")74 c.Assert(err, gc.ErrorMatches, "environment configuration has no admin-secret")
7575
76 fixEnv("admin-secret", "whatever")76 fixEnv("admin-secret", "whatever")
77 err = bootstrap.Bootstrap(coretesting.Context(c), env, constraints.Value{})77 err = bootstrap.Bootstrap(coretesting.Context(c), env, environs.BootstrapParams{})
78 c.Assert(err, gc.ErrorMatches, "environment configuration has no ca-cert")78 c.Assert(err, gc.ErrorMatches, "environment configuration has no ca-cert")
7979
80 fixEnv("ca-cert", coretesting.CACert)80 fixEnv("ca-cert", coretesting.CACert)
81 err = bootstrap.Bootstrap(coretesting.Context(c), env, constraints.Value{})81 err = bootstrap.Bootstrap(coretesting.Context(c), env, environs.BootstrapParams{})
82 c.Assert(err, gc.ErrorMatches, "environment configuration has no ca-private-key")82 c.Assert(err, gc.ErrorMatches, "environment configuration has no ca-private-key")
8383
84 fixEnv("ca-private-key", coretesting.CAKey)84 fixEnv("ca-private-key", coretesting.CAKey)
85 uploadTools(c, env)85 uploadTools(c, env)
86 err = bootstrap.Bootstrap(coretesting.Context(c), env, constraints.Value{})86 err = bootstrap.Bootstrap(coretesting.Context(c), env, environs.BootstrapParams{})
87 c.Assert(err, gc.IsNil)87 c.Assert(err, gc.IsNil)
88}88}
8989
@@ -96,20 +96,30 @@
96func (s *bootstrapSuite) TestBootstrapEmptyConstraints(c *gc.C) {96func (s *bootstrapSuite) TestBootstrapEmptyConstraints(c *gc.C) {
97 env := newEnviron("foo", useDefaultKeys, nil)97 env := newEnviron("foo", useDefaultKeys, nil)
98 s.setDummyStorage(c, env)98 s.setDummyStorage(c, env)
99 err := bootstrap.Bootstrap(coretesting.Context(c), env, constraints.Value{})99 err := bootstrap.Bootstrap(coretesting.Context(c), env, environs.BootstrapParams{})
100 c.Assert(err, gc.IsNil)100 c.Assert(err, gc.IsNil)
101 c.Assert(env.bootstrapCount, gc.Equals, 1)101 c.Assert(env.bootstrapCount, gc.Equals, 1)
102 c.Assert(env.constraints, gc.DeepEquals, constraints.Value{})102 c.Assert(env.args, gc.DeepEquals, environs.BootstrapParams{})
103}103}
104104
105func (s *bootstrapSuite) TestBootstrapSpecifiedConstraints(c *gc.C) {105func (s *bootstrapSuite) TestBootstrapSpecifiedConstraints(c *gc.C) {
106 env := newEnviron("foo", useDefaultKeys, nil)106 env := newEnviron("foo", useDefaultKeys, nil)
107 s.setDummyStorage(c, env)107 s.setDummyStorage(c, env)
108 cons := constraints.MustParse("cpu-cores=2 mem=4G")108 cons := constraints.MustParse("cpu-cores=2 mem=4G")
109 err := bootstrap.Bootstrap(coretesting.Context(c), env, cons)109 err := bootstrap.Bootstrap(coretesting.Context(c), env, environs.BootstrapParams{Constraints: cons})
110 c.Assert(err, gc.IsNil)110 c.Assert(err, gc.IsNil)
111 c.Assert(env.bootstrapCount, gc.Equals, 1)111 c.Assert(env.bootstrapCount, gc.Equals, 1)
112 c.Assert(env.constraints, gc.DeepEquals, cons)112 c.Assert(env.args.Constraints, gc.DeepEquals, cons)
113}
114
115func (s *bootstrapSuite) TestBootstrapSpecifiedPlacement(c *gc.C) {
116 env := newEnviron("foo", useDefaultKeys, nil)
117 s.setDummyStorage(c, env)
118 placement := "directive"
119 err := bootstrap.Bootstrap(coretesting.Context(c), env, environs.BootstrapParams{Placement: placement})
120 c.Assert(err, gc.IsNil)
121 c.Assert(env.bootstrapCount, gc.Equals, 1)
122 c.Assert(env.args.Placement, gc.DeepEquals, placement)
113}123}
114124
115var bootstrapSetAgentVersionTests = []envtesting.BootstrapToolsTest{125var bootstrapSetAgentVersionTests = []envtesting.BootstrapToolsTest{
@@ -179,7 +189,7 @@
179 if test.Arch != "" {189 if test.Arch != "" {
180 cons = constraints.MustParse("arch=" + test.Arch)190 cons = constraints.MustParse("arch=" + test.Arch)
181 }191 }
182 err = bootstrap.Bootstrap(coretesting.Context(c), env, cons)192 err = bootstrap.Bootstrap(coretesting.Context(c), env, environs.BootstrapParams{Constraints: cons})
183 if test.Err != "" {193 if test.Err != "" {
184 c.Check(err, gc.NotNil)194 c.Check(err, gc.NotNil)
185 if err != nil {195 if err != nil {
@@ -206,7 +216,7 @@
206 env := newEnviron("foo", useDefaultKeys, nil)216 env := newEnviron("foo", useDefaultKeys, nil)
207 s.setDummyStorage(c, env)217 s.setDummyStorage(c, env)
208 envtesting.RemoveFakeTools(c, env.Storage())218 envtesting.RemoveFakeTools(c, env.Storage())
209 err := bootstrap.Bootstrap(coretesting.Context(c), env, constraints.Value{})219 err := bootstrap.Bootstrap(coretesting.Context(c), env, environs.BootstrapParams{})
210 // bootstrap.Bootstrap leaves it to the provider to220 // bootstrap.Bootstrap leaves it to the provider to
211 // locate bootstrap tools.221 // locate bootstrap tools.
212 c.Assert(err, gc.IsNil)222 c.Assert(err, gc.IsNil)
@@ -479,7 +489,7 @@
479489
480 // The following fields are filled in when Bootstrap is called.490 // The following fields are filled in when Bootstrap is called.
481 bootstrapCount int491 bootstrapCount int
482 constraints constraints.Value492 args environs.BootstrapParams
483 storage storage.Storage493 storage storage.Storage
484}494}
485495
@@ -525,9 +535,9 @@
525 return e.name535 return e.name
526}536}
527537
528func (e *bootstrapEnviron) Bootstrap(ctx environs.BootstrapContext, cons constraints.Value) error {538func (e *bootstrapEnviron) Bootstrap(ctx environs.BootstrapContext, args environs.BootstrapParams) error {
529 e.bootstrapCount++539 e.bootstrapCount++
530 e.constraints = cons540 e.args = args
531 return nil541 return nil
532}542}
533543
534544
=== modified file 'environs/interface.go'
--- environs/interface.go 2014-04-22 09:23:39 +0000
+++ environs/interface.go 2014-04-24 03:34:13 +0000
@@ -65,6 +65,17 @@
65 Config() *config.Config65 Config() *config.Config
66}66}
6767
68// BootstrapParams holds the parameters for bootstrapping an environment.
69type BootstrapParams struct {
70 // Constraints are used to choose the initial instance specification,
71 // and will be stored in the new environment's state.
72 Constraints constraints.Value
73
74 // Placement, if non-empty, holds an environment-specific placement
75 // directive used to choose the initial instance.
76 Placement string
77}
78
68// An Environ represents a juju environment as specified79// An Environ represents a juju environment as specified
69// in the environments.yaml file.80// in the environments.yaml file.
70//81//
@@ -91,13 +102,10 @@
91 // environment via the juju package, the password hash will be102 // environment via the juju package, the password hash will be
92 // automatically replaced by the real password.103 // automatically replaced by the real password.
93 //104 //
94 // The supplied constraints are used to choose the initial instance
95 // specification, and will be stored in the new environment's state.
96 //
97 // Bootstrap is responsible for selecting the appropriate tools,105 // Bootstrap is responsible for selecting the appropriate tools,
98 // and setting the agent-version configuration attribute prior to106 // and setting the agent-version configuration attribute prior to
99 // bootstrapping the environment.107 // bootstrapping the environment.
100 Bootstrap(ctx BootstrapContext, cons constraints.Value) error108 Bootstrap(ctx BootstrapContext, params BootstrapParams) error
101109
102 // StateInfo returns information on the state initialized110 // StateInfo returns information on the state initialized
103 // by Bootstrap.111 // by Bootstrap.
104112
=== modified file 'environs/jujutest/livetests.go'
--- environs/jujutest/livetests.go 2014-04-22 09:23:39 +0000
+++ environs/jujutest/livetests.go 2014-04-24 03:34:13 +0000
@@ -139,7 +139,7 @@
139 envtesting.UploadFakeTools(c, t.Env.Storage())139 envtesting.UploadFakeTools(c, t.Env.Storage())
140 err := bootstrap.EnsureNotBootstrapped(t.Env)140 err := bootstrap.EnsureNotBootstrapped(t.Env)
141 c.Assert(err, gc.IsNil)141 c.Assert(err, gc.IsNil)
142 err = bootstrap.Bootstrap(coretesting.Context(c), t.Env, cons)142 err = bootstrap.Bootstrap(coretesting.Context(c), t.Env, environs.BootstrapParams{Constraints: cons})
143 c.Assert(err, gc.IsNil)143 c.Assert(err, gc.IsNil)
144 t.bootstrapped = true144 t.bootstrapped = true
145}145}
@@ -917,7 +917,7 @@
917 err = storageCopy(dummyStorage, currentName, envStorage, otherName)917 err = storageCopy(dummyStorage, currentName, envStorage, otherName)
918 c.Assert(err, gc.IsNil)918 c.Assert(err, gc.IsNil)
919919
920 err = bootstrap.Bootstrap(coretesting.Context(c), env, constraints.Value{})920 err = bootstrap.Bootstrap(coretesting.Context(c), env, environs.BootstrapParams{})
921 c.Assert(err, gc.IsNil)921 c.Assert(err, gc.IsNil)
922922
923 conn, err := juju.NewConn(env)923 conn, err := juju.NewConn(env)
924924
=== modified file 'environs/jujutest/tests.go'
--- environs/jujutest/tests.go 2014-04-14 12:36:13 +0000
+++ environs/jujutest/tests.go 2014-04-24 03:34:13 +0000
@@ -12,7 +12,6 @@
12 jc "github.com/juju/testing/checkers"12 jc "github.com/juju/testing/checkers"
13 gc "launchpad.net/gocheck"13 gc "launchpad.net/gocheck"
1414
15 "launchpad.net/juju-core/constraints"
16 "launchpad.net/juju-core/environs"15 "launchpad.net/juju-core/environs"
17 "launchpad.net/juju-core/environs/bootstrap"16 "launchpad.net/juju-core/environs/bootstrap"
18 "launchpad.net/juju-core/environs/config"17 "launchpad.net/juju-core/environs/config"
@@ -133,7 +132,7 @@
133 envtesting.UploadFakeTools(c, e.Storage())132 envtesting.UploadFakeTools(c, e.Storage())
134 err := bootstrap.EnsureNotBootstrapped(e)133 err := bootstrap.EnsureNotBootstrapped(e)
135 c.Assert(err, gc.IsNil)134 c.Assert(err, gc.IsNil)
136 err = bootstrap.Bootstrap(coretesting.Context(c), e, constraints.Value{})135 err = bootstrap.Bootstrap(coretesting.Context(c), e, environs.BootstrapParams{})
137 c.Assert(err, gc.IsNil)136 c.Assert(err, gc.IsNil)
138137
139 info, apiInfo, err := e.StateInfo()138 info, apiInfo, err := e.StateInfo()
@@ -161,7 +160,7 @@
161160
162 err = bootstrap.EnsureNotBootstrapped(e3)161 err = bootstrap.EnsureNotBootstrapped(e3)
163 c.Assert(err, gc.IsNil)162 c.Assert(err, gc.IsNil)
164 err = bootstrap.Bootstrap(coretesting.Context(c), e3, constraints.Value{})163 err = bootstrap.Bootstrap(coretesting.Context(c), e3, environs.BootstrapParams{})
165 c.Assert(err, gc.IsNil)164 c.Assert(err, gc.IsNil)
166165
167 err = bootstrap.EnsureNotBootstrapped(e3)166 err = bootstrap.EnsureNotBootstrapped(e3)
168167
=== modified file 'environs/open_test.go'
--- environs/open_test.go 2014-04-14 12:36:13 +0000
+++ environs/open_test.go 2014-04-24 03:34:13 +0000
@@ -10,7 +10,6 @@
10 gc "launchpad.net/gocheck"10 gc "launchpad.net/gocheck"
1111
12 "launchpad.net/juju-core/cert"12 "launchpad.net/juju-core/cert"
13 "launchpad.net/juju-core/constraints"
14 "launchpad.net/juju-core/environs"13 "launchpad.net/juju-core/environs"
15 "launchpad.net/juju-core/environs/bootstrap"14 "launchpad.net/juju-core/environs/bootstrap"
16 "launchpad.net/juju-core/environs/config"15 "launchpad.net/juju-core/environs/config"
@@ -41,7 +40,7 @@
41 env, err := environs.Prepare(cfg, ctx, configstore.NewMem())40 env, err := environs.Prepare(cfg, ctx, configstore.NewMem())
42 c.Assert(err, gc.IsNil)41 c.Assert(err, gc.IsNil)
43 envtesting.UploadFakeTools(c, env.Storage())42 envtesting.UploadFakeTools(c, env.Storage())
44 err = bootstrap.Bootstrap(ctx, env, constraints.Value{})43 err = bootstrap.Bootstrap(ctx, env, environs.BootstrapParams{})
45 c.Assert(err, gc.IsNil)44 c.Assert(err, gc.IsNil)
46}45}
4746
4847
=== modified file 'instance/placement.go'
--- instance/placement.go 2014-04-23 05:38:27 +0000
+++ instance/placement.go 2014-04-24 03:34:13 +0000
@@ -28,7 +28,7 @@
28 // If Scope is empty, then it must be inferred from the context.28 // If Scope is empty, then it must be inferred from the context.
29 Scope string29 Scope string
3030
31 // Directive is a scope-specific placement idrective.31 // Directive is a scope-specific placement directive.
32 //32 //
33 // For MachineScope or a container scope, this may be empty or33 // For MachineScope or a container scope, this may be empty or
34 // the ID of an existing machine.34 // the ID of an existing machine.
3535
=== modified file 'juju/apiconn_test.go'
--- juju/apiconn_test.go 2014-04-22 14:34:29 +0000
+++ juju/apiconn_test.go 2014-04-24 03:34:13 +0000
@@ -11,7 +11,6 @@
11 jc "github.com/juju/testing/checkers"11 jc "github.com/juju/testing/checkers"
12 gc "launchpad.net/gocheck"12 gc "launchpad.net/gocheck"
1313
14 "launchpad.net/juju-core/constraints"
15 "launchpad.net/juju-core/environs"14 "launchpad.net/juju-core/environs"
16 "launchpad.net/juju-core/environs/bootstrap"15 "launchpad.net/juju-core/environs/bootstrap"
17 "launchpad.net/juju-core/environs/config"16 "launchpad.net/juju-core/environs/config"
@@ -53,7 +52,7 @@
53 c.Assert(err, gc.IsNil)52 c.Assert(err, gc.IsNil)
5453
55 envtesting.UploadFakeTools(c, env.Storage())54 envtesting.UploadFakeTools(c, env.Storage())
56 err = bootstrap.Bootstrap(ctx, env, constraints.Value{})55 err = bootstrap.Bootstrap(ctx, env, environs.BootstrapParams{})
57 c.Assert(err, gc.IsNil)56 c.Assert(err, gc.IsNil)
5857
59 cfg = env.Config()58 cfg = env.Config()
@@ -601,7 +600,7 @@
601 c.Assert(err, gc.IsNil)600 c.Assert(err, gc.IsNil)
602 defer dummy.Reset()601 defer dummy.Reset()
603 envtesting.UploadFakeTools(c, env.Storage())602 envtesting.UploadFakeTools(c, env.Storage())
604 err = bootstrap.Bootstrap(ctx, env, constraints.Value{})603 err = bootstrap.Bootstrap(ctx, env, environs.BootstrapParams{})
605 c.Assert(err, gc.IsNil)604 c.Assert(err, gc.IsNil)
606605
607 // Note: if we get Bootstrap to start caching the API endpoint606 // Note: if we get Bootstrap to start caching the API endpoint
608607
=== modified file 'juju/conn_test.go'
--- juju/conn_test.go 2014-04-14 12:36:13 +0000
+++ juju/conn_test.go 2014-04-24 03:34:13 +0000
@@ -70,7 +70,7 @@
70 env, err := environs.Prepare(cfg, ctx, configstore.NewMem())70 env, err := environs.Prepare(cfg, ctx, configstore.NewMem())
71 c.Assert(err, gc.IsNil)71 c.Assert(err, gc.IsNil)
72 envtesting.UploadFakeTools(c, env.Storage())72 envtesting.UploadFakeTools(c, env.Storage())
73 err = bootstrap.Bootstrap(ctx, env, constraints.Value{})73 err = bootstrap.Bootstrap(ctx, env, environs.BootstrapParams{})
74 c.Assert(err, gc.IsNil)74 c.Assert(err, gc.IsNil)
7575
76 attrs := env.Config().AllAttrs()76 attrs := env.Config().AllAttrs()
@@ -90,7 +90,7 @@
90 env, err := environs.PrepareFromName(envName, ctx, store)90 env, err := environs.PrepareFromName(envName, ctx, store)
91 c.Assert(err, gc.IsNil)91 c.Assert(err, gc.IsNil)
92 envtesting.UploadFakeTools(c, env.Storage())92 envtesting.UploadFakeTools(c, env.Storage())
93 err = bootstrap.Bootstrap(ctx, env, constraints.Value{})93 err = bootstrap.Bootstrap(ctx, env, environs.BootstrapParams{})
94 c.Assert(err, gc.IsNil)94 c.Assert(err, gc.IsNil)
95}95}
9696
@@ -136,7 +136,7 @@
136 env, err := environs.Prepare(cfg, ctx, configstore.NewMem())136 env, err := environs.Prepare(cfg, ctx, configstore.NewMem())
137 c.Assert(err, gc.IsNil)137 c.Assert(err, gc.IsNil)
138 envtesting.UploadFakeTools(c, env.Storage())138 envtesting.UploadFakeTools(c, env.Storage())
139 err = bootstrap.Bootstrap(ctx, env, constraints.Value{})139 err = bootstrap.Bootstrap(ctx, env, environs.BootstrapParams{})
140 c.Assert(err, gc.IsNil)140 c.Assert(err, gc.IsNil)
141 info, _, err := env.StateInfo()141 info, _, err := env.StateInfo()
142 c.Assert(err, gc.IsNil)142 c.Assert(err, gc.IsNil)
@@ -180,7 +180,7 @@
180 env, err := environs.Prepare(cfg, ctx, configstore.NewMem())180 env, err := environs.Prepare(cfg, ctx, configstore.NewMem())
181 c.Assert(err, gc.IsNil)181 c.Assert(err, gc.IsNil)
182 envtesting.UploadFakeTools(c, env.Storage())182 envtesting.UploadFakeTools(c, env.Storage())
183 err = bootstrap.Bootstrap(ctx, env, constraints.Value{})183 err = bootstrap.Bootstrap(ctx, env, environs.BootstrapParams{})
184 c.Assert(err, gc.IsNil)184 c.Assert(err, gc.IsNil)
185185
186 // Make a new Conn, which will push the secrets.186 // Make a new Conn, which will push the secrets.
@@ -217,7 +217,7 @@
217 env, err := environs.Prepare(cfg, ctx, configstore.NewMem())217 env, err := environs.Prepare(cfg, ctx, configstore.NewMem())
218 c.Assert(err, gc.IsNil)218 c.Assert(err, gc.IsNil)
219 envtesting.UploadFakeTools(c, env.Storage())219 envtesting.UploadFakeTools(c, env.Storage())
220 err = bootstrap.Bootstrap(ctx, env, constraints.Value{})220 err = bootstrap.Bootstrap(ctx, env, environs.BootstrapParams{})
221 c.Assert(err, gc.IsNil)221 c.Assert(err, gc.IsNil)
222222
223 // Check that Bootstrap has correctly used a hash223 // Check that Bootstrap has correctly used a hash
@@ -272,7 +272,7 @@
272 environ, err := environs.Prepare(cfg, ctx, configstore.NewMem())272 environ, err := environs.Prepare(cfg, ctx, configstore.NewMem())
273 c.Assert(err, gc.IsNil)273 c.Assert(err, gc.IsNil)
274 envtesting.UploadFakeTools(c, environ.Storage())274 envtesting.UploadFakeTools(c, environ.Storage())
275 err = bootstrap.Bootstrap(ctx, environ, constraints.Value{})275 err = bootstrap.Bootstrap(ctx, environ, environs.BootstrapParams{})
276 c.Assert(err, gc.IsNil)276 c.Assert(err, gc.IsNil)
277 s.conn, err = juju.NewConn(environ)277 s.conn, err = juju.NewConn(environ)
278 c.Assert(err, gc.IsNil)278 c.Assert(err, gc.IsNil)
279279
=== modified file 'juju/testing/conn.go'
--- juju/testing/conn.go 2014-04-11 17:51:58 +0000
+++ juju/testing/conn.go 2014-04-24 03:34:13 +0000
@@ -14,7 +14,6 @@
1414
15 "launchpad.net/juju-core/agent"15 "launchpad.net/juju-core/agent"
16 "launchpad.net/juju-core/charm"16 "launchpad.net/juju-core/charm"
17 "launchpad.net/juju-core/constraints"
18 "launchpad.net/juju-core/environs"17 "launchpad.net/juju-core/environs"
19 "launchpad.net/juju-core/environs/bootstrap"18 "launchpad.net/juju-core/environs/bootstrap"
20 "launchpad.net/juju-core/environs/config"19 "launchpad.net/juju-core/environs/config"
@@ -220,7 +219,7 @@
220219
221 // Upload tools for both preferred and fake default series220 // Upload tools for both preferred and fake default series
222 envtesting.MustUploadFakeToolsVersions(environ.Storage(), versions...)221 envtesting.MustUploadFakeToolsVersions(environ.Storage(), versions...)
223 c.Assert(bootstrap.Bootstrap(ctx, environ, constraints.Value{}), gc.IsNil)222 c.Assert(bootstrap.Bootstrap(ctx, environ, environs.BootstrapParams{}), gc.IsNil)
224223
225 s.BackingState = environ.(GetStater).GetStateInAPIServer()224 s.BackingState = environ.(GetStater).GetStateInAPIServer()
226225
227226
=== modified file 'provider/azure/environ.go'
--- provider/azure/environ.go 2014-04-22 09:38:55 +0000
+++ provider/azure/environ.go 2014-04-24 03:34:13 +0000
@@ -260,7 +260,7 @@
260}260}
261261
262// Bootstrap is specified in the Environ interface.262// Bootstrap is specified in the Environ interface.
263func (env *azureEnviron) Bootstrap(ctx environs.BootstrapContext, cons constraints.Value) (err error) {263func (env *azureEnviron) Bootstrap(ctx environs.BootstrapContext, args environs.BootstrapParams) (err error) {
264 // The creation of the affinity group and the virtual network is specific to the Azure provider.264 // The creation of the affinity group and the virtual network is specific to the Azure provider.
265 err = env.createAffinityGroup()265 err = env.createAffinityGroup()
266 if err != nil {266 if err != nil {
@@ -282,7 +282,7 @@
282 env.deleteVirtualNetwork()282 env.deleteVirtualNetwork()
283 }283 }
284 }()284 }()
285 err = common.Bootstrap(ctx, env, cons)285 err = common.Bootstrap(ctx, env, args)
286 return err286 return err
287}287}
288288
289289
=== modified file 'provider/common/bootstrap.go'
--- provider/common/bootstrap.go 2014-04-11 11:51:08 +0000
+++ provider/common/bootstrap.go 2014-04-24 03:34:13 +0000
@@ -15,7 +15,6 @@
1515
16 coreCloudinit "launchpad.net/juju-core/cloudinit"16 coreCloudinit "launchpad.net/juju-core/cloudinit"
17 "launchpad.net/juju-core/cloudinit/sshinit"17 "launchpad.net/juju-core/cloudinit/sshinit"
18 "launchpad.net/juju-core/constraints"
19 "launchpad.net/juju-core/environs"18 "launchpad.net/juju-core/environs"
20 "launchpad.net/juju-core/environs/bootstrap"19 "launchpad.net/juju-core/environs/bootstrap"
21 "launchpad.net/juju-core/environs/cloudinit"20 "launchpad.net/juju-core/environs/cloudinit"
@@ -33,7 +32,7 @@
33// Bootstrap is a common implementation of the Bootstrap method defined on32// Bootstrap is a common implementation of the Bootstrap method defined on
34// environs.Environ; we strongly recommend that this implementation be used33// environs.Environ; we strongly recommend that this implementation be used
35// when writing a new provider.34// when writing a new provider.
36func Bootstrap(ctx environs.BootstrapContext, env environs.Environ, cons constraints.Value) (err error) {35func Bootstrap(ctx environs.BootstrapContext, env environs.Environ, args environs.BootstrapParams) (err error) {
37 // TODO make safe in the case of racing Bootstraps36 // TODO make safe in the case of racing Bootstraps
38 // If two Bootstraps are called concurrently, there's37 // If two Bootstraps are called concurrently, there's
39 // no way to make sure that only one succeeds.38 // no way to make sure that only one succeeds.
@@ -42,7 +41,7 @@
42 defer func() { handleBootstrapError(err, ctx, inst, env) }()41 defer func() { handleBootstrapError(err, ctx, inst, env) }()
4342
44 // First thing, ensure we have tools otherwise there's no point.43 // First thing, ensure we have tools otherwise there's no point.
45 selectedTools, err := EnsureBootstrapTools(ctx, env, config.PreferredSeries(env.Config()), cons.Arch)44 selectedTools, err := EnsureBootstrapTools(ctx, env, config.PreferredSeries(env.Config()), args.Constraints.Arch)
46 if err != nil {45 if err != nil {
47 return err46 return err
48 }47 }
@@ -64,9 +63,10 @@
6463
65 fmt.Fprintln(ctx.GetStderr(), "Launching instance")64 fmt.Fprintln(ctx.GetStderr(), "Launching instance")
66 inst, hw, _, err := env.StartInstance(environs.StartInstanceParams{65 inst, hw, _, err := env.StartInstance(environs.StartInstanceParams{
67 Constraints: cons,66 Constraints: args.Constraints,
68 Tools: selectedTools,67 Tools: selectedTools,
69 MachineConfig: machineConfig,68 MachineConfig: machineConfig,
69 Placement: args.Placement,
70 })70 })
71 if err != nil {71 if err != nil {
72 return fmt.Errorf("cannot start bootstrap instance: %v", err)72 return fmt.Errorf("cannot start bootstrap instance: %v", err)
7373
=== modified file 'provider/common/bootstrap_test.go'
--- provider/common/bootstrap_test.go 2014-04-18 16:37:28 +0000
+++ provider/common/bootstrap_test.go 2014-04-24 03:34:13 +0000
@@ -76,13 +76,15 @@
76}76}
7777
78func (s *BootstrapSuite) TestCannotStartInstance(c *gc.C) {78func (s *BootstrapSuite) TestCannotStartInstance(c *gc.C) {
79 checkPlacement := "directive"
79 checkCons := constraints.MustParse("mem=8G")80 checkCons := constraints.MustParse("mem=8G")
8081
81 startInstance := func(82 startInstance := func(
82 cons constraints.Value, _, _ []string, possibleTools tools.List, mcfg *cloudinit.MachineConfig,83 placement string, cons constraints.Value, _, _ []string, possibleTools tools.List, mcfg *cloudinit.MachineConfig,
83 ) (84 ) (
84 instance.Instance, *instance.HardwareCharacteristics, []network.Info, error,85 instance.Instance, *instance.HardwareCharacteristics, []network.Info, error,
85 ) {86 ) {
87 c.Assert(placement, gc.DeepEquals, checkPlacement)
86 c.Assert(cons, gc.DeepEquals, checkCons)88 c.Assert(cons, gc.DeepEquals, checkCons)
87 c.Assert(mcfg, gc.DeepEquals, environs.NewBootstrapMachineConfig(mcfg.SystemPrivateSSHKey))89 c.Assert(mcfg, gc.DeepEquals, environs.NewBootstrapMachineConfig(mcfg.SystemPrivateSSHKey))
88 return nil, nil, nil, fmt.Errorf("meh, not started")90 return nil, nil, nil, fmt.Errorf("meh, not started")
@@ -95,7 +97,10 @@
95 }97 }
9698
97 ctx := coretesting.Context(c)99 ctx := coretesting.Context(c)
98 err := common.Bootstrap(ctx, env, checkCons)100 err := common.Bootstrap(ctx, env, environs.BootstrapParams{
101 Constraints: checkCons,
102 Placement: checkPlacement,
103 })
99 c.Assert(err, gc.ErrorMatches, "cannot start bootstrap instance: meh, not started")104 c.Assert(err, gc.ErrorMatches, "cannot start bootstrap instance: meh, not started")
100}105}
101106
@@ -104,7 +109,7 @@
104 stor := &mockStorage{Storage: innerStorage}109 stor := &mockStorage{Storage: innerStorage}
105110
106 startInstance := func(111 startInstance := func(
107 _ constraints.Value, _, _ []string, _ tools.List, _ *cloudinit.MachineConfig,112 _ string, _ constraints.Value, _, _ []string, _ tools.List, _ *cloudinit.MachineConfig,
108 ) (113 ) (
109 instance.Instance, *instance.HardwareCharacteristics, []network.Info, error,114 instance.Instance, *instance.HardwareCharacteristics, []network.Info, error,
110 ) {115 ) {
@@ -126,7 +131,7 @@
126 }131 }
127132
128 ctx := coretesting.Context(c)133 ctx := coretesting.Context(c)
129 err := common.Bootstrap(ctx, env, constraints.Value{})134 err := common.Bootstrap(ctx, env, environs.BootstrapParams{})
130 c.Assert(err, gc.ErrorMatches, "cannot save state: suddenly a wild blah")135 c.Assert(err, gc.ErrorMatches, "cannot save state: suddenly a wild blah")
131 c.Assert(stopped, gc.HasLen, 1)136 c.Assert(stopped, gc.HasLen, 1)
132 c.Assert(stopped[0].Id(), gc.Equals, instance.Id("i-blah"))137 c.Assert(stopped[0].Id(), gc.Equals, instance.Id("i-blah"))
@@ -137,7 +142,7 @@
137 stor := &mockStorage{Storage: innerStorage}142 stor := &mockStorage{Storage: innerStorage}
138143
139 startInstance := func(144 startInstance := func(
140 _ constraints.Value, _, _ []string, _ tools.List, _ *cloudinit.MachineConfig,145 _ string, _ constraints.Value, _, _ []string, _ tools.List, _ *cloudinit.MachineConfig,
141 ) (146 ) (
142 instance.Instance, *instance.HardwareCharacteristics, []network.Info, error,147 instance.Instance, *instance.HardwareCharacteristics, []network.Info, error,
143 ) {148 ) {
@@ -163,7 +168,7 @@
163 }168 }
164169
165 ctx := coretesting.Context(c)170 ctx := coretesting.Context(c)
166 err := common.Bootstrap(ctx, env, constraints.Value{})171 err := common.Bootstrap(ctx, env, environs.BootstrapParams{})
167 c.Assert(err, gc.ErrorMatches, "cannot save state: suddenly a wild blah")172 c.Assert(err, gc.ErrorMatches, "cannot save state: suddenly a wild blah")
168 c.Assert(stopped, gc.HasLen, 1)173 c.Assert(stopped, gc.HasLen, 1)
169 c.Assert(stopped[0].Id(), gc.Equals, instance.Id("i-blah"))174 c.Assert(stopped[0].Id(), gc.Equals, instance.Id("i-blah"))
@@ -178,7 +183,7 @@
178 checkHardware := instance.MustParseHardware("mem=2T")183 checkHardware := instance.MustParseHardware("mem=2T")
179184
180 startInstance := func(185 startInstance := func(
181 _ constraints.Value, _, _ []string, _ tools.List, mcfg *cloudinit.MachineConfig,186 _ string, _ constraints.Value, _, _ []string, _ tools.List, mcfg *cloudinit.MachineConfig,
182 ) (187 ) (
183 instance.Instance, *instance.HardwareCharacteristics, []network.Info, error,188 instance.Instance, *instance.HardwareCharacteristics, []network.Info, error,
184 ) {189 ) {
@@ -206,7 +211,7 @@
206 }211 }
207 originalAuthKeys := env.Config().AuthorizedKeys()212 originalAuthKeys := env.Config().AuthorizedKeys()
208 ctx := coretesting.Context(c)213 ctx := coretesting.Context(c)
209 err := common.Bootstrap(ctx, env, constraints.Value{})214 err := common.Bootstrap(ctx, env, environs.BootstrapParams{})
210 c.Assert(err, gc.IsNil)215 c.Assert(err, gc.IsNil)
211216
212 authKeys := env.Config().AuthorizedKeys()217 authKeys := env.Config().AuthorizedKeys()
213218
=== modified file 'provider/common/mock_test.go'
--- provider/common/mock_test.go 2014-04-18 16:37:28 +0000
+++ provider/common/mock_test.go 2014-04-24 03:34:13 +0000
@@ -18,7 +18,7 @@
18)18)
1919
20type allInstancesFunc func() ([]instance.Instance, error)20type allInstancesFunc func() ([]instance.Instance, error)
21type startInstanceFunc func(constraints.Value, []string, []string, tools.List, *cloudinit.MachineConfig) (instance.Instance, *instance.HardwareCharacteristics, []network.Info, error)21type startInstanceFunc func(string, constraints.Value, []string, []string, tools.List, *cloudinit.MachineConfig) (instance.Instance, *instance.HardwareCharacteristics, []network.Info, error)
22type stopInstancesFunc func([]instance.Instance) error22type stopInstancesFunc func([]instance.Instance) error
23type getToolsSourcesFunc func() ([]simplestreams.DataSource, error)23type getToolsSourcesFunc func() ([]simplestreams.DataSource, error)
24type configFunc func() *config.Config24type configFunc func() *config.Config
@@ -52,6 +52,7 @@
52}52}
53func (env *mockEnviron) StartInstance(args environs.StartInstanceParams) (instance.Instance, *instance.HardwareCharacteristics, []network.Info, error) {53func (env *mockEnviron) StartInstance(args environs.StartInstanceParams) (instance.Instance, *instance.HardwareCharacteristics, []network.Info, error) {
54 return env.startInstance(54 return env.startInstance(
55 args.Placement,
55 args.Constraints,56 args.Constraints,
56 args.MachineConfig.IncludeNetworks,57 args.MachineConfig.IncludeNetworks,
57 args.MachineConfig.ExcludeNetworks,58 args.MachineConfig.ExcludeNetworks,
5859
=== modified file 'provider/dummy/environs.go'
--- provider/dummy/environs.go 2014-04-22 09:23:39 +0000
+++ provider/dummy/environs.go 2014-04-24 03:34:13 +0000
@@ -98,9 +98,9 @@
98type Operation interface{}98type Operation interface{}
9999
100type OpBootstrap struct {100type OpBootstrap struct {
101 Context environs.BootstrapContext101 Context environs.BootstrapContext
102 Env string102 Env string
103 Constraints constraints.Value103 Args environs.BootstrapParams
104}104}
105105
106type OpDestroy struct {106type OpDestroy struct {
@@ -562,8 +562,8 @@
562 storage.NewStorageSimpleStreamsDataSource("cloud storage", e.Storage(), storage.BaseToolsPath)}, nil562 storage.NewStorageSimpleStreamsDataSource("cloud storage", e.Storage(), storage.BaseToolsPath)}, nil
563}563}
564564
565func (e *environ) Bootstrap(ctx environs.BootstrapContext, cons constraints.Value) error {565func (e *environ) Bootstrap(ctx environs.BootstrapContext, args environs.BootstrapParams) error {
566 selectedTools, err := common.EnsureBootstrapTools(ctx, e, config.PreferredSeries(e.Config()), cons.Arch)566 selectedTools, err := common.EnsureBootstrapTools(ctx, e, config.PreferredSeries(e.Config()), args.Constraints.Arch)
567 if err != nil {567 if err != nil {
568 return err568 return err
569 }569 }
@@ -615,7 +615,7 @@
615 if err != nil {615 if err != nil {
616 panic(err)616 panic(err)
617 }617 }
618 if err := st.SetEnvironConstraints(cons); err != nil {618 if err := st.SetEnvironConstraints(args.Constraints); err != nil {
619 panic(err)619 panic(err)
620 }620 }
621 if err := st.SetAdminMongoPassword(utils.UserPasswordHash(password, utils.CompatSalt)); err != nil {621 if err := st.SetAdminMongoPassword(utils.UserPasswordHash(password, utils.CompatSalt)); err != nil {
@@ -632,7 +632,7 @@
632 estate.apiState = st632 estate.apiState = st
633 }633 }
634 estate.bootstrapped = true634 estate.bootstrapped = true
635 estate.ops <- OpBootstrap{Context: ctx, Env: e.name, Constraints: cons}635 estate.ops <- OpBootstrap{Context: ctx, Env: e.name, Args: args}
636 return nil636 return nil
637}637}
638638
639639
=== modified file 'provider/ec2/ec2.go'
--- provider/ec2/ec2.go 2014-04-22 09:23:39 +0000
+++ provider/ec2/ec2.go 2014-04-24 03:34:13 +0000
@@ -323,8 +323,8 @@
323 return stor323 return stor
324}324}
325325
326func (e *environ) Bootstrap(ctx environs.BootstrapContext, cons constraints.Value) error {326func (e *environ) Bootstrap(ctx environs.BootstrapContext, args environs.BootstrapParams) error {
327 return common.Bootstrap(ctx, e, cons)327 return common.Bootstrap(ctx, e, args)
328}328}
329329
330func (e *environ) StateInfo() (*state.Info, *api.Info, error) {330func (e *environ) StateInfo() (*state.Info, *api.Info, error) {
331331
=== modified file 'provider/ec2/local_test.go'
--- provider/ec2/local_test.go 2014-04-22 09:23:39 +0000
+++ provider/ec2/local_test.go 2014-04-24 03:34:13 +0000
@@ -218,7 +218,7 @@
218func (t *localServerSuite) TestBootstrapInstanceUserDataAndState(c *gc.C) {218func (t *localServerSuite) TestBootstrapInstanceUserDataAndState(c *gc.C) {
219 env := t.Prepare(c)219 env := t.Prepare(c)
220 envtesting.UploadFakeTools(c, env.Storage())220 envtesting.UploadFakeTools(c, env.Storage())
221 err := bootstrap.Bootstrap(coretesting.Context(c), env, constraints.Value{})221 err := bootstrap.Bootstrap(coretesting.Context(c), env, environs.BootstrapParams{})
222 c.Assert(err, gc.IsNil)222 c.Assert(err, gc.IsNil)
223223
224 // check that the state holds the id of the bootstrap machine.224 // check that the state holds the id of the bootstrap machine.
@@ -303,7 +303,7 @@
303func (t *localServerSuite) TestInstanceStatus(c *gc.C) {303func (t *localServerSuite) TestInstanceStatus(c *gc.C) {
304 env := t.Prepare(c)304 env := t.Prepare(c)
305 envtesting.UploadFakeTools(c, env.Storage())305 envtesting.UploadFakeTools(c, env.Storage())
306 err := bootstrap.Bootstrap(coretesting.Context(c), env, constraints.Value{})306 err := bootstrap.Bootstrap(coretesting.Context(c), env, environs.BootstrapParams{})
307 c.Assert(err, gc.IsNil)307 c.Assert(err, gc.IsNil)
308 t.srv.ec2srv.SetInitialInstanceState(ec2test.Terminated)308 t.srv.ec2srv.SetInitialInstanceState(ec2test.Terminated)
309 inst, _ := testing.AssertStartInstance(c, env, "1")309 inst, _ := testing.AssertStartInstance(c, env, "1")
@@ -314,7 +314,7 @@
314func (t *localServerSuite) TestStartInstanceHardwareCharacteristics(c *gc.C) {314func (t *localServerSuite) TestStartInstanceHardwareCharacteristics(c *gc.C) {
315 env := t.Prepare(c)315 env := t.Prepare(c)
316 envtesting.UploadFakeTools(c, env.Storage())316 envtesting.UploadFakeTools(c, env.Storage())
317 err := bootstrap.Bootstrap(coretesting.Context(c), env, constraints.Value{})317 err := bootstrap.Bootstrap(coretesting.Context(c), env, environs.BootstrapParams{})
318 c.Assert(err, gc.IsNil)318 c.Assert(err, gc.IsNil)
319 _, hc := testing.AssertStartInstance(c, env, "1")319 _, hc := testing.AssertStartInstance(c, env, "1")
320 c.Check(*hc.Arch, gc.Equals, "amd64")320 c.Check(*hc.Arch, gc.Equals, "amd64")
@@ -326,7 +326,7 @@
326func (t *localServerSuite) TestAddresses(c *gc.C) {326func (t *localServerSuite) TestAddresses(c *gc.C) {
327 env := t.Prepare(c)327 env := t.Prepare(c)
328 envtesting.UploadFakeTools(c, env.Storage())328 envtesting.UploadFakeTools(c, env.Storage())
329 err := bootstrap.Bootstrap(coretesting.Context(c), env, constraints.Value{})329 err := bootstrap.Bootstrap(coretesting.Context(c), env, environs.BootstrapParams{})
330 c.Assert(err, gc.IsNil)330 c.Assert(err, gc.IsNil)
331 inst, _ := testing.AssertStartInstance(c, env, "1")331 inst, _ := testing.AssertStartInstance(c, env, "1")
332 c.Assert(err, gc.IsNil)332 c.Assert(err, gc.IsNil)
333333
=== modified file 'provider/joyent/environ.go'
--- provider/joyent/environ.go 2014-04-22 09:38:55 +0000
+++ provider/joyent/environ.go 2014-04-24 03:34:13 +0000
@@ -154,8 +154,8 @@
154 return environs.EmptyStorage154 return environs.EmptyStorage
155}155}
156156
157func (env *joyentEnviron) Bootstrap(ctx environs.BootstrapContext, cons constraints.Value) error {157func (env *joyentEnviron) Bootstrap(ctx environs.BootstrapContext, args environs.BootstrapParams) error {
158 return common.Bootstrap(ctx, env, cons)158 return common.Bootstrap(ctx, env, args)
159}159}
160160
161func (env *joyentEnviron) StateInfo() (*state.Info, *api.Info, error) {161func (env *joyentEnviron) StateInfo() (*state.Info, *api.Info, error) {
162162
=== modified file 'provider/joyent/local_test.go'
--- provider/joyent/local_test.go 2014-04-18 13:49:33 +0000
+++ provider/joyent/local_test.go 2014-04-24 03:34:13 +0000
@@ -190,7 +190,7 @@
190func (s *localServerSuite) TestStartInstance(c *gc.C) {190func (s *localServerSuite) TestStartInstance(c *gc.C) {
191 env := s.Prepare(c)191 env := s.Prepare(c)
192 envtesting.UploadFakeTools(c, env.Storage())192 envtesting.UploadFakeTools(c, env.Storage())
193 err := bootstrap.Bootstrap(bootstrapContext(c), env, constraints.Value{})193 err := bootstrap.Bootstrap(bootstrapContext(c), env, environs.BootstrapParams{})
194 c.Assert(err, gc.IsNil)194 c.Assert(err, gc.IsNil)
195 inst, _ := testing.AssertStartInstance(c, env, "100")195 inst, _ := testing.AssertStartInstance(c, env, "100")
196 err = env.StopInstances([]instance.Instance{inst})196 err = env.StopInstances([]instance.Instance{inst})
@@ -200,7 +200,7 @@
200func (s *localServerSuite) TestStartInstanceHardwareCharacteristics(c *gc.C) {200func (s *localServerSuite) TestStartInstanceHardwareCharacteristics(c *gc.C) {
201 env := s.Prepare(c)201 env := s.Prepare(c)
202 envtesting.UploadFakeTools(c, env.Storage())202 envtesting.UploadFakeTools(c, env.Storage())
203 err := bootstrap.Bootstrap(bootstrapContext(c), env, constraints.Value{})203 err := bootstrap.Bootstrap(bootstrapContext(c), env, environs.BootstrapParams{})
204 c.Assert(err, gc.IsNil)204 c.Assert(err, gc.IsNil)
205 _, hc := testing.AssertStartInstanceWithConstraints(c, env, "100", constraints.MustParse("mem=1024"))205 _, hc := testing.AssertStartInstanceWithConstraints(c, env, "100", constraints.MustParse("mem=1024"))
206 c.Check(*hc.Arch, gc.Equals, "amd64")206 c.Check(*hc.Arch, gc.Equals, "amd64")
@@ -310,7 +310,7 @@
310func (s *localServerSuite) TestBootstrapInstanceUserDataAndState(c *gc.C) {310func (s *localServerSuite) TestBootstrapInstanceUserDataAndState(c *gc.C) {
311 env := s.Prepare(c)311 env := s.Prepare(c)
312 envtesting.UploadFakeTools(c, env.Storage())312 envtesting.UploadFakeTools(c, env.Storage())
313 err := bootstrap.Bootstrap(bootstrapContext(c), env, constraints.Value{})313 err := bootstrap.Bootstrap(bootstrapContext(c), env, environs.BootstrapParams{})
314 c.Assert(err, gc.IsNil)314 c.Assert(err, gc.IsNil)
315315
316 // check that the state holds the id of the bootstrap machine.316 // check that the state holds the id of the bootstrap machine.
317317
=== modified file 'provider/local/config_test.go'
--- provider/local/config_test.go 2014-03-25 02:18:04 +0000
+++ provider/local/config_test.go 2014-04-24 03:34:13 +0000
@@ -8,7 +8,7 @@
88
9 gc "launchpad.net/gocheck"9 gc "launchpad.net/gocheck"
1010
11 "launchpad.net/juju-core/constraints"11 "launchpad.net/juju-core/environs"
12 "launchpad.net/juju-core/environs/config"12 "launchpad.net/juju-core/environs/config"
13 "launchpad.net/juju-core/juju/osenv"13 "launchpad.net/juju-core/juju/osenv"
14 "launchpad.net/juju-core/provider"14 "launchpad.net/juju-core/provider"
@@ -109,6 +109,6 @@
109 s.PatchValue(local.CheckIfRoot, func() bool { return true })109 s.PatchValue(local.CheckIfRoot, func() bool { return true })
110 env, err := local.Provider.Prepare(testing.Context(c), minimalConfig(c))110 env, err := local.Provider.Prepare(testing.Context(c), minimalConfig(c))
111 c.Assert(err, gc.IsNil)111 c.Assert(err, gc.IsNil)
112 err = env.Bootstrap(testing.Context(c), constraints.Value{})112 err = env.Bootstrap(testing.Context(c), environs.BootstrapParams{})
113 c.Assert(err, gc.ErrorMatches, "bootstrapping a local environment must not be done as root")113 c.Assert(err, gc.ErrorMatches, "bootstrapping a local environment must not be done as root")
114}114}
115115
=== modified file 'provider/local/environ.go'
--- provider/local/environ.go 2014-04-22 09:23:39 +0000
+++ provider/local/environ.go 2014-04-24 03:34:13 +0000
@@ -111,7 +111,7 @@
111}111}
112112
113// Bootstrap is specified in the Environ interface.113// Bootstrap is specified in the Environ interface.
114func (env *localEnviron) Bootstrap(ctx environs.BootstrapContext, cons constraints.Value) error {114func (env *localEnviron) Bootstrap(ctx environs.BootstrapContext, args environs.BootstrapParams) error {
115 if err := ensureNotRoot(); err != nil {115 if err := ensureNotRoot(); err != nil {
116 return err116 return err
117 }117 }
@@ -161,7 +161,7 @@
161 agent.StorageDir: env.config.storageDir(),161 agent.StorageDir: env.config.storageDir(),
162 agent.StorageAddr: env.config.storageAddr(),162 agent.StorageAddr: env.config.storageAddr(),
163 }163 }
164 if err := environs.FinishMachineConfig(mcfg, cfg, cons); err != nil {164 if err := environs.FinishMachineConfig(mcfg, cfg, args.Constraints); err != nil {
165 return err165 return err
166 }166 }
167 // don't write proxy settings for local machine167 // don't write proxy settings for local machine
168168
=== modified file 'provider/local/environ_test.go'
--- provider/local/environ_test.go 2014-04-21 23:10:05 +0000
+++ provider/local/environ_test.go 2014-04-24 03:34:13 +0000
@@ -169,7 +169,7 @@
169 c.Assert(err, gc.IsNil)169 c.Assert(err, gc.IsNil)
170 envtesting.UploadFakeTools(c, environ.Storage())170 envtesting.UploadFakeTools(c, environ.Storage())
171 defer environ.Storage().RemoveAll()171 defer environ.Storage().RemoveAll()
172 err = environ.Bootstrap(ctx, constraints.Value{})172 err = environ.Bootstrap(ctx, environs.BootstrapParams{})
173 c.Assert(err, gc.IsNil)173 c.Assert(err, gc.IsNil)
174 return environ174 return environ
175}175}
176176
=== modified file 'provider/maas/environ.go'
--- provider/maas/environ.go 2014-04-23 09:33:46 +0000
+++ provider/maas/environ.go 2014-04-24 03:34:13 +0000
@@ -90,8 +90,8 @@
90}90}
9191
92// Bootstrap is specified in the Environ interface.92// Bootstrap is specified in the Environ interface.
93func (env *maasEnviron) Bootstrap(ctx environs.BootstrapContext, cons constraints.Value) error {93func (env *maasEnviron) Bootstrap(ctx environs.BootstrapContext, args environs.BootstrapParams) error {
94 return common.Bootstrap(ctx, env, cons)94 return common.Bootstrap(ctx, env, args)
95}95}
9696
97// StateInfo is specified in the Environ interface.97// StateInfo is specified in the Environ interface.
9898
=== modified file 'provider/maas/environ_whitebox_test.go'
--- provider/maas/environ_whitebox_test.go 2014-04-23 09:33:46 +0000
+++ provider/maas/environ_whitebox_test.go 2014-04-24 03:34:13 +0000
@@ -199,7 +199,7 @@
199 lshwXML, err := suite.generateHWTemplate(map[string]string{"aa:bb:cc:dd:ee:f0": "eth0"})199 lshwXML, err := suite.generateHWTemplate(map[string]string{"aa:bb:cc:dd:ee:f0": "eth0"})
200 c.Assert(err, gc.IsNil)200 c.Assert(err, gc.IsNil)
201 suite.testMAASObject.TestServer.AddNodeDetails("node0", lshwXML)201 suite.testMAASObject.TestServer.AddNodeDetails("node0", lshwXML)
202 err = bootstrap.Bootstrap(coretesting.Context(c), env, constraints.Value{})202 err = bootstrap.Bootstrap(coretesting.Context(c), env, environs.BootstrapParams{})
203 c.Assert(err, gc.IsNil)203 c.Assert(err, gc.IsNil)
204 // The bootstrap node has been acquired and started.204 // The bootstrap node has been acquired and started.
205 operations := suite.testMAASObject.TestServer.NodeOperations()205 operations := suite.testMAASObject.TestServer.NodeOperations()
@@ -496,7 +496,7 @@
496 lshwXML, err := suite.generateHWTemplate(map[string]string{"aa:bb:cc:dd:ee:f0": "eth0"})496 lshwXML, err := suite.generateHWTemplate(map[string]string{"aa:bb:cc:dd:ee:f0": "eth0"})
497 c.Assert(err, gc.IsNil)497 c.Assert(err, gc.IsNil)
498 suite.testMAASObject.TestServer.AddNodeDetails("thenode", lshwXML)498 suite.testMAASObject.TestServer.AddNodeDetails("thenode", lshwXML)
499 err = bootstrap.Bootstrap(coretesting.Context(c), env, constraints.Value{})499 err = bootstrap.Bootstrap(coretesting.Context(c), env, environs.BootstrapParams{})
500 c.Assert(err, gc.IsNil)500 c.Assert(err, gc.IsNil)
501}501}
502502
@@ -512,7 +512,7 @@
512 c.Assert(err, gc.IsNil)512 c.Assert(err, gc.IsNil)
513 err = env.SetConfig(cfg)513 err = env.SetConfig(cfg)
514 c.Assert(err, gc.IsNil)514 c.Assert(err, gc.IsNil)
515 err = bootstrap.Bootstrap(coretesting.Context(c), env, constraints.Value{})515 err = bootstrap.Bootstrap(coretesting.Context(c), env, environs.BootstrapParams{})
516 stripped := strings.Replace(err.Error(), "\n", "", -1)516 stripped := strings.Replace(err.Error(), "\n", "", -1)
517 c.Check(stripped,517 c.Check(stripped,
518 gc.Matches,518 gc.Matches,
@@ -522,7 +522,7 @@
522func (suite *environSuite) TestBootstrapFailsIfNoNodes(c *gc.C) {522func (suite *environSuite) TestBootstrapFailsIfNoNodes(c *gc.C) {
523 suite.setupFakeTools(c)523 suite.setupFakeTools(c)
524 env := suite.makeEnviron()524 env := suite.makeEnviron()
525 err := bootstrap.Bootstrap(coretesting.Context(c), env, constraints.Value{})525 err := bootstrap.Bootstrap(coretesting.Context(c), env, environs.BootstrapParams{})
526 // Since there are no nodes, the attempt to allocate one returns a526 // Since there are no nodes, the attempt to allocate one returns a
527 // 409: Conflict.527 // 409: Conflict.
528 c.Check(err, gc.ErrorMatches, ".*409.*")528 c.Check(err, gc.ErrorMatches, ".*409.*")
529529
=== modified file 'provider/manual/environ.go'
--- provider/manual/environ.go 2014-04-22 09:23:39 +0000
+++ provider/manual/environ.go 2014-04-24 03:34:13 +0000
@@ -102,7 +102,7 @@
102 return false102 return false
103}103}
104104
105func (e *manualEnviron) Bootstrap(ctx environs.BootstrapContext, cons constraints.Value) error {105func (e *manualEnviron) Bootstrap(ctx environs.BootstrapContext, args environs.BootstrapParams) error {
106 // Set "use-sshstorage" to false, so agents know not to use sshstorage.106 // Set "use-sshstorage" to false, so agents know not to use sshstorage.
107 cfg, err := e.Config().Apply(map[string]interface{}{"use-sshstorage": false})107 cfg, err := e.Config().Apply(map[string]interface{}{"use-sshstorage": false})
108 if err != nil {108 if err != nil {
@@ -112,6 +112,7 @@
112 return err112 return err
113 }113 }
114 envConfig := e.envConfig()114 envConfig := e.envConfig()
115 // TODO(axw) consider how we can use placement to override bootstrap-host.
115 host := envConfig.bootstrapHost()116 host := envConfig.bootstrapHost()
116 hc, series, err := manual.DetectSeriesAndHardwareCharacteristics(host)117 hc, series, err := manual.DetectSeriesAndHardwareCharacteristics(host)
117 if err != nil {118 if err != nil {
118119
=== modified file 'provider/openstack/live_test.go'
--- provider/openstack/live_test.go 2014-02-18 02:53:44 +0000
+++ provider/openstack/live_test.go 2014-04-24 03:34:13 +0000
@@ -14,7 +14,6 @@
14 "launchpad.net/goose/identity"14 "launchpad.net/goose/identity"
15 "launchpad.net/goose/nova"15 "launchpad.net/goose/nova"
1616
17 "launchpad.net/juju-core/constraints"
18 "launchpad.net/juju-core/environs"17 "launchpad.net/juju-core/environs"
19 "launchpad.net/juju-core/environs/bootstrap"18 "launchpad.net/juju-core/environs/bootstrap"
20 "launchpad.net/juju-core/environs/config"19 "launchpad.net/juju-core/environs/config"
@@ -230,7 +229,7 @@
230 c.Assert(env, gc.NotNil)229 c.Assert(env, gc.NotNil)
231 defer env.Destroy()230 defer env.Destroy()
232 // Bootstrap and start an instance.231 // Bootstrap and start an instance.
233 err = bootstrap.Bootstrap(coretesting.Context(c), env, constraints.Value{})232 err = bootstrap.Bootstrap(coretesting.Context(c), env, environs.BootstrapParams{})
234 c.Assert(err, gc.IsNil)233 c.Assert(err, gc.IsNil)
235 inst, _ := jujutesting.AssertStartInstance(c, env, "100")234 inst, _ := jujutesting.AssertStartInstance(c, env, "100")
236 // Check whether the instance has the default security group assigned.235 // Check whether the instance has the default security group assigned.
237236
=== modified file 'provider/openstack/local_test.go'
--- provider/openstack/local_test.go 2014-04-22 10:04:16 +0000
+++ provider/openstack/local_test.go 2014-04-24 03:34:13 +0000
@@ -232,7 +232,7 @@
232 c.Assert(err, gc.IsNil)232 c.Assert(err, gc.IsNil)
233 env, err := environs.New(cfg)233 env, err := environs.New(cfg)
234 c.Assert(err, gc.IsNil)234 c.Assert(err, gc.IsNil)
235 err = bootstrap.Bootstrap(coretesting.Context(c), env, constraints.Value{})235 err = bootstrap.Bootstrap(coretesting.Context(c), env, environs.BootstrapParams{})
236 c.Assert(err, gc.ErrorMatches, "(.|\n)*cannot allocate a public IP as needed(.|\n)*")236 c.Assert(err, gc.ErrorMatches, "(.|\n)*cannot allocate a public IP as needed(.|\n)*")
237}237}
238238
@@ -261,7 +261,7 @@
261 c.Assert(err, gc.IsNil)261 c.Assert(err, gc.IsNil)
262 env, err := environs.Prepare(cfg, coretesting.Context(c), s.ConfigStore)262 env, err := environs.Prepare(cfg, coretesting.Context(c), s.ConfigStore)
263 c.Assert(err, gc.IsNil)263 c.Assert(err, gc.IsNil)
264 err = bootstrap.Bootstrap(coretesting.Context(c), env, constraints.Value{})264 err = bootstrap.Bootstrap(coretesting.Context(c), env, environs.BootstrapParams{})
265 c.Assert(err, gc.IsNil)265 c.Assert(err, gc.IsNil)
266 inst, _ := testing.AssertStartInstance(c, env, "100")266 inst, _ := testing.AssertStartInstance(c, env, "100")
267 err = env.StopInstances([]instance.Instance{inst})267 err = env.StopInstances([]instance.Instance{inst})
@@ -270,7 +270,7 @@
270270
271func (s *localServerSuite) TestStartInstanceHardwareCharacteristics(c *gc.C) {271func (s *localServerSuite) TestStartInstanceHardwareCharacteristics(c *gc.C) {
272 env := s.Prepare(c)272 env := s.Prepare(c)
273 err := bootstrap.Bootstrap(coretesting.Context(c), env, constraints.Value{})273 err := bootstrap.Bootstrap(coretesting.Context(c), env, environs.BootstrapParams{})
274 c.Assert(err, gc.IsNil)274 c.Assert(err, gc.IsNil)
275 _, hc := testing.AssertStartInstanceWithConstraints(c, env, "100", constraints.MustParse("mem=1024"))275 _, hc := testing.AssertStartInstanceWithConstraints(c, env, "100", constraints.MustParse("mem=1024"))
276 c.Check(*hc.Arch, gc.Equals, "amd64")276 c.Check(*hc.Arch, gc.Equals, "amd64")
@@ -574,7 +574,7 @@
574// It should be moved to environs.jujutests.Tests.574// It should be moved to environs.jujutests.Tests.
575func (s *localServerSuite) TestBootstrapInstanceUserDataAndState(c *gc.C) {575func (s *localServerSuite) TestBootstrapInstanceUserDataAndState(c *gc.C) {
576 env := s.Prepare(c)576 env := s.Prepare(c)
577 err := bootstrap.Bootstrap(coretesting.Context(c), env, constraints.Value{})577 err := bootstrap.Bootstrap(coretesting.Context(c), env, environs.BootstrapParams{})
578 c.Assert(err, gc.IsNil)578 c.Assert(err, gc.IsNil)
579579
580 // check that the state holds the id of the bootstrap machine.580 // check that the state holds the id of the bootstrap machine.
@@ -933,7 +933,7 @@
933 openstack.UseTestImageData(metadataStorage, s.cred)933 openstack.UseTestImageData(metadataStorage, s.cred)
934 defer openstack.RemoveTestImageData(metadataStorage)934 defer openstack.RemoveTestImageData(metadataStorage)
935935
936 err = bootstrap.Bootstrap(coretesting.Context(c), s.env, constraints.Value{})936 err = bootstrap.Bootstrap(coretesting.Context(c), s.env, environs.BootstrapParams{})
937 c.Assert(err, gc.IsNil)937 c.Assert(err, gc.IsNil)
938}938}
939939
@@ -1076,7 +1076,7 @@
10761076
1077func (s *localServerSuite) TestAllInstancesIgnoresOtherMachines(c *gc.C) {1077func (s *localServerSuite) TestAllInstancesIgnoresOtherMachines(c *gc.C) {
1078 env := s.Prepare(c)1078 env := s.Prepare(c)
1079 err := bootstrap.Bootstrap(coretesting.Context(c), env, constraints.Value{})1079 err := bootstrap.Bootstrap(coretesting.Context(c), env, environs.BootstrapParams{})
1080 c.Assert(err, gc.IsNil)1080 c.Assert(err, gc.IsNil)
10811081
1082 // Check that we see 1 instance in the environment1082 // Check that we see 1 instance in the environment
10831083
=== modified file 'provider/openstack/provider.go'
--- provider/openstack/provider.go 2014-04-22 09:23:39 +0000
+++ provider/openstack/provider.go 2014-04-24 03:34:13 +0000
@@ -566,7 +566,7 @@
566 return stor566 return stor
567}567}
568568
569func (e *environ) Bootstrap(ctx environs.BootstrapContext, cons constraints.Value) error {569func (e *environ) Bootstrap(ctx environs.BootstrapContext, args environs.BootstrapParams) error {
570 // The client's authentication may have been reset when finding tools if the agent-version570 // The client's authentication may have been reset when finding tools if the agent-version
571 // attribute was updated so we need to re-authenticate. This will be a no-op if already authenticated.571 // attribute was updated so we need to re-authenticate. This will be a no-op if already authenticated.
572 // An authenticated client is needed for the URL() call below.572 // An authenticated client is needed for the URL() call below.
@@ -574,7 +574,7 @@
574 if err != nil {574 if err != nil {
575 return err575 return err
576 }576 }
577 return common.Bootstrap(ctx, e, cons)577 return common.Bootstrap(ctx, e, args)
578}578}
579579
580func (e *environ) StateInfo() (*state.Info, *api.Info, error) {580func (e *environ) StateInfo() (*state.Info, *api.Info, error) {

Subscribers

People subscribed via source and target branches

to status/vote changes: