Chris Roberts d8222b1656
Add support for uploading directly to storage on Vagrant Cloud (#10193)
Vagrant Cloud provides support for uploading directly to the backend
storage instead of streaming through Vagrant Cloud. This adds support
for direct to storage uploads and sets it as the default upload method.
A new option has been added to disable this behavior and revert back
to streaming upload via Vagrant Cloud (`no_direct_upload`).

This default for uploading directly to the backend storage also matches
up with changes being added to Vagrant proper for box upload behavior:
hashicorp/vagrant#11916
2020-11-05 20:01:55 -05:00

74 lines
1.8 KiB
Go

package vagrantcloud
import (
"context"
"fmt"
"log"
"net/http"
"time"
"github.com/hashicorp/packer/common/retry"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
)
type stepUpload struct {
}
func (s *stepUpload) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
client := state.Get("client").(*VagrantCloudClient)
config := state.Get("config").(*Config)
ui := state.Get("ui").(packer.Ui)
upload := state.Get("upload").(*Upload)
artifactFilePath := state.Get("artifactFilePath").(string)
url := upload.UploadPath
ui.Say(fmt.Sprintf("Uploading box: %s", artifactFilePath))
ui.Message(
"Depending on your internet connection and the size of the box,\n" +
"this may take some time")
err := retry.Config{
Tries: 3,
RetryDelay: (&retry.Backoff{InitialBackoff: 10 * time.Second, MaxBackoff: 10 * time.Second, Multiplier: 2}).Linear,
}.Run(ctx, func(ctx context.Context) error {
ui.Message(fmt.Sprintf("Uploading box"))
var err error
var resp *http.Response
if config.NoDirectUpload {
resp, err = client.Upload(artifactFilePath, url)
} else {
resp, err = client.DirectUpload(artifactFilePath, url)
}
if err != nil {
ui.Message(fmt.Sprintf(
"Error uploading box! Will retry in 10 seconds. Error: %s", err))
return err
}
if resp.StatusCode != 200 {
err := fmt.Errorf("bad HTTP status: %d", resp.StatusCode)
log.Print(err)
ui.Message(fmt.Sprintf(
"Error uploading box! Will retry in 10 seconds. Status: %d",
resp.StatusCode))
return err
}
return err
})
if err != nil {
state.Put("error", err)
return multistep.ActionHalt
}
ui.Message("Box successfully uploaded")
return multistep.ActionContinue
}
func (s *stepUpload) Cleanup(state multistep.StateBag) {
// No cleanup
}