diff --git a/builder/amazon/chroot/step_attach_volume.go b/builder/amazon/chroot/step_attach_volume.go index 7698ece07..7044e0218 100644 --- a/builder/amazon/chroot/step_attach_volume.go +++ b/builder/amazon/chroot/step_attach_volume.go @@ -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) } diff --git a/builder/amazon/chroot/step_create_volume.go b/builder/amazon/chroot/step_create_volume.go index c10fda4da..725c8240b 100644 --- a/builder/amazon/chroot/step_create_volume.go +++ b/builder/amazon/chroot/step_create_volume.go @@ -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) diff --git a/builder/amazon/chroot/step_register_ami.go b/builder/amazon/chroot/step_register_ami.go index 31a41cb9d..4f3ad54c4 100644 --- a/builder/amazon/chroot/step_register_ami.go +++ b/builder/amazon/chroot/step_register_ami.go @@ -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 } diff --git a/builder/amazon/chroot/step_snapshot.go b/builder/amazon/chroot/step_snapshot.go index 4e9070bc5..4c66b4fd1 100644 --- a/builder/amazon/chroot/step_snapshot.go +++ b/builder/amazon/chroot/step_snapshot.go @@ -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) diff --git a/builder/amazon/common/state.go b/builder/amazon/common/state.go index 50e4e4b7a..7104bc7ab 100644 --- a/builder/amazon/common/state.go +++ b/builder/amazon/common/state.go @@ -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 diff --git a/builder/amazon/common/step_ami_region_copy.go b/builder/amazon/common/step_ami_region_copy.go index 511a523fb..d14fa472e 100644 --- a/builder/amazon/common/step_ami_region_copy.go +++ b/builder/amazon/common/step_ami_region_copy.go @@ -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) } diff --git a/builder/amazon/common/step_encrypted_ami.go b/builder/amazon/common/step_encrypted_ami.go index 5125a70b0..0ad8bd5d3 100644 --- a/builder/amazon/common/step_encrypted_ami.go +++ b/builder/amazon/common/step_encrypted_ami.go @@ -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()) diff --git a/builder/amazon/common/step_run_source_instance.go b/builder/amazon/common/step_run_source_instance.go index a7fb84076..7c31fa1f8 100644 --- a/builder/amazon/common/step_run_source_instance.go +++ b/builder/amazon/common/step_run_source_instance.go @@ -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()) } } diff --git a/builder/amazon/common/step_run_spot_instance.go b/builder/amazon/common/step_run_spot_instance.go index 4b0dc6005..9e5678f7f 100644 --- a/builder/amazon/common/step_run_spot_instance.go +++ b/builder/amazon/common/step_run_spot_instance.go @@ -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()) } } diff --git a/builder/amazon/ebs/step_create_ami.go b/builder/amazon/ebs/step_create_ami.go index cb3329325..1d081db70 100644 --- a/builder/amazon/ebs/step_create_ami.go +++ b/builder/amazon/ebs/step_create_ami.go @@ -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 { diff --git a/builder/amazon/ebssurrogate/step_register_ami.go b/builder/amazon/ebssurrogate/step_register_ami.go index 4f6a88667..63e0f5581 100644 --- a/builder/amazon/ebssurrogate/step_register_ami.go +++ b/builder/amazon/ebssurrogate/step_register_ami.go @@ -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()) diff --git a/builder/amazon/ebssurrogate/step_snapshot_volumes.go b/builder/amazon/ebssurrogate/step_snapshot_volumes.go index 3beef0a8e..f238815e1 100644 --- a/builder/amazon/ebssurrogate/step_snapshot_volumes.go +++ b/builder/amazon/ebssurrogate/step_snapshot_volumes.go @@ -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) diff --git a/builder/amazon/instance/step_register_ami.go b/builder/amazon/instance/step_register_ami.go index 7ddb5bd57..20df1f0d4 100644 --- a/builder/amazon/instance/step_register_ami.go +++ b/builder/amazon/instance/step_register_ami.go @@ -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()) diff --git a/post-processor/amazon-import/post-processor.go b/post-processor/amazon-import/post-processor.go index 2dbbcc6c7..ecf72e555 100644 --- a/post-processor/amazon-import/post-processor.go +++ b/post-processor/amazon-import/post-processor.go @@ -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) }