diff --git a/weed/s3api/object_lock_utils.go b/weed/s3api/object_lock_utils.go index a3eddca45..06ec7f4f2 100644 --- a/weed/s3api/object_lock_utils.go +++ b/weed/s3api/object_lock_utils.go @@ -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) diff --git a/weed/s3api/s3api_object_retention_test.go b/weed/s3api/s3api_object_retention_test.go index be42df700..44089deb3 100644 --- a/weed/s3api/s3api_object_retention_test.go +++ b/weed/s3api/s3api_object_retention_test.go @@ -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