~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.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/ssh"
 
25
        "github.com/juju/version"
25
26
        goyaml "gopkg.in/yaml.v2"
26
27
        "launchpad.net/gnuflag"
27
28
 
28
29
        "github.com/juju/juju/agent"
 
30
        "github.com/juju/juju/agent/agentbootstrap"
29
31
        agenttools "github.com/juju/juju/agent/tools"
30
32
        agentcmd "github.com/juju/juju/cmd/jujud/agent"
31
33
        cmdutil "github.com/juju/juju/cmd/jujud/util"
39
41
        "github.com/juju/juju/mongo"
40
42
        "github.com/juju/juju/network"
41
43
        "github.com/juju/juju/state"
 
44
        "github.com/juju/juju/state/binarystorage"
42
45
        "github.com/juju/juju/state/cloudimagemetadata"
43
46
        "github.com/juju/juju/state/multiwatcher"
44
47
        "github.com/juju/juju/state/storage"
45
 
        "github.com/juju/juju/state/toolstorage"
46
48
        "github.com/juju/juju/storage/poolmanager"
47
49
        "github.com/juju/juju/tools"
48
 
        "github.com/juju/juju/version"
 
50
        jujuversion "github.com/juju/juju/version"
49
51
        "github.com/juju/juju/worker/peergrouper"
50
52
)
51
53
 
52
54
var (
53
55
        initiateMongoServer  = peergrouper.InitiateMongoServer
54
 
        agentInitializeState = agent.InitializeState
 
56
        agentInitializeState = agentbootstrap.InitializeState
55
57
        sshGenerateKey       = ssh.GenerateKey
56
58
        newStateStorage      = storage.NewStorage
57
59
        minSocketTimeout     = 1 * time.Minute
62
64
type BootstrapCommand struct {
63
65
        cmd.CommandBase
64
66
        agentcmd.AgentConf
65
 
        EnvConfig            map[string]interface{}
66
 
        BootstrapConstraints constraints.Value
67
 
        EnvironConstraints   constraints.Value
68
 
        Hardware             instance.HardwareCharacteristics
69
 
        InstanceId           string
70
 
        AdminUsername        string
71
 
        ImageMetadataDir     string
 
67
        ControllerModelConfig map[string]interface{}
 
68
        HostedModelConfig     map[string]interface{}
 
69
        BootstrapConstraints  constraints.Value
 
70
        ModelConstraints      constraints.Value
 
71
        Hardware              instance.HardwareCharacteristics
 
72
        InstanceId            string
 
73
        AdminUsername         string
 
74
        ImageMetadataDir      string
72
75
}
73
76
 
74
77
// NewBootstrapCommand returns a new BootstrapCommand that has been initialized.
89
92
// SetFlags adds the flags for this command to the passed gnuflag.FlagSet.
90
93
func (c *BootstrapCommand) SetFlags(f *gnuflag.FlagSet) {
91
94
        c.AgentConf.AddFlags(f)
92
 
        yamlBase64Var(f, &c.EnvConfig, "model-config", "", "initial model configuration (yaml, base64 encoded)")
 
95
        yamlBase64Var(f, &c.ControllerModelConfig, "model-config", "", "controller model configuration (yaml, base64 encoded)")
 
96
        yamlBase64Var(f, &c.HostedModelConfig, "hosted-model-config", "", "initial hosted model configuration (yaml, base64 encoded)")
93
97
        f.Var(constraints.ConstraintsValue{Target: &c.BootstrapConstraints}, "bootstrap-constraints", "bootstrap machine constraints (space-separated strings)")
94
 
        f.Var(constraints.ConstraintsValue{Target: &c.EnvironConstraints}, "constraints", "initial constraints (space-separated strings)")
 
98
        f.Var(constraints.ConstraintsValue{Target: &c.ModelConstraints}, "constraints", "initial constraints (space-separated strings)")
95
99
        f.Var(&c.Hardware, "hardware", "hardware characteristics (space-separated strings)")
96
100
        f.StringVar(&c.InstanceId, "instance-id", "", "unique instance-id for bootstrap machine")
97
101
        f.StringVar(&c.AdminUsername, "admin-user", "admin", "set the name for the juju admin user")
100
104
 
101
105
// Init initializes the command for running.
102
106
func (c *BootstrapCommand) Init(args []string) error {
103
 
        if len(c.EnvConfig) == 0 {
 
107
        if len(c.ControllerModelConfig) == 0 {
104
108
                return cmdutil.RequiredError("model-config")
105
109
        }
 
110
        if len(c.HostedModelConfig) == 0 {
 
111
                return cmdutil.RequiredError("hosted-model-config")
 
112
        }
106
113
        if c.InstanceId == "" {
107
114
                return cmdutil.RequiredError("instance-id")
108
115
        }
114
121
 
115
122
// Run initializes state for an environment.
116
123
func (c *BootstrapCommand) Run(_ *cmd.Context) error {
117
 
        envCfg, err := config.New(config.NoDefaults, c.EnvConfig)
 
124
        envCfg, err := config.New(config.NoDefaults, c.ControllerModelConfig)
118
125
        if err != nil {
119
126
                return err
120
127
        }
147
154
        // Check to see if a newer agent version has been requested
148
155
        // by the bootstrap client.
149
156
        desiredVersion, ok := envCfg.AgentVersion()
150
 
        if ok && desiredVersion != version.Current {
 
157
        if ok && desiredVersion != jujuversion.Current {
151
158
                // If we have been asked for a newer version, ensure the newer
152
159
                // tools can actually be found, or else bootstrap won't complete.
153
160
                stream := envtools.PreferredStream(&desiredVersion, envCfg.Development(), envCfg.AgentStream())
164
171
                if errors.IsNotFound(toolsErr) {
165
172
                        // Newer tools not available, so revert to using the tools
166
173
                        // matching the current agent version.
167
 
                        logger.Warningf("newer tools for %q not available, sticking with version %q", desiredVersion, version.Current)
168
 
                        newConfigAttrs["agent-version"] = version.Current.String()
 
174
                        logger.Warningf("newer tools for %q not available, sticking with version %q", desiredVersion, jujuversion.Current)
 
175
                        newConfigAttrs["agent-version"] = jujuversion.Current.String()
169
176
                } else if toolsErr != nil {
170
177
                        logger.Errorf("cannot find newer tools: %v", toolsErr)
171
178
                        return toolsErr
271
278
                st, m, stateErr = agentInitializeState(
272
279
                        adminTag,
273
280
                        agentConfig,
274
 
                        envCfg,
275
 
                        agent.BootstrapMachineConfig{
 
281
                        envCfg, c.HostedModelConfig,
 
282
                        agentbootstrap.BootstrapMachineConfig{
276
283
                                Addresses:            addrs,
277
284
                                BootstrapConstraints: c.BootstrapConstraints,
278
 
                                ModelConstraints:     c.EnvironConstraints,
 
285
                                ModelConstraints:     c.ModelConstraints,
279
286
                                Jobs:                 jobs,
280
287
                                InstanceId:           instanceId,
281
288
                                Characteristics:      c.Hardware,
296
303
                return err
297
304
        }
298
305
 
 
306
        // Populate the GUI archive catalogue.
 
307
        if err := c.populateGUIArchive(st, env); err != nil {
 
308
                return err
 
309
        }
 
310
 
299
311
        // Add custom image metadata to environment storage.
300
312
        if c.ImageMetadataDir != "" {
301
313
                if err := c.saveCustomImageMetadata(st, env); err != nil {
376
388
func (c *BootstrapCommand) populateTools(st *state.State, env environs.Environ) error {
377
389
        agentConfig := c.CurrentConfig()
378
390
        dataDir := agentConfig.DataDir()
 
391
 
379
392
        current := version.Binary{
380
 
                Number: version.Current,
 
393
                Number: jujuversion.Current,
381
394
                Arch:   arch.HostArch(),
382
395
                Series: series.HostSeries(),
383
396
        }
394
407
                return errors.Trace(err)
395
408
        }
396
409
 
397
 
        storage, err := st.ToolsStorage()
 
410
        toolstorage, err := st.ToolsStorage()
398
411
        if err != nil {
399
412
                return errors.Trace(err)
400
413
        }
401
 
        defer storage.Close()
 
414
        defer toolstorage.Close()
402
415
 
403
416
        var toolsVersions []version.Binary
404
417
        if strings.HasPrefix(tools.URL, "file://") {
419
432
        }
420
433
 
421
434
        for _, toolsVersion := range toolsVersions {
422
 
                metadata := toolstorage.Metadata{
423
 
                        Version: toolsVersion,
 
435
                metadata := binarystorage.Metadata{
 
436
                        Version: toolsVersion.String(),
424
437
                        Size:    tools.Size,
425
438
                        SHA256:  tools.SHA256,
426
439
                }
427
440
                logger.Debugf("Adding tools: %v", toolsVersion)
428
 
                if err := storage.AddTools(bytes.NewReader(data), metadata); err != nil {
 
441
                if err := toolstorage.Add(bytes.NewReader(data), metadata); err != nil {
429
442
                        return errors.Trace(err)
430
443
                }
431
444
        }
432
445
        return nil
433
446
}
434
447
 
 
448
// populateGUIArchive stores uploaded Juju GUI archive in provider storage
 
449
// and updates the GUI metadata.
 
450
func (c *BootstrapCommand) populateGUIArchive(st *state.State, env environs.Environ) error {
 
451
        agentConfig := c.CurrentConfig()
 
452
        dataDir := agentConfig.DataDir()
 
453
        guistorage, err := st.GUIStorage()
 
454
        if err != nil {
 
455
                return errors.Trace(err)
 
456
        }
 
457
        defer guistorage.Close()
 
458
        gui, err := agenttools.ReadGUIArchive(dataDir)
 
459
        if err != nil {
 
460
                // TODO frankban: ignore the error for now, as the GUI could not be
 
461
                // there at all. This needs to be changed before merging into master,
 
462
                // return errors.Annotate(err, "cannot fetch GUI info")
 
463
                return nil
 
464
        }
 
465
        f, err := os.Open(filepath.Join(agenttools.SharedGUIDir(dataDir), "gui.tar.bz2"))
 
466
        if err != nil {
 
467
                return errors.Annotate(err, "cannot read GUI archive")
 
468
        }
 
469
        defer f.Close()
 
470
        if err := guistorage.Add(f, binarystorage.Metadata{
 
471
                Version: gui.Version.String(),
 
472
                Size:    gui.Size,
 
473
                SHA256:  gui.SHA256,
 
474
        }); err != nil {
 
475
                return errors.Annotate(err, "cannot store GUI archive")
 
476
        }
 
477
        return nil
 
478
}
 
479
 
435
480
// storeCustomImageMetadata reads the custom image metadata from disk,
436
481
// and stores the files in environment storage with the same relative
437
482
// paths.