commit
4ead224c3b
|
@ -1,4 +1,4 @@
|
||||||
package common
|
package retry
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -15,7 +15,7 @@ var RetryExhaustedError error = fmt.Errorf("Function never succeeded in Retry")
|
||||||
type RetryableFunc func(uint) (bool, error)
|
type RetryableFunc func(uint) (bool, error)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Retry retries a function up to numTries times with exponential backoff.
|
Run retries a function up to numTries times with exponential backoff.
|
||||||
If numTries == 0, retry indefinitely.
|
If numTries == 0, retry indefinitely.
|
||||||
If interval == 0, Retry will not delay retrying and there will be no
|
If interval == 0, Retry will not delay retrying and there will be no
|
||||||
exponential backoff.
|
exponential backoff.
|
||||||
|
@ -24,7 +24,7 @@ Intervals are in seconds.
|
||||||
Returns an error if initial > max intervals, if retries are exhausted, or if the passed function returns
|
Returns an error if initial > max intervals, if retries are exhausted, or if the passed function returns
|
||||||
an error.
|
an error.
|
||||||
*/
|
*/
|
||||||
func Retry(initialInterval float64, maxInterval float64, numTries uint, function RetryableFunc) error {
|
func Run(initialInterval float64, maxInterval float64, numTries uint, function RetryableFunc) error {
|
||||||
if maxInterval == 0 {
|
if maxInterval == 0 {
|
||||||
maxInterval = math.Inf(1)
|
maxInterval = math.Inf(1)
|
||||||
} else if initialInterval < 0 || initialInterval > maxInterval {
|
} else if initialInterval < 0 || initialInterval > maxInterval {
|
|
@ -1,4 +1,4 @@
|
||||||
package common
|
package retry
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -8,7 +8,7 @@ import (
|
||||||
func TestRetry(t *testing.T) {
|
func TestRetry(t *testing.T) {
|
||||||
numTries := uint(0)
|
numTries := uint(0)
|
||||||
// Test that a passing function only gets called once.
|
// Test that a passing function only gets called once.
|
||||||
err := Retry(0, 0, 0, func(i uint) (bool, error) {
|
err := Run(0, 0, 0, func(i uint) (bool, error) {
|
||||||
numTries++
|
numTries++
|
||||||
return true, nil
|
return true, nil
|
||||||
})
|
})
|
||||||
|
@ -22,7 +22,7 @@ func TestRetry(t *testing.T) {
|
||||||
// Test that a failing function gets retried (once in this example).
|
// Test that a failing function gets retried (once in this example).
|
||||||
numTries = 0
|
numTries = 0
|
||||||
results := []bool{false, true}
|
results := []bool{false, true}
|
||||||
err = Retry(0, 0, 0, func(i uint) (bool, error) {
|
err = Run(0, 0, 0, func(i uint) (bool, error) {
|
||||||
result := results[numTries]
|
result := results[numTries]
|
||||||
numTries++
|
numTries++
|
||||||
return result, nil
|
return result, nil
|
||||||
|
@ -37,7 +37,7 @@ func TestRetry(t *testing.T) {
|
||||||
// Test that a function error gets returned, and the function does not get called again.
|
// Test that a function error gets returned, and the function does not get called again.
|
||||||
numTries = 0
|
numTries = 0
|
||||||
funcErr := fmt.Errorf("This function had an error!")
|
funcErr := fmt.Errorf("This function had an error!")
|
||||||
err = Retry(0, 0, 0, func(i uint) (bool, error) {
|
err = Run(0, 0, 0, func(i uint) (bool, error) {
|
||||||
numTries++
|
numTries++
|
||||||
return false, funcErr
|
return false, funcErr
|
||||||
})
|
})
|
||||||
|
@ -51,7 +51,7 @@ func TestRetry(t *testing.T) {
|
||||||
// Test when a function exhausts its retries.
|
// Test when a function exhausts its retries.
|
||||||
numTries = 0
|
numTries = 0
|
||||||
expectedTries := uint(3)
|
expectedTries := uint(3)
|
||||||
err = Retry(0, 0, expectedTries, func(i uint) (bool, error) {
|
err = Run(0, 0, expectedTries, func(i uint) (bool, error) {
|
||||||
numTries++
|
numTries++
|
||||||
return false, nil
|
return false, nil
|
||||||
})
|
})
|
|
@ -6,7 +6,7 @@ import (
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/antihax/optional"
|
"github.com/antihax/optional"
|
||||||
"github.com/hashicorp/packer/common"
|
"github.com/hashicorp/packer/builder/osc/common/retry"
|
||||||
"github.com/outscale/osc-sdk-go/osc"
|
"github.com/outscale/osc-sdk-go/osc"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ func WaitUntilOscSnapshotDone(conn *osc.APIClient, snapshotID string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func waitForState(errCh chan<- error, target string, refresh stateRefreshFunc) {
|
func waitForState(errCh chan<- error, target string, refresh stateRefreshFunc) {
|
||||||
err := common.Retry(2, 2, 0, func(_ uint) (bool, error) {
|
err := retry.Run(2, 2, 0, func(_ uint) (bool, error) {
|
||||||
state, err := refresh()
|
state, err := refresh()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
|
|
||||||
"github.com/antihax/optional"
|
"github.com/antihax/optional"
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
retry "github.com/hashicorp/packer/common"
|
"github.com/hashicorp/packer/builder/osc/common/retry"
|
||||||
"github.com/hashicorp/packer/helper/multistep"
|
"github.com/hashicorp/packer/helper/multistep"
|
||||||
"github.com/hashicorp/packer/packer"
|
"github.com/hashicorp/packer/packer"
|
||||||
"github.com/hashicorp/packer/packer-plugin-sdk/template/interpolate"
|
"github.com/hashicorp/packer/packer-plugin-sdk/template/interpolate"
|
||||||
|
@ -90,7 +90,7 @@ func (s *StepCreateTags) Run(_ context.Context, state multistep.StateBag) multis
|
||||||
snapshotTags.Report(ui)
|
snapshotTags.Report(ui)
|
||||||
|
|
||||||
// Retry creating tags for about 2.5 minutes
|
// Retry creating tags for about 2.5 minutes
|
||||||
err = retry.Retry(0.2, 30, 11, func(_ uint) (bool, error) {
|
err = retry.Run(0.2, 30, 11, func(_ uint) (bool, error) {
|
||||||
// Tag images and snapshots
|
// Tag images and snapshots
|
||||||
_, _, err := regionconn.TagApi.CreateTags(context.Background(), &osc.CreateTagsOpts{
|
_, _, err := regionconn.TagApi.CreateTags(context.Background(), &osc.CreateTagsOpts{
|
||||||
CreateTagsRequest: optional.NewInterface(osc.CreateTagsRequest{
|
CreateTagsRequest: optional.NewInterface(osc.CreateTagsRequest{
|
||||||
|
|
|
@ -12,7 +12,7 @@ import (
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
"github.com/outscale/osc-sdk-go/osc"
|
"github.com/outscale/osc-sdk-go/osc"
|
||||||
|
|
||||||
retry "github.com/hashicorp/packer/common"
|
"github.com/hashicorp/packer/builder/osc/common/retry"
|
||||||
"github.com/hashicorp/packer/helper/communicator"
|
"github.com/hashicorp/packer/helper/communicator"
|
||||||
"github.com/hashicorp/packer/helper/multistep"
|
"github.com/hashicorp/packer/helper/multistep"
|
||||||
"github.com/hashicorp/packer/packer"
|
"github.com/hashicorp/packer/packer"
|
||||||
|
@ -234,7 +234,7 @@ func (s *StepRunSourceVm) Run(ctx context.Context, state multistep.StateBag) mul
|
||||||
if s.IsRestricted {
|
if s.IsRestricted {
|
||||||
oscTags.Report(ui)
|
oscTags.Report(ui)
|
||||||
// Retry creating tags for about 2.5 minutes
|
// Retry creating tags for about 2.5 minutes
|
||||||
err = retry.Retry(0.2, 30, 11, func(_ uint) (bool, error) {
|
err = retry.Run(0.2, 30, 11, func(_ uint) (bool, error) {
|
||||||
_, _, err := oscconn.TagApi.CreateTags(context.Background(), &osc.CreateTagsOpts{
|
_, _, err := oscconn.TagApi.CreateTags(context.Background(), &osc.CreateTagsOpts{
|
||||||
CreateTagsRequest: optional.NewInterface(osc.CreateTagsRequest{
|
CreateTagsRequest: optional.NewInterface(osc.CreateTagsRequest{
|
||||||
Tags: oscTags,
|
Tags: oscTags,
|
||||||
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
|
|
||||||
"github.com/antihax/optional"
|
"github.com/antihax/optional"
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
"github.com/hashicorp/packer/common"
|
"github.com/hashicorp/packer/builder/osc/common/retry"
|
||||||
"github.com/hashicorp/packer/helper/multistep"
|
"github.com/hashicorp/packer/helper/multistep"
|
||||||
"github.com/hashicorp/packer/packer"
|
"github.com/hashicorp/packer/packer"
|
||||||
"github.com/outscale/osc-sdk-go/osc"
|
"github.com/outscale/osc-sdk-go/osc"
|
||||||
|
@ -41,7 +41,7 @@ func (s *StepStopBSUBackedVm) Run(ctx context.Context, state multistep.StateBag)
|
||||||
// does not exist.
|
// does not exist.
|
||||||
|
|
||||||
// Work around this by retrying a few times, up to about 5 minutes.
|
// Work around this by retrying a few times, up to about 5 minutes.
|
||||||
err := common.Retry(10, 60, 6, func(i uint) (bool, error) {
|
err := retry.Run(10, 60, 6, func(i uint) (bool, error) {
|
||||||
ui.Message(fmt.Sprintf("Stopping vm, attempt %d", i+1))
|
ui.Message(fmt.Sprintf("Stopping vm, attempt %d", i+1))
|
||||||
|
|
||||||
_, _, err = oscconn.VmApi.StopVms(context.Background(), &osc.StopVmsOpts{
|
_, _, err = oscconn.VmApi.StopVms(context.Background(), &osc.StopVmsOpts{
|
||||||
|
|
|
@ -7,7 +7,6 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/hashicorp/packer/common"
|
|
||||||
"github.com/hashicorp/packer/common/retry"
|
"github.com/hashicorp/packer/common/retry"
|
||||||
"github.com/hashicorp/packer/helper/multistep"
|
"github.com/hashicorp/packer/helper/multistep"
|
||||||
"github.com/hashicorp/packer/packer"
|
"github.com/hashicorp/packer/packer"
|
||||||
|
@ -62,12 +61,13 @@ func (s *stepConvertDisk) Run(ctx context.Context, state multistep.StateBag) mul
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == common.RetryExhaustedError {
|
switch err.(type) {
|
||||||
|
case *retry.RetryExhaustedError:
|
||||||
err = fmt.Errorf("Exhausted retries for getting file lock: %s", err)
|
err = fmt.Errorf("Exhausted retries for getting file lock: %s", err)
|
||||||
state.Put("error", err)
|
state.Put("error", err)
|
||||||
ui.Error(err.Error())
|
ui.Error(err.Error())
|
||||||
return multistep.ActionHalt
|
return multistep.ActionHalt
|
||||||
} else {
|
default:
|
||||||
err := fmt.Errorf("Error converting hard drive: %s", err)
|
err := fmt.Errorf("Error converting hard drive: %s", err)
|
||||||
state.Put("error", err)
|
state.Put("error", err)
|
||||||
ui.Error(err.Error())
|
ui.Error(err.Error())
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
package common
|
|
||||||
|
|
||||||
// call into one of the platform-specific implementations to get the current terminal dimensions
|
|
||||||
func GetTerminalDimensions() (width, height int, err error) {
|
|
||||||
return platformGetTerminalDimensions()
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
// +build !windows
|
|
||||||
|
|
||||||
package common
|
|
||||||
|
|
||||||
// Imports for determining terminal information across platforms
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
|
||||||
|
|
||||||
// posix api
|
|
||||||
func platformGetTerminalDimensions() (width, height int, err error) {
|
|
||||||
|
|
||||||
// grab the handle to stdin
|
|
||||||
// XXX: in some cases, packer closes stdin, so the following can't be guaranteed
|
|
||||||
/*
|
|
||||||
tty := os.Stdin
|
|
||||||
*/
|
|
||||||
|
|
||||||
// open up a handle to the current tty
|
|
||||||
tty, err := os.Open("/dev/tty")
|
|
||||||
if err != nil {
|
|
||||||
return 0, 0, err
|
|
||||||
}
|
|
||||||
defer tty.Close()
|
|
||||||
|
|
||||||
// convert the handle into a file descriptor
|
|
||||||
fd := int(tty.Fd())
|
|
||||||
|
|
||||||
// use it to make an Ioctl
|
|
||||||
ws, err := unix.IoctlGetWinsize(fd, unix.TIOCGWINSZ)
|
|
||||||
if err != nil {
|
|
||||||
return 0, 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// return the width and height
|
|
||||||
return int(ws.Col), int(ws.Row), nil
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
package common
|
|
||||||
|
|
||||||
import "testing"
|
|
||||||
|
|
||||||
func TestGetTerminalDimensions(t *testing.T) {
|
|
||||||
if _, _, err := GetTerminalDimensions(); err != nil {
|
|
||||||
t.Fatalf("Unable to get terminal dimensions: %s", err)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,86 +0,0 @@
|
||||||
// +build windows
|
|
||||||
|
|
||||||
package common
|
|
||||||
|
|
||||||
import (
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
// windows constants and structures pulled from msdn
|
|
||||||
const (
|
|
||||||
_STD_INPUT_HANDLE = -10
|
|
||||||
_STD_OUTPUT_HANDLE = -11
|
|
||||||
_STD_ERROR_HANDLE = -12
|
|
||||||
)
|
|
||||||
|
|
||||||
type (
|
|
||||||
_SHORT int16
|
|
||||||
_WORD uint16
|
|
||||||
|
|
||||||
_SMALL_RECT struct {
|
|
||||||
Left, Top, Right, Bottom _SHORT
|
|
||||||
}
|
|
||||||
_COORD struct {
|
|
||||||
X, Y _SHORT
|
|
||||||
}
|
|
||||||
_CONSOLE_SCREEN_BUFFER_INFO struct {
|
|
||||||
dwSize, dwCursorPosition _COORD
|
|
||||||
wAttributes _WORD
|
|
||||||
srWindow _SMALL_RECT
|
|
||||||
dwMaximumWindowSize _COORD
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// Low-level functions that call into Windows API for getting console info
|
|
||||||
var kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
|
||||||
var kernel32_GetStdHandleProc = kernel32.NewProc("GetStdHandle")
|
|
||||||
var kernel32_GetConsoleScreenBufferInfoProc = kernel32.NewProc("GetConsoleScreenBufferInfo")
|
|
||||||
|
|
||||||
func kernel32_GetStdHandle(nStdHandle int32) (syscall.Handle, error) {
|
|
||||||
res, _, err := kernel32_GetStdHandleProc.Call(uintptr(nStdHandle))
|
|
||||||
if res == uintptr(syscall.InvalidHandle) {
|
|
||||||
return syscall.InvalidHandle, error(err)
|
|
||||||
}
|
|
||||||
return syscall.Handle(res), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func kernel32_GetConsoleScreenBufferInfo(hConsoleOutput syscall.Handle, info *_CONSOLE_SCREEN_BUFFER_INFO) error {
|
|
||||||
ok, _, err := kernel32_GetConsoleScreenBufferInfoProc.Call(uintptr(hConsoleOutput), uintptr(unsafe.Pointer(info)))
|
|
||||||
if int(ok) == 0 {
|
|
||||||
return error(err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// windows api to get the console screen buffer info
|
|
||||||
func getConsoleScreenBufferInfo(csbi *_CONSOLE_SCREEN_BUFFER_INFO) (err error) {
|
|
||||||
var (
|
|
||||||
bi _CONSOLE_SCREEN_BUFFER_INFO
|
|
||||||
fd syscall.Handle
|
|
||||||
)
|
|
||||||
|
|
||||||
// Re-open CONOUT$ as in some instances, stdout may be closed and guaranteed an stdout
|
|
||||||
if fd, err = syscall.Open("CONOUT$", syscall.O_RDWR, 0); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer syscall.Close(fd)
|
|
||||||
|
|
||||||
// grab the dimensions for the console
|
|
||||||
if err = kernel32_GetConsoleScreenBufferInfo(fd, &bi); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
*csbi = bi
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func platformGetTerminalDimensions() (width, height int, err error) {
|
|
||||||
var csbi _CONSOLE_SCREEN_BUFFER_INFO
|
|
||||||
|
|
||||||
if err = getConsoleScreenBufferInfo(&csbi); err != nil {
|
|
||||||
return 0, 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return int(csbi.dwSize.X), int(csbi.dwSize.Y), nil
|
|
||||||
}
|
|
Loading…
Reference in New Issue