diff --git a/builder/vmware/builder.go b/builder/vmware/builder.go index 41f6365c4..9e12a49a5 100644 --- a/builder/vmware/builder.go +++ b/builder/vmware/builder.go @@ -225,15 +225,21 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe } else { b.runner = &multistep.BasicRunner{Steps: steps} } + b.runner.Run(state) + // If there was an error, return that + if rawErr, ok := state["error"]; ok { + return nil, rawErr.(error) + } + // If we were interrupted or cancelled, then just exit. if _, ok := state[multistep.StateCancelled]; ok { - return nil, nil + return nil, errors.New("Build was cancelled.") } if _, ok := state[multistep.StateHalted]; ok { - return nil, nil + return nil, errors.New("Build was halted.") } // Compile the artifact list diff --git a/builder/vmware/step_configure_vnc.go b/builder/vmware/step_configure_vnc.go index 3b09611eb..341097949 100644 --- a/builder/vmware/step_configure_vnc.go +++ b/builder/vmware/step_configure_vnc.go @@ -29,13 +29,17 @@ func (stepConfigureVNC) Run(state map[string]interface{}) multistep.StepAction { f, err := os.Open(vmxPath) if err != nil { - ui.Error(fmt.Sprintf("Error while reading VMX data: %s", err)) + err := fmt.Errorf("Error reading VMX data: %s", err) + state["error"] = err + ui.Error(err.Error()) return multistep.ActionHalt } vmxBytes, err := ioutil.ReadAll(f) if err != nil { - ui.Error(fmt.Sprintf("Error reading VMX data: %s", err)) + err := fmt.Errorf("Error reading VMX data: %s", err) + state["error"] = err + ui.Error(err.Error()) return multistep.ActionHalt } @@ -62,7 +66,9 @@ func (stepConfigureVNC) Run(state map[string]interface{}) multistep.StepAction { vmxData["RemoteDisplay.vnc.port"] = fmt.Sprintf("%d", vncPort) if err := WriteVMX(vmxPath, vmxData); err != nil { - ui.Error(fmt.Sprintf("Error writing VMX data: %s", err)) + err := fmt.Errorf("Error writing VMX data: %s", err) + state["error"] = err + ui.Error(err.Error()) return multistep.ActionHalt } diff --git a/builder/vmware/step_create_disk.go b/builder/vmware/step_create_disk.go index 36da70439..61f578127 100644 --- a/builder/vmware/step_create_disk.go +++ b/builder/vmware/step_create_disk.go @@ -29,7 +29,9 @@ func (stepCreateDisk) Run(state map[string]interface{}) multistep.StepAction { ui.Say("Creating virtual machine disk") output := filepath.Join(config.OutputDir, config.DiskName+".vmdk") if err := driver.CreateDisk(output, "40000M"); err != nil { - ui.Error(fmt.Sprintf("Error creating VMware disk: %s", err)) + err := fmt.Errorf("Error creating disk: %s", err) + state["error"] = err + ui.Error(err.Error()) return multistep.ActionHalt } diff --git a/builder/vmware/step_create_vmx.go b/builder/vmware/step_create_vmx.go index f8ff37665..56e1962ce 100644 --- a/builder/vmware/step_create_vmx.go +++ b/builder/vmware/step_create_vmx.go @@ -57,7 +57,9 @@ func (stepCreateVMX) Run(state map[string]interface{}) multistep.StepAction { vmxPath := filepath.Join(config.OutputDir, config.VMName+".vmx") if err := WriteVMX(vmxPath, vmxData); err != nil { - ui.Error(fmt.Sprintf("Error creating VMX: %s", err)) + err := fmt.Errorf("Error creating VMX file: %s", err) + state["error"] = err + ui.Error(err.Error()) return multistep.ActionHalt } diff --git a/builder/vmware/step_download_iso.go b/builder/vmware/step_download_iso.go index 02d2afc8f..84e9f921e 100644 --- a/builder/vmware/step_download_iso.go +++ b/builder/vmware/step_download_iso.go @@ -29,7 +29,9 @@ func (s stepDownloadISO) Run(state map[string]interface{}) multistep.StepAction checksum, err := hex.DecodeString(config.ISOMD5) if err != nil { - ui.Error(fmt.Sprintf("Error parsing checksum: %s", err)) + err := fmt.Errorf("Error parsing checksum: %s", err) + state["error"] = err + ui.Error(err.Error()) return multistep.ActionHalt } @@ -62,7 +64,9 @@ DownloadWaitLoop: select { case err := <-downloadCompleteCh: if err != nil { - ui.Error(fmt.Sprintf("Error downloading ISO: %s", err)) + err := fmt.Errorf("Error downloading ISO: %s", err) + state["error"] = err + ui.Error(err.Error()) } break DownloadWaitLoop diff --git a/builder/vmware/step_prepare_output_dir.go b/builder/vmware/step_prepare_output_dir.go index 6068e5bb7..976f36b00 100644 --- a/builder/vmware/step_prepare_output_dir.go +++ b/builder/vmware/step_prepare_output_dir.go @@ -11,6 +11,7 @@ func (stepPrepareOutputDir) Run(state map[string]interface{}) multistep.StepActi config := state["config"].(*config) if err := os.MkdirAll(config.OutputDir, 0755); err != nil { + state["error"] = err return multistep.ActionHalt } diff --git a/builder/vmware/step_run.go b/builder/vmware/step_run.go index 5af7afaff..2818571c3 100644 --- a/builder/vmware/step_run.go +++ b/builder/vmware/step_run.go @@ -34,7 +34,9 @@ func (s *stepRun) Run(state map[string]interface{}) multistep.StepAction { ui.Say("Starting virtual machine...") if err := driver.Start(vmxPath); err != nil { - ui.Error(fmt.Sprintf("Error starting VM: %s", err)) + err := fmt.Errorf("Error starting VM: %s", err) + state["error"] = err + ui.Error(err.Error()) return multistep.ActionHalt } diff --git a/builder/vmware/step_shutdown.go b/builder/vmware/step_shutdown.go index a1bef28b0..078a13a0c 100644 --- a/builder/vmware/step_shutdown.go +++ b/builder/vmware/step_shutdown.go @@ -1,6 +1,7 @@ package vmware import ( + "errors" "fmt" "github.com/mitchellh/multistep" "github.com/mitchellh/packer/packer" @@ -34,7 +35,9 @@ func (s *stepShutdown) Run(state map[string]interface{}) multistep.StepAction { log.Printf("Executing shutdown command: %s", config.ShutdownCommand) cmd := &packer.RemoteCmd{Command: config.ShutdownCommand} if err := comm.Start(cmd); err != nil { - ui.Error(fmt.Sprintf("Failed to send shutdown command: %s", err)) + err := fmt.Errorf("Failed to send shutdown command: %s", err) + state["error"] = err + ui.Error(err.Error()) return multistep.ActionHalt } @@ -52,7 +55,9 @@ func (s *stepShutdown) Run(state map[string]interface{}) multistep.StepAction { select { case <-shutdownTimer: - ui.Error("Timeout while waiting for machine to shut down.") + err := errors.New("Timeout while waiting for machine to shut down.") + state["error"] = err + ui.Error(err.Error()) return multistep.ActionHalt default: time.Sleep(1 * time.Second) @@ -60,7 +65,9 @@ func (s *stepShutdown) Run(state map[string]interface{}) multistep.StepAction { } } else { if err := driver.Stop(vmxPath); err != nil { - ui.Error(fmt.Sprintf("Error stopping VM: %s", err)) + err := fmt.Errorf("Error stopping VM: %s", err) + state["error"] = err + ui.Error(err.Error()) return multistep.ActionHalt } } diff --git a/builder/vmware/step_type_boot_command.go b/builder/vmware/step_type_boot_command.go index 0eb09b561..07e5f0574 100644 --- a/builder/vmware/step_type_boot_command.go +++ b/builder/vmware/step_type_boot_command.go @@ -45,14 +45,18 @@ func (s *stepTypeBootCommand) Run(state map[string]interface{}) multistep.StepAc ui.Say("Connecting to VM via VNC") nc, err := net.Dial("tcp", fmt.Sprintf("127.0.0.1:%d", vncPort)) if err != nil { - ui.Error(fmt.Sprintf("Error connecting to VNC: %s", err)) + err := fmt.Errorf("Error connecting to VNC: %s", err) + state["error"] = err + ui.Error(err.Error()) return multistep.ActionHalt } defer nc.Close() c, err := vnc.Client(nc, &vnc.ClientConfig{Exclusive: true}) if err != nil { - ui.Error(fmt.Sprintf("Error handshaking with VNC: %s", err)) + err := fmt.Errorf("Error handshaking with VNC: %s", err) + state["error"] = err + ui.Error(err.Error()) return multistep.ActionHalt } defer c.Close() @@ -63,7 +67,9 @@ func (s *stepTypeBootCommand) Run(state map[string]interface{}) multistep.StepAc ipFinder := &IfconfigIPFinder{"vmnet8"} hostIp, err := ipFinder.HostIP() if err != nil { - ui.Error(fmt.Sprintf("Error detecting host IP: %s", err)) + err := fmt.Errorf("Error detecting host IP: %s", err) + state["error"] = err + ui.Error(err.Error()) return multistep.ActionHalt }