func addMachineForUnit(st *state.State, unit *state.Unit, placement *instance.Placement, networks []string) (*state.Machine, error) { unitCons, err := unit.Constraints() if err != nil { return nil, err } var containerType instance.ContainerType var mid, placementDirective string // Extract container type and parent from container placement directives. if containerType, err = instance.ParseContainerType(placement.Scope); err == nil { mid = placement.Directive } else { switch placement.Scope { case st.EnvironUUID(): placementDirective = placement.Directive case instance.MachineScope: mid = placement.Directive default: return nil, errors.Errorf("invalid environment UUID %q", placement.Scope) } } // Create any new machine marked as dirty so that // nothing else will grab it before we assign the unit to it. // If a container is to be used, create it. if containerType != "" { template := state.MachineTemplate{ Series: unit.Series(), Jobs: []state.MachineJob{state.JobHostUnits}, Dirty: true, Constraints: *unitCons, RequestedNetworks: networks, } return st.AddMachineInsideMachine(template, mid, containerType) } // If a placement directive is to be used, do that here. if placementDirective != "" { template := state.MachineTemplate{ Series: unit.Series(), Jobs: []state.MachineJob{state.JobHostUnits}, Dirty: true, Constraints: *unitCons, RequestedNetworks: networks, Placement: placementDirective, } return st.AddOneMachine(template) } // Otherwise use an existing machine. return st.Machine(mid) }
// initBootstrapMachine initializes the initial bootstrap machine in state. func initBootstrapMachine(c agent.ConfigSetter, st *state.State, args InitializeStateParams) (*state.Machine, error) { logger.Infof("initialising bootstrap machine with config: %+v", args) jobs := make([]state.MachineJob, len(args.BootstrapMachineJobs)) for i, job := range args.BootstrapMachineJobs { machineJob, err := machineJobFromParams(job) if err != nil { return nil, errors.Errorf("invalid bootstrap machine job %q: %v", job, err) } jobs[i] = machineJob } var hardware instance.HardwareCharacteristics if args.BootstrapMachineHardwareCharacteristics != nil { hardware = *args.BootstrapMachineHardwareCharacteristics } m, err := st.AddOneMachine(state.MachineTemplate{ Addresses: args.BootstrapMachineAddresses, Series: series.HostSeries(), Nonce: agent.BootstrapNonce, Constraints: args.BootstrapMachineConstraints, InstanceId: args.BootstrapMachineInstanceId, HardwareCharacteristics: hardware, Jobs: jobs, }) if err != nil { return nil, errors.Errorf("cannot create bootstrap machine in state: %v", err) } if m.Id() != agent.BootstrapMachineId { return nil, errors.Errorf("bootstrap machine expected id 0, got %q", m.Id()) } // Read the machine agent's password and change it to // a new password (other agents will change their password // via the API connection). logger.Debugf("create new random password for machine %v", m.Id()) newPassword, err := utils.RandomPassword() if err != nil { return nil, err } if err := m.SetPassword(newPassword); err != nil { return nil, err } if err := m.SetMongoPassword(newPassword); err != nil { return nil, err } c.SetPassword(newPassword) return m, nil }
// initBootstrapMachine initializes the initial bootstrap machine in state. func initBootstrapMachine(c ConfigSetter, st *state.State, cfg BootstrapMachineConfig) (*state.Machine, error) { logger.Infof("initialising bootstrap machine with config: %+v", cfg) jobs := make([]state.MachineJob, len(cfg.Jobs)) for i, job := range cfg.Jobs { machineJob, err := state.MachineJobFromParams(job) if err != nil { return nil, fmt.Errorf("invalid bootstrap machine job %q: %v", job, err) } jobs[i] = machineJob } m, err := st.AddOneMachine(state.MachineTemplate{ Addresses: cfg.Addresses, Series: version.Current.Series, Nonce: BootstrapNonce, Constraints: cfg.Constraints, InstanceId: cfg.InstanceId, HardwareCharacteristics: cfg.Characteristics, Jobs: jobs, }) if err != nil { return nil, fmt.Errorf("cannot create bootstrap machine in state: %v", err) } if m.Id() != BootstrapMachineId { return nil, fmt.Errorf("bootstrap machine expected id 0, got %q", m.Id()) } // Read the machine agent's password and change it to // a new password (other agents will change their password // via the API connection). logger.Debugf("create new random password for machine %v", m.Id()) newPassword, err := utils.RandomPassword() if err != nil { return nil, err } if err := m.SetPassword(newPassword); err != nil { return nil, err } if err := m.SetMongoPassword(newPassword); err != nil { return nil, err } c.SetPassword(newPassword) return m, nil }