mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-08-21 22:56:55 +00:00
fix(s3api): clear stale object lock years (#9890)
Problem: Re-storing object-lock default retention with Days left a previous Years extended attribute in place, so later loads could see both Days and stale Years. Root cause: StoreObjectLockConfigurationInExtended only wrote period fields that were set on the new configuration and did not delete old Days or Years keys before writing the replacement rule. Fix: Clear stored default-retention Days and Years keys before writing the current default retention period fields. Reproduction: go test ./weed/s3api -run TestStoreObjectLockConfigurationClearsStaleYears -count=1 failed before the fix because the stale years key remained. Validation: go test ./weed/s3api -run TestStoreObjectLockConfigurationClearsStaleYears -count=1; go test ./weed/s3api -count=1; git diff --check; git diff --cached --check Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
@@ -95,6 +95,9 @@ func StoreObjectLockConfigurationInExtended(entry *filer_pb.Entry, config *Objec
|
||||
if config.Rule != nil && config.Rule.DefaultRetention != nil {
|
||||
defaultRetention := config.Rule.DefaultRetention
|
||||
|
||||
delete(entry.Extended, s3_constants.ExtObjectLockDefaultDaysKey)
|
||||
delete(entry.Extended, s3_constants.ExtObjectLockDefaultYearsKey)
|
||||
|
||||
// Store mode
|
||||
if defaultRetention.Mode != "" {
|
||||
entry.Extended[s3_constants.ExtObjectLockDefaultModeKey] = []byte(defaultRetention.Mode)
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb/filer_pb"
|
||||
"github.com/seaweedfs/seaweedfs/weed/s3api/s3_constants"
|
||||
)
|
||||
|
||||
@@ -817,6 +818,41 @@ func TestValidateDefaultRetention(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestStoreObjectLockConfigurationClearsStaleYears(t *testing.T) {
|
||||
entry := &filer_pb.Entry{
|
||||
Extended: map[string][]byte{
|
||||
s3_constants.ExtObjectLockEnabledKey: []byte(s3_constants.ObjectLockEnabled),
|
||||
s3_constants.ExtObjectLockDefaultModeKey: []byte(s3_constants.RetentionModeCompliance),
|
||||
s3_constants.ExtObjectLockDefaultYearsKey: []byte("1"),
|
||||
},
|
||||
}
|
||||
config := CreateObjectLockConfiguration(true, s3_constants.RetentionModeGovernance, 30, 0)
|
||||
|
||||
if err := StoreObjectLockConfigurationInExtended(entry, config); err != nil {
|
||||
t.Fatalf("StoreObjectLockConfigurationInExtended returned error: %v", err)
|
||||
}
|
||||
|
||||
if _, exists := entry.Extended[s3_constants.ExtObjectLockDefaultYearsKey]; exists {
|
||||
t.Fatalf("stale default retention years key was not cleared")
|
||||
}
|
||||
|
||||
loaded, found := LoadObjectLockConfigurationFromExtended(entry)
|
||||
if !found {
|
||||
t.Fatalf("expected stored object lock configuration to load")
|
||||
}
|
||||
if loaded.Rule == nil || loaded.Rule.DefaultRetention == nil {
|
||||
t.Fatalf("expected loaded configuration to include default retention")
|
||||
}
|
||||
|
||||
retention := loaded.Rule.DefaultRetention
|
||||
if !retention.DaysSet || retention.Days != 30 {
|
||||
t.Fatalf("expected loaded retention days to be 30, got DaysSet=%v Days=%d", retention.DaysSet, retention.Days)
|
||||
}
|
||||
if retention.YearsSet || retention.Years != 0 {
|
||||
t.Fatalf("expected loaded retention years to be cleared, got YearsSet=%v Years=%d", retention.YearsSet, retention.Years)
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to create a time pointer
|
||||
func timePtr(t time.Time) *time.Time {
|
||||
return &t
|
||||
|
||||
Reference in New Issue
Block a user