fix: preserve metadata during bucket creation and adoption

After storage bucket creation, merge required versioning and lock defaults into the latest on-disk metadata under metadata.lock. Avoid ForceCreate and site-adoption rewrites that replaced existing bucket configuration.\n\nRefs: #102

Signed-off-by: Feng Ruohang <rh@vonng.com>
This commit is contained in:
Feng Ruohang
2026-09-02 00:42:00 +08:00
parent 312397739e
commit 62d8c649fe
2 changed files with 64 additions and 34 deletions
+44 -13
View File
@@ -882,23 +882,54 @@ func (z *erasureServerPools) MakeBucket(ctx context.Context, bucket string, opts
return err
}
// If it doesn't exist we get a new, so ignore errors
meta := newBucketMetadata(bucket)
meta.SetCreatedAt(opts.CreatedAt)
if opts.LockEnabled {
meta.VersioningConfigXML = enabledBucketVersioningConfig
meta.ObjectLockConfigXML = enabledBucketObjectLockConfig
if isMinioMetaBucketName(bucket) {
meta := newBucketMetadata(bucket)
meta.SetCreatedAt(opts.CreatedAt)
if err := meta.Save(context.Background(), z); err != nil {
return toObjectErr(err, bucket)
}
globalBucketMetadataSys.Set(bucket, meta)
return nil
}
if opts.VersioningEnabled {
meta.VersioningConfigXML = enabledBucketVersioningConfig
}
if err := meta.Save(context.Background(), z); err != nil {
ctx, unlock, err := lockBucketMetadata(ctx, z, bucket)
if err != nil {
return toObjectErr(err, bucket)
}
err = func() error {
defer unlock()
meta, err := readBucketMetadata(ctx, z, bucket)
if errors.Is(err, errConfigNotFound) {
meta = newBucketMetadata(bucket)
} else if err != nil {
return err
}
if meta.Created.IsZero() {
meta.SetCreatedAt(opts.CreatedAt)
}
if opts.LockEnabled {
if len(meta.VersioningConfigXML) == 0 {
meta.VersioningConfigXML = enabledBucketVersioningConfig
meta.VersioningConfigUpdatedAt = meta.Created
}
if len(meta.ObjectLockConfigXML) == 0 {
meta.ObjectLockConfigXML = enabledBucketObjectLockConfig
meta.ObjectLockConfigUpdatedAt = meta.Created
}
}
if opts.VersioningEnabled && len(meta.VersioningConfigXML) == 0 {
meta.VersioningConfigXML = enabledBucketVersioningConfig
meta.VersioningConfigUpdatedAt = meta.Created
}
if err = meta.Save(ctx, z); err != nil {
return err
}
globalBucketMetadataSys.Set(bucket, meta)
return nil
}()
if err != nil {
return toObjectErr(err, bucket)
}
globalBucketMetadataSys.Set(bucket, meta)
// Success.
return nil
+20 -21
View File
@@ -930,35 +930,34 @@ func (c *SiteReplicationSys) PeerBucketMakeWithVersioningHandler(ctx context.Con
if !ok1 && !ok2 {
return wrapSRErr(c.annotateErr(makeBucketWithVersion, err))
}
} else {
// Load updated bucket metadata into memory as new
// bucket was created.
globalNotificationSys.LoadBucketMetadata(GlobalContext, bucket)
}
meta, err := globalBucketMetadataSys.Get(bucket)
ctx, unlock, err := lockBucketMetadata(ctx, objAPI, bucket)
if err != nil {
return wrapSRErr(c.annotateErr(makeBucketWithVersion, err))
}
meta.SetCreatedAt(opts.CreatedAt)
if err := enablePeerBucketVersioning(&meta); err != nil {
return wrapSRErr(err)
}
if opts.LockEnabled && len(meta.ObjectLockConfigXML) == 0 {
meta.ObjectLockConfigXML = enabledBucketObjectLockConfig
if meta.ObjectLockConfigUpdatedAt.IsZero() {
meta.ObjectLockConfigUpdatedAt = meta.Created
err = func() error {
defer unlock()
meta, err := loadBucketMetadataParse(ctx, objAPI, bucket, true)
if err != nil {
return err
}
}
meta.SetCreatedAt(opts.CreatedAt)
if err := meta.Save(context.Background(), objAPI); err != nil {
return wrapSRErr(err)
if err = enablePeerBucketVersioning(&meta); err != nil {
return err
}
if opts.LockEnabled && len(meta.ObjectLockConfigXML) == 0 {
meta.ObjectLockConfigXML = enabledBucketObjectLockConfig
if meta.ObjectLockConfigUpdatedAt.IsZero() {
meta.ObjectLockConfigUpdatedAt = meta.Created
}
}
return globalBucketMetadataSys.saveMetadata(ctx, objAPI, meta)
}()
if err != nil {
return wrapSRErr(c.annotateErr(makeBucketWithVersion, err))
}
globalBucketMetadataSys.Set(bucket, meta)
// Load updated bucket metadata into memory as new metadata updated.
globalNotificationSys.LoadBucketMetadata(GlobalContext, bucket)
return nil