Merge lp:~axwalk/juju-core/lp1306902-ha-upgrade-take2 into lp:~go-bot/juju-core/trunk
- lp1306902-ha-upgrade-take2
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Andrew Wilkins |
Approved revision: | no longer in the source branch. |
Merged at revision: | 2654 |
Proposed branch: | lp:~axwalk/juju-core/lp1306902-ha-upgrade-take2 |
Merge into: | lp:~go-bot/juju-core/trunk |
Diff against target: |
506 lines (+181/-94) 9 files modified
agent/format-1.18.go (+7/-4) agent/mongo/mongo.go (+3/-6) cmd/jujud/bootstrap.go (+4/-4) cmd/jujud/machine.go (+126/-58) cmd/jujud/machine_test.go (+18/-8) worker/peergrouper/desired_test.go (+0/-6) worker/peergrouper/initiate.go (+8/-8) worker/peergrouper/initiate_test.go (+1/-0) worker/peergrouper/suite_test.go (+14/-0) |
To merge this branch: | bzr merge lp:~axwalk/juju-core/lp1306902-ha-upgrade-take2 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Juju Engineering | Pending | ||
Review via email: mp+216245@code.launchpad.net |
Commit message
HA: upgrade upstart and initiate replset
The machine agent will now upgrade the
Mongo upstart script and initiate the
replicaset when upgrading from a version
prior to 1.19.0.
Tested upgrading 1.18.1 to 1.19.1 with and
without HA enabled; tested straight bootstrap
to 1.19.1 with and without HA enabled.
(Supersedes https:/
Description of the change
HA: upgrade upstart and initiate replset
The machine agent will now upgrade the
Mongo upstart script and initiate the
replicaset when upgrading from a version
prior to 1.19.0.
Tested upgrading 1.18.1 to 1.19.1 with and
without HA enabled; tested straight bootstrap
to 1.19.1 with and without HA enabled.
(Supersedes https:/
Andrew Wilkins (axwalk) wrote : | # |
Roger Peppe (rogpeppe) wrote : | # |
LGTM with two minor suggestions.
https:/
File cmd/jujud/
https:/
cmd/jujud/
ensureMongoServ
can we put this after StateWorker, so functions read generally from
higher level to lower level?
https:/
cmd/jujud/
perhaps refresh agentConfig here?
(I actually think that ChangeConfig should probably always return the
new version of the agent configuration)
Andrew Wilkins (axwalk) wrote : | # |
Please take a look.
https:/
File cmd/jujud/
https:/
cmd/jujud/
ensureMongoServ
On 2014/04/17 18:20:23, rog wrote:
> can we put this after StateWorker, so functions read generally from
higher level
> to lower level?
Done.
https:/
cmd/jujud/
On 2014/04/17 18:20:23, rog wrote:
> perhaps refresh agentConfig here?
> (I actually think that ChangeConfig should probably always return the
new
> version of the agent configuration)
Done.
Andrew Wilkins (axwalk) wrote : | # |
Please take a look.
Preview Diff
1 | === modified file 'agent/format-1.18.go' |
2 | --- agent/format-1.18.go 2014-04-11 17:51:58 +0000 |
3 | +++ agent/format-1.18.go 2014-04-18 04:41:05 +0000 |
4 | @@ -46,6 +46,7 @@ |
5 | StateServerKey string `yaml:",omitempty"` |
6 | APIPort int `yaml:",omitempty"` |
7 | StatePort int `yaml:",omitempty"` |
8 | + SharedSecret string `yaml:",omitempty"` |
9 | } |
10 | |
11 | func init() { |
12 | @@ -99,10 +100,11 @@ |
13 | } |
14 | if len(format.StateServerKey) != 0 { |
15 | config.servingInfo = ¶ms.StateServingInfo{ |
16 | - Cert: format.StateServerCert, |
17 | - PrivateKey: format.StateServerKey, |
18 | - APIPort: format.APIPort, |
19 | - StatePort: format.StatePort, |
20 | + Cert: format.StateServerCert, |
21 | + PrivateKey: format.StateServerKey, |
22 | + APIPort: format.APIPort, |
23 | + StatePort: format.StatePort, |
24 | + SharedSecret: format.SharedSecret, |
25 | } |
26 | // There's a private key, then we need the state port, |
27 | // which wasn't always in the 1.18 format. If it's not present |
28 | @@ -144,6 +146,7 @@ |
29 | format.StateServerKey = config.servingInfo.PrivateKey |
30 | format.APIPort = config.servingInfo.APIPort |
31 | format.StatePort = config.servingInfo.StatePort |
32 | + format.SharedSecret = config.servingInfo.SharedSecret |
33 | } |
34 | if config.stateDetails != nil { |
35 | format.StateAddresses = config.stateDetails.addresses |
36 | |
37 | === modified file 'agent/mongo/mongo.go' |
38 | --- agent/mongo/mongo.go 2014-04-17 12:33:55 +0000 |
39 | +++ agent/mongo/mongo.go 2014-04-18 04:41:05 +0000 |
40 | @@ -192,14 +192,11 @@ |
41 | } |
42 | logMongoVersion(mongoPath) |
43 | |
44 | - // TODO(natefinch) 2014-04-12 https://launchpad.net/bugs/1306902 |
45 | - // remove this once we support upgrading to HA |
46 | - if upstartConf.Installed() { |
47 | - return nil |
48 | + if err := upstartServiceStop(&upstartConf.Service); err != nil { |
49 | + return fmt.Errorf("failed to stop mongo: %v", err) |
50 | } |
51 | - |
52 | if err := makeJournalDirs(dbDir); err != nil { |
53 | - return fmt.Errorf("Error creating journal directories: %v", err) |
54 | + return fmt.Errorf("error creating journal directories: %v", err) |
55 | } |
56 | return upstartConfInstall(upstartConf) |
57 | } |
58 | |
59 | === modified file 'cmd/jujud/bootstrap.go' |
60 | --- cmd/jujud/bootstrap.go 2014-04-17 16:26:01 +0000 |
61 | +++ cmd/jujud/bootstrap.go 2014-04-18 04:41:05 +0000 |
62 | @@ -18,7 +18,6 @@ |
63 | "launchpad.net/juju-core/environs" |
64 | "launchpad.net/juju-core/environs/config" |
65 | "launchpad.net/juju-core/instance" |
66 | - "launchpad.net/juju-core/provider" |
67 | "launchpad.net/juju-core/state" |
68 | "launchpad.net/juju-core/state/api/params" |
69 | "launchpad.net/juju-core/worker/peergrouper" |
70 | @@ -171,14 +170,15 @@ |
71 | dialInfo.Addrs = []string{ |
72 | net.JoinHostPort("127.0.0.1", fmt.Sprint(servingInfo.StatePort)), |
73 | } |
74 | + |
75 | logger.Debugf("calling ensureMongoServer") |
76 | - providerType := agentConfig.Value(agent.ProviderType) |
77 | - withHA := providerType != provider.Local |
78 | + withHA := shouldEnableHA(agentConfig) |
79 | err = ensureMongoServer( |
80 | agentConfig.DataDir(), |
81 | agentConfig.Value(agent.Namespace), |
82 | servingInfo, |
83 | - withHA) |
84 | + withHA, |
85 | + ) |
86 | if err != nil { |
87 | return err |
88 | } |
89 | |
90 | === modified file 'cmd/jujud/machine.go' |
91 | --- cmd/jujud/machine.go 2014-04-17 17:30:48 +0000 |
92 | +++ cmd/jujud/machine.go 2014-04-18 04:41:05 +0000 |
93 | @@ -5,6 +5,7 @@ |
94 | |
95 | import ( |
96 | "fmt" |
97 | + "net" |
98 | "os" |
99 | "path/filepath" |
100 | "runtime" |
101 | @@ -397,76 +398,19 @@ |
102 | return nil |
103 | } |
104 | |
105 | -func (a *MachineAgent) ensureMongoAdminUser(agentConfig agent.Config) (added bool, err error) { |
106 | - stateInfo, ok1 := agentConfig.StateInfo() |
107 | - servingInfo, ok2 := agentConfig.StateServingInfo() |
108 | - if !ok1 || !ok2 { |
109 | - return false, fmt.Errorf("no state serving info configuration") |
110 | - } |
111 | - dialInfo, err := state.DialInfo(stateInfo, state.DefaultDialOpts()) |
112 | - if err != nil { |
113 | - return false, err |
114 | - } |
115 | - if len(dialInfo.Addrs) > 1 { |
116 | - logger.Infof("more than one state server; admin user must exist") |
117 | - return false, nil |
118 | - } |
119 | - return ensureMongoAdminUser(mongo.EnsureAdminUserParams{ |
120 | - DialInfo: dialInfo, |
121 | - Namespace: agentConfig.Value(agent.Namespace), |
122 | - DataDir: agentConfig.DataDir(), |
123 | - Port: servingInfo.StatePort, |
124 | - User: stateInfo.Tag, |
125 | - Password: stateInfo.Password, |
126 | - }) |
127 | -} |
128 | - |
129 | // StateJobs returns a worker running all the workers that require |
130 | // a *state.State connection. |
131 | func (a *MachineAgent) StateWorker() (worker.Worker, error) { |
132 | agentConfig := a.CurrentConfig() |
133 | - |
134 | - servingInfo, ok := agentConfig.StateServingInfo() |
135 | - if !ok { |
136 | - return nil, fmt.Errorf("state worker was started with no state serving info") |
137 | - } |
138 | - providerType := agentConfig.Value(agent.ProviderType) |
139 | - namespace := agentConfig.Value(agent.Namespace) |
140 | - withHA := providerType != provider.Local |
141 | - err := ensureMongoServer( |
142 | - agentConfig.DataDir(), |
143 | - namespace, |
144 | - servingInfo, |
145 | - withHA, |
146 | - ) |
147 | - if err != nil { |
148 | + if err := a.ensureMongoServer(agentConfig); err != nil { |
149 | return nil, err |
150 | } |
151 | - |
152 | st, m, err := openState(agentConfig) |
153 | - if errors.IsUnauthorized(err) { |
154 | - // TODO(axw) remove this when we no longer need |
155 | - // to upgrade from pre-HA-capable environments. |
156 | - logger.Debugf("failed to open state, reattempt after ensuring admin user exists: %v", err) |
157 | - added, ensureErr := a.ensureMongoAdminUser(agentConfig) |
158 | - if ensureErr != nil { |
159 | - err = ensureErr |
160 | - } |
161 | - if !added { |
162 | - // No user added, so it's probably a genuine unauthorized error. |
163 | - return nil, err |
164 | - } |
165 | - st, m, err = openState(agentConfig) |
166 | - } |
167 | if err != nil { |
168 | return nil, err |
169 | } |
170 | reportOpenedState(st) |
171 | |
172 | - // TODO(rog) call maybeInitiateMongoServer to upgrade mongo |
173 | - // from old environments. We'll need to acquire a non-localhost |
174 | - // address for the current instance before we do. |
175 | - |
176 | singularStateConn := singularStateConn{st.MongoSession(), m} |
177 | runner := newRunner(connectionIsFatal(st), moreImportant) |
178 | singularRunner, err := newSingularRunner(runner, singularStateConn) |
179 | @@ -476,6 +420,7 @@ |
180 | |
181 | // Take advantage of special knowledge here in that we will only ever want |
182 | // the storage provider on one machine, and that is the "bootstrap" node. |
183 | + providerType := agentConfig.Value(agent.ProviderType) |
184 | if (providerType == provider.Local || provider.IsManual(providerType)) && m.Id() == bootstrapMachineId { |
185 | a.startWorkerAfterUpgrade(runner, "local-storage", func() (worker.Worker, error) { |
186 | // TODO(axw) 2013-09-24 bug #1229507 |
187 | @@ -540,6 +485,129 @@ |
188 | return newCloseWorker(runner, st), nil |
189 | } |
190 | |
191 | +// ensureMongoServer ensures that mongo is installed and running, |
192 | +// and ready for opening a state connection. |
193 | +func (a *MachineAgent) ensureMongoServer(agentConfig agent.Config) error { |
194 | + servingInfo, ok := agentConfig.StateServingInfo() |
195 | + if !ok { |
196 | + return fmt.Errorf("state worker was started with no state serving info") |
197 | + } |
198 | + namespace := agentConfig.Value(agent.Namespace) |
199 | + withHA := shouldEnableHA(agentConfig) |
200 | + |
201 | + // When upgrading from a pre-HA-capable environment, |
202 | + // we must add machine-0 to the admin database and |
203 | + // initiate its replicaset. |
204 | + // |
205 | + // TODO(axw) remove this when we no longer need |
206 | + // to upgrade from pre-HA-capable environments. |
207 | + var shouldInitiateMongoServer bool |
208 | + var addrs []instance.Address |
209 | + if isPreHAVersion(agentConfig.UpgradedToVersion()) { |
210 | + _, err := a.ensureMongoAdminUser(agentConfig) |
211 | + if err != nil { |
212 | + return err |
213 | + } |
214 | + if servingInfo.SharedSecret == "" { |
215 | + servingInfo.SharedSecret, err = mongo.GenerateSharedSecret() |
216 | + if err != nil { |
217 | + return err |
218 | + } |
219 | + if err = a.ChangeConfig(func(config agent.ConfigSetter) { |
220 | + config.SetStateServingInfo(servingInfo) |
221 | + }); err != nil { |
222 | + return err |
223 | + } |
224 | + agentConfig = a.CurrentConfig() |
225 | + } |
226 | + st, m, err := openState(agentConfig) |
227 | + if err != nil { |
228 | + return err |
229 | + } |
230 | + if err := st.SetStateServingInfo(servingInfo); err != nil { |
231 | + st.Close() |
232 | + return fmt.Errorf("cannot set state serving info: %v", err) |
233 | + } |
234 | + st.Close() |
235 | + addrs = m.Addresses() |
236 | + shouldInitiateMongoServer = withHA |
237 | + } |
238 | + |
239 | + // ensureMongoServer installs/upgrades the upstart config as necessary. |
240 | + if err := ensureMongoServer( |
241 | + agentConfig.DataDir(), |
242 | + namespace, |
243 | + servingInfo, |
244 | + withHA, |
245 | + ); err != nil { |
246 | + return err |
247 | + } |
248 | + if !shouldInitiateMongoServer { |
249 | + return nil |
250 | + } |
251 | + |
252 | + // Initiate the replicaset for upgraded environments. |
253 | + // |
254 | + // TODO(axw) remove this when we no longer need |
255 | + // to upgrade from pre-HA-capable environments. |
256 | + stateInfo, ok := agentConfig.StateInfo() |
257 | + if !ok { |
258 | + return fmt.Errorf("state worker was started with no state serving info") |
259 | + } |
260 | + dialInfo, err := state.DialInfo(stateInfo, state.DefaultDialOpts()) |
261 | + if err != nil { |
262 | + return err |
263 | + } |
264 | + peerAddr := mongo.SelectPeerAddress(addrs) |
265 | + if peerAddr == "" { |
266 | + return fmt.Errorf("no appropriate peer address found in %q", addrs) |
267 | + } |
268 | + return maybeInitiateMongoServer(peergrouper.InitiateMongoParams{ |
269 | + DialInfo: dialInfo, |
270 | + MemberHostPort: net.JoinHostPort(peerAddr, fmt.Sprint(servingInfo.StatePort)), |
271 | + User: stateInfo.Tag, |
272 | + Password: stateInfo.Password, |
273 | + }) |
274 | +} |
275 | + |
276 | +func (a *MachineAgent) ensureMongoAdminUser(agentConfig agent.Config) (added bool, err error) { |
277 | + stateInfo, ok1 := agentConfig.StateInfo() |
278 | + servingInfo, ok2 := agentConfig.StateServingInfo() |
279 | + if !ok1 || !ok2 { |
280 | + return false, fmt.Errorf("no state serving info configuration") |
281 | + } |
282 | + dialInfo, err := state.DialInfo(stateInfo, state.DefaultDialOpts()) |
283 | + if err != nil { |
284 | + return false, err |
285 | + } |
286 | + if len(dialInfo.Addrs) > 1 { |
287 | + logger.Infof("more than one state server; admin user must exist") |
288 | + return false, nil |
289 | + } |
290 | + return ensureMongoAdminUser(mongo.EnsureAdminUserParams{ |
291 | + DialInfo: dialInfo, |
292 | + Namespace: agentConfig.Value(agent.Namespace), |
293 | + DataDir: agentConfig.DataDir(), |
294 | + Port: servingInfo.StatePort, |
295 | + User: stateInfo.Tag, |
296 | + Password: stateInfo.Password, |
297 | + }) |
298 | +} |
299 | + |
300 | +func isPreHAVersion(v version.Number) bool { |
301 | + return v.Compare(version.MustParse("1.19.0")) < 0 |
302 | +} |
303 | + |
304 | +// shouldEnableHA reports whether HA should be enabled. |
305 | +// |
306 | +// Eventually this should always be true, and ideally |
307 | +// it should be true before 1.20 is released or we'll |
308 | +// have more upgrade scenarios on our hands. |
309 | +func shouldEnableHA(agentConfig agent.Config) bool { |
310 | + providerType := agentConfig.Value(agent.ProviderType) |
311 | + return providerType != provider.Local |
312 | +} |
313 | + |
314 | func openState(agentConfig agent.Config) (_ *state.State, _ *state.Machine, err error) { |
315 | info, ok := agentConfig.StateInfo() |
316 | if !ok { |
317 | |
318 | === modified file 'cmd/jujud/machine_test.go' |
319 | --- cmd/jujud/machine_test.go 2014-04-17 17:30:48 +0000 |
320 | +++ cmd/jujud/machine_test.go 2014-04-18 04:41:05 +0000 |
321 | @@ -59,6 +59,7 @@ |
322 | agentSuite |
323 | singularRecord *singularRunnerRecord |
324 | lxctesting.TestSuite |
325 | + fakeEnsureMongo fakeEnsure |
326 | } |
327 | |
328 | func (s *commonMachineSuite) SetUpSuite(c *gc.C) { |
329 | @@ -96,6 +97,10 @@ |
330 | testing.PatchValue(&peergrouperNew, func(st *state.State) (worker.Worker, error) { |
331 | return newDummyWorker(), nil |
332 | }) |
333 | + |
334 | + s.fakeEnsureMongo = fakeEnsure{} |
335 | + s.PatchValue(&ensureMongoServer, s.fakeEnsureMongo.fakeEnsureMongo) |
336 | + s.PatchValue(&maybeInitiateMongoServer, s.fakeEnsureMongo.fakeInitiateMongo) |
337 | } |
338 | |
339 | func fakeCmd(path string) { |
340 | @@ -123,6 +128,10 @@ |
341 | inst, md := jujutesting.AssertStartInstance(c, s.Conn.Environ, m.Id()) |
342 | c.Assert(m.SetProvisioned(inst.Id(), state.BootstrapNonce, md), gc.IsNil) |
343 | |
344 | + // Add an address for the tests in case the maybeInitiateMongoServer |
345 | + // codepath is exercised. |
346 | + s.setFakeMachineAddresses(c, m) |
347 | + |
348 | // Set up the new machine. |
349 | err = m.SetAgentVersion(vers) |
350 | c.Assert(err, gc.IsNil) |
351 | @@ -327,7 +336,7 @@ |
352 | return ctx, func() { newDeployContext = orig } |
353 | } |
354 | |
355 | -func (s *MachineSuite) setFakeMachineAddresses(c *gc.C, machine *state.Machine) { |
356 | +func (s *commonMachineSuite) setFakeMachineAddresses(c *gc.C, machine *state.Machine) { |
357 | addrs := []instance.Address{ |
358 | instance.NewAddress("0.1.2.3", instance.NetworkUnknown), |
359 | } |
360 | @@ -347,7 +356,6 @@ |
361 | usefulVersion.Series = "quantal" // to match the charm created below |
362 | envtesting.AssertUploadFakeToolsVersions(c, s.Conn.Environ.Storage(), usefulVersion) |
363 | m, _, _ := s.primeAgent(c, version.Current, state.JobManageEnviron) |
364 | - s.setFakeMachineAddresses(c, m) |
365 | op := make(chan dummy.Operation, 200) |
366 | dummy.Listen(op) |
367 | |
368 | @@ -405,7 +413,6 @@ |
369 | usefulVersion.Series = "quantal" // to match the charm created below |
370 | envtesting.AssertUploadFakeToolsVersions(c, s.Conn.Environ.Storage(), usefulVersion) |
371 | m, _, _ := s.primeAgent(c, version.Current, state.JobManageEnviron) |
372 | - s.setFakeMachineAddresses(c, m) |
373 | a := s.newAgent(c, m) |
374 | defer a.Stop() |
375 | go func() { |
376 | @@ -469,7 +476,6 @@ |
377 | usefulVersion.Series = "quantal" |
378 | envtesting.AssertUploadFakeToolsVersions(c, s.Conn.Environ.Storage(), usefulVersion) |
379 | m, _, _ := s.primeAgent(c, version.Current, state.JobManageEnviron) |
380 | - s.setFakeMachineAddresses(c, m) |
381 | calledChan := make(chan struct{}, 1) |
382 | s.PatchValue(&useMultipleCPUs, func() { calledChan <- struct{}{} }) |
383 | // Now, start the agent, and observe that a JobManageEnviron agent |
384 | @@ -489,7 +495,6 @@ |
385 | c.Check(a.Stop(), gc.IsNil) |
386 | // However, an agent that just JobHostUnits doesn't call UseMultipleCPUs |
387 | m2, _, _ := s.primeAgent(c, version.Current, state.JobHostUnits) |
388 | - s.setFakeMachineAddresses(c, m2) |
389 | a2 := s.newAgent(c, m2) |
390 | defer a2.Stop() |
391 | go func() { |
392 | @@ -923,9 +928,12 @@ |
393 | c.Fatalf("timeout while waiting for agent config to change") |
394 | } |
395 | |
396 | -func (s *MachineSuite) TestMachineAgentEnsureAdminUser(c *gc.C) { |
397 | - m, _, _ := s.primeAgent(c, version.Current, state.JobManageEnviron) |
398 | - err := s.State.MongoSession().DB("admin").RemoveUser(m.Tag()) |
399 | +func (s *MachineSuite) TestMachineAgentUpgradeMongo(c *gc.C) { |
400 | + m, agentConfig, _ := s.primeAgent(c, version.Current, state.JobManageEnviron) |
401 | + agentConfig.SetUpgradedToVersion(version.MustParse("1.18.0")) |
402 | + err := agentConfig.Write() |
403 | + c.Assert(err, gc.IsNil) |
404 | + err = s.State.MongoSession().DB("admin").RemoveUser(m.Tag()) |
405 | c.Assert(err, gc.IsNil) |
406 | |
407 | s.PatchValue(&ensureMongoAdminUser, func(p mongo.EnsureAdminUserParams) (bool, error) { |
408 | @@ -954,6 +962,8 @@ |
409 | c.Fatalf("state not opened") |
410 | } |
411 | s.waitStopped(c, state.JobManageEnviron, a, done) |
412 | + c.Assert(s.fakeEnsureMongo.ensureCount, gc.Equals, 1) |
413 | + c.Assert(s.fakeEnsureMongo.initiateCount, gc.Equals, 1) |
414 | } |
415 | |
416 | // MachineWithCharmsSuite provides infrastructure for tests which need to |
417 | |
418 | === modified file 'worker/peergrouper/desired_test.go' |
419 | --- worker/peergrouper/desired_test.go 2014-04-17 16:27:08 +0000 |
420 | +++ worker/peergrouper/desired_test.go 2014-04-18 04:41:05 +0000 |
421 | @@ -8,21 +8,15 @@ |
422 | "sort" |
423 | "strconv" |
424 | "strings" |
425 | - stdtesting "testing" |
426 | |
427 | jc "github.com/juju/testing/checkers" |
428 | gc "launchpad.net/gocheck" |
429 | |
430 | "launchpad.net/juju-core/instance" |
431 | "launchpad.net/juju-core/replicaset" |
432 | - coretesting "launchpad.net/juju-core/testing" |
433 | "launchpad.net/juju-core/testing/testbase" |
434 | ) |
435 | |
436 | -func TestPackage(t *stdtesting.T) { |
437 | - coretesting.MgoTestPackage(t) |
438 | -} |
439 | - |
440 | type desiredPeerGroupSuite struct { |
441 | testbase.LoggingSuite |
442 | } |
443 | |
444 | === modified file 'worker/peergrouper/initiate.go' |
445 | --- worker/peergrouper/initiate.go 2014-04-15 16:37:08 +0000 |
446 | +++ worker/peergrouper/initiate.go 2014-04-18 04:41:05 +0000 |
447 | @@ -39,20 +39,20 @@ |
448 | return nil |
449 | } |
450 | p.DialInfo.Direct = true |
451 | + |
452 | + // TODO(rog) remove this code when we no longer need to upgrade |
453 | + // from pre-HA-capable environments. |
454 | + if p.User != "" { |
455 | + p.DialInfo.Username = p.User |
456 | + p.DialInfo.Password = p.Password |
457 | + } |
458 | + |
459 | session, err := mgo.DialWithInfo(p.DialInfo) |
460 | if err != nil { |
461 | return fmt.Errorf("can't dial mongo to initiate replicaset: %v", err) |
462 | } |
463 | defer session.Close() |
464 | |
465 | - // TODO(rog) remove this code when we no longer need to upgrade |
466 | - // from pre-HA-capable environments. |
467 | - if p.User != "" { |
468 | - err := session.DB("admin").Login(p.User, p.Password) |
469 | - if err != nil { |
470 | - logger.Errorf("cannot login to admin db as %q, password %q, falling back: %v", p.User, p.Password, err) |
471 | - } |
472 | - } |
473 | cfg, err := replicaset.CurrentConfig(session) |
474 | if err == nil && len(cfg.Members) > 0 { |
475 | logger.Infof("replica set configuration already found: %#v", cfg) |
476 | |
477 | === modified file 'worker/peergrouper/initiate_test.go' |
478 | --- worker/peergrouper/initiate_test.go 2014-04-14 19:23:22 +0000 |
479 | +++ worker/peergrouper/initiate_test.go 2014-04-18 04:41:05 +0000 |
480 | @@ -25,6 +25,7 @@ |
481 | inst := &coretesting.MgoInstance{Params: []string{"--replSet", "juju"}} |
482 | err = inst.Start(true) |
483 | c.Assert(err, gc.IsNil) |
484 | + defer inst.Destroy() |
485 | |
486 | info := inst.DialInfo() |
487 | args := peergrouper.InitiateMongoParams{ |
488 | |
489 | === added file 'worker/peergrouper/suite_test.go' |
490 | --- worker/peergrouper/suite_test.go 1970-01-01 00:00:00 +0000 |
491 | +++ worker/peergrouper/suite_test.go 2014-04-18 04:41:05 +0000 |
492 | @@ -0,0 +1,14 @@ |
493 | +// Copyright 2014 Canonical Ltd. |
494 | +// Licensed under the AGPLv3, see LICENCE file for details. |
495 | + |
496 | +package peergrouper_test |
497 | + |
498 | +import ( |
499 | + stdtesting "testing" |
500 | + |
501 | + "launchpad.net/juju-core/testing" |
502 | +) |
503 | + |
504 | +func TestPackage(t *stdtesting.T) { |
505 | + testing.MgoTestPackage(t) |
506 | +} |
Reviewers: mp+216245_ code.launchpad. net,
Message:
Please take a look.
Description:
HA: upgrade upstart and initiate replset
The machine agent will now upgrade the
Mongo upstart script and initiate the
replicaset when upgrading from a version
prior to 1.19.0.
Tested upgrading 1.18.1 to 1.19.1 with and
without HA enabled; tested straight bootstrap
to 1.19.1 with and without HA enabled.
(Supersedes https:/ /codereview. appspot. com/88350043/)
https:/ /code.launchpad .net/~axwalk/ juju-core/ lp1306902- ha-upgrade- take2/+ merge/216245
(do not edit description out of merge proposal)
Please review this at https:/ /codereview. appspot. com/88790043/
Affected files (+153, -66 lines): 1.18.go mongo.go bootstrap. go machine. go machine_ test.go peergrouper/ desired_ test.go peergrouper/ initiate. go peergrouper/ initiate_ test.go peergrouper/ suite_test. go
A [revision details]
M agent/format-
M agent/mongo/
M cmd/jujud/
M cmd/jujud/
M cmd/jujud/
M worker/
M worker/
M worker/
A worker/