move UI call to before the wait; add context to these steps

This commit is contained in:
Megan Marsh 2018-06-01 16:17:30 -07:00
parent cf63dd10bf
commit f49a2d8aed
14 changed files with 54 additions and 50 deletions

View File

@ -5,6 +5,7 @@ import (
"fmt"
"strings"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
awscommon "github.com/hashicorp/packer/builder/amazon/common"
"github.com/hashicorp/packer/helper/multistep"
@ -22,7 +23,7 @@ type StepAttachVolume struct {
volumeId string
}
func (s *StepAttachVolume) Run(_ context.Context, state multistep.StateBag) multistep.StepAction {
func (s *StepAttachVolume) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
ec2conn := state.Get("ec2").(*ec2.EC2)
device := state.Get("device").(string)
instance := state.Get("instance").(*ec2.Instance)
@ -50,7 +51,7 @@ func (s *StepAttachVolume) Run(_ context.Context, state multistep.StateBag) mult
s.volumeId = volumeId
// Wait for the volume to become attached
err = awscommon.WaitUntilVolumeAttached(ec2conn, s.volumeId)
err = awscommon.WaitUntilVolumeAttached(ctx, ec2conn, s.volumeId)
if err != nil {
err := fmt.Errorf("Error waiting for volume: %s", err)
state.Put("error", err)
@ -86,7 +87,7 @@ func (s *StepAttachVolume) CleanupFunc(state multistep.StateBag) error {
s.attached = false
// Wait for the volume to detach
err = awscommon.WaitUntilVolumeDetached(ec2conn, s.volumeId)
err = awscommon.WaitUntilVolumeDetached(aws.BackgroundContext(), ec2conn, s.volumeId)
if err != nil {
return fmt.Errorf("Error waiting for volume: %s", err)
}

View File

@ -22,7 +22,7 @@ type StepCreateVolume struct {
RootVolumeSize int64
}
func (s *StepCreateVolume) Run(_ context.Context, state multistep.StateBag) multistep.StepAction {
func (s *StepCreateVolume) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
config := state.Get("config").(*Config)
ec2conn := state.Get("ec2").(*ec2.EC2)
instance := state.Get("instance").(*ec2.Instance)
@ -84,7 +84,7 @@ func (s *StepCreateVolume) Run(_ context.Context, state multistep.StateBag) mult
log.Printf("Volume ID: %s", s.volumeId)
// Wait for the volume to become ready
err = awscommon.WaitUntilVolumeAvailable(ec2conn, s.volumeId)
err = awscommon.WaitUntilVolumeAvailable(ctx, ec2conn, s.volumeId)
if err != nil {
err := fmt.Errorf("Error waiting for volume: %s", err)
state.Put("error", err)

View File

@ -102,16 +102,14 @@ func (s *StepRegisterAMI) Run(ctx context.Context, state multistep.StateBag) mul
amis[*ec2conn.Config.Region] = *registerResp.ImageId
state.Put("amis", amis)
// Wait for the image to become ready
if err := awscommon.WaitUntilAMIAvailable(ec2conn, *registerResp.ImageId); err != nil {
ui.Say("Waiting for AMI to become ready...")
if err := awscommon.WaitUntilAMIAvailable(ctx, ec2conn, *registerResp.ImageId); err != nil {
err := fmt.Errorf("Error waiting for AMI: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
ui.Say("Waiting for AMI to become ready...")
return multistep.ActionContinue
}

View File

@ -19,7 +19,7 @@ type StepSnapshot struct {
snapshotId string
}
func (s *StepSnapshot) Run(_ context.Context, state multistep.StateBag) multistep.StepAction {
func (s *StepSnapshot) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
ec2conn := state.Get("ec2").(*ec2.EC2)
ui := state.Get("ui").(packer.Ui)
volumeId := state.Get("volume_id").(string)
@ -43,7 +43,7 @@ func (s *StepSnapshot) Run(_ context.Context, state multistep.StateBag) multiste
ui.Message(fmt.Sprintf("Snapshot ID: %s", s.snapshotId))
// Wait for the snapshot to be ready
err = awscommon.WaitUntilSnapshotDone(ec2conn, s.snapshotId)
err = awscommon.WaitUntilSnapshotDone(ctx, ec2conn, s.snapshotId)
if err != nil {
err := fmt.Errorf("Error waiting for snapshot: %s", err)
state.Put("error", err)

View File

@ -35,58 +35,63 @@ type StateChangeConf struct {
// Following are wrapper functions that use Packer's environment-variables to
// determing retry logic, then call the AWS SDK's built-in waiters.
func WaitUntilAMIAvailable(conn *ec2.EC2, imageId string) error {
func WaitUntilAMIAvailable(ctx aws.Context, conn *ec2.EC2, imageId string) error {
imageInput := ec2.DescribeImagesInput{
ImageIds: []*string{&imageId},
}
err := conn.WaitUntilImageAvailableWithContext(aws.BackgroundContext(),
err := conn.WaitUntilImageAvailableWithContext(
ctx,
&imageInput,
getWaiterOptions()...)
return err
}
func WaitUntilInstanceTerminated(conn *ec2.EC2, instanceId string) error {
func WaitUntilInstanceTerminated(ctx aws.Context, conn *ec2.EC2, instanceId string) error {
instanceInput := ec2.DescribeInstancesInput{
InstanceIds: []*string{&instanceId},
}
err := conn.WaitUntilInstanceTerminatedWithContext(aws.BackgroundContext(),
err := conn.WaitUntilInstanceTerminatedWithContext(
ctx,
&instanceInput,
getWaiterOptions()...)
return err
}
// This function works for both requesting and cancelling spot instances.
func WaitUntilSpotRequestFulfilled(conn *ec2.EC2, spotRequestId string) error {
func WaitUntilSpotRequestFulfilled(ctx aws.Context, conn *ec2.EC2, spotRequestId string) error {
spotRequestInput := ec2.DescribeSpotInstanceRequestsInput{
SpotInstanceRequestIds: []*string{&spotRequestId},
}
err := conn.WaitUntilSpotInstanceRequestFulfilledWithContext(aws.BackgroundContext(),
err := conn.WaitUntilSpotInstanceRequestFulfilledWithContext(
ctx,
&spotRequestInput,
getWaiterOptions()...)
return err
}
func WaitUntilVolumeAvailable(conn *ec2.EC2, volumeId string) error {
func WaitUntilVolumeAvailable(ctx aws.Context, conn *ec2.EC2, volumeId string) error {
volumeInput := ec2.DescribeVolumesInput{
VolumeIds: []*string{&volumeId},
}
err := conn.WaitUntilVolumeAvailableWithContext(aws.BackgroundContext(),
err := conn.WaitUntilVolumeAvailableWithContext(
ctx,
&volumeInput,
getWaiterOptions()...)
return err
}
func WaitUntilSnapshotDone(conn *ec2.EC2, snapshotID string) error {
func WaitUntilSnapshotDone(ctx aws.Context, conn *ec2.EC2, snapshotID string) error {
snapInput := ec2.DescribeSnapshotsInput{
SnapshotIds: []*string{&snapshotID},
}
err := conn.WaitUntilSnapshotCompletedWithContext(aws.BackgroundContext(),
err := conn.WaitUntilSnapshotCompletedWithContext(
ctx,
&snapInput,
getWaiterOptions()...)
return err
@ -94,37 +99,37 @@ func WaitUntilSnapshotDone(conn *ec2.EC2, snapshotID string) error {
// Wrappers for our custom AWS waiters
func WaitUntilVolumeAttached(conn *ec2.EC2, volumeId string) error {
func WaitUntilVolumeAttached(ctx aws.Context, conn *ec2.EC2, volumeId string) error {
volumeInput := ec2.DescribeVolumesInput{
VolumeIds: []*string{&volumeId},
}
err := WaitForVolumeToBeAttached(conn,
aws.BackgroundContext(),
ctx,
&volumeInput,
getWaiterOptions()...)
return err
}
func WaitUntilVolumeDetached(conn *ec2.EC2, volumeId string) error {
func WaitUntilVolumeDetached(ctx aws.Context, conn *ec2.EC2, volumeId string) error {
volumeInput := ec2.DescribeVolumesInput{
VolumeIds: []*string{&volumeId},
}
err := WaitForVolumeToBeAttached(conn,
aws.BackgroundContext(),
err := WaitForVolumeToBeDetached(conn,
ctx,
&volumeInput,
getWaiterOptions()...)
return err
}
func WaitUntilImageImported(conn *ec2.EC2, taskID string) error {
func WaitUntilImageImported(ctx aws.Context, conn *ec2.EC2, taskID string) error {
importInput := ec2.DescribeImportImageTasksInput{
ImportTaskIds: []*string{&taskID},
}
err := WaitForImageToBeImported(conn,
aws.BackgroundContext(),
ctx,
&importInput,
getWaiterOptions()...)
return err

View File

@ -20,7 +20,7 @@ type StepAMIRegionCopy struct {
Name string
}
func (s *StepAMIRegionCopy) Run(_ context.Context, state multistep.StateBag) multistep.StepAction {
func (s *StepAMIRegionCopy) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
ec2conn := state.Get("ec2").(*ec2.EC2)
ui := state.Get("ui").(packer.Ui)
amis := state.Get("amis").(map[string]string)
@ -53,7 +53,7 @@ func (s *StepAMIRegionCopy) Run(_ context.Context, state multistep.StateBag) mul
go func(region string) {
defer wg.Done()
id, snapshotIds, err := amiRegionCopy(state, s.AccessConfig, s.Name, ami, region, *ec2conn.Config.Region, regKeyID)
id, snapshotIds, err := amiRegionCopy(ctx, state, s.AccessConfig, s.Name, ami, region, *ec2conn.Config.Region, regKeyID)
lock.Lock()
defer lock.Unlock()
amis[region] = id
@ -85,7 +85,7 @@ func (s *StepAMIRegionCopy) Cleanup(state multistep.StateBag) {
// amiRegionCopy does a copy for the given AMI to the target region and
// returns the resulting ID and snapshot IDs, or error.
func amiRegionCopy(state multistep.StateBag, config *AccessConfig, name string, imageId string,
func amiRegionCopy(ctx context.Context, state multistep.StateBag, config *AccessConfig, name string, imageId string,
target string, source string, keyID string) (string, []string, error) {
snapshotIds := []string{}
isEncrypted := false
@ -117,7 +117,7 @@ func amiRegionCopy(state multistep.StateBag, config *AccessConfig, name string,
}
// Wait for the image to become ready
if err := WaitUntilAMIAvailable(regionconn, *resp.ImageId); err != nil {
if err := WaitUntilAMIAvailable(ctx, regionconn, *resp.ImageId); err != nil {
return "", snapshotIds, fmt.Errorf("Error waiting for AMI (%s) in region (%s): %s",
*resp.ImageId, target, err)
}

View File

@ -19,7 +19,7 @@ type StepCreateEncryptedAMICopy struct {
AMIMappings []BlockDevice
}
func (s *StepCreateEncryptedAMICopy) Run(_ context.Context, state multistep.StateBag) multistep.StepAction {
func (s *StepCreateEncryptedAMICopy) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
ec2conn := state.Get("ec2").(*ec2.EC2)
ui := state.Get("ui").(packer.Ui)
kmsKeyId := s.KeyID
@ -66,7 +66,7 @@ func (s *StepCreateEncryptedAMICopy) Run(_ context.Context, state multistep.Stat
// Wait for the copy to become ready
ui.Say("Waiting for AMI copy to become ready...")
if err := WaitUntilAMIAvailable(ec2conn, *copyResp.ImageId); err != nil {
if err := WaitUntilAMIAvailable(ctx, ec2conn, *copyResp.ImageId); err != nil {
err := fmt.Errorf("Error waiting for AMI Copy: %s", err)
state.Put("error", err)
ui.Error(err.Error())

View File

@ -304,7 +304,7 @@ func (s *StepRunSourceInstance) Cleanup(state multistep.StateBag) {
return
}
if err := WaitUntilInstanceTerminated(ec2conn, s.instanceId); err != nil {
if err := WaitUntilInstanceTerminated(aws.BackgroundContext(), ec2conn, s.instanceId); err != nil {
ui.Error(err.Error())
}
}

View File

@ -202,7 +202,7 @@ func (s *StepRunSpotInstance) Run(ctx context.Context, state multistep.StateBag)
spotRequestId := s.spotRequest.SpotInstanceRequestId
ui.Message(fmt.Sprintf("Waiting for spot request (%s) to become active...", *spotRequestId))
err = WaitUntilSpotRequestFulfilled(ec2conn, *spotRequestId)
err = WaitUntilSpotRequestFulfilled(ctx, ec2conn, *spotRequestId)
if err != nil {
err := fmt.Errorf("Error waiting for spot request (%s) to become ready: %s", *spotRequestId, err)
state.Put("error", err)
@ -339,7 +339,7 @@ func (s *StepRunSpotInstance) Cleanup(state multistep.StateBag) {
return
}
err := WaitUntilSpotRequestFulfilled(ec2conn, *s.spotRequest.SpotInstanceRequestId)
err := WaitUntilSpotRequestFulfilled(aws.BackgroundContext(), ec2conn, *s.spotRequest.SpotInstanceRequestId)
if err != nil {
ui.Error(err.Error())
}
@ -354,7 +354,7 @@ func (s *StepRunSpotInstance) Cleanup(state multistep.StateBag) {
return
}
if err := WaitUntilInstanceTerminated(ec2conn, s.instanceId); err != nil {
if err := WaitUntilInstanceTerminated(aws.BackgroundContext(), ec2conn, s.instanceId); err != nil {
ui.Error(err.Error())
}
}

View File

@ -15,7 +15,7 @@ type stepCreateAMI struct {
image *ec2.Image
}
func (s *stepCreateAMI) Run(_ context.Context, state multistep.StateBag) multistep.StepAction {
func (s *stepCreateAMI) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
config := state.Get("config").(Config)
ec2conn := state.Get("ec2").(*ec2.EC2)
instance := state.Get("instance").(*ec2.Instance)
@ -45,7 +45,7 @@ func (s *stepCreateAMI) Run(_ context.Context, state multistep.StateBag) multist
// Wait for the image to become ready
ui.Say("Waiting for AMI to become ready...")
if err := awscommon.WaitUntilAMIAvailable(ec2conn, *createResp.ImageId); err != nil {
if err := awscommon.WaitUntilAMIAvailable(ctx, ec2conn, *createResp.ImageId); err != nil {
log.Printf("Error waiting for AMI: %s", err)
imagesResp, err := ec2conn.DescribeImages(&ec2.DescribeImagesInput{ImageIds: []*string{createResp.ImageId}})
if err != nil {

View File

@ -21,7 +21,7 @@ type StepRegisterAMI struct {
image *ec2.Image
}
func (s *StepRegisterAMI) Run(_ context.Context, state multistep.StateBag) multistep.StepAction {
func (s *StepRegisterAMI) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
config := state.Get("config").(*Config)
ec2conn := state.Get("ec2").(*ec2.EC2)
snapshotIds := state.Get("snapshot_ids").(map[string]string)
@ -64,7 +64,7 @@ func (s *StepRegisterAMI) Run(_ context.Context, state multistep.StateBag) multi
// Wait for the image to become ready
ui.Say("Waiting for AMI to become ready...")
if err := awscommon.WaitUntilAMIAvailable(ec2conn, *registerResp.ImageId); err != nil {
if err := awscommon.WaitUntilAMIAvailable(ctx, ec2conn, *registerResp.ImageId); err != nil {
err := fmt.Errorf("Error waiting for AMI: %s", err)
state.Put("error", err)
ui.Error(err.Error())

View File

@ -22,7 +22,7 @@ type StepSnapshotVolumes struct {
snapshotIds map[string]string
}
func (s *StepSnapshotVolumes) snapshotVolume(deviceName string, state multistep.StateBag) error {
func (s *StepSnapshotVolumes) snapshotVolume(ctx context.Context, deviceName string, state multistep.StateBag) error {
ec2conn := state.Get("ec2").(*ec2.EC2)
ui := state.Get("ui").(packer.Ui)
instance := state.Get("instance").(*ec2.Instance)
@ -52,11 +52,11 @@ func (s *StepSnapshotVolumes) snapshotVolume(deviceName string, state multistep.
s.snapshotIds[deviceName] = *createSnapResp.SnapshotId
// Wait for snapshot to be created
err = awscommon.WaitUntilSnapshotDone(ec2conn, *createSnapResp.SnapshotId)
err = awscommon.WaitUntilSnapshotDone(ctx, ec2conn, *createSnapResp.SnapshotId)
return err
}
func (s *StepSnapshotVolumes) Run(_ context.Context, state multistep.StateBag) multistep.StepAction {
func (s *StepSnapshotVolumes) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
ui := state.Get("ui").(packer.Ui)
s.snapshotIds = map[string]string{}
@ -67,7 +67,7 @@ func (s *StepSnapshotVolumes) Run(_ context.Context, state multistep.StateBag) m
wg.Add(1)
go func(device *ec2.BlockDeviceMapping) {
defer wg.Done()
if err := s.snapshotVolume(*device.DeviceName, state); err != nil {
if err := s.snapshotVolume(ctx, *device.DeviceName, state); err != nil {
errs = multierror.Append(errs, err)
}
}(device)

View File

@ -16,7 +16,7 @@ type StepRegisterAMI struct {
EnableAMISriovNetSupport bool
}
func (s *StepRegisterAMI) Run(_ context.Context, state multistep.StateBag) multistep.StepAction {
func (s *StepRegisterAMI) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
config := state.Get("config").(*Config)
ec2conn := state.Get("ec2").(*ec2.EC2)
manifestPath := state.Get("remote_manifest_path").(string)
@ -59,7 +59,7 @@ func (s *StepRegisterAMI) Run(_ context.Context, state multistep.StateBag) multi
// Wait for the image to become ready
ui.Say("Waiting for AMI to become ready...")
if err := awscommon.WaitUntilAMIAvailable(ec2conn, *registerResp.ImageId); err != nil {
if err := awscommon.WaitUntilAMIAvailable(ctx, ec2conn, *registerResp.ImageId); err != nil {
err := fmt.Errorf("Error waiting for AMI: %s", err)
state.Put("error", err)
ui.Error(err.Error())

View File

@ -186,7 +186,7 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac
// Wait for import process to complete, this takes a while
ui.Message(fmt.Sprintf("Waiting for task %s to complete (may take a while)", *import_start.ImportTaskId))
err = awscommon.WaitUntilImageImported(ec2conn, *import_start.ImportTaskId)
err = awscommon.WaitUntilImageImported(aws.BackgroundContext(), ec2conn, *import_start.ImportTaskId)
// Retrieve what the outcome was for the import task
import_result, err := ec2conn.DescribeImportImageTasks(&ec2.DescribeImportImageTasksInput{
@ -226,7 +226,7 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac
ui.Message(fmt.Sprintf("Waiting for AMI rename to complete (may take a while)"))
if err := awscommon.WaitUntilAMIAvailable(ec2conn, *resp.ImageId); err != nil {
if err := awscommon.WaitUntilAMIAvailable(aws.BackgroundContext(), ec2conn, *resp.ImageId); err != nil {
return nil, false, fmt.Errorf("Error waiting for AMI (%s): %s", *resp.ImageId, err)
}