Merge pull request #4705 from mitchellh/floppyretry

builder/virtualbox: retry removing floppy controller
This commit is contained in:
Matthew Hooker 2017-03-24 00:01:53 -07:00 committed by GitHub
commit ec12b99cde
2 changed files with 25 additions and 9 deletions

View File

@ -2,7 +2,10 @@ package common
import (
"fmt"
"log"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/common"
"github.com/mitchellh/packer/packer"
)
@ -39,14 +42,25 @@ func (s *StepRemoveDevices) Run(state multistep.StateBag) multistep.StepAction {
return multistep.ActionHalt
}
// Don't forget to remove the floppy controller as well
command = []string{
"storagectl", vmName,
"--name", "Floppy Controller",
"--remove",
}
if err := driver.VBoxManage(command...); err != nil {
err := fmt.Errorf("Error removing floppy controller: %s", err)
var vboxErr error
// Retry for 10 minutes to remove the floppy controller.
log.Printf("Trying for 10 minutes to remove floppy controller.")
err := common.Retry(15, 15, 40, func() (bool, error) {
// Don't forget to remove the floppy controller as well
command = []string{
"storagectl", vmName,
"--name", "Floppy Controller",
"--remove",
}
vboxErr = driver.VBoxManage(command...)
if vboxErr != nil {
log.Printf("Error removing floppy controller. Retrying")
return false, nil
}
return true, nil
})
if err == common.RetryExhaustedError {
err := fmt.Errorf("Error removing floppy controller: %s", vboxErr)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt

View File

@ -8,13 +8,15 @@ import (
var RetryExhaustedError error = fmt.Errorf("Function never succeeded in Retry")
type RetryableFunc func() (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
// no exponential backoff. 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 func() (bool, error)) error {
func Retry(initialInterval float64, maxInterval float64, numTries uint, function RetryableFunc) error {
if maxInterval == 0 {
maxInterval = math.Inf(1)
} else if initialInterval < 0 || initialInterval > maxInterval {