func (task *provisionerTask) setErrorStatus(message string, machine *apiprovisioner.Machine, err error) error { logger.Errorf(message, machine, err) if err1 := machine.SetStatus(params.StatusError, err.Error(), nil); err1 != nil { // Something is wrong with this machine, better report it back. return errors.Annotatef(err1, "cannot set error status for machine %q", machine) } return nil }
func (task *provisionerTask) startMachine( machine *apiprovisioner.Machine, provisioningInfo *params.ProvisioningInfo, startInstanceParams environs.StartInstanceParams, ) error { var result *environs.StartInstanceResult for attemptsLeft := task.retryStartInstanceStrategy.retryCount; attemptsLeft >= 0; attemptsLeft-- { attemptResult, err := task.broker.StartInstance(startInstanceParams) if err == nil { result = attemptResult break } else if attemptsLeft <= 0 { // 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. return task.setErrorStatus("cannot start instance for machine %q: %v", machine, err) } logger.Warningf("%v", errors.Annotate(err, "starting instance")) retryMsg := fmt.Sprintf("will retry to start instance in %v", task.retryStartInstanceStrategy.retryDelay) if err2 := machine.SetStatus(status.Pending, retryMsg, nil); err2 != nil { logger.Errorf("%v", err2) } logger.Infof(retryMsg) select { case <-task.catacomb.Dying(): return task.catacomb.ErrDying() case <-time.After(task.retryStartInstanceStrategy.retryDelay): } } networkConfig := networkingcommon.NetworkConfigFromInterfaceInfo(result.NetworkInfo) volumes := volumesToAPIserver(result.Volumes) volumeNameToAttachmentInfo := volumeAttachmentsToAPIserver(result.VolumeAttachments) if err := machine.SetInstanceInfo( result.Instance.Id(), startInstanceParams.InstanceConfig.MachineNonce, result.Hardware, networkConfig, volumes, volumeNameToAttachmentInfo, ); err != nil { // We need to stop the instance right away here, set error status and go on. if err2 := task.setErrorStatus("cannot register instance for machine %v: %v", machine, err); err2 != nil { logger.Errorf("%v", errors.Annotate(err2, "cannot set machine's status")) } if err2 := task.broker.StopInstances(result.Instance.Id()); err2 != nil { logger.Errorf("%v", errors.Annotate(err2, "after failing to set instance info")) } return errors.Annotate(err, "cannot set instance info") } logger.Infof( "started machine %s as instance %s with hardware %q, network config %+v, volumes %v, volume attachments %v, subnets to zones %v", machine, result.Instance.Id(), result.Hardware, networkConfig, volumes, volumeNameToAttachmentInfo, startInstanceParams.SubnetsToZones, ) return nil }