Repository navigation
Description
Describe the bug
SeaweedFS in Cozystack stores an S3 bucket lifecycle configuration and returns it, but nothing in the platform acts on it, on any bucket (the platform backup bucket and tenant Bucket apps alike). docs/operations/backup-classes.md tells operators to bound cozy-backups with an S3 lifecycle policy on the object store until platform retention lands (MongoDB useSystemBucket section and "Tuning via a custom BackupClass"). Following that advice gives a 200 response and no expiry.
Environment
Cozystack v1.7.0, SeaweedFS 4.45 (cozystack-patched).
To reproduce
Create a Bucket app, put a lifecycle rule with the AWS CLI against the S3 endpoint, upload an object.
aws --endpoint-url https://s3.<host> s3api put-bucket-lifecycle-configuration --bucket <bucket> \
--lifecycle-configuration '{"Rules":[{"ID":"x","Status":"Enabled","Filter":{"Prefix":"p/"},"Expiration":{"Days":1}}]}'
aws --endpoint-url https://s3.<host> s3api get-bucket-lifecycle-configuration --bucket <bucket>
aws --endpoint-url https://s3.<host> s3 cp file s3://<bucket>/p/file
kubectl -n tenant-root exec seaweedfs-master-0 -- sh -c "printf 'fs.meta.cat /buckets/<bucket>/p/file\n' | weed shell" | grep ttlSecActual behaviour
put and get return 200 and the rule. It sits in the bucket entry (s3-bucket-lifecycle-configuration-xml), the uploaded object has "ttlSec": 0. There are no admin or worker pods in tenant-root, and the Cozystack package values (packages/system/seaweedfs/values.yaml, packages/extra/seaweedfs/values.yaml, packages/extra/seaweedfs/templates/seaweedfs.yaml) have no switch for them, I did not find anything else that runs lifecycle. One day is the S3 minimum, so I did not wait to see the object survive it.
What works without those components, tested on this version: a filer path TTL for new writes under one prefix, weed shell fs.configure -locationPrefix=/buckets/<bucket>/<ns>/<app>/ -ttl=30d -apply (objects written afterwards expired and their volumes were removed, old objects untouched), and s3.bucket.lifecycle.fastpath -name <bucket> -enable, which turns Expiration.Days rules into the same write time TTL. Platform does not configure, expose or document either, and the rule lives only in the filer. Each new bucket or TTL value takes 3 volume slots and a volume node here has 23, so per prefix rules add up fast.
Expected behaviour
The object is removed after the rule says so, or the API refuses the rule, or the docs say how to enforce it.
Pick one and say it in the docs: deploy the worker and admin (or a periodic s3.lifecycle.run-shard job) so rules are enforced, manage a per prefix TTL from the Bucket app or the backup storage values, or at least change the doc to say lifecycle rules are not enforced and show the working command. Platform side retention (PR #4192) is a separate layer and still needed.
Activity
dosubot commentedon Nov 4, 2026
There is already an implementation starting point in the vendored chart: it includes an admin StatefulSet and worker Deployment, both gated by disabled-by-default
admin.enabled/worker.enabledvalues. At the Cozystack system-chart level these sit underseaweedfs:. So deploying those components can build on the existing subchart rather than requiring new workload manifests, though enabling them alone is not yet a verified lifecycle fix. [1] [2] [3] [4] [5]The documentation correction should also cover the MongoDB cleanup escape hatch: the v1.7 guide explicitly says namespace termination or
backups.cozystack.io/skip-artifact-cleanup=truereleases theBackupand leaves its object for bucket lifecycle to reclaim. Given your reproduction, that fallback also needs an explicit manual-cleanup warning until enforcement exists, not just a correction to scheduled-retention advice. [6]To reply, just mention @dosu.
Share context across your team and agents. Try Dosu.
scooby87 commentedon Nov 12, 2026
Fixed by #5228.