From 7db824f4573dd4ddb15ea4a2abcda8a224a52dcb Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 19 Jun 2013 21:00:51 -0700 Subject: [PATCH] builder/digitalocean: Properly return errors --- builder/digitalocean/builder.go | 5 +++++ builder/digitalocean/step_connect_ssh.go | 13 ++++++++++--- builder/digitalocean/step_create_droplet.go | 3 ++- builder/digitalocean/step_create_ssh_key.go | 3 ++- builder/digitalocean/step_droplet_info.go | 7 +++++-- builder/digitalocean/step_power_off.go | 6 +++++- builder/digitalocean/step_snapshot.go | 11 ++++++++++- 7 files changed, 39 insertions(+), 9 deletions(-) diff --git a/builder/digitalocean/builder.go b/builder/digitalocean/builder.go index a45b15d87..a9224ae7e 100644 --- a/builder/digitalocean/builder.go +++ b/builder/digitalocean/builder.go @@ -184,6 +184,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) + } + if _, ok := state["snapshot_name"]; !ok { log.Println("Failed to find snapshot_name in state. Bug?") return nil, nil diff --git a/builder/digitalocean/step_connect_ssh.go b/builder/digitalocean/step_connect_ssh.go index e7af18628..d764a35d3 100644 --- a/builder/digitalocean/step_connect_ssh.go +++ b/builder/digitalocean/step_connect_ssh.go @@ -2,6 +2,7 @@ package digitalocean import ( gossh "code.google.com/p/go.crypto/ssh" + "errors" "fmt" "github.com/mitchellh/multistep" "github.com/mitchellh/packer/communicator/ssh" @@ -26,7 +27,9 @@ func (s *stepConnectSSH) Run(state map[string]interface{}) multistep.StepAction keyring := &ssh.SimpleKeychain{} err := keyring.AddPEMKey(privateKey) if err != nil { - ui.Say(fmt.Sprintf("Error setting up SSH config: %s", err)) + err := fmt.Errorf("Error setting up SSH config: %s", err) + state["error"] = err + ui.Error(err.Error()) return multistep.ActionHalt } @@ -87,7 +90,9 @@ ConnectWaitLoop: // We connected. Just break the loop. break ConnectWaitLoop case <-timeout: - ui.Error("Timeout while waiting to connect to SSH.") + err := errors.New("Timeout waiting for SSH to become available.") + state["error"] = err + ui.Error(err.Error()) return multistep.ActionHalt case <-time.After(1 * time.Second): if _, ok := state[multistep.StateCancelled]; ok { @@ -103,7 +108,9 @@ ConnectWaitLoop: } if err != nil { - ui.Error(fmt.Sprintf("Error connecting to SSH: %s", err)) + err := fmt.Errorf("Error connecting to SSH: %s", err) + state["error"] = err + ui.Error(err.Error()) return multistep.ActionHalt } diff --git a/builder/digitalocean/step_create_droplet.go b/builder/digitalocean/step_create_droplet.go index 1a2dff3e3..d4e538f30 100644 --- a/builder/digitalocean/step_create_droplet.go +++ b/builder/digitalocean/step_create_droplet.go @@ -27,8 +27,9 @@ func (s *stepCreateDroplet) Run(state map[string]interface{}) multistep.StepActi // Create the droplet based on configuration dropletId, err := client.CreateDroplet(name, c.SizeID, c.ImageID, c.RegionID, sshKeyId) - if err != nil { + err := fmt.Errorf("Error creating droplet: %s", err) + state["error"] = err ui.Error(err.Error()) return multistep.ActionHalt } diff --git a/builder/digitalocean/step_create_ssh_key.go b/builder/digitalocean/step_create_ssh_key.go index 6f0025a92..ecadd92ef 100644 --- a/builder/digitalocean/step_create_ssh_key.go +++ b/builder/digitalocean/step_create_ssh_key.go @@ -46,8 +46,9 @@ func (s *stepCreateSSHKey) Run(state map[string]interface{}) multistep.StepActio // Create the key! keyId, err := client.CreateKey(name, pub_sshformat) - if err != nil { + err := fmt.Errorf("Error creating temporary SSH key: %s", err) + state["error"] = err ui.Error(err.Error()) return multistep.ActionHalt } diff --git a/builder/digitalocean/step_droplet_info.go b/builder/digitalocean/step_droplet_info.go index ba3fb6987..8e9b5693d 100644 --- a/builder/digitalocean/step_droplet_info.go +++ b/builder/digitalocean/step_droplet_info.go @@ -1,6 +1,7 @@ package digitalocean import ( + "fmt" "github.com/mitchellh/multistep" "github.com/mitchellh/packer/packer" ) @@ -15,16 +16,18 @@ func (s *stepDropletInfo) Run(state map[string]interface{}) multistep.StepAction ui.Say("Waiting for droplet to become active...") err := waitForDropletState("active", dropletId, client) - if err != nil { + err := fmt.Errorf("Error waiting for droplet to become active: %s", err) + state["error"] = err ui.Error(err.Error()) return multistep.ActionHalt } // Set the IP on the state for later ip, _, err := client.DropletStatus(dropletId) - if err != nil { + err := fmt.Errorf("Error retrieving droplet ID: %s", err) + state["error"] = err ui.Error(err.Error()) return multistep.ActionHalt } diff --git a/builder/digitalocean/step_power_off.go b/builder/digitalocean/step_power_off.go index 87bab6bb1..f0d85fe94 100644 --- a/builder/digitalocean/step_power_off.go +++ b/builder/digitalocean/step_power_off.go @@ -1,6 +1,7 @@ package digitalocean import ( + "fmt" "github.com/mitchellh/multistep" "github.com/mitchellh/packer/packer" "log" @@ -25,6 +26,8 @@ func (s *stepPowerOff) Run(state map[string]interface{}) multistep.StepAction { err := client.PowerOffDroplet(dropletId) if err != nil { + err := fmt.Errorf("Error powering off droplet: %s", err) + state["error"] = err ui.Error(err.Error()) return multistep.ActionHalt } @@ -32,8 +35,9 @@ func (s *stepPowerOff) Run(state map[string]interface{}) multistep.StepAction { ui.Say("Waiting for droplet to power off...") err = waitForDropletState("off", dropletId, client) - if err != nil { + err := fmt.Errorf("Error waiting for droplet to become 'off': %s", err) + state["error"] = err ui.Error(err.Error()) return multistep.ActionHalt } diff --git a/builder/digitalocean/step_snapshot.go b/builder/digitalocean/step_snapshot.go index 15fa02a1b..8ec3e68e7 100644 --- a/builder/digitalocean/step_snapshot.go +++ b/builder/digitalocean/step_snapshot.go @@ -1,6 +1,7 @@ package digitalocean import ( + "errors" "fmt" "github.com/mitchellh/multistep" "github.com/mitchellh/packer/packer" @@ -18,6 +19,8 @@ func (s *stepSnapshot) Run(state map[string]interface{}) multistep.StepAction { ui.Say(fmt.Sprintf("Creating snapshot: %v", c.SnapshotName)) err := client.CreateSnapshot(dropletId, c.SnapshotName) if err != nil { + err := fmt.Errorf("Error creating snapshot: %s", err) + state["error"] = err ui.Error(err.Error()) return multistep.ActionHalt } @@ -25,6 +28,8 @@ func (s *stepSnapshot) Run(state map[string]interface{}) multistep.StepAction { ui.Say("Waiting for snapshot to complete...") err = waitForDropletState("active", dropletId, client) if err != nil { + err := fmt.Errorf("Error waiting for snapshot to complete: %s", err) + state["error"] = err ui.Error(err.Error()) return multistep.ActionHalt } @@ -32,6 +37,8 @@ func (s *stepSnapshot) Run(state map[string]interface{}) multistep.StepAction { log.Printf("Looking up snapshot ID for snapshot: %s", c.SnapshotName) images, err := client.Images() if err != nil { + err := fmt.Errorf("Error looking up snapshot ID: %s", err) + state["error"] = err ui.Error(err.Error()) return multistep.ActionHalt } @@ -45,7 +52,9 @@ func (s *stepSnapshot) Run(state map[string]interface{}) multistep.StepAction { } if imageId == 0 { - ui.Error("Couldn't find snapshot to get the image ID. Bug?") + err := errors.New("Couldn't find snapshot to get the image ID. Bug?") + state["error"] = err + ui.Error(err.Error()) return multistep.ActionHalt }