Merge lp:~wallyworld/juju-core/agent-conf-upgradedto into lp:~go-bot/juju-core/trunk

Proposed by Ian Booth
Status: Merged
Approved by: Ian Booth
Approved revision: no longer in the source branch.
Merged at revision: 2359
Proposed branch: lp:~wallyworld/juju-core/agent-conf-upgradedto
Merge into: lp:~go-bot/juju-core/trunk
Diff against target: 948 lines (+338/-206)
14 files modified
agent/agent.go (+71/-41)
agent/agent_test.go (+122/-78)
agent/bootstrap_test.go (+12/-10)
agent/format-1.12_whitebox_test.go (+3/-0)
agent/format-1.16.go (+35/-18)
agent/format-1.16_whitebox_test.go (+25/-1)
agent/format_whitebox_test.go (+8/-6)
cmd/jujud/agent_test.go (+16/-14)
cmd/jujud/bootstrap_test.go (+9/-7)
environs/cloudinit/cloudinit.go (+10/-8)
juju/testing/conn.go (+8/-7)
worker/deployer/simple.go (+5/-4)
worker/provisioner/kvm-broker_test.go (+7/-6)
worker/provisioner/lxc-broker_test.go (+7/-6)
To merge this branch: bzr merge lp:~wallyworld/juju-core/agent-conf-upgradedto
Reviewer Review Type Date Requested Status
Tim Penhey (community) Approve
Review via email: mp+207600@code.launchpad.net

Commit message

Record upgradedToVersion in agent conf

The agent config files now record the version for
which upgrade steps were run. If there is no entry
in a config file, is is assumed the version is 1.16.
So there is no need for any migration, nor are there
compatibility issues. When 1.18 is deployed, the upgrade
steps are run and the config file will have 1.18 written
to it, allowing 1.20 to know that it is upgrding from
1.18 etc.

https://codereview.appspot.com/66870044/

Description of the change

Record upgradedToVersion in agent conf

The agent config files now record the version for
which upgrade steps were run. If there is no entry
in a config file, is is assumed the version is 1.16.
So there is no need for any migration, nor are there
compatibility issues. When 1.18 is deployed, the upgrade
steps are run and the config file will have 1.18 written
to it, allowing 1.20 to know that it is upgrding from
1.18 etc.

https://codereview.appspot.com/66870044/

To post a comment you must log in.
Revision history for this message
Ian Booth (wallyworld) wrote :

Reviewers: mp+207600_code.launchpad.net,

Message:
Please take a look.

Description:
Record upgradedToVersion in agent conf

The agent config files now record the version for
which upgrade steps were run. If there is no entry
in a config file, is is assumed the version is 1.16.
So there is no need for any migration, nor are there
compatibility issues. When 1.18 is deployed, the upgrade
steps are run and the config file will have 1.18 written
to it, allowing 1.20 to know that it is upgrding from
1.18 etc.

https://code.launchpad.net/~wallyworld/juju-core/agent-conf-upgradedto/+merge/207600

(do not edit description out of merge proposal)

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

Affected files (+332, -203 lines):
   A [revision details]
   M agent/agent.go
   M agent/agent_test.go
   M agent/bootstrap_test.go
   M agent/format-1.12_whitebox_test.go
   M agent/format-1.16.go
   M agent/format-1.16_whitebox_test.go
   M agent/format_whitebox_test.go
   M cmd/jujud/agent_test.go
   M cmd/jujud/bootstrap_test.go
   M environs/cloudinit/cloudinit.go
   M juju/testing/conn.go
   M worker/deployer/simple.go
   M worker/provisioner/kvm-broker_test.go
   M worker/provisioner/lxc-broker_test.go

Revision history for this message
Tim Penhey (thumper) wrote :

https://codereview.appspot.com/66870044/diff/1/agent/agent.go
File agent/agent.go (right):

https://codereview.appspot.com/66870044/diff/1/agent/agent.go#newcode412
agent/agent.go:412: return c.Write()
If c.Write fails we now have the wrong version stored locally.

Care to fix that?

https://codereview.appspot.com/66870044/diff/1/agent/agent_test.go
File agent/agent_test.go (right):

https://codereview.appspot.com/66870044/diff/1/agent/agent_test.go#newcode226
agent/agent_test.go:226: rereadCommands, err := c2.WriteCommands()
these variable names no longer make sense.

https://codereview.appspot.com/66870044/diff/1/agent/format-1.16.go
File agent/format-1.16.go (right):

https://codereview.appspot.com/66870044/diff/1/agent/format-1.16.go#newcode73
agent/format-1.16.go:73: if value != "" {
I find this much more complicated to follow than a version that doesn't
have named params:

func (*formatter_1_16) upgradedToVersion(value string) (version.Number,
error) {
     if value != "" {
         return version.Parse(value)
     }
     return version.MustParse("1.16.0"), nil
}

https://codereview.appspot.com/66870044/

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

Please take a look.

https://codereview.appspot.com/66870044/diff/1/agent/agent_test.go
File agent/agent_test.go (right):

https://codereview.appspot.com/66870044/diff/1/agent/agent_test.go#newcode226
agent/agent_test.go:226: rereadCommands, err := c2.WriteCommands()
On 2014/02/26 02:23:41, thumper wrote:
> these variable names no longer make sense.

Done.

https://codereview.appspot.com/66870044/diff/1/agent/format-1.16.go
File agent/format-1.16.go (right):

https://codereview.appspot.com/66870044/diff/1/agent/format-1.16.go#newcode73
agent/format-1.16.go:73: if value != "" {
On 2014/02/26 02:23:41, thumper wrote:
> I find this much more complicated to follow than a version that
doesn't have
> named params:

> func (*formatter_1_16) upgradedToVersion(value string)
(version.Number, error) {
> if value != "" {
> return version.Parse(value)
> }
> return version.MustParse("1.16.0"), nil
> }

Done.

https://codereview.appspot.com/66870044/

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

https://codereview.appspot.com/66870044/diff/1/agent/agent.go
File agent/agent.go (right):

https://codereview.appspot.com/66870044/diff/1/agent/agent.go#newcode412
agent/agent.go:412: return c.Write()
On 2014/02/26 02:23:41, thumper wrote:
> If c.Write fails we now have the wrong version stored locally.

> Care to fix that?

Done.

https://codereview.appspot.com/66870044/

Revision history for this message
Tim Penhey (thumper) wrote :
Revision history for this message
Tim Penhey (thumper) :
review: Approve
Revision history for this message
Go Bot (go-bot) wrote :
Download full text (9.6 KiB)

The attempt to merge lp:~wallyworld/juju-core/agent-conf-upgradedto into lp:juju-core failed. Below is the output from the failed tests.

ok launchpad.net/juju-core 0.017s
ok launchpad.net/juju-core/agent 1.236s
ok launchpad.net/juju-core/agent/tools 0.257s
ok launchpad.net/juju-core/bzr 7.054s
ok launchpad.net/juju-core/cert 3.641s
ok launchpad.net/juju-core/charm 0.534s
? 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.037s
ok launchpad.net/juju-core/cloudinit/sshinit 1.200s
ok launchpad.net/juju-core/cmd 0.202s
ok launchpad.net/juju-core/cmd/charm-admin 0.812s
? launchpad.net/juju-core/cmd/charmd [no test files]
? launchpad.net/juju-core/cmd/charmload [no test files]
ok launchpad.net/juju-core/cmd/juju 252.830s
ok launchpad.net/juju-core/cmd/jujud 62.086s
ok launchpad.net/juju-core/cmd/plugins/juju-metadata 13.722s
? launchpad.net/juju-core/cmd/plugins/juju-restore [no test files]
ok launchpad.net/juju-core/constraints 0.027s
ok launchpad.net/juju-core/container 0.040s
ok launchpad.net/juju-core/container/factory 0.055s
ok launchpad.net/juju-core/container/kvm 0.254s
ok launchpad.net/juju-core/container/kvm/mock 0.039s
? launchpad.net/juju-core/container/kvm/testing [no test files]
ok launchpad.net/juju-core/container/lxc 0.304s
? 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.305s
ok launchpad.net/juju-core/environs 3.213s
ok launchpad.net/juju-core/environs/bootstrap 4.695s
ok launchpad.net/juju-core/environs/cloudinit 0.649s
ok launchpad.net/juju-core/environs/config 2.194s
ok launchpad.net/juju-core/environs/configstore 0.049s
ok launchpad.net/juju-core/environs/filestorage 0.032s
ok launchpad.net/juju-core/environs/httpstorage 1.016s
ok launchpad.net/juju-core/environs/imagemetadata 0.608s
? launchpad.net/juju-core/environs/imagemetadata/testing [no test files]
ok launchpad.net/juju-core/environs/instances 0.061s
ok launchpad.net/juju-core/environs/jujutest 0.242s
ok launchpad.net/juju-core/environs/manual 15.725s
ok launchpad.net/juju-core/environs/simplestreams 0.389s
? launchpad.net/juju-core/environs/simplestreams/testing [no test files]
ok launchpad.net/juju-core/environs/sshstorage 1.184s
ok launchpad.net/juju-core/environs/storage 1.162s
ok launchpad.net/juju-core/environs/sync 36.513s
ok launchpad.net/juju-core/environs/testing 0.206s
ok launchpad.net/juju-core/environs/tools 6.740s
? launchpad.net/juju-core/environs/tools/testing [no test files]
ok launchpad.net/juju-core/errors 0.016s
ok launchpad.net/juju-core/instance 0.024s
? launchpad.net/juju-core/instance/testing [no test files]
ok launchpad.net/juju-core/juju 24.882s
ok launchpad.net/juju-core/juju/osenv 0.020s
? launchpad.net/juju-core/juju/testing [no test files]
ok launchpad.net/juju-core/log 0.015s
ok launchpad.net/juju-core/log/syslog 0.023s
? launchpad.net/juju-co...

Read more...

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'agent/agent.go'
2--- agent/agent.go 2014-02-18 05:43:06 +0000
3+++ agent/agent.go 2014-02-26 03:43:42 +0000
4@@ -17,6 +17,7 @@
5 "launchpad.net/juju-core/state/api"
6 "launchpad.net/juju-core/state/api/params"
7 "launchpad.net/juju-core/utils"
8+ "launchpad.net/juju-core/version"
9 )
10
11 var logger = loggo.GetLogger("juju.agent")
12@@ -88,6 +89,14 @@
13 // APIServerDetails returns the details needed to run an API server.
14 APIServerDetails() (port int, cert, key []byte)
15
16+ // UpgradedToVersion returns the version for which all upgrade steps have been
17+ // successfully run, which is also the same as the initially deployed version.
18+ UpgradedToVersion() version.Number
19+
20+ // WriteUpgradedToVersion updates the config's UpgradedToVersion and writes
21+ // the new agent configuration.
22+ WriteUpgradedToVersion(newVersion version.Number) error
23+
24 // Value returns the value associated with the key, or an empty string if
25 // the key is not found.
26 Value(key string) string
27@@ -122,63 +131,69 @@
28 }
29
30 type configInternal struct {
31- dataDir string
32- tag string
33- nonce string
34- caCert []byte
35- stateDetails *connectionDetails
36- apiDetails *connectionDetails
37- oldPassword string
38- stateServerCert []byte
39- stateServerKey []byte
40- apiPort int
41- values map[string]string
42+ dataDir string
43+ tag string
44+ upgradedToVersion version.Number
45+ nonce string
46+ caCert []byte
47+ stateDetails *connectionDetails
48+ apiDetails *connectionDetails
49+ oldPassword string
50+ stateServerCert []byte
51+ stateServerKey []byte
52+ apiPort int
53+ values map[string]string
54 }
55
56 type AgentConfigParams struct {
57- DataDir string
58- Tag string
59- Password string
60- Nonce string
61- StateAddresses []string
62- APIAddresses []string
63- CACert []byte
64- Values map[string]string
65+ DataDir string
66+ Tag string
67+ UpgradedToVersion version.Number
68+ Password string
69+ Nonce string
70+ StateAddresses []string
71+ APIAddresses []string
72+ CACert []byte
73+ Values map[string]string
74 }
75
76 // NewAgentConfig returns a new config object suitable for use for a
77 // machine or unit agent.
78-func NewAgentConfig(params AgentConfigParams) (Config, error) {
79- if params.DataDir == "" {
80+func NewAgentConfig(configParams AgentConfigParams) (Config, error) {
81+ if configParams.DataDir == "" {
82 return nil, errgo.Trace(requiredError("data directory"))
83 }
84- if params.Tag == "" {
85+ if configParams.Tag == "" {
86 return nil, errgo.Trace(requiredError("entity tag"))
87 }
88- if params.Password == "" {
89+ if configParams.UpgradedToVersion == version.Zero {
90+ return nil, errgo.Trace(requiredError("upgradedToVersion"))
91+ }
92+ if configParams.Password == "" {
93 return nil, errgo.Trace(requiredError("password"))
94 }
95- if params.CACert == nil {
96+ if configParams.CACert == nil {
97 return nil, errgo.Trace(requiredError("CA certificate"))
98 }
99 // Note that the password parts of the state and api information are
100 // blank. This is by design.
101 config := &configInternal{
102- dataDir: params.DataDir,
103- tag: params.Tag,
104- nonce: params.Nonce,
105- caCert: params.CACert,
106- oldPassword: params.Password,
107- values: params.Values,
108+ dataDir: configParams.DataDir,
109+ tag: configParams.Tag,
110+ upgradedToVersion: configParams.UpgradedToVersion,
111+ nonce: configParams.Nonce,
112+ caCert: configParams.CACert,
113+ oldPassword: configParams.Password,
114+ values: configParams.Values,
115 }
116- if len(params.StateAddresses) > 0 {
117+ if len(configParams.StateAddresses) > 0 {
118 config.stateDetails = &connectionDetails{
119- addresses: params.StateAddresses,
120+ addresses: configParams.StateAddresses,
121 }
122 }
123- if len(params.APIAddresses) > 0 {
124+ if len(configParams.APIAddresses) > 0 {
125 config.apiDetails = &connectionDetails{
126- addresses: params.APIAddresses,
127+ addresses: configParams.APIAddresses,
128 }
129 }
130 if err := config.check(); err != nil {
131@@ -200,21 +215,21 @@
132
133 // NewStateMachineConfig returns a configuration suitable for
134 // a machine running the state server.
135-func NewStateMachineConfig(params StateMachineConfigParams) (Config, error) {
136- if params.StateServerCert == nil {
137+func NewStateMachineConfig(configParams StateMachineConfigParams) (Config, error) {
138+ if configParams.StateServerCert == nil {
139 return nil, errgo.Trace(requiredError("state server cert"))
140 }
141- if params.StateServerKey == nil {
142+ if configParams.StateServerKey == nil {
143 return nil, errgo.Trace(requiredError("state server key"))
144 }
145- config0, err := NewAgentConfig(params.AgentConfigParams)
146+ config0, err := NewAgentConfig(configParams.AgentConfigParams)
147 if err != nil {
148 return nil, err
149 }
150 config := config0.(*configInternal)
151- config.stateServerCert = params.StateServerCert
152- config.stateServerKey = params.StateServerKey
153- config.apiPort = params.APIPort
154+ config.stateServerCert = configParams.StateServerCert
155+ config.stateServerKey = configParams.StateServerKey
156+ config.apiPort = configParams.APIPort
157 return config, nil
158 }
159
160@@ -279,6 +294,10 @@
161 return c.nonce
162 }
163
164+func (c *configInternal) UpgradedToVersion() version.Number {
165+ return c.upgradedToVersion
166+}
167+
168 func (c *configInternal) CACert() []byte {
169 // Give the caller their own copy of the cert to avoid any possibility of
170 // modifying the config's copy.
171@@ -388,6 +407,17 @@
172 return currentFormatter.write(c)
173 }
174
175+func (c *configInternal) WriteUpgradedToVersion(newVersion version.Number) error {
176+ originalVersion := c.upgradedToVersion
177+ c.upgradedToVersion = newVersion
178+ err := c.Write()
179+ if err != nil {
180+ // We don't want to retain the new version if there's been an error writing the file.
181+ c.upgradedToVersion = originalVersion
182+ }
183+ return err
184+}
185+
186 func (c *configInternal) WriteCommands() ([]string, error) {
187 return currentFormatter.writeCommands(c)
188 }
189
190=== modified file 'agent/agent_test.go'
191--- agent/agent_test.go 2013-11-19 13:23:51 +0000
192+++ agent/agent_test.go 2014-02-26 03:43:42 +0000
193@@ -8,6 +8,7 @@
194
195 "launchpad.net/juju-core/agent"
196 "launchpad.net/juju-core/testing/testbase"
197+ "launchpad.net/juju-core/version"
198 )
199
200 type suite struct {
201@@ -30,87 +31,103 @@
202 },
203 checkErr: "entity tag not found in configuration",
204 }, {
205+ about: "missing upgraded to version",
206+ params: agent.AgentConfigParams{
207+ DataDir: "/data/dir",
208+ Tag: "omg",
209+ },
210+ checkErr: "upgradedToVersion not found in configuration",
211+}, {
212 about: "missing password",
213 params: agent.AgentConfigParams{
214- DataDir: "/data/dir",
215- Tag: "omg",
216+ DataDir: "/data/dir",
217+ Tag: "omg",
218+ UpgradedToVersion: version.Current.Number,
219 },
220 checkErr: "password not found in configuration",
221 }, {
222 about: "missing CA cert",
223 params: agent.AgentConfigParams{
224- DataDir: "/data/dir",
225- Tag: "omg",
226- Password: "sekrit",
227+ DataDir: "/data/dir",
228+ Tag: "omg",
229+ UpgradedToVersion: version.Current.Number,
230+ Password: "sekrit",
231 },
232 checkErr: "CA certificate not found in configuration",
233 }, {
234 about: "need either state or api addresses",
235 params: agent.AgentConfigParams{
236- DataDir: "/data/dir",
237- Tag: "omg",
238- Password: "sekrit",
239- CACert: []byte("ca cert"),
240+ DataDir: "/data/dir",
241+ Tag: "omg",
242+ UpgradedToVersion: version.Current.Number,
243+ Password: "sekrit",
244+ CACert: []byte("ca cert"),
245 },
246 checkErr: "state or API addresses not found in configuration",
247 }, {
248 about: "invalid state address",
249 params: agent.AgentConfigParams{
250- DataDir: "/data/dir",
251- Tag: "omg",
252- Password: "sekrit",
253- CACert: []byte("ca cert"),
254- StateAddresses: []string{"localhost:8080", "bad-address"},
255+ DataDir: "/data/dir",
256+ Tag: "omg",
257+ UpgradedToVersion: version.Current.Number,
258+ Password: "sekrit",
259+ CACert: []byte("ca cert"),
260+ StateAddresses: []string{"localhost:8080", "bad-address"},
261 },
262 checkErr: `invalid state server address "bad-address"`,
263 }, {
264 about: "invalid api address",
265 params: agent.AgentConfigParams{
266- DataDir: "/data/dir",
267- Tag: "omg",
268- Password: "sekrit",
269- CACert: []byte("ca cert"),
270- APIAddresses: []string{"localhost:8080", "bad-address"},
271+ DataDir: "/data/dir",
272+ Tag: "omg",
273+ UpgradedToVersion: version.Current.Number,
274+ Password: "sekrit",
275+ CACert: []byte("ca cert"),
276+ APIAddresses: []string{"localhost:8080", "bad-address"},
277 },
278 checkErr: `invalid API server address "bad-address"`,
279 }, {
280 about: "good state addresses",
281 params: agent.AgentConfigParams{
282- DataDir: "/data/dir",
283- Tag: "omg",
284- Password: "sekrit",
285- CACert: []byte("ca cert"),
286- StateAddresses: []string{"localhost:1234"},
287+ DataDir: "/data/dir",
288+ Tag: "omg",
289+ UpgradedToVersion: version.Current.Number,
290+ Password: "sekrit",
291+ CACert: []byte("ca cert"),
292+ StateAddresses: []string{"localhost:1234"},
293 },
294 }, {
295 about: "good api addresses",
296 params: agent.AgentConfigParams{
297- DataDir: "/data/dir",
298- Tag: "omg",
299- Password: "sekrit",
300- CACert: []byte("ca cert"),
301- APIAddresses: []string{"localhost:1234"},
302+ DataDir: "/data/dir",
303+ Tag: "omg",
304+ UpgradedToVersion: version.Current.Number,
305+ Password: "sekrit",
306+ CACert: []byte("ca cert"),
307+ APIAddresses: []string{"localhost:1234"},
308 },
309 }, {
310 about: "both state and api addresses",
311 params: agent.AgentConfigParams{
312- DataDir: "/data/dir",
313- Tag: "omg",
314- Password: "sekrit",
315- CACert: []byte("ca cert"),
316- StateAddresses: []string{"localhost:1234"},
317- APIAddresses: []string{"localhost:1235"},
318+ DataDir: "/data/dir",
319+ Tag: "omg",
320+ UpgradedToVersion: version.Current.Number,
321+ Password: "sekrit",
322+ CACert: []byte("ca cert"),
323+ StateAddresses: []string{"localhost:1234"},
324+ APIAddresses: []string{"localhost:1235"},
325 },
326 }, {
327 about: "everything...",
328 params: agent.AgentConfigParams{
329- DataDir: "/data/dir",
330- Tag: "omg",
331- Password: "sekrit",
332- CACert: []byte("ca cert"),
333- StateAddresses: []string{"localhost:1234"},
334- APIAddresses: []string{"localhost:1235"},
335- Nonce: "a nonce",
336+ DataDir: "/data/dir",
337+ Tag: "omg",
338+ Password: "sekrit",
339+ UpgradedToVersion: version.Current.Number,
340+ CACert: []byte("ca cert"),
341+ StateAddresses: []string{"localhost:1234"},
342+ APIAddresses: []string{"localhost:1235"},
343+ Nonce: "a nonce",
344 },
345 }}
346
347@@ -168,13 +185,14 @@
348 }
349
350 var attributeParams = agent.AgentConfigParams{
351- DataDir: "/data/dir",
352- Tag: "omg",
353- Password: "sekrit",
354- CACert: []byte("ca cert"),
355- StateAddresses: []string{"localhost:1234"},
356- APIAddresses: []string{"localhost:1235"},
357- Nonce: "a nonce",
358+ DataDir: "/data/dir",
359+ Tag: "omg",
360+ UpgradedToVersion: version.Current.Number,
361+ Password: "sekrit",
362+ CACert: []byte("ca cert"),
363+ StateAddresses: []string{"localhost:1234"},
364+ APIAddresses: []string{"localhost:1235"},
365+ Nonce: "a nonce",
366 }
367
368 func (*suite) TestAttributes(c *gc.C) {
369@@ -184,6 +202,7 @@
370 c.Assert(conf.Tag(), gc.Equals, "omg")
371 c.Assert(conf.Dir(), gc.Equals, "/data/dir/agents/omg")
372 c.Assert(conf.Nonce(), gc.Equals, "a nonce")
373+ c.Assert(conf.UpgradedToVersion(), gc.DeepEquals, version.Current.Number)
374 }
375
376 func (s *suite) TestApiAddressesCantWriteBack(c *gc.C) {
377@@ -198,22 +217,27 @@
378 c.Assert(err, gc.IsNil)
379 c.Assert(newValue, gc.DeepEquals, []string{"localhost:1235"})
380 }
381-func (*suite) TestWriteAndRead(c *gc.C) {
382- testParams := attributeParams
383- testParams.DataDir = c.MkDir()
384- conf, err := agent.NewAgentConfig(testParams)
385- c.Assert(err, gc.IsNil)
386
387- c.Assert(conf.Write(), gc.IsNil)
388- reread, err := agent.ReadConf(conf.DataDir(), conf.Tag())
389- c.Assert(err, gc.IsNil)
390+func assertConfigEqual(c *gc.C, c1, c2 agent.Config) {
391 // Since we can't directly poke the internals, we'll use the WriteCommands
392 // method.
393- confCommands, err := conf.WriteCommands()
394- c.Assert(err, gc.IsNil)
395- rereadCommands, err := reread.WriteCommands()
396- c.Assert(err, gc.IsNil)
397- c.Assert(confCommands, gc.DeepEquals, rereadCommands)
398+ conf1Commands, err := c1.WriteCommands()
399+ c.Assert(err, gc.IsNil)
400+ conf2Commands, err := c2.WriteCommands()
401+ c.Assert(err, gc.IsNil)
402+ c.Assert(conf1Commands, gc.DeepEquals, conf2Commands)
403+}
404+
405+func (*suite) TestWriteAndRead(c *gc.C) {
406+ testParams := attributeParams
407+ testParams.DataDir = c.MkDir()
408+ conf, err := agent.NewAgentConfig(testParams)
409+ c.Assert(err, gc.IsNil)
410+
411+ c.Assert(conf.Write(), gc.IsNil)
412+ reread, err := agent.ReadConf(conf.DataDir(), conf.Tag())
413+ c.Assert(err, gc.IsNil)
414+ assertConfigEqual(c, conf, reread)
415 }
416
417 func (*suite) TestWriteNewPassword(c *gc.C) {
418@@ -224,30 +248,33 @@
419 }{{
420 about: "good state addresses",
421 params: agent.AgentConfigParams{
422- DataDir: c.MkDir(),
423- Tag: "omg",
424- Password: "sekrit",
425- CACert: []byte("ca cert"),
426- StateAddresses: []string{"localhost:1234"},
427+ DataDir: c.MkDir(),
428+ Tag: "omg",
429+ UpgradedToVersion: version.Current.Number,
430+ Password: "sekrit",
431+ CACert: []byte("ca cert"),
432+ StateAddresses: []string{"localhost:1234"},
433 },
434 }, {
435 about: "good api addresses",
436 params: agent.AgentConfigParams{
437- DataDir: c.MkDir(),
438- Tag: "omg",
439- Password: "sekrit",
440- CACert: []byte("ca cert"),
441- APIAddresses: []string{"localhost:1234"},
442+ DataDir: c.MkDir(),
443+ Tag: "omg",
444+ UpgradedToVersion: version.Current.Number,
445+ Password: "sekrit",
446+ CACert: []byte("ca cert"),
447+ APIAddresses: []string{"localhost:1234"},
448 },
449 }, {
450 about: "both state and api addresses",
451 params: agent.AgentConfigParams{
452- DataDir: c.MkDir(),
453- Tag: "omg",
454- Password: "sekrit",
455- CACert: []byte("ca cert"),
456- StateAddresses: []string{"localhost:1234"},
457- APIAddresses: []string{"localhost:1235"},
458+ DataDir: c.MkDir(),
459+ Tag: "omg",
460+ UpgradedToVersion: version.Current.Number,
461+ Password: "sekrit",
462+ CACert: []byte("ca cert"),
463+ StateAddresses: []string{"localhost:1234"},
464+ APIAddresses: []string{"localhost:1235"},
465 },
466 }} {
467 c.Logf("%v: %s", i, test.about)
468@@ -263,6 +290,23 @@
469 }
470 }
471
472+func (*suite) TestWriteUpgradedToVersion(c *gc.C) {
473+ testParams := attributeParams
474+ testParams.DataDir = c.MkDir()
475+ conf, err := agent.NewAgentConfig(testParams)
476+ c.Assert(err, gc.IsNil)
477+ c.Assert(conf.Write(), gc.IsNil)
478+
479+ newVersion := version.Current.Number
480+ newVersion.Major++
481+ c.Assert(conf.WriteUpgradedToVersion(newVersion), gc.IsNil)
482+ c.Assert(conf.UpgradedToVersion(), gc.DeepEquals, newVersion)
483+
484+ // Show that the upgradedToVersion is saved.
485+ reread, err := agent.ReadConf(conf.DataDir(), conf.Tag())
486+ assertConfigEqual(c, conf, reread)
487+}
488+
489 // Actual opening of state and api requires a lot more boiler plate to make
490 // sure they are valid connections. This is done in the cmd/jujud tests for
491 // bootstrap, machine and unit tests.
492
493=== modified file 'agent/bootstrap_test.go'
494--- agent/bootstrap_test.go 2014-02-19 06:50:24 +0000
495+++ agent/bootstrap_test.go 2014-02-26 03:43:42 +0000
496@@ -51,11 +51,12 @@
497
498 pwHash := utils.UserPasswordHash(testing.DefaultMongoPassword, utils.CompatSalt)
499 cfg, err := agent.NewAgentConfig(agent.AgentConfigParams{
500- DataDir: dataDir,
501- Tag: "machine-0",
502- StateAddresses: []string{testing.MgoServer.Addr()},
503- CACert: []byte(testing.CACert),
504- Password: pwHash,
505+ DataDir: dataDir,
506+ Tag: "machine-0",
507+ UpgradedToVersion: version.Current.Number,
508+ StateAddresses: []string{testing.MgoServer.Addr()},
509+ CACert: []byte(testing.CACert),
510+ Password: pwHash,
511 })
512 c.Assert(err, gc.IsNil)
513 expectConstraints := constraints.MustParse("mem=1024M")
514@@ -116,11 +117,12 @@
515 dataDir := c.MkDir()
516 pwHash := utils.UserPasswordHash(testing.DefaultMongoPassword, utils.CompatSalt)
517 cfg, err := agent.NewAgentConfig(agent.AgentConfigParams{
518- DataDir: dataDir,
519- Tag: "machine-0",
520- StateAddresses: []string{testing.MgoServer.Addr()},
521- CACert: []byte(testing.CACert),
522- Password: pwHash,
523+ DataDir: dataDir,
524+ Tag: "machine-0",
525+ UpgradedToVersion: version.Current.Number,
526+ StateAddresses: []string{testing.MgoServer.Addr()},
527+ CACert: []byte(testing.CACert),
528+ Password: pwHash,
529 })
530 c.Assert(err, gc.IsNil)
531 expectConstraints := constraints.MustParse("mem=1024M")
532
533=== modified file 'agent/format-1.12_whitebox_test.go'
534--- agent/format-1.12_whitebox_test.go 2013-10-04 16:16:10 +0000
535+++ agent/format-1.12_whitebox_test.go 2014-02-26 03:43:42 +0000
536@@ -11,6 +11,7 @@
537
538 jc "launchpad.net/juju-core/testing/checkers"
539 "launchpad.net/juju-core/testing/testbase"
540+ "launchpad.net/juju-core/version"
541 )
542
543 type format_1_12Suite struct {
544@@ -42,6 +43,8 @@
545 }
546
547 func (s *format_1_12Suite) assertWriteAndRead(c *gc.C, config *configInternal) {
548+ // Format 1.12 doesn't know about upgradedToVersion so zero it out.
549+ config.upgradedToVersion = version.Zero
550 err := s.formatter.write(config)
551 c.Assert(err, gc.IsNil)
552 // The readConfig is missing the dataDir initially.
553
554=== modified file 'agent/format-1.16.go'
555--- agent/format-1.16.go 2014-02-12 21:14:17 +0000
556+++ agent/format-1.16.go 2014-02-26 03:43:42 +0000
557@@ -12,6 +12,7 @@
558 "launchpad.net/goyaml"
559
560 "launchpad.net/juju-core/juju/osenv"
561+ "launchpad.net/juju-core/version"
562 )
563
564 const (
565@@ -29,8 +30,9 @@
566
567 // format_1_16Serialization holds information for a given agent.
568 type format_1_16Serialization struct {
569- Tag string
570- Nonce string
571+ Tag string
572+ Nonce string
573+ UpgradedToVersion string `yaml:"upgradedToVersion"`
574 // CACert is base64 encoded
575 CACert string
576 StateAddresses []string `yaml:",omitempty"`
577@@ -64,6 +66,15 @@
578 return
579 }
580
581+// upgradedToVersion parses the upgradedToVersion string value into a version.Number.
582+// An empty value is returned as 1.16.0.
583+func (*formatter_1_16) upgradedToVersion(value string) (version.Number, error) {
584+ if value != "" {
585+ return version.Parse(value)
586+ }
587+ return version.MustParse("1.16.0"), nil
588+}
589+
590 func (formatter *formatter_1_16) read(dirName string) (*configInternal, error) {
591 data, err := ioutil.ReadFile(formatter.configFile(dirName))
592 if err != nil {
593@@ -85,15 +96,20 @@
594 if err != nil {
595 return nil, err
596 }
597+ upgradedToVersion, err := formatter.upgradedToVersion(format.UpgradedToVersion)
598+ if err != nil {
599+ return nil, err
600+ }
601 config := &configInternal{
602- tag: format.Tag,
603- nonce: format.Nonce,
604- caCert: caCert,
605- oldPassword: format.OldPassword,
606- stateServerCert: stateServerCert,
607- stateServerKey: stateServerKey,
608- apiPort: format.APIPort,
609- values: format.Values,
610+ tag: format.Tag,
611+ nonce: format.Nonce,
612+ upgradedToVersion: upgradedToVersion,
613+ caCert: caCert,
614+ oldPassword: format.OldPassword,
615+ stateServerCert: stateServerCert,
616+ stateServerKey: stateServerKey,
617+ apiPort: format.APIPort,
618+ values: format.Values,
619 }
620 if len(format.StateAddresses) > 0 {
621 config.stateDetails = &connectionDetails{
622@@ -112,14 +128,15 @@
623
624 func (formatter *formatter_1_16) makeFormat(config *configInternal) *format_1_16Serialization {
625 format := &format_1_16Serialization{
626- Tag: config.tag,
627- Nonce: config.nonce,
628- CACert: base64.StdEncoding.EncodeToString(config.caCert),
629- OldPassword: config.oldPassword,
630- StateServerCert: base64.StdEncoding.EncodeToString(config.stateServerCert),
631- StateServerKey: base64.StdEncoding.EncodeToString(config.stateServerKey),
632- APIPort: config.apiPort,
633- Values: config.values,
634+ Tag: config.tag,
635+ Nonce: config.nonce,
636+ UpgradedToVersion: config.upgradedToVersion.String(),
637+ CACert: base64.StdEncoding.EncodeToString(config.caCert),
638+ OldPassword: config.oldPassword,
639+ StateServerCert: base64.StdEncoding.EncodeToString(config.stateServerCert),
640+ StateServerKey: base64.StdEncoding.EncodeToString(config.stateServerKey),
641+ APIPort: config.apiPort,
642+ Values: config.values,
643 }
644 if config.stateDetails != nil {
645 format.StateAddresses = config.stateDetails.addresses
646
647=== modified file 'agent/format-1.16_whitebox_test.go'
648--- agent/format-1.16_whitebox_test.go 2014-02-12 21:14:17 +0000
649+++ agent/format-1.16_whitebox_test.go 2014-02-26 03:43:42 +0000
650@@ -8,14 +8,17 @@
651 package agent
652
653 import (
654+ "io/ioutil"
655 "os"
656 "path"
657+ "path/filepath"
658
659 gc "launchpad.net/gocheck"
660
661 "launchpad.net/juju-core/juju/osenv"
662 jc "launchpad.net/juju-core/testing/checkers"
663 "launchpad.net/juju-core/testing/testbase"
664+ "launchpad.net/juju-core/version"
665 )
666
667 type format_1_16Suite struct {
668@@ -48,6 +51,27 @@
669 c.Assert(formatContent, gc.Equals, format_1_16)
670 }
671
672+var configDataWithoutUpgradedToVersion = `
673+tag: omg
674+nonce: a nonce
675+cacert: Y2EgY2VydA==
676+stateaddresses:
677+- localhost:1234
678+apiaddresses:
679+- localhost:1235
680+oldpassword: sekrit
681+values: {}
682+`
683+
684+func (s *format_1_16Suite) TestMissingUpgradedToVersion(c *gc.C) {
685+ dataDir := c.MkDir()
686+ err := ioutil.WriteFile(filepath.Join(dataDir, "agent.conf"), []byte(configDataWithoutUpgradedToVersion), 0600)
687+ c.Assert(err, gc.IsNil)
688+ readConfig, err := s.formatter.read(dataDir)
689+ c.Assert(err, gc.IsNil)
690+ c.Assert(readConfig.UpgradedToVersion(), gc.Equals, version.MustParse("1.16.0"))
691+}
692+
693 func (s *format_1_16Suite) assertWriteAndRead(c *gc.C, config *configInternal) {
694 err := s.formatter.write(config)
695 c.Assert(err, gc.IsNil)
696@@ -56,7 +80,7 @@
697 c.Assert(err, gc.IsNil)
698 c.Assert(readConfig.dataDir, gc.Equals, "")
699 // This is put in by the ReadConf method that we are avoiding using
700- // becuase it will have side-effects soon around migrating configs.
701+ // because it will have side-effects soon around migrating configs.
702 readConfig.dataDir = config.dataDir
703 c.Assert(readConfig, gc.DeepEquals, config)
704 }
705
706=== modified file 'agent/format_whitebox_test.go'
707--- agent/format_whitebox_test.go 2013-10-04 16:16:10 +0000
708+++ agent/format_whitebox_test.go 2014-02-26 03:43:42 +0000
709@@ -10,6 +10,7 @@
710 gc "launchpad.net/gocheck"
711
712 "launchpad.net/juju-core/testing/testbase"
713+ "launchpad.net/juju-core/version"
714 )
715
716 type formatSuite struct {
717@@ -21,12 +22,13 @@
718 // The agentParams are used by the specific formatter whitebox tests, and is
719 // located here for easy reuse.
720 var agentParams = AgentConfigParams{
721- Tag: "omg",
722- Password: "sekrit",
723- CACert: []byte("ca cert"),
724- StateAddresses: []string{"localhost:1234"},
725- APIAddresses: []string{"localhost:1235"},
726- Nonce: "a nonce",
727+ Tag: "omg",
728+ UpgradedToVersion: version.Current.Number,
729+ Password: "sekrit",
730+ CACert: []byte("ca cert"),
731+ StateAddresses: []string{"localhost:1234"},
732+ APIAddresses: []string{"localhost:1235"},
733+ Nonce: "a nonce",
734 }
735
736 func (*formatSuite) TestReadFormatEmptyDir(c *gc.C) {
737
738=== modified file 'cmd/jujud/agent_test.go'
739--- cmd/jujud/agent_test.go 2014-02-20 08:23:40 +0000
740+++ cmd/jujud/agent_test.go 2014-02-26 03:43:42 +0000
741@@ -207,13 +207,14 @@
742 apiInfo := s.APIInfo(c)
743 conf, err := agent.NewAgentConfig(
744 agent.AgentConfigParams{
745- DataDir: s.DataDir(),
746- Tag: tag,
747- Password: password,
748- Nonce: state.BootstrapNonce,
749- StateAddresses: stateInfo.Addrs,
750- APIAddresses: apiInfo.Addrs,
751- CACert: stateInfo.CACert,
752+ DataDir: s.DataDir(),
753+ Tag: tag,
754+ UpgradedToVersion: version.Current.Number,
755+ Password: password,
756+ Nonce: state.BootstrapNonce,
757+ StateAddresses: stateInfo.Addrs,
758+ APIAddresses: apiInfo.Addrs,
759+ CACert: stateInfo.CACert,
760 })
761 c.Assert(conf.Write(), gc.IsNil)
762 return conf, agentTools
763@@ -226,13 +227,14 @@
764 conf, err := agent.NewStateMachineConfig(
765 agent.StateMachineConfigParams{
766 AgentConfigParams: agent.AgentConfigParams{
767- DataDir: dataDir,
768- Tag: tag,
769- Password: password,
770- Nonce: state.BootstrapNonce,
771- StateAddresses: stateInfo.Addrs,
772- APIAddresses: apiAddr,
773- CACert: stateInfo.CACert,
774+ DataDir: dataDir,
775+ Tag: tag,
776+ UpgradedToVersion: version.Current.Number,
777+ Password: password,
778+ Nonce: state.BootstrapNonce,
779+ StateAddresses: stateInfo.Addrs,
780+ APIAddresses: apiAddr,
781+ CACert: stateInfo.CACert,
782 },
783 StateServerCert: []byte(coretesting.ServerCert),
784 StateServerKey: []byte(coretesting.ServerKey),
785
786=== modified file 'cmd/jujud/bootstrap_test.go'
787--- cmd/jujud/bootstrap_test.go 2014-02-19 06:31:52 +0000
788+++ cmd/jujud/bootstrap_test.go 2014-02-26 03:43:42 +0000
789@@ -24,6 +24,7 @@
790 jc "launchpad.net/juju-core/testing/checkers"
791 "launchpad.net/juju-core/testing/testbase"
792 "launchpad.net/juju-core/utils"
793+ "launchpad.net/juju-core/version"
794 )
795
796 // We don't want to use JujuConnSuite because it gives us
797@@ -85,13 +86,14 @@
798 // NOTE: the old test used an equivalent of the NewAgentConfig, but it
799 // really should be using NewStateMachineConfig.
800 params := agent.AgentConfigParams{
801- DataDir: s.dataDir,
802- Tag: "bootstrap",
803- Password: testPasswordHash(),
804- Nonce: state.BootstrapNonce,
805- StateAddresses: []string{testing.MgoServer.Addr()},
806- APIAddresses: []string{"0.1.2.3:1234"},
807- CACert: []byte(testing.CACert),
808+ DataDir: s.dataDir,
809+ Tag: "bootstrap",
810+ UpgradedToVersion: version.Current.Number,
811+ Password: testPasswordHash(),
812+ Nonce: state.BootstrapNonce,
813+ StateAddresses: []string{testing.MgoServer.Addr()},
814+ APIAddresses: []string{"0.1.2.3:1234"},
815+ CACert: []byte(testing.CACert),
816 }
817 bootConf, err := agent.NewAgentConfig(params)
818 c.Assert(err, gc.IsNil)
819
820=== modified file 'environs/cloudinit/cloudinit.go'
821--- environs/cloudinit/cloudinit.go 2014-02-20 15:03:08 +0000
822+++ environs/cloudinit/cloudinit.go 2014-02-26 03:43:42 +0000
823@@ -27,6 +27,7 @@
824 coretools "launchpad.net/juju-core/tools"
825 "launchpad.net/juju-core/upstart"
826 "launchpad.net/juju-core/utils"
827+ "launchpad.net/juju-core/version"
828 )
829
830 // BootstrapStateURLFile is used to communicate to the first bootstrap node
831@@ -436,14 +437,15 @@
832 password = cfg.StateInfo.Password
833 }
834 configParams := agent.AgentConfigParams{
835- DataDir: cfg.DataDir,
836- Tag: tag,
837- Password: password,
838- Nonce: cfg.MachineNonce,
839- StateAddresses: cfg.stateHostAddrs(),
840- APIAddresses: cfg.apiHostAddrs(),
841- CACert: cfg.StateInfo.CACert,
842- Values: cfg.AgentEnvironment,
843+ DataDir: cfg.DataDir,
844+ Tag: tag,
845+ UpgradedToVersion: version.Current.Number,
846+ Password: password,
847+ Nonce: cfg.MachineNonce,
848+ StateAddresses: cfg.stateHostAddrs(),
849+ APIAddresses: cfg.apiHostAddrs(),
850+ CACert: cfg.StateInfo.CACert,
851+ Values: cfg.AgentEnvironment,
852 }
853 if !cfg.StateServer {
854 return agent.NewAgentConfig(configParams)
855
856=== modified file 'juju/testing/conn.go'
857--- juju/testing/conn.go 2014-02-20 04:59:31 +0000
858+++ juju/testing/conn.go 2014-02-26 03:43:42 +0000
859@@ -300,13 +300,14 @@
860 c.Assert(err, gc.IsNil)
861 config, err := agent.NewAgentConfig(
862 agent.AgentConfigParams{
863- DataDir: s.DataDir(),
864- Tag: tag,
865- Password: password,
866- Nonce: "nonce",
867- StateAddresses: s.StateInfo(c).Addrs,
868- APIAddresses: s.APIInfo(c).Addrs,
869- CACert: []byte(testing.CACert),
870+ DataDir: s.DataDir(),
871+ Tag: tag,
872+ UpgradedToVersion: version.Current.Number,
873+ Password: password,
874+ Nonce: "nonce",
875+ StateAddresses: s.StateInfo(c).Addrs,
876+ APIAddresses: s.APIInfo(c).Addrs,
877+ CACert: []byte(testing.CACert),
878 })
879 c.Assert(err, gc.IsNil)
880 return config
881
882=== modified file 'worker/deployer/simple.go'
883--- worker/deployer/simple.go 2014-02-12 07:24:47 +0000
884+++ worker/deployer/simple.go 2014-02-26 03:43:42 +0000
885@@ -102,10 +102,11 @@
886 namespace := ctx.agentConfig.Value(agent.Namespace)
887 conf, err := agent.NewAgentConfig(
888 agent.AgentConfigParams{
889- DataDir: dataDir,
890- Tag: tag,
891- Password: initialPassword,
892- Nonce: "unused",
893+ DataDir: dataDir,
894+ Tag: tag,
895+ UpgradedToVersion: version.Current.Number,
896+ Password: initialPassword,
897+ Nonce: "unused",
898 // TODO: remove the state addresses here and test when api only.
899 StateAddresses: result.StateAddresses,
900 APIAddresses: result.APIAddresses,
901
902=== modified file 'worker/provisioner/kvm-broker_test.go'
903--- worker/provisioner/kvm-broker_test.go 2014-01-22 19:28:08 +0000
904+++ worker/provisioner/kvm-broker_test.go 2014-02-26 03:43:42 +0000
905@@ -66,12 +66,13 @@
906 var err error
907 s.agentConfig, err = agent.NewAgentConfig(
908 agent.AgentConfigParams{
909- DataDir: "/not/used/here",
910- Tag: "tag",
911- Password: "dummy-secret",
912- Nonce: "nonce",
913- APIAddresses: []string{"10.0.0.1:1234"},
914- CACert: []byte(coretesting.CACert),
915+ DataDir: "/not/used/here",
916+ Tag: "tag",
917+ UpgradedToVersion: version.Current.Number,
918+ Password: "dummy-secret",
919+ Nonce: "nonce",
920+ APIAddresses: []string{"10.0.0.1:1234"},
921+ CACert: []byte(coretesting.CACert),
922 })
923 c.Assert(err, gc.IsNil)
924 s.broker, err = provisioner.NewKvmBroker(&fakeAPI{}, tools, s.agentConfig)
925
926=== modified file 'worker/provisioner/lxc-broker_test.go'
927--- worker/provisioner/lxc-broker_test.go 2014-02-14 11:33:57 +0000
928+++ worker/provisioner/lxc-broker_test.go 2014-02-26 03:43:42 +0000
929@@ -68,12 +68,13 @@
930 var err error
931 s.agentConfig, err = agent.NewAgentConfig(
932 agent.AgentConfigParams{
933- DataDir: "/not/used/here",
934- Tag: "tag",
935- Password: "dummy-secret",
936- Nonce: "nonce",
937- APIAddresses: []string{"10.0.0.1:1234"},
938- CACert: []byte(coretesting.CACert),
939+ DataDir: "/not/used/here",
940+ Tag: "tag",
941+ UpgradedToVersion: version.Current.Number,
942+ Password: "dummy-secret",
943+ Nonce: "nonce",
944+ APIAddresses: []string{"10.0.0.1:1234"},
945+ CACert: []byte(coretesting.CACert),
946 })
947 c.Assert(err, gc.IsNil)
948 s.broker = provisioner.NewLxcBroker(&fakeAPI{}, tools, s.agentConfig)

Subscribers

People subscribed via source and target branches

to status/vote changes: