From 650eb3a4f2d89d173cdd6581a6d1232511a8e219 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Fri, 27 Dec 2024 19:32:39 +0400 Subject: [PATCH] refactor: rewrite cloud uploader to use AWS SDK Go v2 The v1 SDK was deprecated and archived. Signed-off-by: Andrey Smirnov --- hack/cloud-image-uploader/aws.go | 268 +++++++++++++++++++----------- hack/cloud-image-uploader/go.mod | 22 ++- hack/cloud-image-uploader/go.sum | 49 +++++- hack/cloud-image-uploader/main.go | 6 +- 4 files changed, 232 insertions(+), 113 deletions(-) diff --git a/hack/cloud-image-uploader/aws.go b/hack/cloud-image-uploader/aws.go index 593333cb4f..262a614f46 100644 --- a/hack/cloud-image-uploader/aws.go +++ b/hack/cloud-image-uploader/aws.go @@ -11,13 +11,16 @@ import ( "os" "time" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/session" - "github.com/aws/aws-sdk-go/service/ec2" - "github.com/aws/aws-sdk-go/service/s3" - "github.com/aws/aws-sdk-go/service/s3/s3manager" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/aws-sdk-go-v2/feature/s3/manager" + "github.com/aws/aws-sdk-go-v2/service/ec2" + "github.com/aws/aws-sdk-go-v2/service/ec2/types" + "github.com/aws/aws-sdk-go-v2/service/s3" + s3types "github.com/aws/aws-sdk-go-v2/service/s3/types" "github.com/google/uuid" "github.com/klauspost/compress/zstd" + "github.com/siderolabs/gen/xslices" "github.com/siderolabs/go-pointer" "github.com/siderolabs/go-retry/retry" "golang.org/x/sync/errgroup" @@ -46,60 +49,59 @@ var denyInsecurePolicyTemplate = `{ }` // GetAWSDefaultRegions returns a list of regions which are enabled for this account. -func GetAWSDefaultRegions() ([]string, error) { - sess, err := session.NewSession(&aws.Config{ - Region: aws.String("us-east-1"), - }) - if err != nil { - return nil, fmt.Errorf("failed creating AWS session: %w", err) - } - - result, err := ec2.New(sess).DescribeRegions(&ec2.DescribeRegionsInput{}) +func GetAWSDefaultRegions(ctx context.Context) ([]string, error) { + cfg, err := config.LoadDefaultConfig(ctx, config.WithRegion("us-east-1")) if err != nil { - return nil, fmt.Errorf("failed getting list of regions: %w", err) + return nil, fmt.Errorf("failed loading AWS config: %w", err) } - var regions []string + svc := ec2.NewFromConfig(cfg) - for _, r := range result.Regions { - if r.OptInStatus != nil { - if *r.OptInStatus == "opt-in-not-required" || *r.OptInStatus == "opted-in" { - regions = append(regions, *r.RegionName) - } - } + resp, err := svc.DescribeRegions(ctx, &ec2.DescribeRegionsInput{ + Filters: []types.Filter{ + { + Name: pointer.To("opt-in-status"), + Values: []string{"opt-in-not-required", "opted-in"}, + }, + }, + }) + if err != nil { + return nil, fmt.Errorf("failed describing regions: %w", err) } - return regions, nil + return xslices.Map(resp.Regions, func(r types.Region) string { + return pointer.SafeDeref(r.RegionName) + }), nil } // AWSUploader registers AMI in the AWS. type AWSUploader struct { Options Options - sess *session.Session - ec2svcs map[string]*ec2.EC2 + cfg aws.Config + ec2svcs map[string]*ec2.Client } -var awsArchitectures = map[string]string{ - "amd64": "x86_64", - "arm64": "arm64", +var awsArchitectures = map[string]types.ArchitectureValues{ + "amd64": types.ArchitectureValuesX8664, + "arm64": types.ArchitectureValuesArm64, } // Upload image and register with AWS. func (au *AWSUploader) Upload(ctx context.Context) error { var err error - au.sess, err = session.NewSession(&aws.Config{ - Region: aws.String("us-west-2"), // gets overridden in each uploader with specific region - }) + au.cfg, err = config.LoadDefaultConfig(ctx) if err != nil { - return fmt.Errorf("failed creating AWS session: %w", err) + return fmt.Errorf("failed loading AWS config: %w", err) } - au.ec2svcs = make(map[string]*ec2.EC2) + au.ec2svcs = make(map[string]*ec2.Client) for _, region := range au.Options.AWSRegions { - au.ec2svcs[region] = ec2.New(au.sess, aws.NewConfig().WithRegion(region)) + au.ec2svcs[region] = ec2.NewFromConfig(au.cfg, func(o *ec2.Options) { + o.Region = region + }) } return au.RegisterAMIs(ctx) @@ -125,46 +127,113 @@ func (au *AWSUploader) RegisterAMIs(ctx context.Context) error { return g.Wait() } -func (au *AWSUploader) registerAMI(ctx context.Context, region string, svc *ec2.EC2) error { - s3Svc := s3.New(au.sess, aws.NewConfig().WithRegion(region)) - bucketName := fmt.Sprintf("talos-image-upload-%s", uuid.New()) +func cleanupBucket(s3Svc *s3.Client, bucketName string) { + // create a detached context, as context might be canceled + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + + mpuPaginator := s3.NewListMultipartUploadsPaginator(s3Svc, &s3.ListMultipartUploadsInput{ + Bucket: pointer.To(bucketName), + }) - _, err := s3Svc.CreateBucketWithContext(ctx, &s3.CreateBucketInput{ + for mpuPaginator.HasMorePages() { + page, err := mpuPaginator.NextPage(ctx) + if err != nil { + log.Printf("failed listing multipart uploads: %s", err) + + break + } + + for _, upload := range page.Uploads { + _, err = s3Svc.AbortMultipartUpload(ctx, &s3.AbortMultipartUploadInput{ + Bucket: pointer.To(bucketName), + Key: upload.Key, + UploadId: upload.UploadId, + }) + if err != nil { + log.Printf("failed aborting multipart upload: %s", err) + } + } + } + + objectsPaginator := s3.NewListObjectsV2Paginator(s3Svc, &s3.ListObjectsV2Input{ + Bucket: pointer.To(bucketName), + }) + + for objectsPaginator.HasMorePages() { + page, err := objectsPaginator.NextPage(ctx) + if err != nil { + log.Printf("failed listing objects: %s", err) + + break + } + + if len(page.Contents) == 0 { + break + } + + _, err = s3Svc.DeleteObjects(ctx, &s3.DeleteObjectsInput{ + Bucket: pointer.To(bucketName), + Delete: &s3types.Delete{ + Objects: xslices.Map(page.Contents, func(obj s3types.Object) s3types.ObjectIdentifier { + return s3types.ObjectIdentifier{ + Key: obj.Key, + } + }), + }, + }) + if err != nil { + log.Printf("failed deleting objects: %s", err) + } + } + + _, err := s3Svc.DeleteBucket(ctx, &s3.DeleteBucketInput{ Bucket: aws.String(bucketName), }) if err != nil { - return fmt.Errorf("failed creating S3 bucket: %w", err) + log.Printf("failed deleting bucket: %s", err) } - err = s3Svc.WaitUntilBucketExistsWithContext(ctx, &s3.HeadBucketInput{ - Bucket: aws.String(bucketName), + log.Printf("aws: deleted bucket %q", bucketName) +} + +func (au *AWSUploader) registerAMI(ctx context.Context, region string, svc *ec2.Client) error { + s3Svc := s3.NewFromConfig(au.cfg, func(o *s3.Options) { + o.Region = region + }) + bucketName := fmt.Sprintf("talos-image-upload-%s", uuid.New()) + + var createBucketConfiguration *s3types.CreateBucketConfiguration + + if region != "us-east-1" { + createBucketConfiguration = &s3types.CreateBucketConfiguration{ + LocationConstraint: s3types.BucketLocationConstraint(region), + } + } + + _, err := s3Svc.CreateBucket(ctx, &s3.CreateBucketInput{ + Bucket: pointer.To(bucketName), + CreateBucketConfiguration: createBucketConfiguration, }) if err != nil { return fmt.Errorf("failed creating S3 bucket: %w", err) } + if err = s3.NewBucketExistsWaiter(s3Svc).Wait(ctx, &s3.HeadBucketInput{ + Bucket: pointer.To(bucketName), + }, time.Minute); err != nil { + return fmt.Errorf("failed waiting for S3 bucket: %w", err) + } + log.Printf("aws: created bucket %q for %s", bucketName, region) defer func() { - iter := s3manager.NewDeleteListIterator(s3Svc, &s3.ListObjectsInput{ - Bucket: aws.String(bucketName), - }) - - if err = s3manager.NewBatchDeleteWithClient(s3Svc).Delete(aws.BackgroundContext(), iter); err != nil { - log.Printf("Unable to delete objects from bucket %q, %v", bucketName, err) - } - - _, err = s3Svc.DeleteBucket(&s3.DeleteBucketInput{ - Bucket: aws.String(bucketName), - }) - if err != nil { - log.Printf("failed deleting bucket: %s", err) - } + cleanupBucket(s3Svc, bucketName) }() - _, err = s3Svc.PutBucketPolicyWithContext(ctx, &s3.PutBucketPolicyInput{ - Bucket: aws.String(bucketName), - Policy: aws.String(fmt.Sprintf(denyInsecurePolicyTemplate, bucketName, bucketName)), + _, err = s3Svc.PutBucketPolicy(ctx, &s3.PutBucketPolicyInput{ + Bucket: pointer.To(bucketName), + Policy: pointer.To(fmt.Sprintf(denyInsecurePolicyTemplate, bucketName, bucketName)), }) if err != nil { return fmt.Errorf("failed applying S3 bucket policy: %w", err) @@ -172,7 +241,7 @@ func (au *AWSUploader) registerAMI(ctx context.Context, region string, svc *ec2. log.Printf("aws: applied policy to bucket %q", bucketName) - uploader := s3manager.NewUploaderWithClient(s3Svc) + uploader := manager.NewUploader(s3Svc) var g errgroup.Group @@ -191,8 +260,8 @@ func (au *AWSUploader) registerAMI(ctx context.Context, region string, svc *ec2. } //nolint:gocyclo -func (au *AWSUploader) registerAMIArch(ctx context.Context, region string, svc *ec2.EC2, arch, bucketName string, uploader *s3manager.Uploader) error { - err := retry.Constant(5*time.Minute, retry.WithUnits(time.Second)).Retry(func() error { +func (au *AWSUploader) registerAMIArch(ctx context.Context, region string, svc *ec2.Client, arch, bucketName string, uploader *manager.Uploader) error { + err := retry.Constant(15*time.Minute, retry.WithUnits(time.Second), retry.WithErrorLogging(true)).RetryWithContext(ctx, func(ctx context.Context) error { source, err := os.Open(au.Options.AWSImage(arch)) if err != nil { return err @@ -205,9 +274,11 @@ func (au *AWSUploader) registerAMIArch(ctx context.Context, region string, svc * return err } - _, err = uploader.UploadWithContext(ctx, &s3manager.UploadInput{ - Bucket: aws.String(bucketName), - Key: aws.String(fmt.Sprintf("disk-%s.raw", arch)), + defer image.Close() + + _, err = uploader.Upload(ctx, &s3.PutObjectInput{ + Bucket: pointer.To(bucketName), + Key: pointer.To(fmt.Sprintf("disk-%s.raw", arch)), Body: image, }) @@ -219,13 +290,14 @@ func (au *AWSUploader) registerAMIArch(ctx context.Context, region string, svc * log.Printf("aws: import into %s/%s, image uploaded to S3", region, arch) - resp, err := svc.ImportSnapshotWithContext(ctx, &ec2.ImportSnapshotInput{ - Description: aws.String(fmt.Sprintf("Talos Image %s %s %s", au.Options.Tag, arch, region)), - DiskContainer: &ec2.SnapshotDiskContainer{ - Format: aws.String("raw"), - UserBucket: &ec2.UserBucket{ - S3Bucket: aws.String(bucketName), - S3Key: aws.String(fmt.Sprintf("disk-%s.raw", arch)), + resp, err := svc.ImportSnapshot(ctx, &ec2.ImportSnapshotInput{ + Description: pointer.To(fmt.Sprintf("Talos Image %s %s %s", au.Options.Tag, arch, region)), + DiskContainer: &types.SnapshotDiskContainer{ + Description: pointer.To(fmt.Sprintf("Talos Image %s %s %s", au.Options.Tag, arch, region)), + Format: pointer.To("raw"), + UserBucket: &types.UserBucket{ + S3Bucket: pointer.To(bucketName), + S3Key: pointer.To(fmt.Sprintf("disk-%s.raw", arch)), }, }, }) @@ -244,18 +316,14 @@ func (au *AWSUploader) registerAMIArch(ctx context.Context, region string, svc * err = retry.Constant(30*time.Minute, retry.WithUnits(30*time.Second)).Retry(func() error { var status *ec2.DescribeImportSnapshotTasksOutput - status, err = svc.DescribeImportSnapshotTasksWithContext(ctx, &ec2.DescribeImportSnapshotTasksInput{ - ImportTaskIds: aws.StringSlice([]string{taskID}), + status, err = svc.DescribeImportSnapshotTasks(ctx, &ec2.DescribeImportSnapshotTasksInput{ + ImportTaskIds: []string{taskID}, }) if err != nil { return err } for _, task := range status.ImportSnapshotTasks { - if task == nil { - continue - } - if pointer.SafeDeref(task.ImportTaskId) == taskID { if task.SnapshotTaskDetail == nil { continue @@ -293,11 +361,11 @@ func (au *AWSUploader) registerAMIArch(ctx context.Context, region string, svc * imageName = fmt.Sprintf("%s-%s-%s-%s", au.Options.NamePrefix, au.Options.Tag, region, arch) } - imageResp, err := svc.DescribeImagesWithContext(ctx, &ec2.DescribeImagesInput{ - Filters: []*ec2.Filter{ + imageResp, err := svc.DescribeImages(ctx, &ec2.DescribeImagesInput{ + Filters: []types.Filter{ { Name: aws.String("name"), - Values: aws.StringSlice([]string{imageName}), + Values: []string{imageName}, }, }, }) @@ -306,7 +374,7 @@ func (au *AWSUploader) registerAMIArch(ctx context.Context, region string, svc * } for _, image := range imageResp.Images { - _, err = svc.DeregisterImageWithContext(ctx, &ec2.DeregisterImageInput{ + _, err = svc.DeregisterImage(ctx, &ec2.DeregisterImageInput{ ImageId: image.ImageId, }) if err != nil { @@ -316,26 +384,26 @@ func (au *AWSUploader) registerAMIArch(ctx context.Context, region string, svc * log.Printf("aws: import into %s/%s, deregistered image ID %q", region, arch, *image.ImageId) } - registerResp, err := svc.RegisterImageWithContext(ctx, &ec2.RegisterImageInput{ + registerResp, err := svc.RegisterImage(ctx, &ec2.RegisterImageInput{ Name: aws.String(imageName), - BlockDeviceMappings: []*ec2.BlockDeviceMapping{ + BlockDeviceMappings: []types.BlockDeviceMapping{ { - DeviceName: aws.String("/dev/xvda"), - VirtualName: aws.String("talos"), - Ebs: &ec2.EbsBlockDevice{ - DeleteOnTermination: aws.Bool(true), - SnapshotId: aws.String(snapshotID), - VolumeSize: aws.Int64(20), - VolumeType: aws.String("gp2"), + DeviceName: pointer.To("/dev/xvda"), + VirtualName: pointer.To("talos"), + Ebs: &types.EbsBlockDevice{ + DeleteOnTermination: pointer.To(true), + SnapshotId: pointer.To(snapshotID), + VolumeSize: pointer.To[int32](20), + VolumeType: types.VolumeTypeGp2, }, }, }, - RootDeviceName: aws.String("/dev/xvda"), - VirtualizationType: aws.String("hvm"), - EnaSupport: aws.Bool(true), - Description: aws.String(fmt.Sprintf("Talos AMI %s %s %s", au.Options.Tag, arch, region)), - Architecture: aws.String(awsArchitectures[arch]), - ImdsSupport: aws.String("v2.0"), + RootDeviceName: pointer.To("/dev/xvda"), + VirtualizationType: pointer.To("hvm"), + EnaSupport: pointer.To(true), + Description: pointer.To(fmt.Sprintf("Talos AMI %s %s %s", au.Options.Tag, arch, region)), + Architecture: awsArchitectures[arch], + ImdsSupport: types.ImdsSupportValuesV20, }) if err != nil { return err @@ -345,12 +413,12 @@ func (au *AWSUploader) registerAMIArch(ctx context.Context, region string, svc * log.Printf("aws: import into %s/%s, registered image ID %q", region, arch, imageID) - _, err = svc.ModifyImageAttributeWithContext(ctx, &ec2.ModifyImageAttributeInput{ + _, err = svc.ModifyImageAttribute(ctx, &ec2.ModifyImageAttributeInput{ ImageId: aws.String(imageID), - LaunchPermission: &ec2.LaunchPermissionModifications{ - Add: []*ec2.LaunchPermission{ + LaunchPermission: &types.LaunchPermissionModifications{ + Add: []types.LaunchPermission{ { - Group: aws.String("all"), + Group: types.PermissionGroupAll, }, }, }, diff --git a/hack/cloud-image-uploader/go.mod b/hack/cloud-image-uploader/go.mod index e9432fd1cf..e5c7a9c624 100644 --- a/hack/cloud-image-uploader/go.mod +++ b/hack/cloud-image-uploader/go.mod @@ -12,7 +12,11 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.5.0 github.com/Azure/go-autorest/autorest v0.11.29 github.com/Azure/go-autorest/autorest/azure/auth v0.5.13 - github.com/aws/aws-sdk-go v1.55.5 + github.com/aws/aws-sdk-go-v2 v1.32.7 + github.com/aws/aws-sdk-go-v2/config v1.28.7 + github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.44 + github.com/aws/aws-sdk-go-v2/service/ec2 v1.198.1 + github.com/aws/aws-sdk-go-v2/service/s3 v1.71.1 github.com/blang/semver/v4 v4.0.0 github.com/google/uuid v1.6.0 github.com/klauspost/compress v1.17.11 @@ -45,6 +49,21 @@ require ( github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.25.0 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.48.1 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.48.1 // indirect + github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.17.48 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.22 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.26 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.26 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.26 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.7 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.7 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.7 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.24.8 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.7 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.33.3 // indirect + github.com/aws/smithy-go v1.22.1 // indirect github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78 // indirect @@ -60,7 +79,6 @@ require ( github.com/google/s2a-go v0.1.8 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.4 // indirect github.com/googleapis/gax-go/v2 v2.14.0 // indirect - github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect diff --git a/hack/cloud-image-uploader/go.sum b/hack/cloud-image-uploader/go.sum index d13b4ac68d..dd7b805a37 100644 --- a/hack/cloud-image-uploader/go.sum +++ b/hack/cloud-image-uploader/go.sum @@ -82,8 +82,46 @@ github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0 github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.48.1/go.mod h1:0wEl7vrAD8mehJyohS9HZy+WyEOaQO2mJx86Cvh93kM= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.48.1 h1:8nn+rsCvTq9axyEh382S0PFLBeaFwNsT43IrPWzctRU= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.48.1/go.mod h1:viRWSEhtMZqz1rhwmOVKkWl6SwmVowfL9O2YR5gI2PE= -github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU= -github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= +github.com/aws/aws-sdk-go-v2 v1.32.7 h1:ky5o35oENWi0JYWUZkB7WYvVPP+bcRF5/Iq7JWSb5Rw= +github.com/aws/aws-sdk-go-v2 v1.32.7/go.mod h1:P5WJBrYqqbWVaOxgH0X/FYYD47/nooaPOZPlQdmiN2U= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7 h1:lL7IfaFzngfx0ZwUGOZdsFFnQ5uLvR0hWqqhyE7Q9M8= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7/go.mod h1:QraP0UcVlQJsmHfioCrveWOC1nbiWUl3ej08h4mXWoc= +github.com/aws/aws-sdk-go-v2/config v1.28.7 h1:GduUnoTXlhkgnxTD93g1nv4tVPILbdNQOzav+Wpg7AE= +github.com/aws/aws-sdk-go-v2/config v1.28.7/go.mod h1:vZGX6GVkIE8uECSUHB6MWAUsd4ZcG2Yq/dMa4refR3M= +github.com/aws/aws-sdk-go-v2/credentials v1.17.48 h1:IYdLD1qTJ0zanRavulofmqut4afs45mOWEI+MzZtTfQ= +github.com/aws/aws-sdk-go-v2/credentials v1.17.48/go.mod h1:tOscxHN3CGmuX9idQ3+qbkzrjVIx32lqDSU1/0d/qXs= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.22 h1:kqOrpojG71DxJm/KDPO+Z/y1phm1JlC8/iT+5XRmAn8= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.22/go.mod h1:NtSFajXVVL8TA2QNngagVZmUtXciyrHOt7xgz4faS/M= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.44 h1:2zxMLXLedpB4K1ilbJFxtMKsVKaexOqDttOhc0QGm3Q= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.44/go.mod h1:VuLHdqwjSvgftNC7yqPWyGVhEwPmJpeRi07gOgOfHF8= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.26 h1:I/5wmGMffY4happ8NOCuIUEWGUvvFp5NSeQcXl9RHcI= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.26/go.mod h1:FR8f4turZtNy6baO0KJ5FJUmXH/cSkI9fOngs0yl6mA= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.26 h1:zXFLuEuMMUOvEARXFUVJdfqZ4bvvSgdGRq/ATcrQxzM= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.26/go.mod h1:3o2Wpy0bogG1kyOPrgkXA8pgIfEEv0+m19O9D5+W8y8= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.26 h1:GeNJsIFHB+WW5ap2Tec4K6dzcVTsRbsT1Lra46Hv9ME= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.26/go.mod h1:zfgMpwHDXX2WGoG84xG2H+ZlPTkJUU4YUvx2svLQYWo= +github.com/aws/aws-sdk-go-v2/service/ec2 v1.198.1 h1:YbNopxjd9baM83YEEmkaYHi+NuJt0AszeaSLqo0CVr0= +github.com/aws/aws-sdk-go-v2/service/ec2 v1.198.1/go.mod h1:mwr3iRm8u1+kkEx4ftDM2Q6Yr0XQFBKrP036ng+k5Lk= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1 h1:iXtILhvDxB6kPvEXgsDhGaZCSC6LQET5ZHSdJozeI0Y= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1/go.mod h1:9nu0fVANtYiAePIBh2/pFUSwtJ402hLnp854CNoDOeE= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.7 h1:tB4tNw83KcajNAzaIMhkhVI2Nt8fAZd5A5ro113FEMY= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.7/go.mod h1:lvpyBGkZ3tZ9iSsUIcC2EWp+0ywa7aK3BLT+FwZi+mQ= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.7 h1:8eUsivBQzZHqe/3FE+cqwfH+0p5Jo8PFM/QYQSmeZ+M= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.7/go.mod h1:kLPQvGUmxn/fqiCrDeohwG33bq2pQpGeY62yRO6Nrh0= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.7 h1:Hi0KGbrnr57bEHWM0bJ1QcBzxLrL/k2DHvGYhb8+W1w= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.7/go.mod h1:wKNgWgExdjjrm4qvfbTorkvocEstaoDl4WCvGfeCy9c= +github.com/aws/aws-sdk-go-v2/service/s3 v1.71.1 h1:aOVVZJgWbaH+EJYPvEgkNhCEbXXvH7+oML36oaPK3zE= +github.com/aws/aws-sdk-go-v2/service/s3 v1.71.1/go.mod h1:r+xl5yzMk9083rMR+sJ5TYj9Tihvf/l1oxzZXDgGj2Q= +github.com/aws/aws-sdk-go-v2/service/sso v1.24.8 h1:CvuUmnXI7ebaUAhbJcDy9YQx8wHR69eZ9I7q5hszt/g= +github.com/aws/aws-sdk-go-v2/service/sso v1.24.8/go.mod h1:XDeGv1opzwm8ubxddF0cgqkZWsyOtw4lr6dxwmb6YQg= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.7 h1:F2rBfNAL5UyswqoeWv9zs74N/NanhK16ydHW1pahX6E= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.7/go.mod h1:JfyQ0g2JG8+Krq0EuZNnRwX0mU0HrwY/tG6JNfcqh4k= +github.com/aws/aws-sdk-go-v2/service/sts v1.33.3 h1:Xgv/hyNgvLda/M9l9qxXc4UFSgppnRczLxlMs5Ae/QY= +github.com/aws/aws-sdk-go-v2/service/sts v1.33.3/go.mod h1:5Gn+d+VaaRgsjewpMvGazt0WfcFO+Md4wLOuBfGR9Bc= +github.com/aws/smithy-go v1.22.1 h1:/HPHZQ0g7f4eUeK6HKglFz8uwVfZKgoI25rb/J+dnro= +github.com/aws/smithy-go v1.22.1/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -158,10 +196,6 @@ github.com/googleapis/enterprise-certificate-proxy v0.3.4 h1:XYIDZApgAnrN1c855gT github.com/googleapis/enterprise-certificate-proxy v0.3.4/go.mod h1:YKe7cfqYXjKGpGvmSg28/fFvhNzinZQm8DGnaburhGA= github.com/googleapis/gax-go/v2 v2.14.0 h1:f+jMrjBPl+DL9nI4IQzLUxMq7XrAqFYB7hBPqMNIe8o= github.com/googleapis/gax-go/v2 v2.14.0/go.mod h1:lhBCnjdLrWRaPvLWhmc8IS24m9mr07qSYnHncrgo+zk= -github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= -github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= -github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= -github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6 h1:IsMZxCuZqKuao2vNdfD82fjjgPLfyHLpR41Z88viRWs= github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6/go.mod h1:3VeWNIJaW+O5xpRQbPp0Ybqu1vJd/pm7s2F473HRrkw= github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= @@ -329,9 +363,6 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/hack/cloud-image-uploader/main.go b/hack/cloud-image-uploader/main.go index e491f0279c..7cd2675604 100644 --- a/hack/cloud-image-uploader/main.go +++ b/hack/cloud-image-uploader/main.go @@ -13,8 +13,10 @@ import ( "io" "log" "os" + "os/signal" "path/filepath" "sync" + "syscall" "github.com/spf13/pflag" "golang.org/x/sync/errgroup" @@ -71,7 +73,7 @@ func run() error { log.Fatalf("error seeding rand: %s", err) } - ctx, cancel := context.WithCancel(context.Background()) + ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM) defer cancel() var g *errgroup.Group @@ -83,7 +85,7 @@ func run() error { case "aws": g.Go(func() error { if len(DefaultOptions.AWSRegions) == 0 { - DefaultOptions.AWSRegions, err = GetAWSDefaultRegions() + DefaultOptions.AWSRegions, err = GetAWSDefaultRegions(ctx) if err != nil { log.Printf("failed to get a list of enabled AWS regions: %s, ignored", err) }