~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/jujud/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:
22
22
        "github.com/juju/utils/arch"
23
23
        "github.com/juju/utils/series"
24
24
        "github.com/juju/utils/set"
 
25
        "github.com/juju/version"
25
26
        gc "gopkg.in/check.v1"
26
27
        "gopkg.in/mgo.v2"
27
28
        goyaml "gopkg.in/yaml.v2"
28
29
 
29
30
        "github.com/juju/juju/agent"
 
31
        "github.com/juju/juju/agent/agentbootstrap"
30
32
        agenttools "github.com/juju/juju/agent/tools"
31
33
        "github.com/juju/juju/apiserver/params"
32
34
        agenttesting "github.com/juju/juju/cmd/jujud/agent/testing"
55
57
        "github.com/juju/juju/storage/poolmanager"
56
58
        "github.com/juju/juju/testing"
57
59
        "github.com/juju/juju/tools"
58
 
        "github.com/juju/juju/version"
 
60
        jujuversion "github.com/juju/juju/version"
59
61
)
60
62
 
61
63
// We don't want to use JujuConnSuite because it gives us
63
65
type BootstrapSuite struct {
64
66
        testing.BaseSuite
65
67
        gitjujutesting.MgoSuite
66
 
        envcfg          *config.Config
67
 
        b64yamlEnvcfg   string
68
 
        instanceId      instance.Id
69
 
        dataDir         string
70
 
        logDir          string
71
 
        mongoOplogSize  string
72
 
        fakeEnsureMongo *agenttesting.FakeEnsureMongo
73
 
        bootstrapName   string
 
68
        envcfg                       *config.Config
 
69
        b64yamlControllerModelConfig string
 
70
        b64yamlHostedModelConfig     string
 
71
        instanceId                   instance.Id
 
72
        dataDir                      string
 
73
        logDir                       string
 
74
        mongoOplogSize               string
 
75
        fakeEnsureMongo              *agenttesting.FakeEnsureMongo
 
76
        bootstrapName                string
 
77
        hostedModelUUID              string
74
78
 
75
79
        toolsStorage storage.Storage
76
80
}
80
84
func (s *BootstrapSuite) SetUpSuite(c *gc.C) {
81
85
        storageDir := c.MkDir()
82
86
        restorer := gitjujutesting.PatchValue(&envtools.DefaultBaseURL, storageDir)
83
 
        s.AddSuiteCleanup(func(*gc.C) {
84
 
                restorer()
85
 
        })
86
87
        stor, err := filestorage.NewFileStorageWriter(storageDir)
87
88
        c.Assert(err, jc.ErrorIsNil)
88
89
        s.toolsStorage = stor
89
90
 
90
91
        s.BaseSuite.SetUpSuite(c)
 
92
        s.AddSuiteCleanup(func(*gc.C) {
 
93
                restorer()
 
94
        })
91
95
        s.MgoSuite.SetUpSuite(c)
92
 
        s.PatchValue(&version.Current, testing.FakeVersionNumber)
 
96
        s.PatchValue(&jujuversion.Current, testing.FakeVersionNumber)
93
97
        s.makeTestEnv(c)
94
98
}
95
99
 
114
118
 
115
119
        // Create fake tools.tar.gz and downloaded-tools.txt.
116
120
        current := version.Binary{
117
 
                Number: version.Current,
 
121
                Number: jujuversion.Current,
118
122
                Arch:   arch.HostArch(),
119
123
                Series: series.HostSeries(),
120
124
        }
124
128
        err = ioutil.WriteFile(filepath.Join(toolsDir, "tools.tar.gz"), nil, 0644)
125
129
        c.Assert(err, jc.ErrorIsNil)
126
130
        s.writeDownloadedTools(c, &tools.Tools{Version: current})
 
131
 
 
132
        // Create fake gui.tar.bz2 and downloaded-gui.txt.
 
133
        guiDir := filepath.FromSlash(agenttools.SharedGUIDir(s.dataDir))
 
134
        err = os.MkdirAll(guiDir, 0755)
 
135
        c.Assert(err, jc.ErrorIsNil)
 
136
        err = ioutil.WriteFile(filepath.Join(guiDir, "gui.tar.bz2"), nil, 0644)
 
137
        c.Assert(err, jc.ErrorIsNil)
 
138
        s.writeDownloadedGUI(c, &tools.GUIArchive{
 
139
                Version: version.MustParse("2.0.42"),
 
140
        })
127
141
}
128
142
 
129
143
func (s *BootstrapSuite) TearDownTest(c *gc.C) {
141
155
        c.Assert(err, jc.ErrorIsNil)
142
156
}
143
157
 
 
158
func (s *BootstrapSuite) writeDownloadedGUI(c *gc.C, gui *tools.GUIArchive) {
 
159
        guiDir := filepath.FromSlash(agenttools.SharedGUIDir(s.dataDir))
 
160
        err := os.MkdirAll(guiDir, 0755)
 
161
        c.Assert(err, jc.ErrorIsNil)
 
162
        data, err := json.Marshal(gui)
 
163
        c.Assert(err, jc.ErrorIsNil)
 
164
        err = ioutil.WriteFile(filepath.Join(guiDir, "downloaded-gui.txt"), data, 0644)
 
165
        c.Assert(err, jc.ErrorIsNil)
 
166
}
 
167
 
 
168
func (s *BootstrapSuite) TestGUIArchiveInfoError(c *gc.C) {
 
169
        dir := filepath.FromSlash(agenttools.SharedGUIDir(s.dataDir))
 
170
        info := filepath.Join(dir, "downloaded-gui.txt")
 
171
        err := os.Remove(info)
 
172
        c.Assert(err, jc.ErrorIsNil)
 
173
        _, cmd, err := s.initBootstrapCommand(
 
174
                c, nil, "--model-config", s.b64yamlControllerModelConfig,
 
175
                "--hosted-model-config", s.b64yamlHostedModelConfig,
 
176
                "--instance-id", string(s.instanceId))
 
177
        c.Assert(err, jc.ErrorIsNil)
 
178
        // TODO frankban: this must return an error before the feature branch is
 
179
        // merged into master.
 
180
        err = cmd.Run(nil)
 
181
        c.Assert(err, jc.ErrorIsNil)
 
182
}
 
183
 
 
184
func (s *BootstrapSuite) TestGUIArchiveError(c *gc.C) {
 
185
        dir := filepath.FromSlash(agenttools.SharedGUIDir(s.dataDir))
 
186
        archive := filepath.Join(dir, "gui.tar.bz2")
 
187
        err := os.Remove(archive)
 
188
        c.Assert(err, jc.ErrorIsNil)
 
189
        _, cmd, err := s.initBootstrapCommand(
 
190
                c, nil, "--model-config", s.b64yamlControllerModelConfig,
 
191
                "--hosted-model-config", s.b64yamlHostedModelConfig,
 
192
                "--instance-id", string(s.instanceId))
 
193
        c.Assert(err, jc.ErrorIsNil)
 
194
        err = cmd.Run(nil)
 
195
        c.Assert(err, gc.ErrorMatches, "cannot read GUI archive: .*")
 
196
}
 
197
 
 
198
func (s *BootstrapSuite) TestGUIArchiveSuccess(c *gc.C) {
 
199
        _, cmd, err := s.initBootstrapCommand(
 
200
                c, nil, "--model-config", s.b64yamlControllerModelConfig,
 
201
                "--hosted-model-config", s.b64yamlHostedModelConfig,
 
202
                "--instance-id", string(s.instanceId))
 
203
        c.Assert(err, jc.ErrorIsNil)
 
204
        err = cmd.Run(nil)
 
205
        c.Assert(err, jc.ErrorIsNil)
 
206
 
 
207
        // Retrieve the state so that it is possible to access the GUI storage.
 
208
        st, err := state.Open(testing.ModelTag, &mongo.MongoInfo{
 
209
                Info: mongo.Info{
 
210
                        Addrs:  []string{gitjujutesting.MgoServer.Addr()},
 
211
                        CACert: testing.CACert,
 
212
                },
 
213
                Password: testPassword,
 
214
        }, mongo.DefaultDialOpts(), environs.NewStatePolicy())
 
215
        c.Assert(err, jc.ErrorIsNil)
 
216
        defer st.Close()
 
217
 
 
218
        // The GUI archive has been uploaded to the GUI storage.
 
219
        storage, err := st.GUIStorage()
 
220
        c.Assert(err, jc.ErrorIsNil)
 
221
        defer storage.Close()
 
222
        allMeta, err := storage.AllMetadata()
 
223
        c.Assert(err, jc.ErrorIsNil)
 
224
        c.Assert(allMeta, gc.HasLen, 1)
 
225
        c.Assert(allMeta[0].Version, gc.Equals, "2.0.42")
 
226
}
 
227
 
144
228
var testPassword = "my-admin-secret"
145
229
 
146
 
func testPasswordHash() string {
147
 
        return utils.UserPasswordHash(testPassword, utils.CompatSalt)
148
 
}
149
 
 
150
230
func (s *BootstrapSuite) initBootstrapCommand(c *gc.C, jobs []multiwatcher.MachineJob, args ...string) (machineConf agent.ConfigSetterWriter, cmd *BootstrapCommand, err error) {
151
231
        if len(jobs) == 0 {
152
232
                // Add default jobs.
165
245
                },
166
246
                Jobs:              jobs,
167
247
                Tag:               names.NewMachineTag("0"),
168
 
                UpgradedToVersion: version.Current,
169
 
                Password:          testPasswordHash(),
 
248
                UpgradedToVersion: jujuversion.Current,
 
249
                Password:          testPassword,
170
250
                Nonce:             agent.BootstrapNonce,
171
251
                Model:             testing.ModelTag,
172
252
                StateAddresses:    []string{gitjujutesting.MgoServer.Addr()},
198
278
 
199
279
func (s *BootstrapSuite) TestInitializeEnvironment(c *gc.C) {
200
280
        hw := instance.MustParseHardware("arch=amd64 mem=8G")
201
 
        machConf, cmd, err := s.initBootstrapCommand(c, nil, "--model-config", s.b64yamlEnvcfg, "--instance-id", string(s.instanceId), "--hardware", hw.String())
 
281
        machConf, cmd, err := s.initBootstrapCommand(
 
282
                c, nil, "--model-config", s.b64yamlControllerModelConfig,
 
283
                "--hosted-model-config", s.b64yamlHostedModelConfig,
 
284
                "--instance-id", string(s.instanceId), "--hardware", hw.String(),
 
285
        )
202
286
        c.Assert(err, jc.ErrorIsNil)
203
287
        err = cmd.Run(nil)
204
288
        c.Assert(err, jc.ErrorIsNil)
234
318
                        Addrs:  []string{gitjujutesting.MgoServer.Addr()},
235
319
                        CACert: testing.CACert,
236
320
                },
237
 
                Password: testPasswordHash(),
 
321
                Password: testPassword,
238
322
        }, mongo.DefaultDialOpts(), environs.NewStatePolicy())
239
323
        c.Assert(err, jc.ErrorIsNil)
240
324
        defer st.Close()
263
347
func (s *BootstrapSuite) TestInitializeEnvironmentInvalidOplogSize(c *gc.C) {
264
348
        s.mongoOplogSize = "NaN"
265
349
        hw := instance.MustParseHardware("arch=amd64 mem=8G")
266
 
        _, cmd, err := s.initBootstrapCommand(c, nil, "--model-config", s.b64yamlEnvcfg, "--instance-id", string(s.instanceId), "--hardware", hw.String())
 
350
        _, cmd, err := s.initBootstrapCommand(
 
351
                c, nil, "--model-config", s.b64yamlControllerModelConfig,
 
352
                "--hosted-model-config", s.b64yamlHostedModelConfig,
 
353
                "--instance-id", string(s.instanceId), "--hardware", hw.String(),
 
354
        )
267
355
        c.Assert(err, jc.ErrorIsNil)
268
356
        err = cmd.Run(nil)
269
357
        c.Assert(err, gc.ErrorMatches, `invalid oplog size: "NaN"`)
275
363
                "agent-version": "1.99.1",
276
364
        })
277
365
        c.Assert(err, jc.ErrorIsNil)
278
 
        b64yamlEnvcfg := b64yaml(envcfg.AllAttrs()).encode()
 
366
        b64yamlControllerModelConfig := b64yaml(envcfg.AllAttrs()).encode()
279
367
 
280
368
        hw := instance.MustParseHardware("arch=amd64 mem=8G")
281
 
        _, cmd, err := s.initBootstrapCommand(c, nil, "--model-config", b64yamlEnvcfg, "--instance-id", string(s.instanceId), "--hardware", hw.String())
 
369
        _, cmd, err := s.initBootstrapCommand(
 
370
                c, nil, "--model-config", b64yamlControllerModelConfig,
 
371
                "--hosted-model-config", s.b64yamlHostedModelConfig,
 
372
                "--instance-id", string(s.instanceId), "--hardware", hw.String(),
 
373
        )
282
374
        c.Assert(err, jc.ErrorIsNil)
283
375
        err = cmd.Run(nil)
284
376
        c.Assert(err, jc.ErrorIsNil)
288
380
                        Addrs:  []string{gitjujutesting.MgoServer.Addr()},
289
381
                        CACert: testing.CACert,
290
382
                },
291
 
                Password: testPasswordHash(),
 
383
                Password: testPassword,
292
384
        }, mongo.DefaultDialOpts(), environs.NewStatePolicy())
293
385
        c.Assert(err, jc.ErrorIsNil)
294
386
        defer st.Close()
302
394
 
303
395
func (s *BootstrapSuite) TestSetConstraints(c *gc.C) {
304
396
        bootstrapCons := constraints.Value{Mem: uint64p(4096), CpuCores: uint64p(4)}
305
 
        environCons := constraints.Value{Mem: uint64p(2048), CpuCores: uint64p(2)}
 
397
        modelCons := constraints.Value{Mem: uint64p(2048), CpuCores: uint64p(2)}
306
398
        _, cmd, err := s.initBootstrapCommand(c, nil,
307
 
                "--model-config", s.b64yamlEnvcfg,
 
399
                "--model-config", s.b64yamlControllerModelConfig,
 
400
                "--hosted-model-config", s.b64yamlHostedModelConfig,
308
401
                "--instance-id", string(s.instanceId),
309
402
                "--bootstrap-constraints", bootstrapCons.String(),
310
 
                "--constraints", environCons.String(),
 
403
                "--constraints", modelCons.String(),
311
404
        )
312
405
        c.Assert(err, jc.ErrorIsNil)
313
406
        err = cmd.Run(nil)
318
411
                        Addrs:  []string{gitjujutesting.MgoServer.Addr()},
319
412
                        CACert: testing.CACert,
320
413
                },
321
 
                Password: testPasswordHash(),
 
414
                Password: testPassword,
322
415
        }, mongo.DefaultDialOpts(), environs.NewStatePolicy())
323
416
        c.Assert(err, jc.ErrorIsNil)
324
417
        defer st.Close()
325
418
 
326
419
        cons, err := st.ModelConstraints()
327
420
        c.Assert(err, jc.ErrorIsNil)
328
 
        c.Assert(cons, gc.DeepEquals, environCons)
 
421
        c.Assert(cons, gc.DeepEquals, modelCons)
329
422
 
330
423
        machines, err := st.AllMachines()
331
424
        c.Assert(err, jc.ErrorIsNil)
345
438
                state.JobHostUnits,
346
439
                state.JobManageNetworking,
347
440
        }
348
 
        _, cmd, err := s.initBootstrapCommand(c, nil, "--model-config", s.b64yamlEnvcfg, "--instance-id", string(s.instanceId))
 
441
        _, cmd, err := s.initBootstrapCommand(c, nil,
 
442
                "--model-config", s.b64yamlControllerModelConfig,
 
443
                "--hosted-model-config", s.b64yamlHostedModelConfig,
 
444
                "--instance-id", string(s.instanceId),
 
445
        )
349
446
        c.Assert(err, jc.ErrorIsNil)
350
447
        err = cmd.Run(nil)
351
448
        c.Assert(err, jc.ErrorIsNil)
355
452
                        Addrs:  []string{gitjujutesting.MgoServer.Addr()},
356
453
                        CACert: testing.CACert,
357
454
                },
358
 
                Password: testPasswordHash(),
 
455
                Password: testPassword,
359
456
        }, mongo.DefaultDialOpts(), environs.NewStatePolicy())
360
457
        c.Assert(err, jc.ErrorIsNil)
361
458
        defer st.Close()
366
463
 
367
464
func (s *BootstrapSuite) TestConfiguredMachineJobs(c *gc.C) {
368
465
        jobs := []multiwatcher.MachineJob{multiwatcher.JobManageModel}
369
 
        _, cmd, err := s.initBootstrapCommand(c, jobs, "--model-config", s.b64yamlEnvcfg, "--instance-id", string(s.instanceId))
 
466
        _, cmd, err := s.initBootstrapCommand(c, jobs,
 
467
                "--model-config", s.b64yamlControllerModelConfig,
 
468
                "--hosted-model-config", s.b64yamlHostedModelConfig,
 
469
                "--instance-id", string(s.instanceId),
 
470
        )
370
471
        c.Assert(err, jc.ErrorIsNil)
371
472
        err = cmd.Run(nil)
372
473
        c.Assert(err, jc.ErrorIsNil)
376
477
                        Addrs:  []string{gitjujutesting.MgoServer.Addr()},
377
478
                        CACert: testing.CACert,
378
479
                },
379
 
                Password: testPasswordHash(),
 
480
                Password: testPassword,
380
481
        }, mongo.DefaultDialOpts(), environs.NewStatePolicy())
381
482
        c.Assert(err, jc.ErrorIsNil)
382
483
        defer st.Close()
398
499
}
399
500
 
400
501
func (s *BootstrapSuite) TestInitialPassword(c *gc.C) {
401
 
        machineConf, cmd, err := s.initBootstrapCommand(c, nil, "--model-config", s.b64yamlEnvcfg, "--instance-id", string(s.instanceId))
 
502
        machineConf, cmd, err := s.initBootstrapCommand(c, nil,
 
503
                "--model-config", s.b64yamlControllerModelConfig,
 
504
                "--hosted-model-config", s.b64yamlHostedModelConfig,
 
505
                "--instance-id", string(s.instanceId),
 
506
        )
402
507
        c.Assert(err, jc.ErrorIsNil)
403
508
 
404
509
        err = cmd.Run(nil)
413
518
 
414
519
        // Check we can log in to mongo as admin.
415
520
        // TODO(dfc) does passing nil for the admin user name make your skin crawl ? mine too.
416
 
        info.Tag, info.Password = nil, testPasswordHash()
 
521
        info.Tag, info.Password = nil, testPassword
417
522
        st, err := state.Open(testing.ModelTag, info, mongo.DefaultDialOpts(), environs.NewStatePolicy())
418
523
        c.Assert(err, jc.ErrorIsNil)
419
524
        defer st.Close()
469
574
                input: []string{"--model-config", "name: banana\n"},
470
575
                err:   ".*illegal base64 data at input byte.*",
471
576
        }, {
 
577
                // no value supplied for hosted-model-config
 
578
                input: []string{
 
579
                        "--model-config", base64.StdEncoding.EncodeToString([]byte("name: banana\n")),
 
580
                },
 
581
                err: "--hosted-model-config option must be set",
 
582
        }, {
472
583
                // no value supplied for instance-id
473
584
                input: []string{
474
585
                        "--model-config", base64.StdEncoding.EncodeToString([]byte("name: banana\n")),
 
586
                        "--hosted-model-config", base64.StdEncoding.EncodeToString([]byte("name: banana\n")),
475
587
                },
476
588
                err: "--instance-id option must be set",
477
589
        }, {
478
590
                // empty instance-id
479
591
                input: []string{
480
592
                        "--model-config", base64.StdEncoding.EncodeToString([]byte("name: banana\n")),
 
593
                        "--hosted-model-config", base64.StdEncoding.EncodeToString([]byte("name: banana\n")),
481
594
                        "--instance-id", "",
482
595
                },
483
596
                err: "--instance-id option must be set",
484
597
        }, {
485
598
                input: []string{
486
599
                        "--model-config", base64.StdEncoding.EncodeToString([]byte("name: banana\n")),
 
600
                        "--hosted-model-config", base64.StdEncoding.EncodeToString([]byte("name: banana\n")),
487
601
                        "--instance-id", "anything",
488
602
                },
489
603
                expectedInstanceId: "anything",
491
605
        }, {
492
606
                input: []string{
493
607
                        "--model-config", base64.StdEncoding.EncodeToString([]byte("name: banana\n")),
 
608
                        "--hosted-model-config", base64.StdEncoding.EncodeToString([]byte("name: banana\n")),
494
609
                        "--instance-id", "anything",
495
610
                        "--hardware", "nonsense",
496
611
                },
498
613
        }, {
499
614
                input: []string{
500
615
                        "--model-config", base64.StdEncoding.EncodeToString([]byte("name: banana\n")),
 
616
                        "--hosted-model-config", base64.StdEncoding.EncodeToString([]byte("name: banana\n")),
501
617
                        "--instance-id", "anything",
502
618
                        "--hardware", "arch=amd64 cpu-cores=4 root-disk=2T",
503
619
                },
516
632
                if t.err == "" {
517
633
                        c.Assert(cmd, gc.NotNil)
518
634
                        c.Assert(err, jc.ErrorIsNil)
519
 
                        c.Assert(cmd.EnvConfig, gc.DeepEquals, t.expectedConfig)
 
635
                        c.Assert(cmd.ControllerModelConfig, gc.DeepEquals, t.expectedConfig)
520
636
                        c.Assert(cmd.InstanceId, gc.Equals, t.expectedInstanceId)
521
637
                        c.Assert(cmd.Hardware, gc.DeepEquals, t.expectedHardware)
522
638
                } else {
527
643
 
528
644
func (s *BootstrapSuite) TestInitializeStateArgs(c *gc.C) {
529
645
        var called int
530
 
        initializeState := func(_ names.UserTag, _ agent.ConfigSetter, envCfg *config.Config, machineCfg agent.BootstrapMachineConfig, dialOpts mongo.DialOpts, policy state.Policy) (_ *state.State, _ *state.Machine, resultErr error) {
 
646
        initializeState := func(_ names.UserTag, _ agent.ConfigSetter, envCfg *config.Config, hostedModelConfig map[string]interface{}, machineCfg agentbootstrap.BootstrapMachineConfig, dialOpts mongo.DialOpts, policy state.Policy) (_ *state.State, _ *state.Machine, resultErr error) {
531
647
                called++
532
648
                c.Assert(dialOpts.Direct, jc.IsTrue)
533
649
                c.Assert(dialOpts.Timeout, gc.Equals, 30*time.Second)
534
650
                c.Assert(dialOpts.SocketTimeout, gc.Equals, 123*time.Second)
 
651
                c.Assert(hostedModelConfig, jc.DeepEquals, map[string]interface{}{
 
652
                        "name": "hosted-model",
 
653
                        "uuid": s.hostedModelUUID,
 
654
                })
535
655
                return nil, nil, errors.New("failed to initialize state")
536
656
        }
537
657
        s.PatchValue(&agentInitializeState, initializeState)
538
 
        _, cmd, err := s.initBootstrapCommand(c, nil, "--model-config", s.b64yamlEnvcfg, "--instance-id", string(s.instanceId))
 
658
        _, cmd, err := s.initBootstrapCommand(c, nil,
 
659
                "--model-config", s.b64yamlControllerModelConfig,
 
660
                "--hosted-model-config", s.b64yamlHostedModelConfig,
 
661
                "--instance-id", string(s.instanceId),
 
662
        )
539
663
        c.Assert(err, jc.ErrorIsNil)
540
664
        err = cmd.Run(nil)
541
665
        c.Assert(err, gc.ErrorMatches, "failed to initialize state")
544
668
 
545
669
func (s *BootstrapSuite) TestInitializeStateMinSocketTimeout(c *gc.C) {
546
670
        var called int
547
 
        initializeState := func(_ names.UserTag, _ agent.ConfigSetter, envCfg *config.Config, machineCfg agent.BootstrapMachineConfig, dialOpts mongo.DialOpts, policy state.Policy) (_ *state.State, _ *state.Machine, resultErr error) {
 
671
        initializeState := func(_ names.UserTag, _ agent.ConfigSetter, envCfg *config.Config, hostedModelConfig map[string]interface{}, machineCfg agentbootstrap.BootstrapMachineConfig, dialOpts mongo.DialOpts, policy state.Policy) (_ *state.State, _ *state.Machine, resultErr error) {
548
672
                called++
549
673
                c.Assert(dialOpts.Direct, jc.IsTrue)
550
674
                c.Assert(dialOpts.SocketTimeout, gc.Equals, 1*time.Minute)
555
679
                "bootstrap-timeout": "13",
556
680
        })
557
681
        c.Assert(err, jc.ErrorIsNil)
558
 
        b64yamlEnvcfg := b64yaml(envcfg.AllAttrs()).encode()
 
682
        b64yamlControllerModelConfig := b64yaml(envcfg.AllAttrs()).encode()
559
683
 
560
684
        s.PatchValue(&agentInitializeState, initializeState)
561
 
        _, cmd, err := s.initBootstrapCommand(c, nil, "--model-config", b64yamlEnvcfg, "--instance-id", string(s.instanceId))
 
685
        _, cmd, err := s.initBootstrapCommand(c, nil,
 
686
                "--model-config", b64yamlControllerModelConfig,
 
687
                "--hosted-model-config", s.b64yamlHostedModelConfig,
 
688
                "--instance-id", string(s.instanceId),
 
689
        )
562
690
        c.Assert(err, jc.ErrorIsNil)
563
691
        err = cmd.Run(nil)
564
692
        c.Assert(err, gc.ErrorMatches, "failed to initialize state")
569
697
        _, err := os.Stat(filepath.Join(s.dataDir, agent.SystemIdentity))
570
698
        c.Assert(err, jc.Satisfies, os.IsNotExist)
571
699
 
572
 
        _, cmd, err := s.initBootstrapCommand(c, nil, "--model-config", s.b64yamlEnvcfg, "--instance-id", string(s.instanceId))
 
700
        _, cmd, err := s.initBootstrapCommand(c, nil,
 
701
                "--model-config", s.b64yamlControllerModelConfig,
 
702
                "--hosted-model-config", s.b64yamlHostedModelConfig,
 
703
                "--instance-id", string(s.instanceId),
 
704
        )
573
705
        c.Assert(err, jc.ErrorIsNil)
574
706
        err = cmd.Run(nil)
575
707
        c.Assert(err, jc.ErrorIsNil)
588
720
        // Tools uploaded over ssh.
589
721
        s.writeDownloadedTools(c, &tools.Tools{
590
722
                Version: version.Binary{
591
 
                        Number: version.Current,
 
723
                        Number: jujuversion.Current,
592
724
                        Arch:   arch.HostArch(),
593
725
                        Series: series.HostSeries(),
594
726
                },
600
732
func (s *BootstrapSuite) testToolsMetadata(c *gc.C, exploded bool) {
601
733
        envtesting.RemoveFakeToolsMetadata(c, s.toolsStorage)
602
734
 
603
 
        _, cmd, err := s.initBootstrapCommand(c, nil, "--model-config", s.b64yamlEnvcfg, "--instance-id", string(s.instanceId))
 
735
        _, cmd, err := s.initBootstrapCommand(c, nil,
 
736
                "--model-config", s.b64yamlControllerModelConfig,
 
737
                "--hosted-model-config", s.b64yamlHostedModelConfig,
 
738
                "--instance-id", string(s.instanceId),
 
739
        )
604
740
        c.Assert(err, jc.ErrorIsNil)
605
741
        err = cmd.Run(nil)
606
742
        c.Assert(err, jc.ErrorIsNil)
618
754
                        Addrs:  []string{gitjujutesting.MgoServer.Addr()},
619
755
                        CACert: testing.CACert,
620
756
                },
621
 
                Password: testPasswordHash(),
 
757
                Password: testPassword,
622
758
        }, mongo.DefaultDialOpts(), environs.NewStatePolicy())
623
759
        c.Assert(err, jc.ErrorIsNil)
624
760
        defer st.Close()
644
780
        c.Assert(err, jc.ErrorIsNil)
645
781
        c.Assert(metadata, gc.HasLen, expectedSeries.Size())
646
782
        for _, m := range metadata {
647
 
                c.Assert(expectedSeries.Contains(m.Version.Series), jc.IsTrue)
 
783
                v := version.MustParseBinary(m.Version)
 
784
                c.Assert(expectedSeries.Contains(v.Series), jc.IsTrue)
648
785
        }
649
786
}
650
787
 
682
819
                    "items": {
683
820
                        "%v": {
684
821
                            "id": "%v",
685
 
                            "root_store": "%v", 
686
 
                            "virt": "%v", 
 
822
                            "root_store": "%v",
 
823
                            "virt": "%v",
687
824
                            "region": "%v",
688
825
                            "endpoint": "endpoint"
689
826
                        }
743
880
                        Addrs:  []string{gitjujutesting.MgoServer.Addr()},
744
881
                        CACert: testing.CACert,
745
882
                },
746
 
                Password: testPasswordHash(),
 
883
                Password: testPassword,
747
884
        }, mongo.DefaultDialOpts(), environs.NewStatePolicy())
748
885
        c.Assert(err, jc.ErrorIsNil)
749
886
        defer st.Close()
760
897
        dir, m, _ := createImageMetadata(c)
761
898
        _, cmd, err := s.initBootstrapCommand(
762
899
                c, nil,
763
 
                "--model-config", s.b64yamlEnvcfg, "--instance-id", string(s.instanceId),
 
900
                "--model-config", s.b64yamlControllerModelConfig,
 
901
                "--hosted-model-config", s.b64yamlHostedModelConfig,
 
902
                "--instance-id", string(s.instanceId),
764
903
                "--image-metadata", dir,
765
904
        )
766
905
        c.Assert(err, jc.ErrorIsNil)
778
917
        dir, _, _ := createImageMetadata(c)
779
918
        _, cmd, err := s.initBootstrapCommand(
780
919
                c, nil,
781
 
                "--model-config", s.b64yamlEnvcfg, "--instance-id", string(s.instanceId),
 
920
                "--model-config", s.b64yamlControllerModelConfig,
 
921
                "--hosted-model-config", s.b64yamlHostedModelConfig,
 
922
                "--instance-id", string(s.instanceId),
782
923
                "--image-metadata", dir,
783
924
        )
784
925
        c.Assert(err, jc.ErrorIsNil)
810
951
 
811
952
        _, cmd, err := s.initBootstrapCommand(
812
953
                c, nil,
813
 
                "--model-config", s.b64yamlEnvcfg, "--instance-id", string(s.instanceId),
 
954
                "--model-config", s.b64yamlControllerModelConfig,
 
955
                "--hosted-model-config", s.b64yamlHostedModelConfig,
 
956
                "--instance-id", string(s.instanceId),
814
957
                "--image-metadata", dir,
815
958
        )
816
959
        c.Assert(err, jc.ErrorIsNil)
828
971
 
829
972
        _, cmd, err := s.initBootstrapCommand(
830
973
                c, nil,
831
 
                "--model-config", s.b64yamlEnvcfg, "--instance-id", string(s.instanceId),
 
974
                "--model-config", s.b64yamlControllerModelConfig,
 
975
                "--hosted-model-config", s.b64yamlHostedModelConfig,
 
976
                "--instance-id", string(s.instanceId),
832
977
                "--image-metadata", metadataDir,
833
978
        )
834
979
        c.Assert(err, jc.ErrorIsNil)
852
997
func (s *BootstrapSuite) makeTestEnv(c *gc.C) {
853
998
        attrs := dummy.SampleConfig().Merge(
854
999
                testing.Attrs{
855
 
                        "agent-version":     version.Current.String(),
 
1000
                        "agent-version":     jujuversion.Current.String(),
856
1001
                        "bootstrap-timeout": "123",
857
1002
                },
858
1003
        ).Delete("admin-secret", "ca-private-key")
860
1005
        c.Assert(err, jc.ErrorIsNil)
861
1006
        provider, err := environs.Provider(cfg.Type())
862
1007
        c.Assert(err, jc.ErrorIsNil)
863
 
        env, err := provider.PrepareForBootstrap(nullContext(), environs.PrepareForBootstrapParams{
864
 
                Config: cfg,
865
 
        })
 
1008
        cfg, err = provider.BootstrapConfig(environs.BootstrapConfigParams{Config: cfg})
 
1009
        c.Assert(err, jc.ErrorIsNil)
 
1010
        env, err := provider.PrepareForBootstrap(nullContext(), cfg)
866
1011
        c.Assert(err, jc.ErrorIsNil)
867
1012
 
868
1013
        s.PatchValue(&juju.JujuPublicKey, sstesting.SignedMetadataPublicKey)
876
1021
        addr, _ := network.SelectPublicAddress(addresses)
877
1022
        s.bootstrapName = addr.Value
878
1023
        s.envcfg = env.Config()
879
 
        s.b64yamlEnvcfg = b64yaml(s.envcfg.AllAttrs()).encode()
 
1024
        s.b64yamlControllerModelConfig = b64yaml(s.envcfg.AllAttrs()).encode()
 
1025
 
 
1026
        s.hostedModelUUID = utils.MustNewUUID().String()
 
1027
        hostedModelConfigAttrs := map[string]interface{}{
 
1028
                "name": "hosted-model",
 
1029
                "uuid": s.hostedModelUUID,
 
1030
        }
 
1031
        s.b64yamlHostedModelConfig = b64yaml(hostedModelConfigAttrs).encode()
880
1032
}
881
1033
 
882
1034
func nullContext() environs.BootstrapContext {
898
1050
}
899
1051
 
900
1052
func (s *BootstrapSuite) TestDefaultStoragePools(c *gc.C) {
901
 
        _, cmd, err := s.initBootstrapCommand(c, nil, "--model-config", s.b64yamlEnvcfg, "--instance-id", string(s.instanceId))
 
1053
        _, cmd, err := s.initBootstrapCommand(
 
1054
                c, nil, "--model-config", s.b64yamlControllerModelConfig,
 
1055
                "--hosted-model-config", s.b64yamlHostedModelConfig,
 
1056
                "--instance-id", string(s.instanceId),
 
1057
        )
902
1058
        c.Assert(err, jc.ErrorIsNil)
903
1059
        err = cmd.Run(nil)
904
1060
        c.Assert(err, jc.ErrorIsNil)
908
1064
                        Addrs:  []string{gitjujutesting.MgoServer.Addr()},
909
1065
                        CACert: testing.CACert,
910
1066
                },
911
 
                Password: testPasswordHash(),
 
1067
                Password: testPassword,
912
1068
        }, mongo.DefaultDialOpts(), environs.NewStatePolicy())
913
1069
        c.Assert(err, jc.ErrorIsNil)
914
1070
        defer st.Close()