From b8103ff9c0569b64a8dc16fedd168ac9ad0658bd Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 19 Jun 2013 21:07:53 -0700 Subject: [PATCH] builder/virtualbox: properly handle errors --- builder/virtualbox/builder.go | 5 +++++ builder/virtualbox/step_attach_iso.go | 4 +++- builder/virtualbox/step_create_disk.go | 12 +++++++++--- builder/virtualbox/step_create_vm.go | 4 +++- builder/virtualbox/step_download_iso.go | 10 +++++++--- builder/virtualbox/step_export.go | 4 +++- builder/virtualbox/step_forward_ssh.go | 4 +++- builder/virtualbox/step_prepare_output_dir.go | 1 + builder/virtualbox/step_run.go | 4 +++- builder/virtualbox/step_shutdown.go | 13 ++++++++++--- builder/virtualbox/step_suppress_messages.go | 4 +++- builder/virtualbox/step_type_boot_command.go | 4 +++- 12 files changed, 53 insertions(+), 16 deletions(-) diff --git a/builder/virtualbox/builder.go b/builder/virtualbox/builder.go index 7383e010b..fdd30db95 100644 --- a/builder/virtualbox/builder.go +++ b/builder/virtualbox/builder.go @@ -226,6 +226,11 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe b.runner.Run(state) + // If there was an error, return that + if rawErr, ok := state["error"]; ok { + return nil, rawErr.(error) + } + return nil, nil } diff --git a/builder/virtualbox/step_attach_iso.go b/builder/virtualbox/step_attach_iso.go index fe1c4df0c..abcde9469 100644 --- a/builder/virtualbox/step_attach_iso.go +++ b/builder/virtualbox/step_attach_iso.go @@ -31,7 +31,9 @@ func (s *stepAttachISO) Run(state map[string]interface{}) multistep.StepAction { "--medium", isoPath, } if err := driver.VBoxManage(command...); err != nil { - ui.Error(fmt.Sprintf("Error attaching hard drive: %s", err)) + err := fmt.Errorf("Error attaching ISO: %s", err) + state["error"] = err + ui.Error(err.Error()) return multistep.ActionHalt } diff --git a/builder/virtualbox/step_create_disk.go b/builder/virtualbox/step_create_disk.go index a197d1816..e48825e21 100644 --- a/builder/virtualbox/step_create_disk.go +++ b/builder/virtualbox/step_create_disk.go @@ -32,7 +32,9 @@ func (s *stepCreateDisk) Run(state map[string]interface{}) multistep.StepAction ui.Say("Creating hard drive...") err := driver.VBoxManage(command...) if err != nil { - ui.Error(fmt.Sprintf("Error creating hard drive: %s", err)) + err := fmt.Errorf("Error creating hard drive: %s", err) + state["error"] = err + ui.Error(err.Error()) return multistep.ActionHalt } @@ -40,7 +42,9 @@ func (s *stepCreateDisk) Run(state map[string]interface{}) multistep.StepAction controllerName := "IDE Controller" err = driver.VBoxManage("storagectl", vmName, "--name", controllerName, "--add", "ide") if err != nil { - ui.Error(fmt.Sprintf("Error creating disk controller: %s", err)) + err := fmt.Errorf("Error creating disk controller: %s", err) + state["error"] = err + ui.Error(err.Error()) return multistep.ActionHalt } @@ -54,7 +58,9 @@ func (s *stepCreateDisk) Run(state map[string]interface{}) multistep.StepAction "--medium", path, } if err := driver.VBoxManage(command...); err != nil { - ui.Error(fmt.Sprintf("Error attaching hard drive: %s", err)) + err := fmt.Errorf("Error attaching hard drive: %s", err) + state["error"] = err + ui.Error(err.Error()) return multistep.ActionHalt } diff --git a/builder/virtualbox/step_create_vm.go b/builder/virtualbox/step_create_vm.go index 29f07e0dd..3e21c5bd7 100644 --- a/builder/virtualbox/step_create_vm.go +++ b/builder/virtualbox/step_create_vm.go @@ -34,7 +34,9 @@ func (s *stepCreateVM) Run(state map[string]interface{}) multistep.StepAction { for _, command := range commands { err := driver.VBoxManage(command...) if err != nil { - ui.Error(fmt.Sprintf("Error creating VM: %s", err)) + err := fmt.Errorf("Error creating VM: %s", err) + state["error"] = err + ui.Error(err.Error()) return multistep.ActionHalt } diff --git a/builder/virtualbox/step_download_iso.go b/builder/virtualbox/step_download_iso.go index a0fadbf56..a4b19f56a 100644 --- a/builder/virtualbox/step_download_iso.go +++ b/builder/virtualbox/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 } @@ -57,12 +59,14 @@ func (s stepDownloadISO) Run(state map[string]interface{}) multistep.StepAction progressTicker := time.NewTicker(5 * time.Second) defer progressTicker.Stop() -DownloadWaitLoop: + DownloadWaitLoop: for { 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/virtualbox/step_export.go b/builder/virtualbox/step_export.go index d2a04a857..e29aabf0b 100644 --- a/builder/virtualbox/step_export.go +++ b/builder/virtualbox/step_export.go @@ -34,7 +34,9 @@ func (s *stepExport) Run(state map[string]interface{}) multistep.StepAction { ui.Say("Exporting virtual machine...") err := driver.VBoxManage(command...) if err != nil { - ui.Error(fmt.Sprintf("Error exporting virtual machine: %s", err)) + err := fmt.Errorf("Error exporting virtual machine: %s", err) + state["error"] = err + ui.Error(err.Error()) return multistep.ActionHalt } diff --git a/builder/virtualbox/step_forward_ssh.go b/builder/virtualbox/step_forward_ssh.go index 8fcf78f45..aee47bf1c 100644 --- a/builder/virtualbox/step_forward_ssh.go +++ b/builder/virtualbox/step_forward_ssh.go @@ -44,7 +44,9 @@ func (s *stepForwardSSH) Run(state map[string]interface{}) multistep.StepAction fmt.Sprintf("packerssh,tcp,127.0.0.1,%d,,%d", sshHostPort, config.SSHPort), } if err := driver.VBoxManage(command...); err != nil { - ui.Error(fmt.Sprintf("Error creating port forwarding rule: %s", err)) + err := fmt.Errorf("Error creating port forwarding rule: %s", err) + state["error"] = err + ui.Error(err.Error()) return multistep.ActionHalt } diff --git a/builder/virtualbox/step_prepare_output_dir.go b/builder/virtualbox/step_prepare_output_dir.go index 86213cb2d..14e0fc7ff 100644 --- a/builder/virtualbox/step_prepare_output_dir.go +++ b/builder/virtualbox/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/virtualbox/step_run.go b/builder/virtualbox/step_run.go index 18a918f0f..3ac1d22c3 100644 --- a/builder/virtualbox/step_run.go +++ b/builder/virtualbox/step_run.go @@ -25,7 +25,9 @@ func (s *stepRun) Run(state map[string]interface{}) multistep.StepAction { ui.Say("Starting the virtual machine...") command := []string{"startvm", vmName, "--type", "gui"} if err := driver.VBoxManage(command...); 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/virtualbox/step_shutdown.go b/builder/virtualbox/step_shutdown.go index acff92a2b..9b250a843 100644 --- a/builder/virtualbox/step_shutdown.go +++ b/builder/virtualbox/step_shutdown.go @@ -1,6 +1,7 @@ package virtualbox 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) @@ -61,7 +66,9 @@ func (s *stepShutdown) Run(state map[string]interface{}) multistep.StepAction { } else { ui.Say("Halting the virtual machine...") if err := driver.Stop(vmName); 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/virtualbox/step_suppress_messages.go b/builder/virtualbox/step_suppress_messages.go index 4197e47d6..5a6a2acce 100644 --- a/builder/virtualbox/step_suppress_messages.go +++ b/builder/virtualbox/step_suppress_messages.go @@ -17,7 +17,9 @@ func (stepSuppressMessages) Run(state map[string]interface{}) multistep.StepActi log.Println("Suppressing annoying messages in VirtualBox") if err := driver.SuppressMessages(); err != nil { - ui.Error(fmt.Sprintf("Error configuring VirtualBox to suppress messages: %s", err)) + err := fmt.Errorf("Error configuring VirtualBox to suppress messages: %s", err) + state["error"] = err + ui.Error(err.Error()) return multistep.ActionHalt } diff --git a/builder/virtualbox/step_type_boot_command.go b/builder/virtualbox/step_type_boot_command.go index 6257aa435..23d019268 100644 --- a/builder/virtualbox/step_type_boot_command.go +++ b/builder/virtualbox/step_type_boot_command.go @@ -66,7 +66,9 @@ func (s *stepTypeBootCommand) Run(state map[string]interface{}) multistep.StepAc } if err := driver.VBoxManage("controlvm", vmName, "keyboardputscancode", code); err != nil { - ui.Error(fmt.Sprintf("Error sending boot command: %s", err)) + err := fmt.Errorf("Error sending boot command: %s", err) + state["error"] = err + ui.Error(err.Error()) return multistep.ActionHalt } }