~juju-qa/ubuntu/yakkety/juju/2.0-rc3-again

« back to all changes in this revision

Viewing changes to src/launchpad.net/juju-core/cmd/jujud/bootstrap.go

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2013-04-24 22:34:47 UTC
  • Revision ID: package-import@ubuntu.com-20130424223447-f0qdji7ubnyo0s71
Tags: upstream-1.10.0.1
ImportĀ upstreamĀ versionĀ 1.10.0.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package main
 
2
 
 
3
import (
 
4
        "encoding/base64"
 
5
        "fmt"
 
6
        "launchpad.net/gnuflag"
 
7
        "launchpad.net/goyaml"
 
8
        "launchpad.net/juju-core/cmd"
 
9
        "launchpad.net/juju-core/constraints"
 
10
        "launchpad.net/juju-core/environs"
 
11
        "launchpad.net/juju-core/environs/config"
 
12
        "launchpad.net/juju-core/state"
 
13
        "launchpad.net/juju-core/version"
 
14
)
 
15
 
 
16
type BootstrapCommand struct {
 
17
        cmd.CommandBase
 
18
        Conf        AgentConf
 
19
        EnvConfig   map[string]interface{}
 
20
        Constraints constraints.Value
 
21
}
 
22
 
 
23
// Info returns a decription of the command.
 
24
func (c *BootstrapCommand) Info() *cmd.Info {
 
25
        return &cmd.Info{
 
26
                Name:    "bootstrap-state",
 
27
                Purpose: "initialize juju state",
 
28
        }
 
29
}
 
30
 
 
31
func (c *BootstrapCommand) SetFlags(f *gnuflag.FlagSet) {
 
32
        c.Conf.addFlags(f)
 
33
        yamlBase64Var(f, &c.EnvConfig, "env-config", "", "initial environment configuration (yaml, base64 encoded)")
 
34
        f.Var(constraints.ConstraintsValue{&c.Constraints}, "constraints", "initial environment constraints (space-separated strings)")
 
35
}
 
36
 
 
37
// Init initializes the command for running.
 
38
func (c *BootstrapCommand) Init(args []string) error {
 
39
        if len(c.EnvConfig) == 0 {
 
40
                return requiredError("env-config")
 
41
        }
 
42
        return c.Conf.checkArgs(args)
 
43
}
 
44
 
 
45
// Run initializes state for an environment.
 
46
func (c *BootstrapCommand) Run(_ *cmd.Context) error {
 
47
        if err := c.Conf.read("bootstrap"); err != nil {
 
48
                return err
 
49
        }
 
50
        cfg, err := config.New(c.EnvConfig)
 
51
        if err != nil {
 
52
                return err
 
53
        }
 
54
        provider, err := environs.Provider(cfg.Type())
 
55
        if err != nil {
 
56
                return err
 
57
        }
 
58
        instanceId, err := provider.InstanceId()
 
59
        if err != nil {
 
60
                return err
 
61
        }
 
62
 
 
63
        // There is no entity that's created at init time.
 
64
        c.Conf.StateInfo.Tag = ""
 
65
        st, err := state.Initialize(c.Conf.StateInfo, cfg, state.DefaultDialOpts())
 
66
        if err != nil {
 
67
                return err
 
68
        }
 
69
        defer st.Close()
 
70
 
 
71
        if err := st.SetEnvironConstraints(c.Constraints); err != nil {
 
72
                return err
 
73
        }
 
74
        // TODO: we need to be able to customize machine jobs, not just hardcode these.
 
75
        m, err := st.InjectMachine(
 
76
                version.Current.Series, instanceId,
 
77
                state.JobManageEnviron, state.JobServeAPI,
 
78
        )
 
79
        if err != nil {
 
80
                return err
 
81
        }
 
82
 
 
83
        // Set up initial authentication.
 
84
        u, err := st.AddUser("admin", "")
 
85
        if err != nil {
 
86
                return err
 
87
        }
 
88
 
 
89
        // Note that at bootstrap time, the password is set to
 
90
        // the hash of its actual value. The first time a client
 
91
        // connects to mongo, it changes the mongo password
 
92
        // to the original password.
 
93
 
 
94
        if err := u.SetPasswordHash(c.Conf.OldPassword); err != nil {
 
95
                return err
 
96
        }
 
97
        if err := m.SetMongoPassword(c.Conf.OldPassword); err != nil {
 
98
                return err
 
99
        }
 
100
        if err := st.SetAdminMongoPassword(c.Conf.OldPassword); err != nil {
 
101
                return err
 
102
        }
 
103
        return nil
 
104
}
 
105
 
 
106
// yamlBase64Value implements gnuflag.Value on a map[string]interface{}.
 
107
type yamlBase64Value map[string]interface{}
 
108
 
 
109
// Set decodes the base64 value into yaml then expands that into a map.
 
110
func (v *yamlBase64Value) Set(value string) error {
 
111
        decoded, err := base64.StdEncoding.DecodeString(value)
 
112
        if err != nil {
 
113
                return err
 
114
        }
 
115
        return goyaml.Unmarshal(decoded, v)
 
116
}
 
117
 
 
118
func (v *yamlBase64Value) String() string {
 
119
        return fmt.Sprintf("%v", *v)
 
120
}
 
121
 
 
122
// yamlBase64Var sets up a gnuflag flag analogous to the FlagSet.*Var methods.
 
123
func yamlBase64Var(fs *gnuflag.FlagSet, target *map[string]interface{}, name string, value string, usage string) {
 
124
        fs.Var((*yamlBase64Value)(target), name, usage)
 
125
}