Merge pull request #1122 from docker/s3_bucket_conflict

s3 bucket name must be unique. Create bucket with uuid name
This commit is contained in:
Nicolas De loof 2021-01-12 12:08:39 +01:00 committed by GitHub
commit f6e5c911ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -31,7 +31,6 @@ import (
"github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/arn" "github.com/aws/aws-sdk-go/aws/arn"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/autoscaling" "github.com/aws/aws-sdk-go/service/autoscaling"
@ -274,40 +273,32 @@ func (s sdk) withTemplate(ctx context.Context, name string, template []byte, reg
return fn(aws.String(string(template)), nil) return fn(aws.String(string(template)), nil)
} }
logrus.Debug("Create s3 bucket to store cloudformation template") key, err := uuid.GenerateUUID()
if err != nil {
return "", err
}
bucket := "com.docker.compose." + key
logrus.Debugf("Create s3 bucket %q to store cloudformation template", bucket)
var configuration *s3.CreateBucketConfiguration var configuration *s3.CreateBucketConfiguration
if region != "us-east-1" { if region != "us-east-1" {
configuration = &s3.CreateBucketConfiguration{ configuration = &s3.CreateBucketConfiguration{
LocationConstraint: aws.String(region), LocationConstraint: aws.String(region),
} }
} }
// CloudFormation will only allow URL from a same-region bucket _, err = s.S3.CreateBucket(&s3.CreateBucketInput{
// to avoid conflicts we suffix bucket name by region, so we can create comparable buckets in other regions.
bucket := "com.docker.compose." + region
_, err := s.S3.CreateBucket(&s3.CreateBucketInput{
Bucket: aws.String(bucket), Bucket: aws.String(bucket),
CreateBucketConfiguration: configuration, CreateBucketConfiguration: configuration,
}) })
if err != nil {
ae, ok := err.(awserr.Error)
if !ok {
return "", err
}
if ae.Code() != s3.ErrCodeBucketAlreadyOwnedByYou {
return "", err
}
}
key, err := uuid.GenerateUUID()
if err != nil { if err != nil {
return "", err return "", err
} }
upload, err := s.uploader.UploadWithContext(ctx, &s3manager.UploadInput{ upload, err := s.uploader.UploadWithContext(ctx, &s3manager.UploadInput{
Key: aws.String(key), Key: aws.String("template.yaml"),
Body: bytes.NewReader(template), Body: bytes.NewReader(template),
Bucket: aws.String(bucket), Bucket: aws.String(bucket),
ContentType: aws.String("application/json"), ContentType: aws.String("application/x-yaml"),
Tagging: aws.String(name), Tagging: aws.String(name),
}) })
@ -315,17 +306,22 @@ func (s sdk) withTemplate(ctx context.Context, name string, template []byte, reg
return "", err return "", err
} }
defer s.S3.DeleteObjects(&s3.DeleteObjectsInput{ //nolint: errcheck defer func() {
Bucket: aws.String(bucket), _, err := s.S3.DeleteObjectWithContext(ctx, &s3.DeleteObjectInput{
Delete: &s3.Delete{ Bucket: aws.String(bucket),
Objects: []*s3.ObjectIdentifier{ Key: aws.String("template.yaml"),
{ VersionId: upload.VersionID,
Key: aws.String(key), })
VersionId: upload.VersionID, if err != nil {
}, logrus.Warnf("Failed to remove S3 bucket: %s", err)
}, }
}, _, err = s.S3.DeleteBucketWithContext(ctx, &s3.DeleteBucketInput{
}) Bucket: aws.String(bucket),
})
if err != nil {
logrus.Warnf("Failed to remove S3 bucket: %s", err)
}
}()
return fn(nil, aws.String(upload.Location)) return fn(nil, aws.String(upload.Location))
} }