Fix evaluation of NewerNoncurrentVersions (#21096)

- Move VersionPurgeStatus into replication package
- ilm: Evaluate policy w/ obj retention/replication
- lifecycle: Use Evaluator to enforce ILM in scanner
- Unit tests covering ILM, replication and retention
- Simplify NewEvaluator constructor
This commit is contained in:
Krishnan Parthasarathi
2025-04-02 23:45:06 -07:00
committed by GitHub
parent 07f31e574c
commit 01447d2438
20 changed files with 916 additions and 471 deletions

View File

@@ -43,6 +43,7 @@ import (
"github.com/klauspost/filepathx"
"github.com/minio/madmin-go/v3"
"github.com/minio/minio/internal/bucket/lifecycle"
"github.com/minio/minio/internal/bucket/replication"
"github.com/minio/minio/internal/cachevalue"
"github.com/minio/minio/internal/config/storageclass"
@@ -552,7 +553,8 @@ func (s *xlStorage) NSScanner(ctx context.Context, cache dataUsageCache, updates
}
// Check if the current bucket has replication configuration
if rcfg, _, err := globalBucketMetadataSys.GetReplicationConfig(ctx, cache.Info.Name); err == nil {
var rcfg *replication.Config
if rcfg, _, err = globalBucketMetadataSys.GetReplicationConfig(ctx, cache.Info.Name); err == nil {
if rcfg.HasActiveRules("", true) {
tgts, err := globalBucketTargetSys.ListBucketTargets(ctx, cache.Info.Name)
if err == nil {
@@ -564,6 +566,13 @@ func (s *xlStorage) NSScanner(ctx context.Context, cache dataUsageCache, updates
}
}
// Check if bucket is object locked.
lr, err := globalBucketObjectLockSys.Get(cache.Info.Name)
if err != nil {
scannerLogOnceIf(ctx, err, cache.Info.Name)
return cache, err
}
vcfg, _ := globalBucketVersioningSys.Get(cache.Info.Name)
// return initialized object layer
@@ -614,6 +623,11 @@ func (s *xlStorage) NSScanner(ctx context.Context, cache dataUsageCache, updates
return sizeSummary{}, errSkipFile
}
versioned := vcfg != nil && vcfg.Versioned(item.objectPath())
objInfos := make([]ObjectInfo, len(fivs.Versions))
for i, fi := range fivs.Versions {
objInfos[i] = fi.ToObjectInfo(item.bucket, item.objectPath(), versioned)
}
sizeS := sizeSummary{}
for _, tier := range globalTierConfigMgr.ListTiers() {
if sizeS.tiers == nil {
@@ -626,35 +640,14 @@ func (s *xlStorage) NSScanner(ctx context.Context, cache dataUsageCache, updates
sizeS.tiers[storageclass.RRS] = tierStats{}
}
done := globalScannerMetrics.time(scannerMetricApplyAll)
objInfos, err := item.applyVersionActions(ctx, objAPI, fivs.Versions, globalExpiryState)
done()
if err != nil {
res["err"] = err.Error()
return sizeSummary{}, errSkipFile
}
versioned := vcfg != nil && vcfg.Versioned(item.objectPath())
var objDeleted bool
for _, oi := range objInfos {
done = globalScannerMetrics.time(scannerMetricApplyVersion)
var sz int64
objDeleted, sz = item.applyActions(ctx, objAPI, oi, &sizeS)
done()
// DeleteAllVersionsAction: The object and all its
// versions are expired and
// doesn't contribute toward data usage.
if objDeleted {
break
}
actualSz, err := oi.GetActualSize()
if err != nil {
continue
}
var objPresent bool
item.applyActions(ctx, objAPI, objInfos, lr, &sizeS, func(oi ObjectInfo, sz, actualSz int64, sizeS *sizeSummary) {
objPresent = true
if oi.DeleteMarker {
sizeS.deleteMarkers++
}
@@ -667,7 +660,7 @@ func (s *xlStorage) NSScanner(ctx context.Context, cache dataUsageCache, updates
// tracking deleted transitioned objects
switch {
case oi.DeleteMarker, oi.TransitionedObject.FreeVersion:
continue
return
}
tier := oi.StorageClass
if tier == "" {
@@ -681,12 +674,12 @@ func (s *xlStorage) NSScanner(ctx context.Context, cache dataUsageCache, updates
sizeS.tiers[tier] = st.add(oi.tierStats())
}
}
}
})
// apply tier sweep action on free versions
for _, freeVersion := range fivs.FreeVersions {
oi := freeVersion.ToObjectInfo(item.bucket, item.objectPath(), versioned)
done = globalScannerMetrics.time(scannerMetricTierObjSweep)
done := globalScannerMetrics.time(scannerMetricTierObjSweep)
globalExpiryState.enqueueFreeVersion(oi)
done()
}
@@ -722,7 +715,7 @@ func (s *xlStorage) NSScanner(ctx context.Context, cache dataUsageCache, updates
}
}
}
if objDeleted {
if !objPresent {
// we return errIgnoreFileContrib to signal this function's
// callers to skip this object's contribution towards
// usage.