diff --git a/go.mod b/go.mod index 8e1323d22..e07b5a838 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( github.com/jackc/pgx/v5 v5.4.1 github.com/microcosm-cc/bluemonday v1.0.24 github.com/miekg/dns v1.1.55 - github.com/minio/minio-go/v7 v7.0.59 + github.com/minio/minio-go/v7 v7.0.60 github.com/mitchellh/mapstructure v1.5.0 github.com/oklog/ulid v1.3.1 github.com/spf13/cobra v1.7.0 diff --git a/go.sum b/go.sum index 8faabcacf..deb6a2ee7 100644 --- a/go.sum +++ b/go.sum @@ -450,8 +450,8 @@ github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo= github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34= github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM= -github.com/minio/minio-go/v7 v7.0.59 h1:lxIXwsTIcQkYoEG25rUJbzpmSB/oWeVDmxFo/uWUUsw= -github.com/minio/minio-go/v7 v7.0.59/go.mod h1:NUDy4A4oXPq1l2yK6LTSvCEzAMeIcoz9lcj5dbzSrRE= +github.com/minio/minio-go/v7 v7.0.60 h1:iHkrmWyHFs/eZiWc2F/5jAHtNBAFy+HjdhMX6FkkPWc= +github.com/minio/minio-go/v7 v7.0.60/go.mod h1:NUDy4A4oXPq1l2yK6LTSvCEzAMeIcoz9lcj5dbzSrRE= github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= github.com/mitchellh/hashstructure/v2 v2.0.2 h1:vGKWl0YJqUNxE8d+h8f6NJLcCJrgbhC4NcD46KavDd4= diff --git a/vendor/github.com/minio/minio-go/v7/api-datatypes.go b/vendor/github.com/minio/minio-go/v7/api-datatypes.go index e1a34e003..97a6f80b2 100644 --- a/vendor/github.com/minio/minio-go/v7/api-datatypes.go +++ b/vendor/github.com/minio/minio-go/v7/api-datatypes.go @@ -220,6 +220,11 @@ type ObjectInfo struct { ChecksumSHA1 string ChecksumSHA256 string + Internal *struct { + K int // Data blocks + M int // Parity blocks + } `xml:"Internal"` + // Error Err error `json:"-"` } diff --git a/vendor/github.com/minio/minio-go/v7/api-list.go b/vendor/github.com/minio/minio-go/v7/api-list.go index 627811cfd..3b50f61d3 100644 --- a/vendor/github.com/minio/minio-go/v7/api-list.go +++ b/vendor/github.com/minio/minio-go/v7/api-list.go @@ -97,7 +97,15 @@ func (c *Client) listObjectsV2(ctx context.Context, bucketName string, opts List // Initiate list objects goroutine here. go func(objectStatCh chan<- ObjectInfo) { - defer close(objectStatCh) + defer func() { + if contextCanceled(ctx) { + objectStatCh <- ObjectInfo{ + Err: ctx.Err(), + } + } + close(objectStatCh) + }() + // Save continuationToken for next request. var continuationToken string for { @@ -304,7 +312,14 @@ func (c *Client) listObjects(ctx context.Context, bucketName string, opts ListOb // Initiate list objects goroutine here. go func(objectStatCh chan<- ObjectInfo) { - defer close(objectStatCh) + defer func() { + if contextCanceled(ctx) { + objectStatCh <- ObjectInfo{ + Err: ctx.Err(), + } + } + close(objectStatCh) + }() marker := opts.StartAfter for { @@ -321,6 +336,7 @@ func (c *Client) listObjects(ctx context.Context, bucketName string, opts ListOb for _, object := range result.Contents { // Save the marker. marker = object.Key + object.ETag = trimEtag(object.ETag) select { // Send object content. case objectStatCh <- object: @@ -393,7 +409,14 @@ func (c *Client) listObjectVersions(ctx context.Context, bucketName string, opts // Initiate list objects goroutine here. go func(resultCh chan<- ObjectInfo) { - defer close(resultCh) + defer func() { + if contextCanceled(ctx) { + resultCh <- ObjectInfo{ + Err: ctx.Err(), + } + } + close(resultCh) + }() var ( keyMarker = "" @@ -424,6 +447,7 @@ func (c *Client) listObjectVersions(ctx context.Context, bucketName string, opts IsDeleteMarker: version.isDeleteMarker, UserTags: version.UserTags, UserMetadata: version.UserMetadata, + Internal: version.Internal, } select { // Send object version info. @@ -698,6 +722,10 @@ func (o *ListObjectsOptions) Set(key, value string) { // for object := range api.ListObjects(ctx, "mytestbucket", minio.ListObjectsOptions{Prefix: "starthere", Recursive:true}) { // fmt.Println(object) // } +// +// If caller cancels the context, then the last entry on the 'chan ObjectInfo' will be the context.Error() +// caller must drain the channel entirely and wait until channel is closed before proceeding, without +// waiting on the channel to be closed completely you might leak goroutines. func (c *Client) ListObjects(ctx context.Context, bucketName string, opts ListObjectsOptions) <-chan ObjectInfo { if opts.WithVersions { return c.listObjectVersions(ctx, bucketName, opts) @@ -738,6 +766,16 @@ func (c *Client) ListIncompleteUploads(ctx context.Context, bucketName, objectPr return c.listIncompleteUploads(ctx, bucketName, objectPrefix, recursive) } +// contextCanceled returns whether a context is canceled. +func contextCanceled(ctx context.Context) bool { + select { + case <-ctx.Done(): + return true + default: + return false + } +} + // listIncompleteUploads lists all incomplete uploads. func (c *Client) listIncompleteUploads(ctx context.Context, bucketName, objectPrefix string, recursive bool) <-chan ObjectMultipartInfo { // Allocate channel for multipart uploads. @@ -765,7 +803,15 @@ func (c *Client) listIncompleteUploads(ctx context.Context, bucketName, objectPr return objectMultipartStatCh } go func(objectMultipartStatCh chan<- ObjectMultipartInfo) { - defer close(objectMultipartStatCh) + defer func() { + if contextCanceled(ctx) { + objectMultipartStatCh <- ObjectMultipartInfo{ + Err: ctx.Err(), + } + } + close(objectMultipartStatCh) + }() + // object and upload ID marker for future requests. var objectMarker string var uploadIDMarker string diff --git a/vendor/github.com/minio/minio-go/v7/api-s3-datatypes.go b/vendor/github.com/minio/minio-go/v7/api-s3-datatypes.go index 6e784be4c..1527b746e 100644 --- a/vendor/github.com/minio/minio-go/v7/api-s3-datatypes.go +++ b/vendor/github.com/minio/minio-go/v7/api-s3-datatypes.go @@ -93,6 +93,11 @@ type Version struct { // Only returned by MinIO servers. UserTags URLMap `json:"userTags,omitempty" xml:"UserTags"` + Internal *struct { + K int // Data blocks + M int // Parity blocks + } `xml:"Internal"` + isDeleteMarker bool } diff --git a/vendor/github.com/minio/minio-go/v7/api.go b/vendor/github.com/minio/minio-go/v7/api.go index 9251c3894..93c255a09 100644 --- a/vendor/github.com/minio/minio-go/v7/api.go +++ b/vendor/github.com/minio/minio-go/v7/api.go @@ -124,7 +124,7 @@ type Options struct { // Global constants. const ( libraryName = "minio-go" - libraryVersion = "v7.0.59" + libraryVersion = "v7.0.60" ) // User Agent should always following the below style. diff --git a/vendor/github.com/minio/minio-go/v7/functional_tests.go b/vendor/github.com/minio/minio-go/v7/functional_tests.go index 2bc6b8645..3c83d6f64 100644 --- a/vendor/github.com/minio/minio-go/v7/functional_tests.go +++ b/vendor/github.com/minio/minio-go/v7/functional_tests.go @@ -2471,7 +2471,8 @@ function := "PutObject(bucketName, objectName, reader,size, opts)" PO minio.PutObjectOptions }{ // Currently there is no way to override the checksum type. - {header: "x-amz-checksum-crc32c", + { + header: "x-amz-checksum-crc32c", hasher: crc32.New(crc32.MakeTable(crc32.Castagnoli)), ChecksumCRC32C: "set", PO: minio.PutObjectOptions{ @@ -2481,7 +2482,8 @@ function := "PutObject(bucketName, objectName, reader,size, opts)" PartSize: 5 << 20, }, }, - {header: "x-amz-checksum-crc32c", + { + header: "x-amz-checksum-crc32c", hasher: crc32.New(crc32.MakeTable(crc32.Castagnoli)), ChecksumCRC32C: "set", PO: minio.PutObjectOptions{ @@ -2491,7 +2493,8 @@ function := "PutObject(bucketName, objectName, reader,size, opts)" PartSize: 6_645_654, // Rather arbitrary size }, }, - {header: "x-amz-checksum-crc32c", + { + header: "x-amz-checksum-crc32c", hasher: crc32.New(crc32.MakeTable(crc32.Castagnoli)), ChecksumCRC32C: "set", PO: minio.PutObjectOptions{ @@ -2501,7 +2504,8 @@ function := "PutObject(bucketName, objectName, reader,size, opts)" PartSize: 5 << 20, }, }, - {header: "x-amz-checksum-crc32c", + { + header: "x-amz-checksum-crc32c", hasher: crc32.New(crc32.MakeTable(crc32.Castagnoli)), ChecksumCRC32C: "set", PO: minio.PutObjectOptions{ diff --git a/vendor/github.com/minio/minio-go/v7/pkg/lifecycle/lifecycle.go b/vendor/github.com/minio/minio-go/v7/pkg/lifecycle/lifecycle.go index 55b0d716f..830061b8e 100644 --- a/vendor/github.com/minio/minio-go/v7/pkg/lifecycle/lifecycle.go +++ b/vendor/github.com/minio/minio-go/v7/pkg/lifecycle/lifecycle.go @@ -308,19 +308,27 @@ func (eDate ExpirationDate) MarshalXML(e *xml.Encoder, startElement xml.StartEle } // ExpireDeleteMarker represents value of ExpiredObjectDeleteMarker field in Expiration XML element. -type ExpireDeleteMarker bool +type ExpireDeleteMarker ExpirationBoolean + +// IsEnabled returns true if the auto delete-marker expiration is enabled +func (e ExpireDeleteMarker) IsEnabled() bool { + return bool(e) +} + +// ExpirationBoolean represents an XML version of 'bool' type +type ExpirationBoolean bool // MarshalXML encodes delete marker boolean into an XML form. -func (b ExpireDeleteMarker) MarshalXML(e *xml.Encoder, startElement xml.StartElement) error { +func (b ExpirationBoolean) MarshalXML(e *xml.Encoder, startElement xml.StartElement) error { if !b { return nil } - type expireDeleteMarkerWrapper ExpireDeleteMarker - return e.EncodeElement(expireDeleteMarkerWrapper(b), startElement) + type booleanWrapper ExpirationBoolean + return e.EncodeElement(booleanWrapper(b), startElement) } -// IsEnabled returns true if the auto delete-marker expiration is enabled -func (b ExpireDeleteMarker) IsEnabled() bool { +// IsEnabled returns true if the expiration boolean is enabled +func (b ExpirationBoolean) IsEnabled() bool { return bool(b) } @@ -330,6 +338,7 @@ type Expiration struct { Date ExpirationDate `xml:"Date,omitempty" json:"Date,omitempty"` Days ExpirationDays `xml:"Days,omitempty" json:"Days,omitempty"` DeleteMarker ExpireDeleteMarker `xml:"ExpiredObjectDeleteMarker,omitempty" json:"ExpiredObjectDeleteMarker,omitempty"` + DeleteAll ExpirationBoolean `xml:"ExpiredObjectAllVersions,omitempty" json:"ExpiredObjectAllVersions,omitempty"` } // MarshalJSON customizes json encoding by removing empty day/date specification. @@ -338,10 +347,12 @@ type expiration struct { Date *ExpirationDate `json:"Date,omitempty"` Days *ExpirationDays `json:"Days,omitempty"` DeleteMarker ExpireDeleteMarker `json:"ExpiredObjectDeleteMarker,omitempty"` + DeleteAll ExpirationBoolean `json:"ExpiredObjectAllVersions,omitempty"` } newexp := expiration{ DeleteMarker: e.DeleteMarker, + DeleteAll: e.DeleteAll, } if !e.IsDaysNull() { newexp.Days = &e.Days diff --git a/vendor/github.com/minio/minio-go/v7/pkg/tags/tags.go b/vendor/github.com/minio/minio-go/v7/pkg/tags/tags.go index 98ae17efa..7a84a6f34 100644 --- a/vendor/github.com/minio/minio-go/v7/pkg/tags/tags.go +++ b/vendor/github.com/minio/minio-go/v7/pkg/tags/tags.go @@ -203,6 +203,10 @@ func (tags *tagSet) set(key, value string, failOnExist bool) error { return nil } +func (tags tagSet) count() int { + return len(tags.tagMap) +} + func (tags tagSet) toMap() map[string]string { m := make(map[string]string, len(tags.tagMap)) for key, value := range tags.tagMap { @@ -279,6 +283,11 @@ func (tags *Tags) Set(key, value string) error { return tags.TagSet.set(key, value, false) } +// Count - return number of tags accounted for +func (tags Tags) Count() int { + return tags.TagSet.count() +} + // ToMap returns copy of tags. func (tags Tags) ToMap() map[string]string { return tags.TagSet.toMap() diff --git a/vendor/modules.txt b/vendor/modules.txt index 8a972826e..69cfd5038 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -386,7 +386,7 @@ github.com/miekg/dns # github.com/minio/md5-simd v1.1.2 ## explicit; go 1.14 github.com/minio/md5-simd -# github.com/minio/minio-go/v7 v7.0.59 +# github.com/minio/minio-go/v7 v7.0.60 ## explicit; go 1.17 github.com/minio/minio-go/v7 github.com/minio/minio-go/v7/pkg/credentials