Merge lp:~rogpeppe/juju-core/105-cloudinit-initial-password into lp:~juju/juju-core/trunk

Proposed by Roger Peppe on 2012-10-05
Status: Merged
Approved by: Gustavo Niemeyer on 2012-10-08
Approved revision: 635
Merged at revision: 628
Proposed branch: lp:~rogpeppe/juju-core/105-cloudinit-initial-password
Merge into: lp:~juju/juju-core/trunk
Prerequisite: lp:~rogpeppe/juju-core/107-jujud-bootstrap-initial-password
Diff against target: 623 lines (+158/-68)
15 files modified
cmd/juju/ssh_test.go (+1/-1)
cmd/juju/status_test.go (+2/-2)
environs/cloudinit/cloudinit.go (+39/-18)
environs/cloudinit/cloudinit_test.go (+63/-18)
environs/dummy/environs.go (+3/-0)
environs/ec2/ec2.go (+3/-1)
environs/ec2/live_test.go (+8/-7)
environs/ec2/local_test.go (+1/-0)
environs/jujutest/livetests.go (+9/-8)
environs/jujutest/test.go (+0/-7)
environs/jujutest/tests.go (+3/-2)
juju/testing/conn.go (+11/-0)
worker/firewaller/firewaller_test.go (+9/-2)
worker/provisioner/provisioner.go (+3/-1)
worker/provisioner/provisioner_test.go (+3/-1)
To merge this branch: bzr merge lp:~rogpeppe/juju-core/105-cloudinit-initial-password
Reviewer Review Type Date Requested Status
The Go Language Gophers 2012-10-05 Pending
Review via email: mp+128222@code.launchpad.net

Description of the Change

environs/cloudinit: use --initial-password

https://codereview.appspot.com/6612054/

To post a comment you must log in.
Roger Peppe (rogpeppe) wrote :
Download full text (6.8 KiB)

Reviewers: mp+128222_code.launchpad.net,

Message:
Please take a look.

Description:
environs/cloudinit: use --initial-password

https://code.launchpad.net/~rogpeppe/juju-core/105-cloudinit-initial-password/+merge/128222

Requires:
https://code.launchpad.net/~rogpeppe/juju-core/107-jujud-bootstrap-initial-password/+merge/128210

(do not edit description out of merge proposal)

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

Affected files:
   A [revision details]
   M environs/cloudinit/cloudinit.go
   M environs/cloudinit/cloudinit_test.go
   M environs/ec2/ec2.go

Index: [revision details]
=== added file '[revision details]'
--- [revision details] 2012-01-01 00:00:00 +0000
+++ [revision details] 2012-01-01 00:00:00 +0000
@@ -0,0 +1,2 @@
+Old revision: <email address hidden>
+New revision: <email address hidden>

Index: environs/cloudinit/cloudinit.go
=== modified file 'environs/cloudinit/cloudinit.go'
--- environs/cloudinit/cloudinit.go 2012-10-05 10:17:49 +0000
+++ environs/cloudinit/cloudinit.go 2012-10-05 10:48:47 +0000
@@ -38,6 +38,7 @@
   // StateInfo holds the means for the new instance to communicate with the
   // juju state. Unless the new machine is running a state server
(StateServer is
   // set), there must be at least one state server address supplied.
+ // The entity name will be ignored.
   StateInfo *state.Info

   // Tools is juju tools to be used on the new machine.
@@ -127,6 +128,7 @@
     " --instance-id "+cfg.InstanceIdAccessor+
     " --env-config "+shquote(base64yaml(cfg.Config))+
     " --state-servers localhost"+mgoPortSuffix+
+ " --initial-password "+shquote(cfg.StateInfo.Password)+
     debugFlag,
    )

@@ -158,11 +160,13 @@
     " --state-servers '%s'"+
     " --log-file /var/log/juju/%s-agent.log"+
     " --data-dir '%s'"+
+ " --initial-password '%s'"+
     " %s",
    toolsDir, kind,
    cfg.zookeeperHostAddrs(),
    name,
    cfg.DataDir,
+ cfg.StateInfo.Password,
    args,
   )
   conf := &upstart.Conf{
@@ -252,6 +256,9 @@
   if cfg.Tools.URL == "" {
    return requiresError("tools URL")
   }
+ if cfg.StateInfo == nil {
+ return requiresError("state info")
+ }
   if cfg.StateServer {
    if cfg.InstanceIdAccessor == "" {
     return requiresError("instance id accessor")
@@ -260,8 +267,13 @@
     return requiresError("environment configuration")
    }
   } else {
- if cfg.StateInfo == nil || len(cfg.StateInfo.Addrs) == 0 {
- return requiresError("zookeeper hosts")
+ if len(cfg.StateInfo.Addrs) == 0 {
+ return requiresError("state hosts")
+ }
+ }
+ for _, r := range cfg.StateInfo.Password {
+ if r == '\'' || r == '\\' || r < 32 {
+ return fmt.Errorf("invalid machine configuration: password has
disallowed characters")
    }
   }
   return nil

Index: environs/cloudinit/cloudinit_test.go
=== modified file 'environs/cloudinit/cloudinit_test.go'
--- environs/cloudinit/cloudinit_test.go 2012-09-28 13:17:11 +0000
+++ environs/cloudinit/cloudinit_test.go 2012-10-05 09:37:03 +0000
@@ -43,8 +43,11 @@
    AuthorizedKeys: "sshkey1",
    Tools: newSimpleTools("1.2.3-linux-amd64"),
    StateServer:...

Read more...

Gustavo Niemeyer (niemeyer) wrote :

One minor:

https://codereview.appspot.com/6612054/diff/2001/environs/cloudinit/cloudinit.go
File environs/cloudinit/cloudinit.go (right):

https://codereview.appspot.com/6612054/diff/2001/environs/cloudinit/cloudinit.go#newcode41
environs/cloudinit/cloudinit.go:41: // The entity name will be ignored.
Rather than ignoring it, we can make pretty good use of it.

Let's validate that when we're running bootstrap-state we've got an
empty EntityName, and when we're not running it, we've got one that
matches the entity name of the machine being started. If those fail, we
can error out and complain that the provider is mis-implemented.

https://codereview.appspot.com/6612054/

Roger Peppe (rogpeppe) wrote :

https://codereview.appspot.com/6612054/diff/2001/environs/cloudinit/cloudinit.go
File environs/cloudinit/cloudinit.go (right):

https://codereview.appspot.com/6612054/diff/2001/environs/cloudinit/cloudinit.go#newcode41
environs/cloudinit/cloudinit.go:41: // The entity name will be ignored.
On 2012/10/05 15:43:41, niemeyer wrote:
> Rather than ignoring it, we can make pretty good use of it.

> Let's validate that when we're running bootstrap-state we've got an
empty
> EntityName, and when we're not running it, we've got one that matches
the entity
> name of the machine being started. If those fail, we can error out and
complain
> that the provider is mis-implemented.

ok. it's slightly strange that when running bootstrap-state, the
password is actually for the admin *and* the machine entity, but seems
reasonable. do you think it's ok to assume the machine entity name
format is well defined, or should we pass in a Machine here instead of a
machine id?

https://codereview.appspot.com/6612054/

Gustavo Niemeyer (niemeyer) wrote :

https://codereview.appspot.com/6612054/diff/2001/environs/cloudinit/cloudinit.go
File environs/cloudinit/cloudinit.go (right):

https://codereview.appspot.com/6612054/diff/2001/environs/cloudinit/cloudinit.go#newcode41
environs/cloudinit/cloudinit.go:41: // The entity name will be ignored.
On 2012/10/05 16:40:12, rog wrote:
> On 2012/10/05 15:43:41, niemeyer wrote:
> > Rather than ignoring it, we can make pretty good use of it.
> >
> > Let's validate that when we're running bootstrap-state we've got an
empty
> > EntityName, and when we're not running it, we've got one that
matches the
> entity
> > name of the machine being started. If those fail, we can error out
and
> complain
> > that the provider is mis-implemented.

> ok. it's slightly strange that when running bootstrap-state, the
password is
> actually for the admin *and* the machine entity, but seems reasonable.
do you
> think it's ok to assume the machine entity name format is well
defined, or
> should we pass in a Machine here instead of a machine id?

if cfg.EntityName != "machine-" + strconv.Itoa(cfg.MachineId) {
     return fmt.Errorf("invalid machine configuration: need
authentication for machine %d", cfg.MachineId)
}

Let's not spend too much time on something that trivial.

https://codereview.appspot.com/6612054/

Roger Peppe (rogpeppe) wrote :
Roger Peppe (rogpeppe) wrote :
Roger Peppe (rogpeppe) wrote :

https://codereview.appspot.com/6612054/diff/2001/environs/cloudinit/cloudinit.go
File environs/cloudinit/cloudinit.go (right):

https://codereview.appspot.com/6612054/diff/2001/environs/cloudinit/cloudinit.go#newcode41
environs/cloudinit/cloudinit.go:41: // The entity name will be ignored.
On 2012/10/05 17:13:04, niemeyer wrote:
> On 2012/10/05 16:40:12, rog wrote:
> > On 2012/10/05 15:43:41, niemeyer wrote:
> > > Rather than ignoring it, we can make pretty good use of it.
> > >
> > > Let's validate that when we're running bootstrap-state we've got
an empty
> > > EntityName, and when we're not running it, we've got one that
matches the
> > entity
> > > name of the machine being started. If those fail, we can error out
and
> > complain
> > > that the provider is mis-implemented.
> >
> > ok. it's slightly strange that when running bootstrap-state, the
password is
> > actually for the admin *and* the machine entity, but seems
reasonable. do you
> > think it's ok to assume the machine entity name format is well
defined, or
> > should we pass in a Machine here instead of a machine id?

> if cfg.EntityName != "machine-" + strconv.Itoa(cfg.MachineId) {
> return fmt.Errorf("invalid machine configuration: need
authentication for
> machine %d", cfg.MachineId)
> }

> Let's not spend too much time on something that trivial.

Done.

https://codereview.appspot.com/6612054/

Gustavo Niemeyer (niemeyer) wrote :

LGTM

https://codereview.appspot.com/6612054/diff/7002/environs/jujutest/test.go
File environs/jujutest/test.go (right):

https://codereview.appspot.com/6612054/diff/7002/environs/jujutest/test.go#newcode18
environs/jujutest/test.go:18: EntityName: fmt.Sprintf("machine-%d",
machineId),
Password: "unimportant",

https://codereview.appspot.com/6612054/

Roger Peppe (rogpeppe) wrote :
Roger Peppe (rogpeppe) wrote :

Please take a look.

https://codereview.appspot.com/6612054/diff/7002/environs/jujutest/test.go
File environs/jujutest/test.go (right):

https://codereview.appspot.com/6612054/diff/7002/environs/jujutest/test.go#newcode18
environs/jujutest/test.go:18: EntityName: fmt.Sprintf("machine-%d",
machineId),
On 2012/10/05 17:39:18, niemeyer wrote:
> Password: "unimportant",

Done. But I've moved this function into juju/testing, because it's
useful elsewhere now.

https://codereview.appspot.com/6612054/

Gustavo Niemeyer (niemeyer) wrote :

LGTM

https://codereview.appspot.com/6612054/diff/20005/juju/testing/conn.go
File juju/testing/conn.go (right):

https://codereview.appspot.com/6612054/diff/20005/juju/testing/conn.go#newcode42
juju/testing/conn.go:42: // machine id of the machine to be started
Please reindent.

https://codereview.appspot.com/6612054/

634. By Roger Peppe on 2012-10-08

merge trunk

635. By Roger Peppe on 2012-10-08

environs/jujutest: fix InvalidStateInfo reference

Roger Peppe (rogpeppe) wrote :
Roger Peppe (rogpeppe) wrote :

*** Submitted:

environs/cloudinit: use --initial-password

R=TheMue, niemeyer
CC=
https://codereview.appspot.com/6612054

https://codereview.appspot.com/6612054/

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'cmd/juju/ssh_test.go'
2--- cmd/juju/ssh_test.go 2012-10-01 01:02:35 +0000
3+++ cmd/juju/ssh_test.go 2012-10-08 16:19:21 +0000
4@@ -121,7 +121,7 @@
5 c.Assert(err, IsNil)
6 // must set an instance id as the ssh command uses that as a signal the machine
7 // has been provisioned
8- inst, err := s.Conn.Environ.StartInstance(m.Id(), nil, nil)
9+ inst, err := s.Conn.Environ.StartInstance(m.Id(), testing.InvalidStateInfo(m.Id()), nil)
10 c.Assert(err, IsNil)
11 c.Assert(m.SetInstanceId(inst.Id()), IsNil)
12 machines[i] = m
13
14=== modified file 'cmd/juju/status_test.go'
15--- cmd/juju/status_test.go 2012-09-28 07:21:43 +0000
16+++ cmd/juju/status_test.go 2012-10-08 16:19:21 +0000
17@@ -59,7 +59,7 @@
18 func(st *state.State, conn *juju.Conn, c *C) {
19 m, err := st.Machine(0)
20 c.Assert(err, IsNil)
21- inst, err := conn.Environ.StartInstance(m.Id(), nil, nil)
22+ inst, err := conn.Environ.StartInstance(m.Id(), testing.InvalidStateInfo(m.Id()), nil)
23 c.Assert(err, IsNil)
24 err = m.SetInstanceId(inst.Id())
25 c.Assert(err, IsNil)
26@@ -146,7 +146,7 @@
27 m, err := st.AddMachine(state.MachinerWorker)
28 c.Assert(err, IsNil)
29 c.Assert(m.Id(), Equals, i)
30- inst, err := conn.Environ.StartInstance(m.Id(), nil, nil)
31+ inst, err := conn.Environ.StartInstance(m.Id(), testing.InvalidStateInfo(m.Id()), nil)
32 c.Assert(err, IsNil)
33 err = m.SetInstanceId(inst.Id())
34 c.Assert(err, IsNil)
35
36=== modified file 'environs/cloudinit/cloudinit.go'
37--- environs/cloudinit/cloudinit.go 2012-10-05 10:17:49 +0000
38+++ environs/cloudinit/cloudinit.go 2012-10-08 16:19:21 +0000
39@@ -9,6 +9,7 @@
40 "launchpad.net/juju-core/environs/config"
41 "launchpad.net/juju-core/log"
42 "launchpad.net/juju-core/state"
43+ "launchpad.net/juju-core/trivial"
44 "launchpad.net/juju-core/upstart"
45 "path"
46 "strings"
47@@ -38,6 +39,8 @@
48 // StateInfo holds the means for the new instance to communicate with the
49 // juju state. Unless the new machine is running a state server (StateServer is
50 // set), there must be at least one state server address supplied.
51+ // The entity name must match that of the machine being started,
52+ // or be empty when starting a state server.
53 StateInfo *state.Info
54
55 // Tools is juju tools to be used on the new machine.
56@@ -62,12 +65,6 @@
57 Config *config.Config
58 }
59
60-type requiresError string
61-
62-func (e requiresError) Error() string {
63- return "invalid machine configuration: missing " + string(e)
64-}
65-
66 func addScripts(c *cloudinit.Config, scripts ...string) {
67 for _, s := range scripts {
68 c.AddRunCmd(s)
69@@ -127,6 +124,7 @@
70 " --instance-id "+cfg.InstanceIdAccessor+
71 " --env-config "+shquote(base64yaml(cfg.Config))+
72 " --state-servers localhost"+mgoPortSuffix+
73+ " --initial-password "+shquote(cfg.StateInfo.Password)+
74 debugFlag,
75 )
76
77@@ -158,11 +156,13 @@
78 " --state-servers '%s'"+
79 " --log-file /var/log/juju/%s-agent.log"+
80 " --data-dir '%s'"+
81+ " --initial-password '%s'"+
82 " %s",
83 toolsDir, kind,
84- cfg.zookeeperHostAddrs(),
85+ cfg.stateHostAddrs(),
86 name,
87 cfg.DataDir,
88+ cfg.StateInfo.Password,
89 args,
90 )
91 conf := &upstart.Conf{
92@@ -218,7 +218,7 @@
93 return environs.ToolsDir(cfg.DataDir, cfg.Tools.Binary)
94 }
95
96-func (cfg *MachineConfig) zookeeperHostAddrs() string {
97+func (cfg *MachineConfig) stateHostAddrs() string {
98 var hosts []string
99 if cfg.StateServer {
100 hosts = append(hosts, "localhost"+mgoPortSuffix)
101@@ -236,32 +236,53 @@
102 return `'` + strings.Replace(s, `'`, `'"'"'`, -1) + `'`
103 }
104
105-func verifyConfig(cfg *MachineConfig) error {
106+type requiresError string
107+
108+func (e requiresError) Error() string {
109+ return "invalid machine configuration: missing " + string(e)
110+}
111+
112+func verifyConfig(cfg *MachineConfig) (err error) {
113+ defer trivial.ErrorContextf(&err, "invalid machine configuration")
114 if cfg.MachineId < 0 {
115- return fmt.Errorf("invalid machine configuration: negative machine id")
116+ return fmt.Errorf("negative machine id")
117 }
118 if cfg.ProviderType == "" {
119- return requiresError("provider type")
120+ return fmt.Errorf("missing provider type")
121 }
122 if cfg.DataDir == "" {
123- return requiresError("var directory")
124+ return fmt.Errorf("missing var directory")
125 }
126 if cfg.Tools == nil {
127- return requiresError("tools")
128+ return fmt.Errorf("missing tools")
129 }
130 if cfg.Tools.URL == "" {
131- return requiresError("tools URL")
132+ return fmt.Errorf("missing tools URL")
133+ }
134+ if cfg.StateInfo == nil {
135+ return fmt.Errorf("missing state info")
136 }
137 if cfg.StateServer {
138 if cfg.InstanceIdAccessor == "" {
139- return requiresError("instance id accessor")
140+ return fmt.Errorf("missing instance id accessor")
141 }
142 if cfg.Config == nil {
143- return requiresError("environment configuration")
144+ return fmt.Errorf("missing environment configuration")
145+ }
146+ if cfg.StateInfo.EntityName != "" {
147+ return fmt.Errorf("entity name must be blank when starting a state server")
148 }
149 } else {
150- if cfg.StateInfo == nil || len(cfg.StateInfo.Addrs) == 0 {
151- return requiresError("zookeeper hosts")
152+ if len(cfg.StateInfo.Addrs) == 0 {
153+ return fmt.Errorf("missing state hosts")
154+ }
155+ if cfg.StateInfo.EntityName != fmt.Sprintf("machine-%d", cfg.MachineId) {
156+ return fmt.Errorf("entity name must match started machine")
157+ }
158+ }
159+ for _, r := range cfg.StateInfo.Password {
160+ if r == '\'' || r == '\\' || r < 32 {
161+ return fmt.Errorf("password has disallowed characters")
162 }
163 }
164 return nil
165
166=== modified file 'environs/cloudinit/cloudinit_test.go'
167--- environs/cloudinit/cloudinit_test.go 2012-09-28 13:17:11 +0000
168+++ environs/cloudinit/cloudinit_test.go 2012-10-08 16:19:21 +0000
169@@ -43,8 +43,11 @@
170 AuthorizedKeys: "sshkey1",
171 Tools: newSimpleTools("1.2.3-linux-amd64"),
172 StateServer: true,
173- Config: envConfig,
174- DataDir: "/var/lib/juju",
175+ StateInfo: &state.Info{
176+ Password: "arble",
177+ },
178+ Config: envConfig,
179+ DataDir: "/var/lib/juju",
180 },
181 {
182 MachineId: 99,
183@@ -53,7 +56,11 @@
184 DataDir: "/var/lib/juju",
185 StateServer: false,
186 Tools: newSimpleTools("1.2.3-linux-amd64"),
187- StateInfo: &state.Info{Addrs: []string{"zk1"}},
188+ StateInfo: &state.Info{
189+ Addrs: []string{"state-addr.example.com"},
190+ EntityName: "machine-99",
191+ Password: "arble",
192+ },
193 },
194 }
195
196@@ -87,9 +94,18 @@
197 t.checkPackage(c, "git")
198
199 if t.cfg.StateServer {
200- t.checkScripts(c, "jujud machine --state-servers 'localhost:37017' .* --machine-id [0-9]+")
201+ t.checkScripts(c, "jujud bootstrap-state"+
202+ ".* --state-servers localhost:37017"+
203+ ".*--initial-password '"+t.cfg.StateInfo.Password+"'")
204+ t.checkScripts(c, "jujud machine"+
205+ " --state-servers 'localhost:37017' "+
206+ ".*--initial-password '"+t.cfg.StateInfo.Password+"'"+
207+ ".* --machine-id [0-9]+")
208 } else {
209- t.checkScripts(c, "jujud machine --state-servers '"+strings.Join(t.cfg.StateInfo.Addrs, ",")+"' .* --machine-id [0-9]+")
210+ t.checkScripts(c, "jujud machine"+
211+ " --state-servers '"+strings.Join(t.cfg.StateInfo.Addrs, ",")+"'"+
212+ ".*--initial-password '"+t.cfg.StateInfo.Password+"'"+
213+ " .*--machine-id [0-9]+")
214 }
215 }
216
217@@ -219,33 +235,59 @@
218 err string
219 mutate func(*cloudinit.MachineConfig)
220 }{
221- {"negative machine id", func(cfg *cloudinit.MachineConfig) { cfg.MachineId = -1 }},
222- {"missing provider type", func(cfg *cloudinit.MachineConfig) { cfg.ProviderType = "" }},
223+ {"negative machine id", func(cfg *cloudinit.MachineConfig) {
224+ cfg.MachineId = -1
225+ }},
226+ {"missing provider type", func(cfg *cloudinit.MachineConfig) {
227+ cfg.ProviderType = ""
228+ }},
229 {"missing instance id accessor", func(cfg *cloudinit.MachineConfig) {
230 cfg.InstanceIdAccessor = ""
231 }},
232 {"missing environment configuration", func(cfg *cloudinit.MachineConfig) {
233 cfg.Config = nil
234 }},
235- {"missing zookeeper hosts", func(cfg *cloudinit.MachineConfig) {
236- cfg.StateServer = false
237+ {"missing state info", func(cfg *cloudinit.MachineConfig) {
238 cfg.StateInfo = nil
239 }},
240- {"missing zookeeper hosts", func(cfg *cloudinit.MachineConfig) {
241+ {"missing state hosts", func(cfg *cloudinit.MachineConfig) {
242 cfg.StateServer = false
243- cfg.StateInfo = &state.Info{}
244+ cfg.StateInfo = &state.Info{EntityName: "machine-99"}
245 }},
246 {"missing var directory", func(cfg *cloudinit.MachineConfig) {
247 cfg.DataDir = ""
248- cfg.StateInfo = &state.Info{}
249 }},
250 {"missing tools", func(cfg *cloudinit.MachineConfig) {
251 cfg.Tools = nil
252- cfg.StateInfo = &state.Info{}
253 }},
254 {"missing tools URL", func(cfg *cloudinit.MachineConfig) {
255 cfg.Tools = &state.Tools{}
256- cfg.StateInfo = &state.Info{}
257+ }},
258+ {"entity name must match started machine", func(cfg *cloudinit.MachineConfig) {
259+ cfg.StateServer = false
260+ info := *cfg.StateInfo
261+ info.EntityName = "machine-0"
262+ cfg.StateInfo = &info
263+ }},
264+ {"entity name must match started machine", func(cfg *cloudinit.MachineConfig) {
265+ cfg.StateServer = false
266+ info := *cfg.StateInfo
267+ info.EntityName = ""
268+ cfg.StateInfo = &info
269+ }},
270+ {"entity name must be blank when starting a state server", func(cfg *cloudinit.MachineConfig) {
271+ info := *cfg.StateInfo
272+ info.EntityName = "machine-0"
273+ cfg.StateInfo = &info
274+ }},
275+ {"password has disallowed characters", func(cfg *cloudinit.MachineConfig) {
276+ cfg.StateInfo.Password = "'"
277+ }},
278+ {"password has disallowed characters", func(cfg *cloudinit.MachineConfig) {
279+ cfg.StateInfo.Password = "\\"
280+ }},
281+ {"password has disallowed characters", func(cfg *cloudinit.MachineConfig) {
282+ cfg.StateInfo.Password = "\n"
283 }},
284 }
285
286@@ -259,15 +301,18 @@
287 MachineId: 99,
288 Tools: newSimpleTools("9.9.9-linux-arble"),
289 AuthorizedKeys: "sshkey1",
290- StateInfo: &state.Info{Addrs: []string{"zkhost"}},
291- Config: envConfig,
292- DataDir: "/var/lib/juju",
293+ StateInfo: &state.Info{
294+ Addrs: []string{"host"},
295+ },
296+ Config: envConfig,
297+ DataDir: "/var/lib/juju",
298 }
299 // check that the base configuration does not give an error
300 _, err := cloudinit.New(cfg)
301 c.Assert(err, IsNil)
302
303- for _, test := range verifyTests {
304+ for i, test := range verifyTests {
305+ c.Logf("test %d. %s", i, test.err)
306 cfg1 := *cfg
307 test.mutate(&cfg1)
308 t, err := cloudinit.New(&cfg1)
309
310=== modified file 'environs/dummy/environs.go'
311--- environs/dummy/environs.go 2012-09-21 11:45:08 +0000
312+++ environs/dummy/environs.go 2012-10-08 16:19:21 +0000
313@@ -468,6 +468,9 @@
314 }
315 e.state.mu.Lock()
316 defer e.state.mu.Unlock()
317+ if info.EntityName != fmt.Sprintf("machine-%d", machineId) {
318+ return nil, fmt.Errorf("entity name must match started machine")
319+ }
320 if tools != nil && (strings.HasPrefix(tools.Series, "unknown") || strings.HasPrefix(tools.Arch, "unknown")) {
321 return nil, fmt.Errorf("cannot find image for %s-%s", tools.Series, tools.Arch)
322 }
323
324=== modified file 'environs/ec2/ec2.go'
325--- environs/ec2/ec2.go 2012-10-04 14:23:00 +0000
326+++ environs/ec2/ec2.go 2012-10-08 16:19:21 +0000
327@@ -233,7 +233,9 @@
328 if err != nil {
329 return fmt.Errorf("unable to determine inital configuration: %v", err)
330 }
331- inst, err := e.startInstance(0, nil, tools, true, config)
332+ // TODO add initial password argument to Bootstrap.
333+ info := &state.Info{}
334+ inst, err := e.startInstance(0, info, tools, true, config)
335 if err != nil {
336 return fmt.Errorf("cannot start bootstrap instance: %v", err)
337 }
338
339=== modified file 'environs/ec2/live_test.go'
340--- environs/ec2/live_test.go 2012-10-05 08:40:36 +0000
341+++ environs/ec2/live_test.go 2012-10-08 16:19:21 +0000
342@@ -10,7 +10,8 @@
343 "launchpad.net/juju-core/environs"
344 "launchpad.net/juju-core/environs/ec2"
345 "launchpad.net/juju-core/environs/jujutest"
346- "launchpad.net/juju-core/testing"
347+ "launchpad.net/juju-core/juju/testing"
348+ coretesting "launchpad.net/juju-core/testing"
349 "strings"
350 "time"
351 )
352@@ -64,7 +65,7 @@
353 // LiveTests contains tests that can be run against the Amazon servers.
354 // Each test runs using the same ec2 connection.
355 type LiveTests struct {
356- testing.LoggingSuite
357+ coretesting.LoggingSuite
358 jujutest.LiveTests
359 }
360
361@@ -102,7 +103,7 @@
362 // TODO(niemeyer): Looks like many of those tests should be moved to jujutest.LiveTests.
363
364 func (t *LiveTests) TestInstanceDNSName(c *C) {
365- inst, err := t.Env.StartInstance(30, jujutest.InvalidStateInfo, nil)
366+ inst, err := t.Env.StartInstance(30, testing.InvalidStateInfo(30), nil)
367 c.Assert(err, IsNil)
368 defer t.Env.StopInstances([]environs.Instance{inst})
369 dns, err := inst.WaitDNSName()
370@@ -153,7 +154,7 @@
371 })
372 c.Assert(err, IsNil)
373
374- inst0, err := t.Env.StartInstance(98, jujutest.InvalidStateInfo, nil)
375+ inst0, err := t.Env.StartInstance(98, testing.InvalidStateInfo(98), nil)
376 c.Assert(err, IsNil)
377 defer t.Env.StopInstances([]environs.Instance{inst0})
378
379@@ -161,7 +162,7 @@
380 // before starting it, to check that it's reused correctly.
381 oldMachineGroup := createGroup(c, ec2conn, groups[2].Name, "old machine group")
382
383- inst1, err := t.Env.StartInstance(99, jujutest.InvalidStateInfo, nil)
384+ inst1, err := t.Env.StartInstance(99, testing.InvalidStateInfo(99), nil)
385 c.Assert(err, IsNil)
386 defer t.Env.StopInstances([]environs.Instance{inst1})
387
388@@ -292,12 +293,12 @@
389 // It would be nice if this test was in jujutest, but
390 // there's no way for jujutest to fabricate a valid-looking
391 // instance id.
392- inst0, err := t.Env.StartInstance(40, jujutest.InvalidStateInfo, nil)
393+ inst0, err := t.Env.StartInstance(40, testing.InvalidStateInfo(40), nil)
394 c.Assert(err, IsNil)
395
396 inst1 := ec2.FabricateInstance(inst0, "i-aaaaaaaa")
397
398- inst2, err := t.Env.StartInstance(41, jujutest.InvalidStateInfo, nil)
399+ inst2, err := t.Env.StartInstance(41, testing.InvalidStateInfo(41), nil)
400 c.Assert(err, IsNil)
401
402 err = t.Env.StopInstances([]environs.Instance{inst0, inst1, inst2})
403
404=== modified file 'environs/ec2/local_test.go'
405--- environs/ec2/local_test.go 2012-10-05 08:40:36 +0000
406+++ environs/ec2/local_test.go 2012-10-08 16:19:21 +0000
407@@ -240,6 +240,7 @@
408 // check that a new instance will be started without
409 // zookeeper, with a machine agent, and without a
410 // provisioning agent.
411+ info.EntityName = "machine-1"
412 inst1, err := t.env.StartInstance(1, info, nil)
413 c.Assert(err, IsNil)
414 inst = t.srv.ec2srv.Instance(inst1.Id())
415
416=== modified file 'environs/jujutest/livetests.go'
417--- environs/jujutest/livetests.go 2012-10-05 15:27:07 +0000
418+++ environs/jujutest/livetests.go 2012-10-08 16:19:21 +0000
419@@ -7,8 +7,9 @@
420 "launchpad.net/juju-core/environs"
421 "launchpad.net/juju-core/environs/config"
422 "launchpad.net/juju-core/juju"
423+ "launchpad.net/juju-core/juju/testing"
424 "launchpad.net/juju-core/state"
425- "launchpad.net/juju-core/testing"
426+ coretesting "launchpad.net/juju-core/testing"
427 "launchpad.net/juju-core/trivial"
428 "launchpad.net/juju-core/version"
429 "time"
430@@ -21,7 +22,7 @@
431 c.Assert(err, IsNil)
432 c.Check(insts, HasLen, 0)
433
434- inst, err := t.Env.StartInstance(0, InvalidStateInfo, nil)
435+ inst, err := t.Env.StartInstance(0, testing.InvalidStateInfo(0), nil)
436 c.Assert(err, IsNil)
437 c.Assert(inst, NotNil)
438 id0 := inst.Id()
439@@ -66,7 +67,7 @@
440 }
441
442 func (t *LiveTests) TestPorts(c *C) {
443- inst1, err := t.Env.StartInstance(1, InvalidStateInfo, nil)
444+ inst1, err := t.Env.StartInstance(1, testing.InvalidStateInfo(1), nil)
445 c.Assert(err, IsNil)
446 c.Assert(inst1, NotNil)
447 defer t.Env.StopInstances([]environs.Instance{inst1})
448@@ -74,7 +75,7 @@
449 c.Assert(err, IsNil)
450 c.Assert(ports, HasLen, 0)
451
452- inst2, err := t.Env.StartInstance(2, InvalidStateInfo, nil)
453+ inst2, err := t.Env.StartInstance(2, testing.InvalidStateInfo(2), nil)
454 c.Assert(err, IsNil)
455 c.Assert(inst2, NotNil)
456 ports, err = inst2.Ports(2)
457@@ -159,14 +160,14 @@
458 c.Assert(err, IsNil)
459
460 // Create instances and check open ports on both instances.
461- inst1, err := t.Env.StartInstance(1, InvalidStateInfo, nil)
462+ inst1, err := t.Env.StartInstance(1, testing.InvalidStateInfo(1), nil)
463 c.Assert(err, IsNil)
464 defer t.Env.StopInstances([]environs.Instance{inst1})
465 ports, err := inst1.Ports(1)
466 c.Assert(err, IsNil)
467 c.Assert(ports, HasLen, 0)
468
469- inst2, err := t.Env.StartInstance(2, InvalidStateInfo, nil)
470+ inst2, err := t.Env.StartInstance(2, testing.InvalidStateInfo(2), nil)
471 c.Assert(err, IsNil)
472 ports, err = inst2.Ports(2)
473 c.Assert(err, IsNil)
474@@ -260,7 +261,7 @@
475 // Create a new service and deploy a unit of it.
476 c.Logf("deploying service")
477 repoDir := c.MkDir()
478- url := testing.Charms.ClonedURL(repoDir, mtools0.Series, "dummy")
479+ url := coretesting.Charms.ClonedURL(repoDir, mtools0.Series, "dummy")
480 sch, err := conn.PutCharm(url, &charm.LocalRepository{repoDir}, false)
481
482 c.Assert(err, IsNil)
483@@ -572,7 +573,7 @@
484 URL: url,
485 }
486
487- inst, err := t.Env.StartInstance(4, InvalidStateInfo, tools)
488+ inst, err := t.Env.StartInstance(4, testing.InvalidStateInfo(4), tools)
489 if inst != nil {
490 err := t.Env.StopInstances([]environs.Instance{inst})
491 c.Check(err, IsNil)
492
493=== modified file 'environs/jujutest/test.go'
494--- environs/jujutest/test.go 2012-10-02 02:02:42 +0000
495+++ environs/jujutest/test.go 2012-10-08 16:19:21 +0000
496@@ -3,17 +3,10 @@
497 import (
498 . "launchpad.net/gocheck"
499 "launchpad.net/juju-core/environs"
500- "launchpad.net/juju-core/state"
501 "launchpad.net/juju-core/testing"
502 "time"
503 )
504
505-// InvalidStateInfo holds information about no state - it will always give
506-// an error when connected to.
507-var InvalidStateInfo = &state.Info{
508- Addrs: []string{"0.1.2.3:1234"},
509-}
510-
511 // Tests is a gocheck suite containing tests verifying juju functionality
512 // against the environment with Name that must exist within Environs. The
513 // tests are not designed to be run against a live server - the Environ
514
515=== modified file 'environs/jujutest/tests.go'
516--- environs/jujutest/tests.go 2012-09-26 10:27:02 +0000
517+++ environs/jujutest/tests.go 2012-10-08 16:19:21 +0000
518@@ -6,6 +6,7 @@
519 "io/ioutil"
520 . "launchpad.net/gocheck"
521 "launchpad.net/juju-core/environs"
522+ "launchpad.net/juju-core/juju/testing"
523 "net/http"
524 "time"
525 )
526@@ -17,12 +18,12 @@
527 c.Assert(err, IsNil)
528 c.Assert(insts, HasLen, 0)
529
530- inst0, err := e.StartInstance(0, InvalidStateInfo, nil)
531+ inst0, err := e.StartInstance(0, testing.InvalidStateInfo(0), nil)
532 c.Assert(err, IsNil)
533 c.Assert(inst0, NotNil)
534 id0 := inst0.Id()
535
536- inst1, err := e.StartInstance(1, InvalidStateInfo, nil)
537+ inst1, err := e.StartInstance(1, testing.InvalidStateInfo(1), nil)
538 c.Assert(err, IsNil)
539 c.Assert(inst1, NotNil)
540 id1 := inst1.Id()
541
542=== modified file 'juju/testing/conn.go'
543--- juju/testing/conn.go 2012-09-21 16:03:23 +0000
544+++ juju/testing/conn.go 2012-10-08 16:19:21 +0000
545@@ -37,6 +37,17 @@
546 oldHome string
547 }
548
549+// InvalidStateInfo holds information about no state - it will always give
550+// an error when connected to. The machine id gives the
551+// machine id of the machine to be started
552+func InvalidStateInfo(machineId int) *state.Info {
553+ return &state.Info{
554+ Addrs: []string{"0.1.2.3:1234"},
555+ EntityName: fmt.Sprintf("machine-%d", machineId),
556+ Password: "unimportant",
557+ }
558+}
559+
560 var config = []byte(`
561 environments:
562 dummyenv:
563
564=== modified file 'worker/firewaller/firewaller_test.go'
565--- worker/firewaller/firewaller_test.go 2012-09-28 17:40:29 +0000
566+++ worker/firewaller/firewaller_test.go 2012-10-08 16:19:21 +0000
567@@ -72,9 +72,16 @@
568 return u, m
569 }
570
571+func (s *FirewallerSuite) StateInfo(c *C, m *state.Machine) *state.Info {
572+ info := s.JujuConnSuite.StateInfo(c)
573+ info.EntityName = m.EntityName()
574+ info.Password = "irrelevant"
575+ return info
576+}
577+
578 // startInstance starts a new instance for the given machine.
579 func (s *FirewallerSuite) startInstance(c *C, m *state.Machine) environs.Instance {
580- inst, err := s.Conn.Environ.StartInstance(m.Id(), s.StateInfo(c), nil)
581+ inst, err := s.Conn.Environ.StartInstance(m.Id(), s.StateInfo(c, m), nil)
582 c.Assert(err, IsNil)
583 err = m.SetInstanceId(inst.Id())
584 c.Assert(err, IsNil)
585@@ -251,7 +258,7 @@
586 func (s *FirewallerSuite) TestFirewallerStartWithPartialState(c *C) {
587 m, err := s.State.AddMachine(state.MachinerWorker)
588 c.Assert(err, IsNil)
589- inst, err := s.Conn.Environ.StartInstance(m.Id(), s.StateInfo(c), nil)
590+ inst, err := s.Conn.Environ.StartInstance(m.Id(), s.StateInfo(c, m), nil)
591 c.Assert(err, IsNil)
592 err = m.SetInstanceId(inst.Id())
593 c.Assert(err, IsNil)
594
595=== modified file 'worker/provisioner/provisioner.go'
596--- worker/provisioner/provisioner.go 2012-09-27 23:26:16 +0000
597+++ worker/provisioner/provisioner.go 2012-10-08 16:19:21 +0000
598@@ -223,7 +223,9 @@
599 // however as the PA only knows one state.Info, and that info is used by MAs and
600 // UAs to locate the ZK for this environment, it is logical to use the same
601 // state.Info as the PA.
602- inst, err := p.environ.StartInstance(m.Id(), p.info, nil)
603+ info := *p.info
604+ info.EntityName = m.EntityName()
605+ inst, err := p.environ.StartInstance(m.Id(), &info, nil)
606 if err != nil {
607 log.Printf("provisioner cannot start machine %s: %v", m, err)
608 return err
609
610=== modified file 'worker/provisioner/provisioner_test.go'
611--- worker/provisioner/provisioner_test.go 2012-09-28 07:21:43 +0000
612+++ worker/provisioner/provisioner_test.go 2012-10-08 16:19:21 +0000
613@@ -73,7 +73,9 @@
614 case o := <-s.op:
615 switch o := o.(type) {
616 case dummy.OpStartInstance:
617- c.Assert(o.Info, DeepEquals, s.StateInfo(c))
618+ info := s.StateInfo(c)
619+ info.EntityName = m.EntityName()
620+ c.Assert(o.Info, DeepEquals, info)
621 c.Assert(o.MachineId, Equals, m.Id())
622 c.Assert(o.Instance, NotNil)
623 s.checkInstanceId(c, m, o.Instance)

Subscribers

People subscribed via source and target branches