~juju-qa/ubuntu/xenial/juju/xenial-2.0-beta3

« back to all changes in this revision

Viewing changes to src/github.com/juju/juju/cmd/juju/commands/bootstrap_test.go

  • Committer: Martin Packman
  • Date: 2016-03-30 19:31:08 UTC
  • mfrom: (1.1.41)
  • Revision ID: martin.packman@canonical.com-20160330193108-h9iz3ak334uk0z5r
Merge new upstream source 2.0~beta3

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
        "github.com/juju/errors"
17
17
        "github.com/juju/testing"
18
18
        jc "github.com/juju/testing/checkers"
 
19
        "github.com/juju/utils"
19
20
        "github.com/juju/utils/arch"
20
21
        jujuos "github.com/juju/utils/os"
21
22
        "github.com/juju/utils/series"
 
23
        "github.com/juju/version"
22
24
        gc "gopkg.in/check.v1"
23
25
 
24
26
        "github.com/juju/juju/apiserver/params"
30
32
        "github.com/juju/juju/environs"
31
33
        "github.com/juju/juju/environs/bootstrap"
32
34
        "github.com/juju/juju/environs/config"
33
 
        "github.com/juju/juju/environs/configstore"
34
35
        "github.com/juju/juju/environs/filestorage"
35
36
        "github.com/juju/juju/environs/imagemetadata"
36
37
        "github.com/juju/juju/environs/simplestreams"
46
47
        "github.com/juju/juju/jujuclient/jujuclienttesting"
47
48
        "github.com/juju/juju/network"
48
49
        "github.com/juju/juju/provider/dummy"
 
50
        "github.com/juju/juju/rpc"
49
51
        coretesting "github.com/juju/juju/testing"
50
52
        coretools "github.com/juju/juju/tools"
51
 
        "github.com/juju/juju/version"
 
53
        jujuversion "github.com/juju/juju/version"
52
54
)
53
55
 
54
56
type BootstrapSuite struct {
56
58
        testing.MgoSuite
57
59
        envtesting.ToolsFixture
58
60
        mockBlockClient *mockBlockClient
59
 
        store           jujuclient.CredentialStore
60
 
        legacyMemStore  configstore.Storage
 
61
        store           *jujuclienttesting.MemStore
61
62
}
62
63
 
63
64
var _ = gc.Suite(&BootstrapSuite{})
84
85
        s.MgoSuite.SetUpTest(c)
85
86
        s.ToolsFixture.SetUpTest(c)
86
87
 
87
 
        // Set version.Current to a known value, for which we
 
88
        // Set jujuversion.Current to a known value, for which we
88
89
        // will make tools available. Individual tests may
89
90
        // override this.
90
 
        s.PatchValue(&version.Current, v100p64.Number)
 
91
        s.PatchValue(&jujuversion.Current, v100p64.Number)
91
92
        s.PatchValue(&arch.HostArch, func() string { return v100p64.Arch })
92
93
        s.PatchValue(&series.HostSeries, func() string { return v100p64.Series })
93
94
        s.PatchValue(&jujuos.HostOS, func() jujuos.OSType { return jujuos.Ubuntu })
106
107
                }
107
108
                return s.mockBlockClient, nil
108
109
        })
109
 
        s.legacyMemStore = configstore.NewMem()
110
 
        s.PatchValue(&configstore.Default, func() (configstore.Storage, error) {
111
 
                return s.legacyMemStore, nil
112
 
        })
113
110
 
114
111
        // TODO(wallyworld) - add test data when tests are improved
115
112
        s.store = jujuclienttesting.NewMemStore()
128
125
}
129
126
 
130
127
func (s *BootstrapSuite) newBootstrapCommand() cmd.Command {
131
 
        return modelcmd.Wrap(&bootstrapCommand{
132
 
                CredentialStore: s.store,
133
 
        })
 
128
        c := &bootstrapCommand{}
 
129
        c.SetClientStore(s.store)
 
130
        return modelcmd.Wrap(c)
134
131
}
135
132
 
136
133
type mockBlockClient struct {
139
136
        discoveringSpacesError int
140
137
}
141
138
 
 
139
var errOther = errors.New("other error")
 
140
 
142
141
func (c *mockBlockClient) List() ([]params.Block, error) {
143
142
        c.retryCount += 1
144
143
        if c.retryCount == 5 {
145
 
                return nil, fmt.Errorf("upgrade in progress")
 
144
                return nil, &rpc.RequestError{Message: params.CodeUpgradeInProgress, Code: params.CodeUpgradeInProgress}
146
145
        }
147
146
        if c.numRetries < 0 {
148
 
                return nil, fmt.Errorf("other error")
 
147
                return nil, errOther
149
148
        }
150
149
        if c.retryCount < c.numRetries {
151
 
                return nil, fmt.Errorf("upgrade in progress")
 
150
                return nil, &rpc.RequestError{Message: params.CodeUpgradeInProgress, Code: params.CodeUpgradeInProgress}
152
151
        }
153
152
        return []params.Block{}, nil
154
153
}
160
159
func (s *BootstrapSuite) TestBootstrapAPIReadyRetries(c *gc.C) {
161
160
        s.PatchValue(&bootstrapReadyPollDelay, 1*time.Millisecond)
162
161
        s.PatchValue(&bootstrapReadyPollCount, 5)
163
 
        defaultSeriesVersion := version.Current
 
162
        defaultSeriesVersion := jujuversion.Current
164
163
        // Force a dev version by having a non zero build number.
165
164
        // This is because we have not uploaded any tools and auto
166
165
        // upload is only enabled for dev versions.
167
166
        defaultSeriesVersion.Build = 1234
168
 
        s.PatchValue(&version.Current, defaultSeriesVersion)
 
167
        s.PatchValue(&jujuversion.Current, defaultSeriesVersion)
169
168
        for _, t := range []struct {
170
169
                numRetries int
171
 
                err        string
 
170
                err        error
172
171
        }{
173
 
                {0, ""},                    // agent ready immediately
174
 
                {2, ""},                    // agent ready after 2 polls
175
 
                {6, "upgrade in progress"}, // agent ready after 6 polls but that's too long
176
 
                {-1, "other error"},        // another error is returned
 
172
                {0, nil}, // agent ready immediately
 
173
                {2, nil}, // agent ready after 2 polls
 
174
                {6, &rpc.RequestError{
 
175
                        Message: params.CodeUpgradeInProgress,
 
176
                        Code:    params.CodeUpgradeInProgress,
 
177
                }}, // agent ready after 6 polls but that's too long
 
178
                {-1, errOther}, // another error is returned
177
179
        } {
178
180
                resetJujuXDGDataHome(c)
179
181
                dummy.Reset()
180
 
                s.legacyMemStore = configstore.NewMem()
 
182
                s.store = jujuclienttesting.NewMemStore()
181
183
 
182
184
                s.mockBlockClient.numRetries = t.numRetries
183
185
                s.mockBlockClient.retryCount = 0
185
187
                        c, s.newBootstrapCommand(),
186
188
                        "devcontroller", "dummy", "--auto-upgrade",
187
189
                )
188
 
                if t.err == "" {
189
 
                        c.Check(err, jc.ErrorIsNil)
190
 
                } else {
191
 
                        c.Check(err, gc.ErrorMatches, t.err)
192
 
                }
 
190
                c.Check(errors.Cause(err), gc.DeepEquals, t.err)
193
191
                expectedRetries := t.numRetries
194
192
                if t.numRetries <= 0 {
195
193
                        expectedRetries = 1
203
201
}
204
202
 
205
203
func (s *BootstrapSuite) TestBootstrapAPIReadyWaitsForSpaceDiscovery(c *gc.C) {
206
 
        defaultSeriesVersion := version.Current
 
204
        defaultSeriesVersion := jujuversion.Current
207
205
        // Force a dev version by having a non zero build number.
208
206
        // This is because we have not uploaded any tools and auto
209
207
        // upload is only enabled for dev versions.
210
208
        defaultSeriesVersion.Build = 1234
211
 
        s.PatchValue(&version.Current, defaultSeriesVersion)
 
209
        s.PatchValue(&jujuversion.Current, defaultSeriesVersion)
212
210
        resetJujuXDGDataHome(c)
213
211
 
214
212
        s.mockBlockClient.discoveringSpacesError = 2
227
225
 
228
226
type bootstrapTest struct {
229
227
        info string
230
 
        // binary version string used to set version.Current
 
228
        // binary version string used to set jujuversion.Current
231
229
        version string
232
230
        sync    bool
233
231
        args    []string
252
250
        // Force a dev version by having a non zero build number.
253
251
        // This is because we have not uploaded any tools and auto
254
252
        // upload is only enabled for dev versions.
255
 
        num := version.Current
 
253
        num := jujuversion.Current
256
254
        num.Build = 1234
257
 
        s.PatchValue(&version.Current, num)
 
255
        s.PatchValue(&jujuversion.Current, num)
258
256
}
259
257
 
260
258
func (s *BootstrapSuite) run(c *gc.C, test bootstrapTest) testing.Restorer {
263
261
        resetJujuXDGDataHome(c)
264
262
        dummy.Reset()
265
263
 
266
 
        addrConnectedTo := "localhost:17070"
267
264
        var restore testing.Restorer = func() {
268
 
                s.legacyMemStore = configstore.NewMem()
 
265
                s.store = jujuclienttesting.NewMemStore()
269
266
        }
270
267
        if test.version != "" {
271
268
                useVersion := strings.Replace(test.version, "%LTS%", config.LatestLtsSeries(), 1)
272
269
                v := version.MustParseBinary(useVersion)
273
 
                restore = restore.Add(testing.PatchValue(&version.Current, v.Number))
 
270
                restore = restore.Add(testing.PatchValue(&jujuversion.Current, v.Number))
274
271
                restore = restore.Add(testing.PatchValue(&arch.HostArch, func() string { return v.Arch }))
275
272
                restore = restore.Add(testing.PatchValue(&series.HostSeries, func() string { return v.Series }))
276
273
        }
280
277
        }
281
278
 
282
279
        controllerName := "peckham-controller"
 
280
        cloudName := "dummy"
 
281
 
283
282
        // Run command and check for uploads.
284
283
        args := append([]string{
285
 
                controllerName, "dummy",
 
284
                controllerName, cloudName,
286
285
                "--config", "default-series=raring",
287
286
        }, test.args...)
288
287
        opc, errc := cmdtesting.RunCommand(cmdtesting.NullContext(c), s.newBootstrapCommand(), args...)
299
298
        }
300
299
 
301
300
        opBootstrap := (<-opc).(dummy.OpBootstrap)
302
 
        c.Check(opBootstrap.Env, gc.Equals, "peckham-controller")
303
 
        c.Check(opBootstrap.Args.EnvironConstraints, gc.DeepEquals, test.constraints)
 
301
        c.Check(opBootstrap.Env, gc.Equals, "admin")
 
302
        c.Check(opBootstrap.Args.ModelConstraints, gc.DeepEquals, test.constraints)
304
303
        if test.bootstrapConstraints == (constraints.Value{}) {
305
304
                test.bootstrapConstraints = test.constraints
306
305
        }
308
307
        c.Check(opBootstrap.Args.Placement, gc.Equals, test.placement)
309
308
 
310
309
        opFinalizeBootstrap := (<-opc).(dummy.OpFinalizeBootstrap)
311
 
        c.Check(opFinalizeBootstrap.Env, gc.Equals, "peckham-controller")
 
310
        c.Check(opFinalizeBootstrap.Env, gc.Equals, "admin")
312
311
        c.Check(opFinalizeBootstrap.InstanceConfig.Tools, gc.NotNil)
313
312
        if test.upload != "" {
314
313
                c.Check(opFinalizeBootstrap.InstanceConfig.Tools.Version.String(), gc.Equals, test.upload)
315
314
        }
316
315
 
317
 
        store, err := configstore.Default()
318
 
        c.Assert(err, jc.ErrorIsNil)
319
 
 
320
 
        // The controller should be recorded with the specified
321
 
        // controller name, but the model should be called "admin".
322
 
        //
323
 
        // Check a CA cert/key was generated by reloading the controller.
324
316
        expectedBootstrappedControllerName := bootstrappedControllerName(controllerName)
325
 
        info, err := store.ReadInfo(expectedBootstrappedControllerName + ":" + controllerName)
326
 
        c.Assert(err, jc.ErrorIsNil)
327
 
        c.Assert(info, gc.NotNil)
328
 
        cfg, err := config.New(config.NoDefaults, info.BootstrapConfig())
329
 
        c.Assert(err, jc.ErrorIsNil)
330
 
        c.Assert(cfg.Name(), gc.Equals, "peckham-controller")
331
 
        _, hasCert := cfg.CACert()
332
 
        c.Check(hasCert, jc.IsTrue)
333
 
        _, hasKey := cfg.CAPrivateKey()
334
 
        c.Check(hasKey, jc.IsTrue)
335
 
        c.Assert(info.APIEndpoint().Addresses, gc.DeepEquals, []string{addrConnectedTo})
336
 
 
337
 
        // Check controllers.yaml has controller
338
 
        endpoint := info.APIEndpoint()
339
 
        controllerStore := jujuclient.NewFileClientStore()
340
 
        controller, err := controllerStore.ControllerByName(expectedBootstrappedControllerName)
341
 
        c.Assert(err, jc.ErrorIsNil)
342
 
        c.Assert(controller.CACert, gc.Equals, endpoint.CACert)
343
 
        c.Assert(controller.Servers, gc.DeepEquals, endpoint.Hostnames)
344
 
        c.Assert(controller.APIEndpoints, gc.DeepEquals, endpoint.Addresses)
345
 
        c.Assert(controller.ControllerUUID, gc.Equals, endpoint.ServerUUID)
 
317
 
 
318
        // Check controllers.yaml controller details.
 
319
        addrConnectedTo := []string{"localhost:17070"}
 
320
 
 
321
        controller, err := s.store.ControllerByName(expectedBootstrappedControllerName)
 
322
        c.Assert(err, jc.ErrorIsNil)
 
323
        c.Assert(controller.CACert, gc.Not(gc.Equals), "")
 
324
        c.Assert(controller.UnresolvedAPIEndpoints, gc.DeepEquals, addrConnectedTo)
 
325
        c.Assert(controller.APIEndpoints, gc.DeepEquals, addrConnectedTo)
 
326
        c.Assert(utils.IsValidUUIDString(controller.ControllerUUID), jc.IsTrue)
 
327
 
 
328
        // Controller model should be called "admin".
 
329
        controllerModel, err := s.store.ModelByName(expectedBootstrappedControllerName, "admin@local", "admin")
 
330
        c.Assert(controllerModel.ModelUUID, gc.Equals, controller.ControllerUUID)
 
331
        c.Assert(err, jc.ErrorIsNil)
 
332
 
 
333
        // Bootstrap config should have been saved, and should only contain
 
334
        // the type, name, and any user-supplied configuration.
 
335
        bootstrapConfig, err := s.store.BootstrapConfigForController(expectedBootstrappedControllerName)
 
336
        c.Assert(err, jc.ErrorIsNil)
 
337
        c.Assert(bootstrapConfig.Cloud, gc.Equals, "dummy")
 
338
        c.Assert(bootstrapConfig.Credential, gc.Equals, "")
 
339
        c.Assert(bootstrapConfig.Config, jc.DeepEquals, map[string]interface{}{
 
340
                "name":           "admin",
 
341
                "type":           "dummy",
 
342
                "default-series": "raring",
 
343
        })
 
344
 
346
345
        return restore
347
346
}
348
347
 
379
378
        version:     "1.3.3-saucy-ppc64el",
380
379
        hostArch:    "ppc64el",
381
380
        args:        []string{"--upload-tools", "--constraints", "arch=ppc64el"},
382
 
        upload:      "1.3.3.1-raring-ppc64el", // from version.Current
 
381
        upload:      "1.3.3.1-raring-ppc64el", // from jujuversion.Current
383
382
        constraints: constraints.MustParse("arch=ppc64el"),
384
383
}, {
385
384
        info:     "--upload-tools rejects mismatched arch",
392
391
        version:  "1.3.3-saucy-mips64",
393
392
        hostArch: "mips64",
394
393
        args:     []string{"--upload-tools"},
395
 
        err:      `failed to bootstrap model: model "peckham-controller" of type dummy does not support instances running on "mips64"`,
 
394
        err:      `failed to bootstrap model: model "admin" of type dummy does not support instances running on "mips64"`,
396
395
}, {
397
396
        info:     "--upload-tools always bumps build number",
398
397
        version:  "1.2.3.4-raring-amd64",
480
479
        currentController, err := modelcmd.ReadCurrentController()
481
480
        c.Assert(err, jc.ErrorIsNil)
482
481
        c.Assert(currentController, gc.Equals, bootstrappedControllerName("devcontroller"))
 
482
        modelName, err := s.store.CurrentModel(currentController, "admin@local")
 
483
        c.Assert(err, jc.ErrorIsNil)
 
484
        c.Assert(modelName, gc.Equals, "default")
 
485
}
 
486
 
 
487
func (s *BootstrapSuite) TestBootstrapDefaultModel(c *gc.C) {
 
488
        s.patchVersionAndSeries(c, "raring")
 
489
 
 
490
        var bootstrap fakeBootstrapFuncs
 
491
        s.PatchValue(&getBootstrapFuncs, func() BootstrapInterface {
 
492
                return &bootstrap
 
493
        })
 
494
 
 
495
        coretesting.RunCommand(
 
496
                c, s.newBootstrapCommand(),
 
497
                "devcontroller", "dummy",
 
498
                "--auto-upgrade",
 
499
                "--default-model", "mymodel",
 
500
                "--config", "foo=bar",
 
501
        )
 
502
        c.Assert(bootstrap.args.HostedModelConfig["name"], gc.Equals, "mymodel")
 
503
        c.Assert(bootstrap.args.HostedModelConfig["foo"], gc.Equals, "bar")
 
504
}
 
505
 
 
506
func (s *BootstrapSuite) TestBootstrapDefaultConfigStripsProcessedAttributes(c *gc.C) {
 
507
        s.patchVersionAndSeries(c, "raring")
 
508
 
 
509
        var bootstrap fakeBootstrapFuncs
 
510
        s.PatchValue(&getBootstrapFuncs, func() BootstrapInterface {
 
511
                return &bootstrap
 
512
        })
 
513
 
 
514
        fakeSSHFile := filepath.Join(c.MkDir(), "ssh")
 
515
        err := ioutil.WriteFile(fakeSSHFile, []byte("ssh-key"), 0600)
 
516
        c.Assert(err, jc.ErrorIsNil)
 
517
        coretesting.RunCommand(
 
518
                c, s.newBootstrapCommand(),
 
519
                "devcontroller", "dummy",
 
520
                "--auto-upgrade",
 
521
                "--config", "authorized-keys-path="+fakeSSHFile,
 
522
        )
 
523
        _, ok := bootstrap.args.HostedModelConfig["authorized-keys-path"]
 
524
        c.Assert(ok, jc.IsFalse)
 
525
}
 
526
 
 
527
func (s *BootstrapSuite) TestBootstrapDefaultConfigStripsInheritedAttributes(c *gc.C) {
 
528
        s.patchVersionAndSeries(c, "raring")
 
529
 
 
530
        var bootstrap fakeBootstrapFuncs
 
531
        s.PatchValue(&getBootstrapFuncs, func() BootstrapInterface {
 
532
                return &bootstrap
 
533
        })
 
534
 
 
535
        fakeSSHFile := filepath.Join(c.MkDir(), "ssh")
 
536
        err := ioutil.WriteFile(fakeSSHFile, []byte("ssh-key"), 0600)
 
537
        c.Assert(err, jc.ErrorIsNil)
 
538
        coretesting.RunCommand(
 
539
                c, s.newBootstrapCommand(),
 
540
                "devcontroller", "dummy",
 
541
                "--auto-upgrade",
 
542
                "--config", "authorized-keys=ssh-key",
 
543
                "--config", "agent-version=1.19.0",
 
544
        )
 
545
        _, ok := bootstrap.args.HostedModelConfig["authorized-keys"]
 
546
        c.Assert(ok, jc.IsFalse)
 
547
        _, ok = bootstrap.args.HostedModelConfig["agent-version"]
 
548
        c.Assert(ok, jc.IsFalse)
483
549
}
484
550
 
485
551
type mockBootstrapInstance struct {
499
565
 
500
566
        store := jujuclienttesting.NewStubStore()
501
567
        store.SetErrors(errors.New("oh noes"))
502
 
        cmd := &bootstrapCommand{CredentialStore: store}
 
568
        cmd := &bootstrapCommand{}
503
569
        cmd.SetClientStore(store)
504
570
        _, err := coretesting.RunCommand(c, modelcmd.Wrap(cmd), controllerName, "dummy", "--auto-upgrade")
505
571
        c.Assert(err, gc.ErrorMatches, `loading credentials: oh noes`)
510
576
func (s *BootstrapSuite) TestBootstrapFailToPrepareDiesGracefully(c *gc.C) {
511
577
 
512
578
        destroyed := false
513
 
        s.PatchValue(&environsDestroy, func(string, environs.Environ, configstore.Storage, jujuclient.ControllerRemover) error {
 
579
        s.PatchValue(&environsDestroy, func(string, environs.Environ, jujuclient.ControllerRemover) error {
514
580
                destroyed = true
515
581
                return nil
516
582
        })
517
583
 
518
584
        s.PatchValue(&environsPrepare, func(
519
585
                environs.BootstrapContext,
520
 
                configstore.Storage,
521
586
                jujuclient.ClientStore,
522
 
                string,
523
 
                environs.PrepareForBootstrapParams,
 
587
                environs.PrepareParams,
524
588
        ) (environs.Environ, error) {
525
589
                return nil, fmt.Errorf("mock-prepare")
526
590
        })
534
598
        c.Check(destroyed, jc.IsFalse)
535
599
}
536
600
 
 
601
func (s *BootstrapSuite) writeControllerModelAccountInfo(c *gc.C, controller, model, account string) {
 
602
        err := s.store.UpdateController(controller, jujuclient.ControllerDetails{
 
603
                CACert:         "x",
 
604
                ControllerUUID: "y",
 
605
        })
 
606
        c.Assert(err, jc.ErrorIsNil)
 
607
        err = modelcmd.WriteCurrentController(controller)
 
608
        c.Assert(err, jc.ErrorIsNil)
 
609
        err = s.store.UpdateAccount(controller, account, jujuclient.AccountDetails{
 
610
                User:     account,
 
611
                Password: "secret",
 
612
        })
 
613
        c.Assert(err, jc.ErrorIsNil)
 
614
        err = s.store.SetCurrentAccount(controller, account)
 
615
        c.Assert(err, jc.ErrorIsNil)
 
616
        err = s.store.UpdateModel(controller, account, model, jujuclient.ModelDetails{
 
617
                ModelUUID: "model-uuid",
 
618
        })
 
619
        c.Assert(err, jc.ErrorIsNil)
 
620
        err = s.store.SetCurrentModel(controller, account, model)
 
621
        c.Assert(err, jc.ErrorIsNil)
 
622
}
 
623
 
 
624
func (s *BootstrapSuite) TestBootstrapErrorRestoresOldMetadata(c *gc.C) {
 
625
        s.patchVersionAndSeries(c, "raring")
 
626
        s.PatchValue(&environsPrepare, func(
 
627
                environs.BootstrapContext,
 
628
                jujuclient.ClientStore,
 
629
                environs.PrepareParams,
 
630
        ) (environs.Environ, error) {
 
631
                s.writeControllerModelAccountInfo(c, "foo", "bar", "foobar@local")
 
632
                return nil, fmt.Errorf("mock-prepare")
 
633
        })
 
634
 
 
635
        s.writeControllerModelAccountInfo(c, "local.olddevcontroller", "fredmodel", "fred@local")
 
636
        _, err := coretesting.RunCommand(c, s.newBootstrapCommand(), "devcontroller", "dummy", "--auto-upgrade")
 
637
        c.Assert(err, gc.ErrorMatches, "mock-prepare")
 
638
 
 
639
        oldCurrentController, err := modelcmd.ReadCurrentController()
 
640
        c.Assert(err, jc.ErrorIsNil)
 
641
        c.Assert(oldCurrentController, gc.Equals, bootstrappedControllerName("olddevcontroller"))
 
642
        oldCurrentAccount, err := s.store.CurrentAccount(oldCurrentController)
 
643
        c.Assert(err, jc.ErrorIsNil)
 
644
        c.Assert(oldCurrentAccount, gc.Equals, "fred@local")
 
645
        oldCurrentModel, err := s.store.CurrentModel(oldCurrentController, oldCurrentAccount)
 
646
        c.Assert(err, jc.ErrorIsNil)
 
647
        c.Assert(oldCurrentModel, gc.Equals, "fredmodel")
 
648
}
 
649
 
537
650
func (s *BootstrapSuite) TestBootstrapAlreadyExists(c *gc.C) {
538
651
        const controllerName = "devcontroller"
539
652
        expectedBootstrappedName := bootstrappedControllerName(controllerName)
540
653
        s.patchVersionAndSeries(c, "raring")
541
654
 
542
 
        store := jujuclient.NewFileClientStore()
543
 
        err := store.UpdateController("local.devcontroller", jujuclient.ControllerDetails{
544
 
                CACert:         "x",
545
 
                ControllerUUID: "y",
546
 
        })
547
 
        c.Assert(err, jc.ErrorIsNil)
 
655
        s.writeControllerModelAccountInfo(c, "local.devcontroller", "fredmodel", "fred@local")
548
656
 
549
657
        ctx := coretesting.Context(c)
550
658
        _, errc := cmdtesting.RunCommand(ctx, s.newBootstrapCommand(), controllerName, "dummy", "--auto-upgrade")
551
 
        err = <-errc
 
659
        err := <-errc
552
660
        c.Assert(err, jc.Satisfies, errors.IsAlreadyExists)
553
661
        c.Assert(err, gc.ErrorMatches, fmt.Sprintf(`controller %q already exists`, expectedBootstrappedName))
 
662
        currentController, err := modelcmd.ReadCurrentController()
 
663
        c.Assert(err, jc.ErrorIsNil)
 
664
        c.Assert(currentController, gc.Equals, "local.devcontroller")
 
665
        currentAccount, err := s.store.CurrentAccount(currentController)
 
666
        c.Assert(err, jc.ErrorIsNil)
 
667
        c.Assert(currentAccount, gc.Equals, "fred@local")
 
668
        currentModel, err := s.store.CurrentModel(currentController, currentAccount)
 
669
        c.Assert(err, jc.ErrorIsNil)
 
670
        c.Assert(currentModel, gc.Equals, "fredmodel")
554
671
}
555
672
 
556
673
func (s *BootstrapSuite) TestInvalidLocalSource(c *gc.C) {
557
 
        s.PatchValue(&version.Current, version.MustParse("1.2.0"))
 
674
        s.PatchValue(&jujuversion.Current, version.MustParse("1.2.0"))
558
675
        resetJujuXDGDataHome(c)
559
676
 
560
677
        // Bootstrap the controller with an invalid source.
616
733
                return &bootstrap
617
734
        })
618
735
 
619
 
        num := version.Current
 
736
        num := jujuversion.Current
620
737
        num.Major = 2
621
738
        num.Minor = 3
622
 
        s.PatchValue(&version.Current, num)
 
739
        s.PatchValue(&jujuversion.Current, num)
623
740
        coretesting.RunCommand(
624
741
                c, s.newBootstrapCommand(),
625
742
                "--agent-version", vers,
655
772
 
656
773
func (s *BootstrapSuite) TestAutoSyncLocalSource(c *gc.C) {
657
774
        sourceDir := createToolsSource(c, vAll)
658
 
        s.PatchValue(&version.Current, version.MustParse("1.2.0"))
 
775
        s.PatchValue(&jujuversion.Current, version.MustParse("1.2.0"))
659
776
        resetJujuXDGDataHome(c)
660
777
 
661
778
        // Bootstrap the controller with the valid source.
667
784
        )
668
785
        c.Assert(err, jc.ErrorIsNil)
669
786
 
670
 
        store, err := configstore.Default()
671
 
        c.Assert(err, jc.ErrorIsNil)
672
 
 
673
 
        info, err := store.ReadInfo(bootstrappedControllerName("devcontroller") + ":devcontroller")
674
 
        c.Assert(err, jc.ErrorIsNil)
675
 
        cfg, err := config.New(config.NoDefaults, info.BootstrapConfig())
676
 
        c.Assert(err, jc.ErrorIsNil)
677
 
        env, err := environs.New(cfg)
 
787
        p, err := environs.Provider("dummy")
 
788
        c.Assert(err, jc.ErrorIsNil)
 
789
        cfg, err := modelcmd.NewGetBootstrapConfigFunc(s.store)("devcontroller")
 
790
        c.Assert(err, jc.ErrorIsNil)
 
791
        env, err := p.PrepareForBootstrap(envtesting.BootstrapContext(c), cfg)
678
792
        c.Assert(err, jc.ErrorIsNil)
679
793
 
680
794
        // Now check the available tools which are the 1.2.0 envtools.
690
804
        // the version and ensure their later restoring.
691
805
        // Set the current version to be something for which there are no tools
692
806
        // so we can test that an upload is forced.
693
 
        s.PatchValue(&version.Current, version.MustParse(vers))
 
807
        s.PatchValue(&jujuversion.Current, version.MustParse(vers))
694
808
        s.PatchValue(&series.HostSeries, func() string { return ser })
695
809
 
696
810
        // Create home with dummy provider and remove all
710
824
                "--auto-upgrade",
711
825
        )
712
826
        c.Assert(<-errc, gc.IsNil)
713
 
        c.Check((<-opc).(dummy.OpBootstrap).Env, gc.Equals, "devcontroller")
 
827
        c.Check((<-opc).(dummy.OpBootstrap).Env, gc.Equals, "admin")
714
828
        icfg := (<-opc).(dummy.OpFinalizeBootstrap).InstanceConfig
715
829
        c.Assert(icfg, gc.NotNil)
716
830
        c.Assert(icfg.Tools.Version.String(), gc.Equals, "1.7.3.1-raring-"+arch.HostArch())
757
871
 
758
872
        c.Check(coretesting.Stderr(ctx), gc.Equals, fmt.Sprintf(`
759
873
Creating Juju controller "local.devcontroller" on dummy-cloud/region-1
760
 
Bootstrapping model "devcontroller"
 
874
Bootstrapping model "admin"
761
875
Starting new instance for initial controller
762
876
Building tools to upload (1.7.3.1-raring-%s)
763
877
`[1:], arch.HostArch()))
965
1079
        err := os.RemoveAll(jenvDir)
966
1080
        c.Assert(err, jc.ErrorIsNil)
967
1081
 
968
 
        for _, path := range []string{
969
 
                jujuclient.JujuControllersPath(),
970
 
                jujuclient.JujuModelsPath(),
971
 
                jujuclient.JujuAccountsPath(),
972
 
        } {
973
 
                os.Remove(path)
974
 
        }
975
 
 
976
1082
        cloudsPath := cloud.JujuPersonalCloudsPath()
977
1083
        err = ioutil.WriteFile(cloudsPath, []byte(`
978
1084
clouds:
990
1096
// checkTools check if the environment contains the passed envtools.
991
1097
func checkTools(c *gc.C, env environs.Environ, expected []version.Binary) {
992
1098
        list, err := envtools.FindTools(
993
 
                env, version.Current.Major, version.Current.Minor, "released", coretools.Filter{})
 
1099
                env, jujuversion.Current.Major, jujuversion.Current.Minor, "released", coretools.Filter{})
994
1100
        c.Check(err, jc.ErrorIsNil)
995
1101
        c.Logf("found: " + list.String())
996
1102
        urls := list.URLs()