fix(ilm): preserve duplicate metadata and reject unapplied purges

Merge lock and tag revisions for duplicate versions before all-pool
lifecycle evaluation using the existing metadata reconciliation rules.

Distinguish ordinary lifecycle refusal from object absence and clear
rejected batch replication state so a late policy withdrawal cannot
schedule a purge. Preserve restored-copy cleanup and real absence.

Cover single and batch protections, legitimate metadata removals, and
actual replication queue and HTTP target behavior.

Signed-off-by: Feng Ruohang <rh@vonng.com>
This commit is contained in:
Feng Ruohang
2026-11-03 22:38:21 +08:00
parent 3a1e132f16
commit ba0b59d0b2
6 changed files with 416 additions and 29 deletions
+6
View File
@@ -19,6 +19,7 @@ package cmd
import (
"context"
"errors"
"maps"
"sort"
"strings"
@@ -769,6 +770,11 @@ func (z *erasureServerPools) deleteObjectsReconciled(ctx context.Context, bucket
deleteOpts.Versioned = opts.PrefixEnabledFn(obj.ObjectName)
}
_, err := z.deleteObjectReconciled(ctx, bucket, obj.ObjectName, deleteOpts)
if errors.Is(err, errLifecycleNotApplicable) {
// A later lifecycle rejection did not commit a local purge. Do
// not let the worker replicate the request's pending decision.
deleted[i].ReplicationState = ReplicationState{}
}
if err != nil && !isErrObjectNotFound(err) && !isErrVersionNotFound(err) {
errs[i] = err
} else {