From 2b2c860df8190ff5de32639822745a5d9676dc47 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Thu, 28 Jun 2018 14:21:28 -0700 Subject: [PATCH] make the convert retryable in case it takes a bit to release a lock --- builder/qemu/step_convert_disk.go | 33 ++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/builder/qemu/step_convert_disk.go b/builder/qemu/step_convert_disk.go index bc5c3f3b1..299c36e65 100644 --- a/builder/qemu/step_convert_disk.go +++ b/builder/qemu/step_convert_disk.go @@ -4,7 +4,9 @@ import ( "context" "fmt" "path/filepath" + "strings" + "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" @@ -46,11 +48,32 @@ func (s *stepConvertDisk) Run(_ context.Context, state multistep.StateBag) multi ) ui.Say("Converting hard drive...") - if err := driver.QemuImg(command...); err != nil { - err := fmt.Errorf("Error converting hard drive: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt + // Retry the conversion a few times in case it takes the qemu process a + // moment to release the lock + err := common.Retry(1, 10, 10, func(_ uint) (bool, error) { + if err := driver.QemuImg(command...); err != nil { + if strings.Contains(err.Error(), `Failed to get shared "write" lock`) { + ui.Say("Error getting file lock for conversion; retrying...") + return false, nil + } + err = fmt.Errorf("Error converting hard drive: %s", err) + return true, err + } + return true, nil + }) + + if err != nil { + if err == common.RetryExhaustedError { + err = fmt.Errorf("Exhausted retries for getting file lock: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } else { + err := fmt.Errorf("Error converting hard drive: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } } if err := os.Rename(targetPath, sourcePath); err != nil {