6
"launchpad.net/gnuflag"
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"
16
type BootstrapCommand struct {
19
EnvConfig map[string]interface{}
20
Constraints constraints.Value
23
// Info returns a decription of the command.
24
func (c *BootstrapCommand) Info() *cmd.Info {
26
Name: "bootstrap-state",
27
Purpose: "initialize juju state",
31
func (c *BootstrapCommand) SetFlags(f *gnuflag.FlagSet) {
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)")
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")
42
return c.Conf.checkArgs(args)
45
// Run initializes state for an environment.
46
func (c *BootstrapCommand) Run(_ *cmd.Context) error {
47
if err := c.Conf.read("bootstrap"); err != nil {
50
cfg, err := config.New(c.EnvConfig)
54
provider, err := environs.Provider(cfg.Type())
58
instanceId, err := provider.InstanceId()
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())
71
if err := st.SetEnvironConstraints(c.Constraints); err != nil {
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,
83
// Set up initial authentication.
84
u, err := st.AddUser("admin", "")
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.
94
if err := u.SetPasswordHash(c.Conf.OldPassword); err != nil {
97
if err := m.SetMongoPassword(c.Conf.OldPassword); err != nil {
100
if err := st.SetAdminMongoPassword(c.Conf.OldPassword); err != nil {
106
// yamlBase64Value implements gnuflag.Value on a map[string]interface{}.
107
type yamlBase64Value map[string]interface{}
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)
115
return goyaml.Unmarshal(decoded, v)
118
func (v *yamlBase64Value) String() string {
119
return fmt.Sprintf("%v", *v)
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)