7
7
"github.com/juju/errors"
8
8
"github.com/juju/loggo"
9
"github.com/juju/names"
10
9
"github.com/juju/utils"
11
10
"github.com/juju/utils/series"
11
"gopkg.in/juju/names.v2"
13
13
"github.com/juju/juju/agent"
14
14
"github.com/juju/juju/apiserver/params"
15
"github.com/juju/juju/constraints"
15
"github.com/juju/juju/cloud"
16
"github.com/juju/juju/cloudconfig/instancecfg"
16
17
"github.com/juju/juju/controller/modelmanager"
17
"github.com/juju/juju/environs/config"
18
18
"github.com/juju/juju/instance"
19
19
"github.com/juju/juju/mongo"
20
20
"github.com/juju/juju/network"
25
25
var logger = loggo.GetLogger("juju.agent.agentbootstrap")
27
// BootstrapMachineConfig holds configuration information
28
// to attach to the bootstrap machine.
29
type BootstrapMachineConfig struct {
30
// Addresses holds the bootstrap machine's addresses.
31
Addresses []network.Address
33
// BootstrapConstraints holds the bootstrap machine's constraints.
34
BootstrapConstraints constraints.Value
36
// ModelConstraints holds the model-level constraints.
37
ModelConstraints constraints.Value
39
// Jobs holds the jobs that the machine agent will run.
40
Jobs []multiwatcher.MachineJob
42
// InstanceId holds the instance id of the bootstrap machine.
43
InstanceId instance.Id
45
// Characteristics holds hardware information on the
47
Characteristics instance.HardwareCharacteristics
27
// InitializeStateParams holds parameters used for initializing the state
29
type InitializeStateParams struct {
30
instancecfg.StateInitializationParams
32
// BootstrapMachineAddresses holds the bootstrap machine's addresses.
33
BootstrapMachineAddresses []network.Address
35
// BootstrapMachineJobs holds the jobs that the bootstrap machine
37
BootstrapMachineJobs []multiwatcher.MachineJob
49
39
// SharedSecret is the Mongo replica set shared secret (keyfile).
50
40
SharedSecret string
92
80
return nil, nil, errors.Annotate(err, "failed to initialize mongo admin user")
83
cloudCredentials := make(map[string]cloud.Credential)
84
if args.ControllerCloudCredential != nil {
85
cloudCredentials[args.ControllerCloudCredentialName] = *args.ControllerCloudCredential
95
88
logger.Debugf("initializing address %v", info.Addrs)
96
st, err := state.Initialize(adminUser, info, cfg, dialOpts, policy)
89
st, err := state.Initialize(state.InitializeParams{
90
ControllerModelArgs: state.ModelArgs{
92
Config: args.ControllerModelConfig,
93
Constraints: args.ModelConstraints,
94
CloudName: args.ControllerCloudName,
95
CloudRegion: args.ControllerCloudRegion,
96
CloudCredential: args.ControllerCloudCredentialName,
98
CloudName: args.ControllerCloudName,
99
Cloud: args.ControllerCloud,
100
CloudCredentials: cloudCredentials,
101
ControllerConfig: args.ControllerConfig,
102
LocalCloudConfig: args.LocalCloudConfig,
104
MongoDialOpts: dialOpts,
98
108
return nil, nil, errors.Errorf("failed to initialize state: %v", err)
106
servingInfo.SharedSecret = machineCfg.SharedSecret
116
servingInfo.SharedSecret = args.SharedSecret
107
117
c.SetStateServingInfo(servingInfo)
109
119
// Filter out any LXC bridge addresses from the machine addresses.
110
machineCfg.Addresses = network.FilterLXCAddresses(machineCfg.Addresses)
120
args.BootstrapMachineAddresses = network.FilterLXCAddresses(args.BootstrapMachineAddresses)
112
if err = initAPIHostPorts(c, st, machineCfg.Addresses, servingInfo.APIPort); err != nil {
122
if err = initAPIHostPorts(c, st, args.BootstrapMachineAddresses, servingInfo.APIPort); err != nil {
113
123
return nil, nil, err
115
125
ssi := paramsStateServingInfoToStateStateServingInfo(servingInfo)
116
126
if err := st.SetStateServingInfo(ssi); err != nil {
117
127
return nil, nil, errors.Errorf("cannot set state serving info: %v", err)
119
m, err := initConstraintsAndBootstrapMachine(c, st, machineCfg)
129
m, err := initBootstrapMachine(c, st, args)
131
return nil, nil, errors.Annotate(err, "cannot initialize bootstrap machine")
124
134
// Create the initial hosted model, with the model config passed to
125
135
// bootstrap, which contains the UUID, name for the hosted model,
126
136
// and any user supplied config.
127
137
attrs := make(map[string]interface{})
128
for k, v := range hostedModelConfigAttrs {
138
for k, v := range args.HostedModelConfig {
131
hostedModelConfig, err := modelmanager.ModelConfigCreator{}.NewModelConfig(modelmanager.IsAdmin, cfg, attrs)
141
// TODO(axw) we shouldn't be adding credentials to model config.
142
if args.ControllerCloudCredential != nil {
143
for k, v := range args.ControllerCloudCredential.Attributes() {
147
controllerUUID := args.ControllerConfig.ControllerUUID()
148
hostedModelConfig, err := modelmanager.ModelConfigCreator{}.NewModelConfig(
149
modelmanager.IsAdmin, controllerUUID, args.ControllerModelConfig, attrs,
133
152
return nil, nil, errors.Annotate(err, "creating hosted model config")
135
154
_, hostedModelState, err := st.NewModel(state.ModelArgs{
136
Config: hostedModelConfig,
156
Config: hostedModelConfig,
157
Constraints: args.ModelConstraints,
158
CloudName: args.ControllerCloudName,
159
CloudRegion: args.ControllerCloudRegion,
160
CloudCredential: args.ControllerCloudCredentialName,
140
163
return nil, nil, errors.Annotate(err, "creating hosted model")
142
if err := hostedModelState.SetModelConstraints(machineCfg.ModelConstraints); err != nil {
143
return nil, nil, errors.Annotate(err, "cannot set initial hosted model constraints")
145
165
hostedModelState.Close()
147
167
return st, m, nil
162
func initConstraintsAndBootstrapMachine(c agent.ConfigSetter, st *state.State, cfg BootstrapMachineConfig) (*state.Machine, error) {
163
if err := st.SetModelConstraints(cfg.ModelConstraints); err != nil {
164
return nil, errors.Annotate(err, "cannot set initial model constraints")
166
m, err := initBootstrapMachine(c, st, cfg)
168
return nil, errors.Annotate(err, "cannot initialize bootstrap machine")
173
182
// initMongoAdminUser adds the admin user with the specified
174
183
// password to the admin database in Mongo.
175
184
func initMongoAdminUser(info mongo.Info, dialOpts mongo.DialOpts, password string) error {
184
193
// initBootstrapMachine initializes the initial bootstrap machine in state.
185
func initBootstrapMachine(c agent.ConfigSetter, st *state.State, cfg BootstrapMachineConfig) (*state.Machine, error) {
186
logger.Infof("initialising bootstrap machine with config: %+v", cfg)
194
func initBootstrapMachine(c agent.ConfigSetter, st *state.State, args InitializeStateParams) (*state.Machine, error) {
195
logger.Infof("initialising bootstrap machine with config: %+v", args)
188
jobs := make([]state.MachineJob, len(cfg.Jobs))
189
for i, job := range cfg.Jobs {
197
jobs := make([]state.MachineJob, len(args.BootstrapMachineJobs))
198
for i, job := range args.BootstrapMachineJobs {
190
199
machineJob, err := machineJobFromParams(job)
192
201
return nil, errors.Errorf("invalid bootstrap machine job %q: %v", job, err)
194
203
jobs[i] = machineJob
205
var hardware instance.HardwareCharacteristics
206
if args.BootstrapMachineHardwareCharacteristics != nil {
207
hardware = *args.BootstrapMachineHardwareCharacteristics
196
209
m, err := st.AddOneMachine(state.MachineTemplate{
197
Addresses: cfg.Addresses,
210
Addresses: args.BootstrapMachineAddresses,
198
211
Series: series.HostSeries(),
199
212
Nonce: agent.BootstrapNonce,
200
Constraints: cfg.BootstrapConstraints,
201
InstanceId: cfg.InstanceId,
202
HardwareCharacteristics: cfg.Characteristics,
213
Constraints: args.BootstrapMachineConstraints,
214
InstanceId: args.BootstrapMachineInstanceId,
215
HardwareCharacteristics: hardware,