* helm chart: one data drive per node - fix1
* refactor(helm): prevent negative or 0 replicaCount
Co-authored-by: Copilot <copilot@github.com>
* refactor(helm): remove env REPLICA_COUNT
* feat(helm): default no logs directory to force stdout
Co-authored-by: Copilot <copilot@github.com>
* feat(helm): add drivesPerNode
* feat(helm): correct default parity with 4 nodes / 1 drive per node
* conditional render of RUSTFS_OBS_LOG_DIRECTORY
* feat(chart): add table doc for parity
* fix(chart): handle invalid annotation objects
* fix(chart): move logging and obsevability options together; default for kubernetes output to stdout
* feat(chart): better table doc for parity
* fix(chart): leave RUSTFS_OBS_LOG_DIRECTORY empty, or the defaults will attempt to write to readonly fs
* fix(chart): chart defaults as the previous version: 4 nodes with 4 drives per node
* feat(chart): render RUSTFS_STORAGE_CLASS_STANDARD in configmap
* minor fix for pvcAnnotations
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Cristian Chiru <cristi.chiru@gmail.com>
* fix(chart): better drivesPerNode handling
* fix(chart): obs_log_directory default non empty again to preserve previous deployments compatibility
* fix(chart): proper drivesPerNode impl
* fix(chart): values clarification for empty vs unset `obs_log_directory`
* feat(chart): add service externalIPs
* feat(helm): add optional service labels
* fix(helm): merge service labels
* fix(helm): storageclass pvcAnnotations
* fix(chart): move logging and obsevability options together; default for kubernetes output to stdout
* fix(helm): remove duplicate keys
* fix(helm): default drivesPerNode null, keep legacy chart behavior
* feat(helm): add template test for externalIPs
* fix(helm): per-pool drivesPerNode inference, restore regression tests
Repairs the drivesPerNode feature from #2693 so it renders and stays
upgrade-safe:
- define the missing drives inference (rustfs.poolDrives) and compute it
per pool inside rustfs.pools, so mixed 4x4 + 16x1 pool deployments keep
their exact legacy volumeClaimTemplates when drivesPerNode is unset
- restore the $poolsEnabled definition dropped in the rebase (chart failed
to render at all)
- fix .Values references inside the pool range (dot is the pool there) and
keep per-pool storageclass pvcAnnotations overrides working
- make rustfs.volumes derive the drive range from pool drives instead of
the pod count, and relax the pools.list 4-or-16 restriction to >= 2
- reject drivesPerNode=0 explicitly instead of silently inferring
- keep default rendering identical to main: storage_class_standard stays
unrendered by default, obs_endpoint.use_stdout stays false, clusterDomain
value restored
- restore the clusterDomain/mTLS SAN/explicit-volumes regression tests that
the branch deleted, keeping the new topology tests
---------
Signed-off-by: Cristian Chiru <cristi.chiru@gmail.com>
Co-authored-by: Cristian Chiru <cristi.chiru@gmail.com>
Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* feat(helm): support multiple server pools for capacity expansion
The server already understands multiple pools (RUSTFS_VOLUMES is split on
spaces, one pool expression each; rc admin pool/expand/rebalance/
decommission exist), but the chart could only render a single StatefulSet.
Add an opt-in pools mode:
- pools.enabled=false (default) renders byte-identical output to the
current chart (verified against five values variants)
- pools.list renders one StatefulSet per entry; entries may set
replicaCount (4 or 16) and a storageclass block, everything else is
inherited from the top-level values
- pool 0 keeps the legacy StatefulSet/pod/PVC names and its (immutable)
selector, so existing single-pool deployments can be expanded in place
without renaming or data loss; additional pools render as
<fullname>-poolN with a rustfs.com/pool label in their selector
- RUSTFS_VOLUMES and RUSTFS_SERVER_DOMAINS enumerate every pool
- pod anti-affinity is scoped per pool so pools may share nodes while
each pool still spreads its own pods across distinct nodes
- template validation fails fast on unsupported replicaCount, an empty
pools.list, or pools in standalone mode
- pools are append-only by design (list index = identity), documented in
values.yaml and the README
* fix(helm): truncate pool names DNS-safely, document PDB pool scope
Truncate <fullname>-poolN to 63 chars by shortening the base name rather
than the suffix, so the pool index always survives and two pools of a
max-length release cannot collide. Document that the single
PodDisruptionBudget deliberately spans all pools.
* fix(helm): pool-mode anti-affinity must be preferred, not required
Found by live-testing in-place expansion on a 5-node cluster (4-replica
pool 0 + 4-replica pool 1): with requiredDuringScheduling anti-affinity
the expansion deadlocks in a cycle that cannot self-heal -
1. the not-yet-rolled pool-0 pods still carry the unscoped required
rule and repel every rustfs pod from their nodes, so part of pool 1
stays Pending (no IP, no headless-DNS record);
2. every pod that already has the new RUSTFS_VOLUMES exits fatally on
'failed to lookup address information' for those Pending peers;
3. the StatefulSet rolling update is gated on the crashing pod going
Ready, so the remaining pool-0 pods never roll and keep repelling.
Because StatefulSets assign revisions per ordinal, even a subsequent
template fix cannot rescue a wedged rollout (Pending ordinals are only
recreated with the new template after the higher ordinals go Ready) -
the new pool's StatefulSet has to be recreated. Shipping the soft
affinity from the start avoids the state entirely; expansion was
re-tested end-to-end with it and converges.
Pool-mode rendering only - pools.enabled=false still renders the
existing required anti-affinity byte-identically.
---------
Co-authored-by: cxymds <Cxymds@qq.com>
Co-authored-by: houseme <housemecn@gmail.com>
Co-authored-by: cxymds <cxymds@gmail.com>