builder/vmware: properly handle errors

This commit is contained in:
Mitchell Hashimoto 2013-06-19 21:20:48 -07:00
parent 64aed2b34a
commit 6d3b09c542
9 changed files with 52 additions and 16 deletions

View File

@ -225,15 +225,21 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
} else { } else {
b.runner = &multistep.BasicRunner{Steps: steps} b.runner = &multistep.BasicRunner{Steps: steps}
} }
b.runner.Run(state) 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 we were interrupted or cancelled, then just exit.
if _, ok := state[multistep.StateCancelled]; ok { if _, ok := state[multistep.StateCancelled]; ok {
return nil, nil return nil, errors.New("Build was cancelled.")
} }
if _, ok := state[multistep.StateHalted]; ok { if _, ok := state[multistep.StateHalted]; ok {
return nil, nil return nil, errors.New("Build was halted.")
} }
// Compile the artifact list // Compile the artifact list

View File

@ -29,13 +29,17 @@ func (stepConfigureVNC) Run(state map[string]interface{}) multistep.StepAction {
f, err := os.Open(vmxPath) f, err := os.Open(vmxPath)
if err != nil { 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 return multistep.ActionHalt
} }
vmxBytes, err := ioutil.ReadAll(f) vmxBytes, err := ioutil.ReadAll(f)
if err != nil { 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 return multistep.ActionHalt
} }
@ -62,7 +66,9 @@ func (stepConfigureVNC) Run(state map[string]interface{}) multistep.StepAction {
vmxData["RemoteDisplay.vnc.port"] = fmt.Sprintf("%d", vncPort) vmxData["RemoteDisplay.vnc.port"] = fmt.Sprintf("%d", vncPort)
if err := WriteVMX(vmxPath, vmxData); err != nil { 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 return multistep.ActionHalt
} }

View File

@ -29,7 +29,9 @@ func (stepCreateDisk) Run(state map[string]interface{}) multistep.StepAction {
ui.Say("Creating virtual machine disk") ui.Say("Creating virtual machine disk")
output := filepath.Join(config.OutputDir, config.DiskName+".vmdk") output := filepath.Join(config.OutputDir, config.DiskName+".vmdk")
if err := driver.CreateDisk(output, "40000M"); err != nil { 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 return multistep.ActionHalt
} }

View File

@ -57,7 +57,9 @@ func (stepCreateVMX) Run(state map[string]interface{}) multistep.StepAction {
vmxPath := filepath.Join(config.OutputDir, config.VMName+".vmx") vmxPath := filepath.Join(config.OutputDir, config.VMName+".vmx")
if err := WriteVMX(vmxPath, vmxData); err != nil { 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 return multistep.ActionHalt
} }

View File

@ -29,7 +29,9 @@ func (s stepDownloadISO) Run(state map[string]interface{}) multistep.StepAction
checksum, err := hex.DecodeString(config.ISOMD5) checksum, err := hex.DecodeString(config.ISOMD5)
if err != nil { 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 return multistep.ActionHalt
} }
@ -62,7 +64,9 @@ DownloadWaitLoop:
select { select {
case err := <-downloadCompleteCh: case err := <-downloadCompleteCh:
if err != nil { 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 break DownloadWaitLoop

View File

@ -11,6 +11,7 @@ func (stepPrepareOutputDir) Run(state map[string]interface{}) multistep.StepActi
config := state["config"].(*config) config := state["config"].(*config)
if err := os.MkdirAll(config.OutputDir, 0755); err != nil { if err := os.MkdirAll(config.OutputDir, 0755); err != nil {
state["error"] = err
return multistep.ActionHalt return multistep.ActionHalt
} }

View File

@ -34,7 +34,9 @@ func (s *stepRun) Run(state map[string]interface{}) multistep.StepAction {
ui.Say("Starting virtual machine...") ui.Say("Starting virtual machine...")
if err := driver.Start(vmxPath); err != nil { 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 return multistep.ActionHalt
} }

View File

@ -1,6 +1,7 @@
package vmware package vmware
import ( import (
"errors"
"fmt" "fmt"
"github.com/mitchellh/multistep" "github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer" "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) log.Printf("Executing shutdown command: %s", config.ShutdownCommand)
cmd := &packer.RemoteCmd{Command: config.ShutdownCommand} cmd := &packer.RemoteCmd{Command: config.ShutdownCommand}
if err := comm.Start(cmd); err != nil { 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 return multistep.ActionHalt
} }
@ -52,7 +55,9 @@ func (s *stepShutdown) Run(state map[string]interface{}) multistep.StepAction {
select { select {
case <-shutdownTimer: 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 return multistep.ActionHalt
default: default:
time.Sleep(1 * time.Second) time.Sleep(1 * time.Second)
@ -60,7 +65,9 @@ func (s *stepShutdown) Run(state map[string]interface{}) multistep.StepAction {
} }
} else { } else {
if err := driver.Stop(vmxPath); err != nil { 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 return multistep.ActionHalt
} }
} }

View File

@ -45,14 +45,18 @@ func (s *stepTypeBootCommand) Run(state map[string]interface{}) multistep.StepAc
ui.Say("Connecting to VM via VNC") ui.Say("Connecting to VM via VNC")
nc, err := net.Dial("tcp", fmt.Sprintf("127.0.0.1:%d", vncPort)) nc, err := net.Dial("tcp", fmt.Sprintf("127.0.0.1:%d", vncPort))
if err != nil { 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 return multistep.ActionHalt
} }
defer nc.Close() defer nc.Close()
c, err := vnc.Client(nc, &vnc.ClientConfig{Exclusive: true}) c, err := vnc.Client(nc, &vnc.ClientConfig{Exclusive: true})
if err != nil { 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 return multistep.ActionHalt
} }
defer c.Close() defer c.Close()
@ -63,7 +67,9 @@ func (s *stepTypeBootCommand) Run(state map[string]interface{}) multistep.StepAc
ipFinder := &IfconfigIPFinder{"vmnet8"} ipFinder := &IfconfigIPFinder{"vmnet8"}
hostIp, err := ipFinder.HostIP() hostIp, err := ipFinder.HostIP()
if err != nil { 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 return multistep.ActionHalt
} }