mirror of
https://github.com/pgsty/minio.git
synced 2026-10-30 04:20:36 +03:00
fix: carry per-bucket CORS through bucket metadata export/import
The admin bucket-metadata handlers enumerate every bucket config by name, and per-bucket CORS was never added to that enumeration: export omitted cors.xml (cmd/admin-bucket-handlers.go:414 cfgFiles) and import ignored the entry outright, with no case in applyImportedBucketMetadata (:598) or SetStatus (:629), so a CORS-only archive reported 0/0 buckets imported and a restored bucket silently lost its configuration. Export now writes the stored document verbatim and import validates it with the same parser and validator as PutBucketCorsHandler, merging it under the existing bucket metadata lock and announcing it through the dedicated SRBucketMetaTypeCorsConfig event; the local CORS timestamp rule is extracted into localCORSUpdatedAt and reused so an imported document always lands strictly above bucket creation, which matters because the import stamps its fields before creating any missing bucket and a CORS event below Created is dropped as an older bucket incarnation. The import reads one byte past the declared entry size so archive/zip reaches EOF and verifies the entry checksum, otherwise a corrupt or over-long entry carrying well formed XML would overwrite the stored document; and the CORS event is sent even when the shared bucket metadata hook failed, so an unreachable peer cannot withhold an already committed CORS document from the reachable ones. Tests: TestAdminBucketMetadataCORSRoundTrip and TestAdminBucketMetadataCORSImportReplicatesPastPeerFailure (new, ErasureSD and Erasure). Compatibility: the ZIP gains one entry, older archives stay importable and leave CORS untouched; no mcli or madmin-go change is needed because madmin.BucketStatus already carries Cors and mcli copies the export ZIP verbatim. Fixes pgsty/silo#112 Signed-off-by: Feng Ruohang <rh@vonng.com> Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L7qJqWwy8oFA6aCXWRzXQe
This commit is contained in:
+18
-8
@@ -1978,6 +1978,23 @@ func updateLocalBucketCORSMetadata(ctx context.Context, objectAPI ObjectLayer, b
|
||||
return applyBucketCORSMetadata(ctx, objectAPI, bucket, configData, time.Time{}, true)
|
||||
}
|
||||
|
||||
// localCORSUpdatedAt returns the timestamp a locally originated CORS update
|
||||
// must carry: now, advanced strictly past both bucket creation and the current
|
||||
// CORS timestamp. A CORS event stamped before bucket creation is discarded as
|
||||
// belonging to an older incarnation of the bucket, so a local write must never
|
||||
// land at or below that floor.
|
||||
func localCORSUpdatedAt(meta BucketMetadata, now time.Time) time.Time {
|
||||
updatedAt := now.UTC()
|
||||
floor := meta.Created
|
||||
if current := meta.CorsConfigUpdatedAt.UTC(); current.After(floor) {
|
||||
floor = current
|
||||
}
|
||||
if !updatedAt.After(floor) {
|
||||
updatedAt = floor.Add(time.Nanosecond)
|
||||
}
|
||||
return updatedAt
|
||||
}
|
||||
|
||||
func applyBucketCORSMetadata(ctx context.Context, objectAPI ObjectLayer, bucket string, configData []byte, sourceUpdatedAt time.Time, local bool) (time.Time, error) {
|
||||
if bucket == "" || (configData != nil && len(configData) == 0) {
|
||||
return time.Time{}, errInvalidArgument
|
||||
@@ -2011,14 +2028,7 @@ func applyBucketCORSMetadata(ctx context.Context, objectAPI ObjectLayer, bucket
|
||||
localState := newCORSReplicationState(meta.CorsConfigXML, meta.CorsConfigUpdatedAt)
|
||||
updatedAt := sourceUpdatedAt.UTC()
|
||||
if local {
|
||||
updatedAt = UTCNow()
|
||||
floor := meta.Created
|
||||
if localState.updatedAt.After(floor) {
|
||||
floor = localState.updatedAt
|
||||
}
|
||||
if !updatedAt.After(floor) {
|
||||
updatedAt = floor.Add(time.Nanosecond)
|
||||
}
|
||||
updatedAt = localCORSUpdatedAt(meta, UTCNow())
|
||||
} else {
|
||||
// CreatedAt is the bucket-lineage floor: an event from an older
|
||||
// incarnation of the bucket must not change the current one.
|
||||
|
||||
Reference in New Issue
Block a user