Skip to content

fix(seaweedfs)!: clean up orphaned data PVCs and cert/db secrets on tenant module delete (#3092) - #3095

Merged
Aleksei Sviridkin (lexfrei) merged 1 commit into
mainfrom
fix/seaweedfs-pvc-secrets-orphaned
Jul 1, 2026
Merged

fix(seaweedfs)!: clean up orphaned data PVCs and cert/db secrets on tenant module delete (#3092)#3095
Aleksei Sviridkin (lexfrei) merged 1 commit into
mainfrom
fix/seaweedfs-pvc-secrets-orphaned

Conversation

@scooby87

@scooby87 scooby87 commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

What this PR does

When the seaweedfs tenant module is disabled, the SeaweedFS StatefulSet data PVCs (data1-<release>-system-volume-*) and a set of certificate/credential secrets were left orphaned in the tenant namespace.

This adds a post-delete cleanup hook (packages/extra/seaweedfs/templates/hooks/cleanup.yaml) that:

  • deletes the volume PVCs by their release-scoped labels (app.kubernetes.io/name=seaweedfs, app.kubernetes.io/instance=<release>-system, app.kubernetes.io/component=volume);
  • deletes the orphaned secrets by name (<release>-s3-ingress-tls, <release>-system-{admin,ca,client,filer,master,volume,worker}-cert, <release>-system-db-secret) — cert-manager TLS secrets carry only the cluster-wide controller.cert-manager.io/fao=true label, so they are removed by name rather than by an unsafe label sweep.

All names are templated from .Release.Name (the chart renders the StatefulSet/cert HelmRelease as <release>-system). CNPG PostgreSQL PVCs (<release>-db-*) are intentionally not targeted — CNPG cleans those itself.

The cleanup Job is hardened: non-root, read-only root fs, dropped capabilities, seccompProfile: RuntimeDefault, resource requests/limits; RBAC scoped to PVC get/list/delete and the secrets by resourceNames. Failures are logged but never block teardown.

Warning

Disabling the seaweedfs module now permanently deletes its volume data PVCs and the object data they hold. This is intentional and fixes the storage leak. Back up before disabling if the data matters.

Fixes #3092.

Release note

fix(seaweedfs): garbage-collect the orphaned SeaweedFS volume PVCs and the certificate/db secrets left behind when a tenant's seaweedfs module is disabled. WARNING: disabling seaweedfs now permanently removes its volume PVCs and the data they hold.

Summary by CodeRabbit

  • New Features
    • Added a Helm post-delete cleanup hook for SeaweedFS to remove orphaned PersistentVolumeClaims and related certificate/database Secrets.
  • Bug Fixes
    • Cleanup deletions now ignore missing resources to reduce hook failures.
  • Tests
    • Added a Helm/Kubernetes test suite validating the cleanup hook behavior when the module is disabled.
  • Chores
    • Marked the SeaweedFS Makefile test target as phony.

@github-actions github-actions Bot added area/storage Issues or PRs related to storage (linstor, seaweedfs, bucket, velero, harbor) kind/bug Categorizes issue or PR as related to a bug size/L This PR changes 100-499 lines, ignoring generated files labels Jun 26, 2026
@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 11c998d7-8654-484f-a20d-363be467fd1f

📥 Commits

Reviewing files that changed from the base of the PR and between 5a3a45b and fff2e77.

📒 Files selected for processing (3)
  • packages/extra/seaweedfs/Makefile
  • packages/extra/seaweedfs/templates/hooks/cleanup.yaml
  • packages/extra/seaweedfs/tests/cleanup_test.yaml
✅ Files skipped from review due to trivial changes (1)
  • packages/extra/seaweedfs/Makefile
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/extra/seaweedfs/tests/cleanup_test.yaml

📝 Walkthrough

Walkthrough

Adds a SeaweedFS post-delete cleanup hook with dedicated ServiceAccount, RBAC, Job logic, Helm tests, and a phony test target.

Changes

SeaweedFS post-delete cleanup hook

Layer / File(s) Summary
Hook service account and RBAC
packages/extra/seaweedfs/templates/hooks/cleanup.yaml
Defines the post-delete ServiceAccount, Role, and RoleBinding used by the cleanup hook.
Cleanup job execution
packages/extra/seaweedfs/templates/hooks/cleanup.yaml
Adds the hook Job, security context, and shell commands that delete SeaweedFS PVCs and named Secrets with --ignore-not-found --wait=false.
Hook tests and make target
packages/extra/seaweedfs/tests/cleanup_test.yaml, packages/extra/seaweedfs/Makefile
Adds Helm assertions for the hook resources, job configuration, and cleanup command, and marks test phony in the SeaweedFS Makefile.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related issues

Suggested labels: area/kubernetes

Suggested reviewers: kvaps, lllamnyp, androndo

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the SeaweedFS tenant-module delete cleanup and matches the main change.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/seaweedfs-pvc-secrets-orphaned

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@dosubot dosubot Bot added the area/extra Issues or PRs related to tenant-specific modules (packages/extra/) label Jun 26, 2026
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses a resource leakage issue where SeaweedFS data PVCs and various secrets remained in the cluster after a tenant module was deleted. By implementing a hardened post-delete Helm hook, the system now ensures these orphaned resources are properly garbage-collected, maintaining a cleaner environment and preventing potential storage accumulation.

Highlights

  • Automated Cleanup Hook: Introduced a post-delete Helm hook that triggers a cleanup Job when the SeaweedFS tenant module is disabled.
  • Resource Garbage Collection: The cleanup Job automatically removes orphaned data PVCs (via label selectors) and specific certificate/credential secrets (by name) to prevent storage and configuration leaks.
  • Security Hardening: The cleanup Job is configured with restricted security contexts, including non-root execution, read-only root filesystem, and minimal RBAC permissions.
  • Testing: Added comprehensive unit tests to verify the cleanup hook's RBAC configuration, Job specifications, and command execution logic.
New Features

🧠 You can now enable Memory (public preview) to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment Gemini (@gemini-code-assist) Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on Gemini (@gemini-code-assist) comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a post-delete cleanup hook for the SeaweedFS package to remove orphaned PVCs and secrets after the module is disabled, along with corresponding unit tests and a Makefile update. The reviewer feedback suggests removing the restrictive component=volume label filter from the PVC deletion command to ensure that PVCs belonging to custom storage pools or multi-zone topologies are also properly cleaned up, and updating the unit tests accordingly.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread packages/extra/seaweedfs/templates/hooks/cleanup.yaml Outdated
Comment thread packages/extra/seaweedfs/tests/cleanup_test.yaml Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/extra/seaweedfs/templates/hooks/cleanup.yaml`:
- Around line 112-120: The cleanup hook’s kubectl delete calls can hang because
they wait for resource deletion by default, so update the SeaweedFS post-delete
cleanup in the hook command to use --wait=false on both the PVC and secret
deletions. Keep the existing logging and ignore-not-found behavior, but ensure
the commands in the cleanup template complete immediately after issuing the
delete request, preventing hook stalls when finalizers block removal.
- Around line 24-26: The PVC cleanup Role is missing the RBAC permission needed
by the cleanup Job’s labeled delete path. Update the persistentvolumeclaims
permissions in the cleanup hook template so the Role used by the Job includes
deletecollection alongside the existing get, list, and delete verbs; this will
let the cleanup shell command that deletes PVCs by label selector work
correctly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: ca7caa9f-abbd-4849-be76-2b2ab6cc6a18

📥 Commits

Reviewing files that changed from the base of the PR and between 01addfc and cbf862c.

📒 Files selected for processing (3)
  • packages/extra/seaweedfs/Makefile
  • packages/extra/seaweedfs/templates/hooks/cleanup.yaml
  • packages/extra/seaweedfs/tests/cleanup_test.yaml

Comment thread packages/extra/seaweedfs/templates/hooks/cleanup.yaml
Comment thread packages/extra/seaweedfs/templates/hooks/cleanup.yaml Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NOT LGTM — the cleanup is correct and well-tested for the default topology, but the PVC selector silently misses volume PVCs created by custom storage pools and MultiZone topologies, leaving the same leak for those configurations.

Verified the resource names against the rendered chart and the reported leak: the 9 secret names all match, and <release>-system-db-secret carries helm.sh/resource-policy: keep so it genuinely orphans.

Blocker

  • templates/hooks/cleanup.yaml:117app.kubernetes.io/component=volume matches only the default volume pool. The volume StatefulSet sets app.kubernetes.io/component to {{ $volumeName }}, which the chart computes as trimSuffix "-" (printf "volume-%s" $vname) — so a named pool/zone produces volume-<name>, which the exact component=volume selector does not match, and those PVCs stay orphaned (the same bug this PR fixes). Dropping the component clause and keeping app.kubernetes.io/name=seaweedfs,app.kubernetes.io/instance={{ .Release.Name }}-system is safe and complete: master/filer use hostPath (no PVCs) and the CNPG db PVCs carry cnpg.io/* labels, so only the volume PVCs match those two labels. The test at tests/cleanup_test.yaml pins the current selector and must be updated in lockstep. Because the hook swallows failures (|| echo, the Job always exits 0), a selector miss is permanently silent — selector correctness is the whole gate.

Non-blocking

  • The subject is fix(seaweedfs):, but disabling the module now permanently deletes volume data. The data loss is documented in the body and release note, but please mark it breaking (fix(seaweedfs)!:) for consistency with the sibling cleanup PR.
  • Consider --wait=false on both kubectl delete commands; the Job has no activeDeadlineSeconds, so a PVC stuck on a finalizer could hang the post-delete hook.

The hardening, hook ordering, --ignore-not-found idempotency, and the helm-unittest coverage (incl. the resourceNames-scoped secret RBAC) all look good. Note: the deletecollection verb is not needed — kubectl delete -l does a list + per-object delete, so get,list,delete is sufficient.

@scooby87
scooby87 force-pushed the fix/seaweedfs-pvc-secrets-orphaned branch from cbf862c to b00ea9b Compare June 29, 2026 13:48
@scooby87 scooby87 changed the title fix(seaweedfs): clean up orphaned data PVCs and cert/db secrets on tenant module delete (#3092) fix(seaweedfs)!: clean up orphaned data PVCs and cert/db secrets on tenant module delete (#3092) Jun 29, 2026
@github-actions github-actions Bot added the kind/breaking-change Indicates the change introduces a breaking API or behaviour change label Jun 29, 2026
@scooby87

Copy link
Copy Markdown
Contributor Author

Aleksei Sviridkin (@lexfrei) thanks for the review — addressed in b00ea9b (force-push):

Blocker — PVC selector misses custom pools/MultiZone: dropped the app.kubernetes.io/component=volume clause. The selector is now app.kubernetes.io/name=seaweedfs,app.kubernetes.io/instance=<release>-system only, so volume-<pool> / volume-<zone>[-<pool>] PVCs are cleaned up too. master/filer use hostPath (no PVCs) and the CNPG db PVCs carry cnpg.io/* labels, so the two labels match only the volume PVCs. Added a notMatchRegex test guard on component= so the filter cannot silently return.

Breaking marker: retitled to fix(seaweedfs)!: and added a BREAKING CHANGE: footer; kind/breaking-change is now applied.

--wait=false: added to both kubectl delete commands, and set activeDeadlineSeconds: 120 on the Job so a finalizer-stuck resource cannot hang the post-delete hook.

deletecollection (CodeRabbit): not applied — kubectl delete -l does a client-side list + per-object delete, so get,list,delete is sufficient; matches your note. Thread resolved.

helm unittest passes (7/7). All review threads resolved.

@scooby87

Copy link
Copy Markdown
Contributor Author

ℹ️ E2E failure is fleet-wide infra, not this PR

The red E2E Tests check is unrelated to this change. Only kubernetes-latest and kubernetes-previous fail, both on the same root cause — the tenant control plane never comes up because cilium-operator times out:

helmrelease/kubernetes-test-latest-version-cilium
  Helm install failed for release cozy-cilium/cilium:
  timeout waiting for: [Deployment/cozy-cilium/cilium-operator status: InProgress]
pod/kubernetes-test-…  Readiness probe failed: …:6443/readyz: connection refused

Evidence it is not caused by this PR:

  • This PR only touches packages/extra/seaweedfs/{Makefile,templates/hooks/cleanup.yaml,tests/cleanup_test.yaml} — nothing in the Kubernetes/CNI path.
  • SeaweedFS itself deploys cleanly in the same run (seaweedfs, seaweedfs-db, seaweedfs-system all True — Helm upgrade succeeded).
  • The same two tests are failing fleet-wide today on the cilium-operator timeout — e.g. fix/cozytest-dead-hooks, renovate/actions-checkout-6.x, feat/migrate-to-etcd-operator-v1alpha2, fix/kubernetes-nodegroup-resources-optional, feat/sdn-security-groups — so a rebase would not change it.
  • Re-ran the failed job once; it reproduced identically (not a transient flake — an environment issue in the e2e sandbox).

Everything in scope is green: helm unittest 7/7, pre-commit, unit & controller tests, CodeQL, DCO, label, size. Please treat the E2E red as a known CI-environment issue; a re-run will pass once the sandbox cilium problem is resolved. Will rebase onto current main right before merge.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — the prior blocker is resolved; dropping the component clause while keeping name+instance correctly covers every volume topology, and I verified the selector against the chart's StatefulSet labels.

The earlier blocker (the component=volume clause left custom-pool and MultiZone PVCs orphaned) is fixed. Verified against packages/system/seaweedfs/charts/seaweedfs/templates/volume/volume-statefulset.yaml: the volume StatefulSet's spec.selector.matchLabels is {app.kubernetes.io/name=seaweedfs, app.kubernetes.io/instance=<inner-release>, app.kubernetes.io/component=<volumeName>}, and the StatefulSet controller stamps exactly those matchLabels onto each volumeClaimTemplate PVC. So -l app.kubernetes.io/name=seaweedfs,app.kubernetes.io/instance=<release>-system (no component clause) matches volume, volume-<pool>, volume-<zone>, and volume-<zone>-<pool> PVCs across Simple/pool/MultiZone — and uses an exact instance match, so there is no cross-release prefix collision. The 9 by-name secrets match the reported orphan set exactly. --wait=false + activeDeadlineSeconds: 120 keep the hook from blocking teardown. helm-unittest passes (7/7).

Non-blocking follow-ups

  1. The PR description is stale: it states PVCs are deleted by labels including app.kubernetes.io/component=volume, but the shipped selector deliberately omits the component clause (and the test asserts it is absent). The body describes the exact bug the code fixes — worth correcting so the merged record is accurate.
  2. No e2e coverage for the cleanup. helm-unittest only pins the rendered command string, not real deletion; seaweedfs has no e2e test today. A toggle-module-off e2e asserting the PVCs/secrets are gone would turn the statically-verified selector into empirical proof and guard against upstream chart label drift.
  3. The secret cleanup is an explicit by-name list tied to the current upstream chart's cert set. If a future chart bump adds or renames a per-component cert (or enables an auto-generated s3/sftp config secret that is not helm-managed), the hook silently will not reap it. Worth a comment noting the list must track the chart's cert templates.

@scooby87
scooby87 force-pushed the fix/seaweedfs-pvc-secrets-orphaned branch from b00ea9b to 5a3a45b Compare June 30, 2026 12:33
…enant module delete (#3092)

When the seaweedfs tenant module is disabled, the StatefulSet volume PVCs and
a set of certificate/credential secrets were left orphaned. Add a post-delete
cleanup hook that deletes the volume PVCs by their release-scoped labels and
the secrets by name (all templated from .Release.Name). CNPG PVCs are not
targeted (CNPG cleans them). The cleanup Job is hardened (non-root, read-only
root fs, dropped caps, resource limits); RBAC scoped via resourceNames;
failures are logged, never blocking teardown.

The PVC selector matches on name + instance only, without an
app.kubernetes.io/component clause, so volume PVCs from custom storage pools
and MultiZone topologies (component volume-<pool>/volume-<zone>[-<pool>]) are
cleaned up too, not just the default pool. Both deletes use --wait=false and
the Job has activeDeadlineSeconds so a finalizer-stuck resource cannot hang
the post-delete hook.

NOTE: disabling seaweedfs now permanently removes its volume PVCs and the data
they hold.

BREAKING CHANGE: disabling the seaweedfs tenant module now permanently deletes
its volume PVCs and the object data they hold. Back up before disabling if the
data matters.

Signed-off-by: Алексей Артамонов <aleksei.artamonov@aenix.io>
@scooby87
scooby87 force-pushed the fix/seaweedfs-pvc-secrets-orphaned branch from 5a3a45b to fff2e77 Compare July 1, 2026 13:43
@lexfrei
Aleksei Sviridkin (lexfrei) merged commit 4783add into main Jul 1, 2026
15 checks passed
@lexfrei
Aleksei Sviridkin (lexfrei) deleted the fix/seaweedfs-pvc-secrets-orphaned branch July 1, 2026 15:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/extra Issues or PRs related to tenant-specific modules (packages/extra/) area/storage Issues or PRs related to storage (linstor, seaweedfs, bucket, velero, harbor) kind/breaking-change Indicates the change introduces a breaking API or behaviour change kind/bug Categorizes issue or PR as related to a bug size/L This PR changes 100-499 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

seaweedfs (tenant module): data PVCs and certificate/db secrets orphaned after the module is disabled

2 participants