From dafe0e79bb6a36fc68614f6360544cb74f567f9c Mon Sep 17 00:00:00 2001 From: Keith Jackson Date: Mon, 17 Aug 2026 00:53:03 -0500 Subject: [PATCH] fix(longhorn): hardcode StorageClass numberOfReplicas to quoted "3" The un-suspend reconcile stalled: platform Kustomization Ready=False with 'StorageClass/longhorn ... .parameters.numberOfReplicas: expected string, got 3'. StorageClass.parameters is map[string]string, but kustomize strips the quotes around the bare "${LONGHORN_DEFAULT_REPLICA_COUNT}" placeholder, so Flux postBuild substitution produced an unquoted numeric that server-side apply rejects as int. Hardcode the quoted numeric literal "3" (kustomize preserves those, as "30" shows); topology is locked at 3 nodes. The replica knob still drives the global default via defaultSettings.defaultReplicaCount in the helmrelease (a Helm int value, unaffected). Co-Authored-By: Claude Opus 4.8 (1M context) --- platform/longhorn/storageclasses.yaml | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/platform/longhorn/storageclasses.yaml b/platform/longhorn/storageclasses.yaml index 6fda688..d2c4446 100644 --- a/platform/longhorn/storageclasses.yaml +++ b/platform/longhorn/storageclasses.yaml @@ -16,10 +16,15 @@ allowVolumeExpansion: true reclaimPolicy: Delete # dev: reclaim space when the PVC is deleted volumeBindingMode: Immediate parameters: - # 3 replicas across 3 nodes — substituted from cluster-vars.longhorn_default_replica_count. - # HARD node anti-affinity in helmrelease.yaml (replicaSoftAntiAffinity=false) guarantees these - # replicas land on distinct nodes, so any single node loss keeps the volume available. - numberOfReplicas: "${LONGHORN_DEFAULT_REPLICA_COUNT}" + # 3 replicas across 3 nodes (topology-LOCKED). HARD node anti-affinity in helmrelease.yaml + # (replicaSoftAntiAffinity=false) guarantees these land on distinct nodes, so any single node + # loss keeps the volume available. + # HARDCODED, not ${LONGHORN_DEFAULT_REPLICA_COUNT}: StorageClass.parameters is map[string]string, + # but kustomize strips the quotes around a bare "${VAR}" placeholder, so Flux postBuild substitution + # yields an unquoted numeric (3) that server-side apply rejects (int, not string). A quoted numeric + # literal like "3"/"30" IS preserved by kustomize. The replica knob still drives the GLOBAL default + # via defaultSettings.defaultReplicaCount in helmrelease.yaml (a Helm int value, unaffected). + numberOfReplicas: "3" staleReplicaTimeout: "30" # minutes before a down replica is considered stale and rebuilt dataLocality: "disabled" # keep replicas spread for durability, not co-located with the pod fsType: "ext4"