From 7bcd8e07bb77a4b8bc941862a012ef1b188f2895 Mon Sep 17 00:00:00 2001 From: Aleksei Sviridkin Date: Wed, 15 Jul 2026 12:53:34 +0300 Subject: [PATCH] fix(seaweedfs): decouple workload names from the Helm release name Upstream chart 4.31 switched resource names from the chart name to the release name. The data-plane release is -system, so every StatefulSet was renamed to -system-*. StatefulSet names are immutable, so the upgrade could not rename in place: Helm stood up a second, empty set beside the running one while the data stayed on the original data1-seaweedfs-volume-* PVCs. Where the node count let both sets run, they shared one S3 Service and one filer metadata database, so the empty set answered reads and mixed volume IDs from an independent sequence into shared metadata. Pin fullnameOverride so the rendered names no longer follow the release name, matching the convention already used by other system packages (cozy-proxy, flux-operator, linstor-scheduler, victoria-metrics-operator). The s3-consumer suite pinned the name/fullname divergence this override removes by default, so it now re-creates that divergence explicitly and keeps guarding it regardless of the shipped default. Assisted-By: Claude Signed-off-by: Aleksei Sviridkin --- .../tests/fullname_override_test.yaml | 62 +++++++++++++++++++ .../tests/s3_service_name_consumers_test.yaml | 15 ++++- packages/system/seaweedfs/values.yaml | 11 ++++ 3 files changed, 85 insertions(+), 3 deletions(-) create mode 100644 packages/system/seaweedfs/tests/fullname_override_test.yaml diff --git a/packages/system/seaweedfs/tests/fullname_override_test.yaml b/packages/system/seaweedfs/tests/fullname_override_test.yaml new file mode 100644 index 000000000..545e949b5 --- /dev/null +++ b/packages/system/seaweedfs/tests/fullname_override_test.yaml @@ -0,0 +1,62 @@ +suite: seaweedfs workload naming is pinned to the chart name + +# Upstream chart 4.31 names workloads after the Helm release (`seaweedfs.fullname`) +# instead of after the chart (`seaweedfs.name`, pre-4.31). The shipped release is +# `seaweedfs-system`, so the bump silently renamed every StatefulSet/Deployment to +# `seaweedfs-system-*`. Those names are immutable, so an upgrade cannot rename in +# place — Helm brings up a second, duplicate set beside the running one while the +# data stays on the original `data1-seaweedfs-volume-*` PVCs. +# +# values.yaml pins `fullnameOverride: seaweedfs` so the rendered names stay +# chart-based regardless of the release name, matching the convention already used +# by other system packages (cozy-proxy, flux-operator, linstor-scheduler, ...). +# These tests pin that contract: names must NOT follow the release name. + +release: + name: seaweedfs-system + namespace: tenant-root + +tests: + - it: names the master StatefulSet after the chart, not the release + template: charts/seaweedfs/templates/master/master-statefulset.yaml + asserts: + - equal: + path: metadata.name + value: seaweedfs-master + - equal: + path: spec.serviceName + value: seaweedfs-master + + - it: names the volume StatefulSet after the chart, so its data PVCs keep the legacy names + template: charts/seaweedfs/templates/volume/volume-statefulset.yaml + asserts: + - equal: + path: metadata.name + value: seaweedfs-volume + # Together with the StatefulSet name this yields data1-seaweedfs-volume-N — + # the PVC names the running clusters already hold their data on. + - equal: + path: spec.volumeClaimTemplates[0].metadata.name + value: data1 + + - it: names the filer StatefulSet after the chart + template: charts/seaweedfs/templates/filer/filer-statefulset.yaml + asserts: + - equal: + path: metadata.name + value: seaweedfs-filer + + - it: keeps the selector labels release-scoped so adopted pods keep matching + template: charts/seaweedfs/templates/master/master-statefulset.yaml + asserts: + # A StatefulSet selector is immutable: in-place adoption only works because + # 4.31 left these labels identical to 4.05. + - equal: + path: spec.selector.matchLabels["app.kubernetes.io/name"] + value: seaweedfs + - equal: + path: spec.selector.matchLabels["app.kubernetes.io/instance"] + value: seaweedfs-system + - equal: + path: spec.selector.matchLabels["app.kubernetes.io/component"] + value: master diff --git a/packages/system/seaweedfs/tests/s3_service_name_consumers_test.yaml b/packages/system/seaweedfs/tests/s3_service_name_consumers_test.yaml index 628d2713b..b536b7c57 100644 --- a/packages/system/seaweedfs/tests/s3_service_name_consumers_test.yaml +++ b/packages/system/seaweedfs/tests/s3_service_name_consumers_test.yaml @@ -13,9 +13,12 @@ suite: seaweedfs s3 consumers resolve the renamed s3 service # `seaweedfs-system-s3` while the real service is `seaweedfs-s3`. With no # matching endpoints, ingress-nginx returns 503 and COSI cannot reach S3. # -# All tests render under the real release name so name != fullname, the exact -# condition that exposes the bug. The all-in-one case documents the other -# ternary branch, which is unchanged and correct. +# values.yaml now pins fullnameOverride: seaweedfs, which makes name == fullname +# and would hide this bug by accident. So each test re-creates the original +# condition explicitly (fullnameOverride: seaweedfs-system => name != fullname) +# and keeps guarding the divergence itself, independent of what the shipped +# default happens to be. The all-in-one case documents the other ternary branch, +# which is unchanged and correct. templates: - charts/seaweedfs/templates/s3/s3-service.yaml @@ -31,6 +34,7 @@ tests: - it: s3 service is named with the name helper, not componentName template: charts/seaweedfs/templates/s3/s3-service.yaml set: + seaweedfs.fullnameOverride: seaweedfs-system seaweedfs.s3.enabled: true asserts: - equal: @@ -40,6 +44,7 @@ tests: - it: s3 ingress backend points at the s3 service, not a fullname-derived name template: charts/seaweedfs/templates/s3/s3-ingress.yaml set: + seaweedfs.fullnameOverride: seaweedfs-system seaweedfs.s3.enabled: true seaweedfs.s3.ingress.enabled: true seaweedfs.s3.ingress.host: s3.example.com @@ -51,6 +56,7 @@ tests: - it: all-in-one ingress backend still resolves to the all-in-one service template: charts/seaweedfs/templates/s3/s3-ingress.yaml set: + seaweedfs.fullnameOverride: seaweedfs-system seaweedfs.allInOne.enabled: true seaweedfs.allInOne.s3.enabled: true seaweedfs.s3.ingress.enabled: true @@ -63,6 +69,7 @@ tests: - it: iceberg ingress backend points at the s3 service too template: charts/seaweedfs/templates/s3/s3-iceberg-ingress.yaml set: + seaweedfs.fullnameOverride: seaweedfs-system seaweedfs.s3.enabled: true seaweedfs.s3.icebergPort: 8334 seaweedfs.s3.icebergIngress.enabled: true @@ -75,6 +82,7 @@ tests: - it: COSI in-cluster ENDPOINT resolves the s3 service when ingress is disabled template: charts/seaweedfs/templates/cosi/cosi-deployment.yaml set: + seaweedfs.fullnameOverride: seaweedfs-system seaweedfs.cosi.enabled: true seaweedfs.s3.enabled: true seaweedfs.s3.ingress.enabled: false @@ -88,6 +96,7 @@ tests: - it: COSI in-cluster ENDPOINT (filer S3 mode) targets the s3 service on the filer s3 port template: charts/seaweedfs/templates/cosi/cosi-deployment.yaml set: + seaweedfs.fullnameOverride: seaweedfs-system seaweedfs.cosi.enabled: true seaweedfs.s3.enabled: false seaweedfs.filer.s3.enabled: true diff --git a/packages/system/seaweedfs/values.yaml b/packages/system/seaweedfs/values.yaml index c363dc3ed..ce126b158 100644 --- a/packages/system/seaweedfs/values.yaml +++ b/packages/system/seaweedfs/values.yaml @@ -11,6 +11,17 @@ global: monitoring: enabled: true seaweedfs: + # Decouple the workload names from the Helm release name. Upstream 4.31 started + # naming resources after the release, and the data-plane release is + # `-system`, so every StatefulSet was renamed to `-system-*`. Those + # names are immutable, so Helm could not rename in place — it stood up a second, + # empty set beside the running one while the data stayed on `data1-seaweedfs-volume-*`. + # Pinning the chart name restores the pre-4.31 names, so the running workloads + # and their volumes are adopted across the bump. extra/seaweedfs does NOT override + # this per release — it relies on this pin — and guards the one case the pin + # cannot serve (a tenant installed fresh on 1.5.x, whose data is on the renamed + # volumes) by refusing to render. + fullnameOverride: seaweedfs master: # 30 GB per volume × 10 GiB PVC = 0 → rounded to 1 maxVolume per # volume server. With defaultReplication=001 (one replica on a