1
// Copyright 2012, 2013 Canonical Ltd.
2
// Licensed under the AGPLv3, see LICENCE file for details.
9
"launchpad.net/juju-core/agent"
10
"launchpad.net/juju-core/constraints"
11
"launchpad.net/juju-core/environs/config"
12
"launchpad.net/juju-core/errors"
13
"launchpad.net/juju-core/state"
14
"launchpad.net/juju-core/utils"
15
"launchpad.net/juju-core/version"
18
// Bootstrap bootstraps the given environment. The supplied constraints are
19
// used to provision the instance, and are also set within the bootstrapped
21
func Bootstrap(environ Environ, cons constraints.Value) error {
22
cfg := environ.Config()
23
if secret := cfg.AdminSecret(); secret == "" {
24
return fmt.Errorf("environment configuration has no admin-secret")
26
if authKeys := cfg.AuthorizedKeys(); authKeys == "" {
27
// Apparently this can never happen, so it's not tested. But, one day,
28
// Config will act differently (it's pretty crazy that, AFAICT, the
29
// authorized-keys are optional config settings... but it's impossible
30
// to actually *create* a config without them)... and when it does,
31
// we'll be here to catch this problem early.
32
return fmt.Errorf("environment configuration has no authorized-keys")
34
if _, hasCACert := cfg.CACert(); !hasCACert {
35
return fmt.Errorf("environment configuration has no ca-cert")
37
if _, hasCAKey := cfg.CAPrivateKey(); !hasCAKey {
38
return fmt.Errorf("environment configuration has no ca-private-key")
40
return environ.Bootstrap(cons)
43
// VerifyBootstrapInit does the common initial check inside bootstrap to
44
// confirm that the environment isn't already running, and that the storage
46
func VerifyBootstrapInit(env Environ, shortAttempt utils.AttemptStrategy) error {
49
// If the state file exists, it might actually have just been
50
// removed by Destroy, and eventual consistency has not caught
51
// up yet, so we retry to verify if that is happening.
52
for a := shortAttempt.Start(); a.Next(); {
53
if _, err = LoadState(env.Storage()); err != nil {
58
return fmt.Errorf("environment is already bootstrapped")
60
if !errors.IsNotFoundError(err) {
61
return fmt.Errorf("cannot query old bootstrap state: %v", err)
64
return VerifyStorage(env.Storage())
67
// BootstrapUsers creates the initial admin user for the database, and sets
68
// the initial password.
69
func BootstrapUsers(st *state.State, cfg *config.Config, passwordHash string) error {
70
logger.Debugf("adding admin user")
71
// Set up initial authentication.
72
u, err := st.AddUser("admin", "")
77
// Note that at bootstrap time, the password is set to
78
// the hash of its actual value. The first time a client
79
// connects to mongo, it changes the mongo password
80
// to the original password.
81
logger.Debugf("setting password hash for admin user")
82
if err := u.SetPasswordHash(passwordHash); err != nil {
85
if err := st.SetAdminMongoPassword(passwordHash); err != nil {
92
// ConfigureBootstrapMachine adds the initial machine into state. As a part
93
// of this process the environmental constraints are saved as constraints used
94
// when bootstrapping are considered constraints for the entire environment.
95
func ConfigureBootstrapMachine(
98
cons constraints.Value,
100
jobs []state.MachineJob,
102
logger.Debugf("setting environment constraints")
103
if err := st.SetEnvironConstraints(cons); err != nil {
107
logger.Debugf("configure bootstrap machine")
108
provider, err := Provider(cfg.Type())
112
instanceId, err := provider.InstanceId()
117
logger.Debugf("create bootstrap machine in state")
118
m, err := st.InjectMachine(version.Current.Series, cons, instanceId, jobs...)
122
// Read the machine agent's password and change it to
123
// a new password (other agents will change their password
124
// via the API connection).
125
logger.Debugf("create new random password for machine %v", m.Id())
126
mconf, err := agent.ReadConf(datadir, m.Tag())
130
newPassword, err := utils.RandomPassword()
134
mconf.StateInfo.Password = newPassword
135
mconf.APIInfo.Password = newPassword
136
mconf.OldPassword = ""
138
if err := mconf.Write(); err != nil {
141
if err := m.SetMongoPassword(newPassword); err != nil {
144
if err := m.SetPassword(newPassword); err != nil {