Merge pull request #5512 from hashicorp/fix5501

builder/virtualbox-ovf retry removing VM.
This commit is contained in:
Matthew Hooker 2017-11-06 15:56:08 -08:00 committed by GitHub
commit 68fa09c308
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 28 additions and 23 deletions

View File

@ -9,6 +9,8 @@ import (
"strconv" "strconv"
"strings" "strings"
"time" "time"
packer "github.com/hashicorp/packer/common"
) )
type VBox42Driver struct { type VBox42Driver struct {
@ -50,7 +52,15 @@ func (d *VBox42Driver) CreateSCSIController(vmName string, name string) error {
} }
func (d *VBox42Driver) Delete(name string) error { func (d *VBox42Driver) Delete(name string) error {
return d.VBoxManage("unregistervm", name, "--delete") return packer.Retry(1, 1, 5, func(i uint) (bool, error) {
if err := d.VBoxManage("unregistervm", name, "--delete"); err != nil {
if i+1 == 5 {
return false, err
}
return false, nil
}
return true, nil
})
} }
func (d *VBox42Driver) Iso() (string, error) { func (d *VBox42Driver) Iso() (string, error) {

View File

@ -2,10 +2,10 @@ package iso
import ( import (
"fmt" "fmt"
vboxcommon "github.com/hashicorp/packer/builder/virtualbox/common" vboxcommon "github.com/hashicorp/packer/builder/virtualbox/common"
"github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/packer"
"github.com/mitchellh/multistep" "github.com/mitchellh/multistep"
"time"
) )
// This step creates the actual virtual machine. // This step creates the actual virtual machine.
@ -73,18 +73,8 @@ func (s *stepCreateVM) Cleanup(state multistep.StateBag) {
return return
} }
ui.Say("Unregistering and deleting virtual machine...") ui.Say("Deregistering and deleting VM...")
var err error = nil if err := driver.Delete(s.vmName); err != nil {
for i := 0; i < 5; i++ { ui.Error(fmt.Sprintf("Error deleting VM: %s", err))
err = driver.Delete(s.vmName)
if err == nil {
break
}
time.Sleep(1 * time.Second * time.Duration(i))
}
if err != nil {
ui.Error(fmt.Sprintf("Error deleting virtual machine: %s", err))
} }
} }

View File

@ -2,6 +2,7 @@ package ovf
import ( import (
"fmt" "fmt"
vboxcommon "github.com/hashicorp/packer/builder/virtualbox/common" vboxcommon "github.com/hashicorp/packer/builder/virtualbox/common"
"github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/packer"
"github.com/mitchellh/multistep" "github.com/mitchellh/multistep"
@ -49,7 +50,7 @@ func (s *StepImport) Cleanup(state multistep.StateBag) {
return return
} }
ui.Say("Unregistering and deleting imported VM...") ui.Say("Deregistering and deleting imported VM...")
if err := driver.Delete(s.vmName); err != nil { if err := driver.Delete(s.vmName); err != nil {
ui.Error(fmt.Sprintf("Error deleting VM: %s", err)) ui.Error(fmt.Sprintf("Error deleting VM: %s", err))
} }

View File

@ -9,17 +9,21 @@ import (
var RetryExhaustedError error = fmt.Errorf("Function never succeeded in Retry") var RetryExhaustedError error = fmt.Errorf("Function never succeeded in Retry")
// RetryableFunc performs an action and returns a bool indicating whether the // RetryableFunc performs an action and returns a bool indicating whether the
// function is done, or if it should keep retrying, and an erorr which will // function is done, or if it should keep retrying, and an error which will
// abort the retry and be returned by the Retry function. The 0-indexed attempt // abort the retry and be returned by the Retry function. The 0-indexed attempt
// is passed with each call. // is passed with each call.
type RetryableFunc func(uint) (bool, error) type RetryableFunc func(uint) (bool, error)
// Retry retries a function up to numTries times with exponential backoff. /*
// If numTries == 0, retry indefinitely. If interval == 0, Retry will not delay retrying and there will be Retry retries a function up to numTries times with exponential backoff.
// no exponential backoff. If maxInterval == 0, maxInterval is set to +Infinity. If numTries == 0, retry indefinitely.
// Intervals are in seconds. If interval == 0, Retry will not delay retrying and there will be no
// Returns an error if initial > max intervals, if retries are exhausted, or if the passed function returns exponential backoff.
// an error. If maxInterval == 0, maxInterval is set to +Infinity.
Intervals are in seconds.
Returns an error if initial > max intervals, if retries are exhausted, or if the passed function returns
an error.
*/
func Retry(initialInterval float64, maxInterval float64, numTries uint, function RetryableFunc) error { func Retry(initialInterval float64, maxInterval float64, numTries uint, function RetryableFunc) error {
if maxInterval == 0 { if maxInterval == 0 {
maxInterval = math.Inf(1) maxInterval = math.Inf(1)