Skip to content

Commit

Permalink
post-processor/vagrant-cloud: try upload once
Browse files Browse the repository at this point in the history
* fixes multiple uploads mentioned in hashicorp#4973
* removed unused token code
  • Loading branch information
mwhooker committed Jun 13, 2017
1 parent 6c9d07f commit 94d7a4c
Show file tree
Hide file tree
Showing 11 changed files with 27 additions and 136 deletions.
2 changes: 1 addition & 1 deletion builder/amazon/common/step_create_tags.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ func (s *StepCreateTags) Run(state multistep.StateBag) multistep.StepAction {
ReportTags(ui, snapshotTags)

// Retry creating tags for about 2.5 minutes
err = retry.Retry(0.2, 30, 11, func() (bool, error) {
err = retry.Retry(0.2, 30, 11, func(_ uint) (bool, error) {
// Tag images and snapshots
_, err := regionconn.CreateTags(&ec2.CreateTagsInput{
Resources: resourceIds,
Expand Down
2 changes: 1 addition & 1 deletion builder/amazon/common/step_run_source_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ func (s *StepRunSourceInstance) Run(state multistep.StateBag) multistep.StepActi
ReportTags(ui, ec2Tags)

// Retry creating tags for about 2.5 minutes
err = retry.Retry(0.2, 30, 11, func() (bool, error) {
err = retry.Retry(0.2, 30, 11, func(_ uint) (bool, error) {
_, err := ec2conn.CreateTags(&ec2.CreateTagsInput{
Tags: ec2Tags,
Resources: []*string{instance.InstanceId},
Expand Down
2 changes: 1 addition & 1 deletion builder/googlecompute/driver_gce.go
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,7 @@ type stateRefreshFunc func() (string, error)
// waitForState will spin in a loop forever waiting for state to
// reach a certain target.
func waitForState(errCh chan<- error, target string, refresh stateRefreshFunc) error {
err := common.Retry(2, 2, 0, func() (bool, error) {
err := common.Retry(2, 2, 0, func(_ uint) (bool, error) {
state, err := refresh()
if err != nil {
return false, err
Expand Down
2 changes: 1 addition & 1 deletion builder/googlecompute/step_wait_startup_script.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func (s *StepWaitStartupScript) Run(state multistep.StateBag) multistep.StepActi
ui.Say("Waiting for any running startup script to finish...")

// Keep checking the serial port output to see if the startup script is done.
err := common.Retry(10, 60, 0, func() (bool, error) {
err := common.Retry(10, 60, 0, func(_ uint) (bool, error) {
status, err := driver.GetInstanceMetadata(config.Zone,
instanceName, StartupScriptStatusKey)

Expand Down
2 changes: 1 addition & 1 deletion builder/virtualbox/common/step_remove_devices.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func (s *StepRemoveDevices) Run(state multistep.StateBag) multistep.StepAction {
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) {
err := common.Retry(15, 15, 40, func(_ uint) (bool, error) {
// Don't forget to remove the floppy controller as well
command = []string{
"storagectl", vmName,
Expand Down
8 changes: 6 additions & 2 deletions common/retry.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ import (

var RetryExhaustedError error = fmt.Errorf("Function never succeeded in Retry")

type RetryableFunc func() (bool, error)
// 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
// abort the retry and be returned by the Retry function. The 0-indexed attempt
// is passed with each call.
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
Expand All @@ -27,7 +31,7 @@ func Retry(initialInterval float64, maxInterval float64, numTries uint, function
done := false
interval := initialInterval
for i := uint(0); !done && (numTries == 0 || i < numTries); i++ {
done, err = function()
done, err = function(i)
if err != nil {
return err
}
Expand Down
8 changes: 4 additions & 4 deletions common/retry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
func TestRetry(t *testing.T) {
numTries := uint(0)
// Test that a passing function only gets called once.
err := Retry(0, 0, 0, func() (bool, error) {
err := Retry(0, 0, 0, func(i uint) (bool, error) {
numTries++
return true, nil
})
Expand All @@ -22,7 +22,7 @@ func TestRetry(t *testing.T) {
// Test that a failing function gets retried (once in this example).
numTries = 0
results := []bool{false, true}
err = Retry(0, 0, 0, func() (bool, error) {
err = Retry(0, 0, 0, func(i uint) (bool, error) {
result := results[numTries]
numTries++
return result, nil
Expand All @@ -37,7 +37,7 @@ func TestRetry(t *testing.T) {
// Test that a function error gets returned, and the function does not get called again.
numTries = 0
funcErr := fmt.Errorf("This function had an error!")
err = Retry(0, 0, 0, func() (bool, error) {
err = Retry(0, 0, 0, func(i uint) (bool, error) {
numTries++
return false, funcErr
})
Expand All @@ -51,7 +51,7 @@ func TestRetry(t *testing.T) {
// Test when a function exhausts its retries.
numTries = 0
expectedTries := uint(3)
err = Retry(0, 0, expectedTries, func() (bool, error) {
err = Retry(0, 0, expectedTries, func(i uint) (bool, error) {
numTries++
return false, nil
})
Expand Down
1 change: 0 additions & 1 deletion post-processor/vagrant-cloud/post-processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,6 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac
new(stepCreateProvider),
new(stepPrepareUpload),
new(stepUpload),
new(stepVerifyUpload),
new(stepReleaseVersion),
}
} else {
Expand Down
4 changes: 1 addition & 3 deletions post-processor/vagrant-cloud/step_prepare_upload.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ package vagrantcloud

import (
"fmt"

"github.com/hashicorp/packer/packer"
"github.com/mitchellh/multistep"
)

type Upload struct {
Token string `json:"token"`
UploadPath string `json:"upload_path"`
}

Expand Down Expand Up @@ -41,8 +41,6 @@ func (s *stepPrepareUpload) Run(state multistep.StateBag) multistep.StepAction {
return multistep.ActionHalt
}

ui.Message(fmt.Sprintf("Box upload prepared with token %s", upload.Token))

// Save the upload details to the state
state.Put("upload", upload)

Expand Down
28 changes: 11 additions & 17 deletions post-processor/vagrant-cloud/step_upload.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ package vagrantcloud

import (
"fmt"
"time"
"log"

"github.com/hashicorp/packer/common"
"github.com/hashicorp/packer/packer"
"github.com/mitchellh/multistep"
)
Expand All @@ -23,34 +24,27 @@ func (s *stepUpload) Run(state multistep.StateBag) multistep.StepAction {
"Depending on your internet connection and the size of the box,\n" +
"this may take some time")

var finalErr error
for i := 0; i < 3; i++ {
if i > 0 {
ui.Message(fmt.Sprintf("Uploading box, attempt %d", i+1))
}
err := common.Retry(10, 10, 3, func(i uint) (bool, error) {
ui.Message(fmt.Sprintf("Uploading box, attempt %d", i+1))

resp, err := client.Upload(artifactFilePath, url)
if err != nil {
finalErr = err
ui.Message(fmt.Sprintf(
"Error uploading box! Will retry in 10 seconds. Error: %s", err))
time.Sleep(10 * time.Second)
continue
return false, nil
}
if resp.StatusCode != 200 {
finalErr = fmt.Errorf("bad HTTP status: %d", resp.StatusCode)
log.Printf("bad HTTP status: %d", resp.StatusCode)
ui.Message(fmt.Sprintf(
"Error uploading box! Will retry in 10 seconds. Status: %d",
resp.StatusCode))
time.Sleep(10 * time.Second)
continue
return false, nil
}
return true, nil
})

finalErr = nil
}

if finalErr != nil {
state.Put("error", finalErr)
if err != nil {
state.Put("error", err)
return multistep.ActionHalt
}

Expand Down
104 changes: 0 additions & 104 deletions post-processor/vagrant-cloud/step_verify_upload.go

This file was deleted.

0 comments on commit 94d7a4c

Please sign in to comment.