diff --git a/blob/blob.go b/blob/blob.go index 9d652ffad..0226b0ca1 100644 --- a/blob/blob.go +++ b/blob/blob.go @@ -1216,6 +1216,7 @@ func (b *Bucket) Copy(ctx context.Context, dstKey, srcKey string, opts *CopyOpti } dopts := &driver.CopyOptions{ BeforeCopy: opts.BeforeCopy, + Tags: opts.Tags, } b.mu.RLock() defer b.mu.RUnlock() @@ -1459,6 +1460,10 @@ type CopyOptions struct { // asFunc converts its argument to driver-specific types. // See https://gocloud.dev/concepts/as/ for background information. BeforeCopy func(asFunc func(any) bool) error + + // Tags holds key/value tags to be associated with the blob, or nil. + // Keys and values must be not empty if specified. + Tags map[string]string } // BucketURLOpener represents types that can open buckets based on a URL. diff --git a/blob/driver/driver.go b/blob/driver/driver.go index 69d9cd7c7..01d77f272 100644 --- a/blob/driver/driver.go +++ b/blob/driver/driver.go @@ -127,6 +127,10 @@ type CopyOptions struct { // asFunc allows drivers to expose driver-specific types; // see Bucket.As for more details. BeforeCopy func(asFunc func(any) bool) error + + // Tags holds key/value tags to be associated with the blob, or nil. + // Keys and values must be not empty if specified. + Tags map[string]string } // ReaderAttributes contains a subset of attributes about a blob that are diff --git a/blob/s3blob/s3blob.go b/blob/s3blob/s3blob.go index 69484018c..5d9a6a481 100644 --- a/blob/s3blob/s3blob.go +++ b/blob/s3blob/s3blob.go @@ -853,6 +853,11 @@ func (b *bucket) Copy(ctx context.Context, dstKey, srcKey string, opts *driver.C if b.kmsKeyId != "" { input.SSEKMSKeyId = aws.String(b.kmsKeyId) } + if len(opts.Tags) > 0 { + encodedTags := encodeTags(opts.Tags) + input.Tagging = aws.String(encodedTags) + } + if opts.BeforeCopy != nil { asFunc := func(i any) bool { switch v := i.(type) {