func (p *Provisioner) startMachine(m *state.Machine) error { // TODO(dfc) the state.Info passed to environ.StartInstance remains contentious // however as the PA only knows one state.Info, and that info is used by MAs and // UAs to locate the state for this environment, it is logical to use the same // state.Info as the PA. stateInfo, apiInfo, err := p.setupAuthentication(m) if err != nil { return err } cons, err := m.Constraints() if err != nil { return err } // Generate a unique nonce for the new instance. uuid, err := utils.NewUUID() if err != nil { return err } // Generated nonce has the format: "machine-#:UUID". The first // part is a badge, specifying the tag of the machine the provisioner // is running on, while the second part is a random UUID. nonce := fmt.Sprintf("%s:%s", state.MachineTag(p.machineId), uuid.String()) inst, err := p.environ.StartInstance(m.Id(), nonce, m.Series(), cons, stateInfo, apiInfo) if err != nil { // Set the state to error, so the machine will be skipped next // time until the error is resolved, but don't return an // error; just keep going with the other machines. log.Errorf("worker/provisioner: cannot start instance for machine %q: %v", m, err) if err1 := m.SetStatus(params.StatusError, err.Error()); err1 != nil { // Something is wrong with this machine, better report it back. log.Errorf("worker/provisioner: cannot set error status for machine %q: %v", m, err1) return err1 } return nil } if err := m.SetProvisioned(inst.Id(), nonce); err != nil { // The machine is started, but we can't record the mapping in // state. It'll keep running while we fail out and restart, // but will then be detected by findUnknownInstances and // killed again. // // TODO(dimitern) Stop the instance right away here. // // Multiple instantiations of a given machine (with the same // machine ID) cannot coexist, because findUnknownInstances is // called before startMachines. However, if the first machine // had started to do work before being replaced, we may // encounter surprising problems. return err } // populate the local cache p.instances[m.Id()] = inst p.machines[inst.Id()] = m.Id() log.Noticef("worker/provisioner: started machine %s as instance %s", m, inst.Id()) return nil }
func (task *provisionerTask) startMachine(machine *state.Machine) error { stateInfo, apiInfo, err := task.auth.SetupAuthentication(machine) if err != nil { logger.Errorf("failed to setup authentication: %v", err) return err } cons, err := machine.Constraints() if err != nil { return err } // Generate a unique nonce for the new instance. uuid, err := utils.NewUUID() if err != nil { return err } // Generated nonce has the format: "machine-#:UUID". The first // part is a badge, specifying the tag of the machine the provisioner // is running on, while the second part is a random UUID. nonce := fmt.Sprintf("%s:%s", names.MachineTag(task.machineId), uuid.String()) inst, metadata, err := task.broker.StartInstance(machine.Id(), nonce, machine.Series(), cons, stateInfo, apiInfo) if err != nil { // Set the state to error, so the machine will be skipped next // time until the error is resolved, but don't return an // error; just keep going with the other machines. logger.Errorf("cannot start instance for machine %q: %v", machine, err) if err1 := machine.SetStatus(params.StatusError, err.Error()); err1 != nil { // Something is wrong with this machine, better report it back. logger.Errorf("cannot set error status for machine %q: %v", machine, err1) return err1 } return nil } if err := machine.SetProvisioned(inst.Id(), nonce, metadata); err != nil { logger.Errorf("cannot register instance for machine %v: %v", machine, err) // The machine is started, but we can't record the mapping in // state. It'll keep running while we fail out and restart, // but will then be detected by findUnknownInstances and // killed again. // // TODO(dimitern) Stop the instance right away here. // // Multiple instantiations of a given machine (with the same // machine ID) cannot coexist, because findUnknownInstances is // called before startMachines. However, if the first machine // had started to do work before being replaced, we may // encounter surprising problems. return err } logger.Infof("started machine %s as instance %s with hardware %q", machine, inst.Id(), metadata) return nil }
// SetStatus sets the status of each given machine. func (m *MachinerAPI) SetStatus(args params.MachinesSetStatus) (params.ErrorResults, error) { result := params.ErrorResults{ Errors: make([]*params.Error, len(args.Machines)), } if len(args.Machines) == 0 { return result, nil } for i, arg := range args.Machines { err := common.ErrPerm if m.auth.AuthOwner(arg.Tag) { var machine *state.Machine machine, err = m.st.Machine(state.MachineIdFromTag(arg.Tag)) if err == nil { err = machine.SetStatus(arg.Status, arg.Info) } } result.Errors[i] = common.ServerError(err) } return result, nil }