From 813f1351f8df3a540ba1fe7f41257d0220de33d0 Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Wed, 13 May 2026 16:57:10 -0700 Subject: [PATCH] feat(s3/lifecycle): enable scheduler by default (#9492) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit S3 lifecycle is a standard bucket feature — operators set PutBucketLifecycleConfiguration through the S3 API expecting the configured expirations to actually fire. With the prior default (scheduler enabled=false), buckets with lifecycle XML silently retained data past their declared expiration until an operator noticed and turned the scheduler on. The failure mode of enabled-by-default is "worker runs every day and fast-exits on buckets with no lifecycle rules" — cheap. The failure mode of disabled-by-default is "data lingers, looks like it expired, doesn't" — bad. Enabled-by-default matches both the AWS S3 default behavior and the operator's natural mental model. Operators who want the worker off can still disable it via the admin UI; once a persisted config exists, this descriptor default no longer applies (the persisted Enabled state wins). Test pins the choice so a future flip to false fails loud. --- weed/worker/tasks/s3_lifecycle/handler.go | 9 +++++++++ weed/worker/tasks/s3_lifecycle/handler_test.go | 14 ++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/weed/worker/tasks/s3_lifecycle/handler.go b/weed/worker/tasks/s3_lifecycle/handler.go index 3b4aad99f..caaf125b7 100644 --- a/weed/worker/tasks/s3_lifecycle/handler.go +++ b/weed/worker/tasks/s3_lifecycle/handler.go @@ -143,6 +143,15 @@ func (h *Handler) Descriptor() *plugin_pb.JobTypeDescriptor { }, }, AdminRuntimeDefaults: &plugin_pb.AdminRuntimeDefaults{ + // On by default: S3 lifecycle is a standard bucket feature + // (PutBucketLifecycleConfiguration is part of the S3 API), + // and a bucket with rules set but no worker running silently + // retains data past its declared expiration. Operators who + // want the worker off can still disable it in the admin UI; + // the default error is "data lingers" not "worker burns CPU + // on empty rule sets" (the worker fast-exits with no + // configured rules). + Enabled: true, DetectionIntervalMinutes: 24 * 60, // daily DetectionTimeoutSeconds: 60, MaxJobsPerDetection: 1, diff --git a/weed/worker/tasks/s3_lifecycle/handler_test.go b/weed/worker/tasks/s3_lifecycle/handler_test.go index 1ea8331fc..5ed1beca4 100644 --- a/weed/worker/tasks/s3_lifecycle/handler_test.go +++ b/weed/worker/tasks/s3_lifecycle/handler_test.go @@ -348,6 +348,20 @@ func TestDescriptor_AdminRuntimeDefaultsDailyCadence(t *testing.T) { assert.Equal(t, int32(1), d.AdminRuntimeDefaults.MaxJobsPerDetection) } +func TestDescriptor_AdminRuntimeDefaultsEnabledByDefault(t *testing.T) { + // S3 lifecycle is a standard bucket feature — operators set + // PutBucketLifecycleConfiguration expecting it to actually fire. + // Default-off would silently retain data past declared expiration + // until an operator notices and flips it on. Document the choice + // here so a future change to disabled-by-default fails the test + // and surfaces a conscious revisit. + h := NewHandler(nil) + d := h.Descriptor() + require.NotNil(t, d.AdminRuntimeDefaults) + assert.True(t, d.AdminRuntimeDefaults.Enabled, + "s3_lifecycle defaults must enable the scheduler so configured rules fire without operator opt-in") +} + // ---------- Execute ---------- // recordingExecSender captures Execute-side messages. The Execute path