This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch main
in repository 
https://gitbox.apache.org/repos/asf/superset-kubernetes-operator.git


The following commit(s) were added to refs/heads/main by this push:
     new a30b0f9  fix(helm): require leader election when replicas > 1 (#390)
a30b0f9 is described below

commit a30b0f927b9fb21b556dab671a41ccf9490ca2e8
Author: Younsung Lee <[email protected]>
AuthorDate: Sat Sep 26 02:06:59 2026 +0900

    fix(helm): require leader election when replicas > 1 (#390)
    
    * fix(helm): require leader election when replicas > 1
    
    Operator replicas are active/standby behind the leader election Lease.
    With leaderElection.enabled=false every replica reconciles the same
    Superset resources and they race on Jobs, drains, and status, so
    replicas > 1 without leader election is never a valid configuration.
    
    Fail rendering in deployment.yaml for that combination, note the
    requirement on the leaderElection.enabled value (and the generated chart
    README), and add helm-unittest cases for the failing combination plus
    the valid replicas > 1 and single-replica paths.
    
    Follow-up to #386, split out as suggested in review:
    
https://github.com/apache/superset-kubernetes-operator/pull/386#pullrequestreview-5308811823
    
    Signed-off-by: younsl <[email protected]>
    
    * docs: add changelog entry for leader election replicas guard
    
    Record the new helm upgrade failure for replicas > 1 without leader
    election under Changed, so operators of affected releases know why the
    upgrade fails and how to fix it.
    
    Signed-off-by: younsl <[email protected]>
    
    ---------
    
    Signed-off-by: younsl <[email protected]>
    Co-authored-by: Ville Brofeldt <[email protected]>
---
 charts/superset-operator/README.md                 |  2 +-
 charts/superset-operator/templates/deployment.yaml |  8 +++++
 .../tests/optout_and_helpers_test.yaml             | 36 ++++++++++++++++++++++
 charts/superset-operator/values.yaml               |  2 +-
 docs/reference/releases.md                         |  1 +
 5 files changed, 47 insertions(+), 2 deletions(-)

diff --git a/charts/superset-operator/README.md 
b/charts/superset-operator/README.md
index 6416365..5028ae9 100644
--- a/charts/superset-operator/README.md
+++ b/charts/superset-operator/README.md
@@ -60,7 +60,7 @@ The chart values schema intentionally allows undeclared 
top-level keys so shared
 | image.repository | string | `"ghcr.io/apache/superset-kubernetes-operator"` 
| Docker image repository for the operator manager. |
 | image.tag | string | `""` | Image tag. Defaults to the chart's appVersion 
when empty. |
 | imagePullSecrets | list | `[]` | Existing Secrets used to pull the operator 
image from a private registry. |
-| leaderElection.enabled | bool | `true` | Enable leader election so only one 
replica is active at a time. |
+| leaderElection.enabled | bool | `true` | Enable leader election so only one 
replica is active at a time. Required when `replicas > 1`. |
 | logLevel | string | `""` | Operator log verbosity (`--zap-log-level`). Leave 
empty for the default (`info`). Set to `debug` (alias `1`) for per-reconcile 
progress logs, or `2` for trace-level internals. |
 | metrics.certSecretName | string | `""` | Name of a Secret containing 
`tls.crt`, `tls.key`, and `ca.crt` to use for the metrics server instead of the 
built-in self-signed certificate. Typically written by cert-manager. |
 | metrics.enabled | bool | `true` | Enable the metrics endpoint. |
diff --git a/charts/superset-operator/templates/deployment.yaml 
b/charts/superset-operator/templates/deployment.yaml
index 405b565..016d558 100644
--- a/charts/superset-operator/templates/deployment.yaml
+++ b/charts/superset-operator/templates/deployment.yaml
@@ -13,6 +13,14 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+{{- /*
+Replicas are active/standby behind the leader election Lease. Without it every
+replica reconciles the same Superset resources and they race on Jobs, drains,
+and status, so the combination is never valid.
+*/}}
+{{- if and (gt (int .Values.replicas) 1) (not .Values.leaderElection.enabled) 
}}
+{{- fail "replicas > 1 requires leaderElection.enabled=true" }}
+{{- end }}
 apiVersion: apps/v1
 kind: Deployment
 metadata:
diff --git a/charts/superset-operator/tests/optout_and_helpers_test.yaml 
b/charts/superset-operator/tests/optout_and_helpers_test.yaml
index 042a26d..eac37fd 100644
--- a/charts/superset-operator/tests/optout_and_helpers_test.yaml
+++ b/charts/superset-operator/tests/optout_and_helpers_test.yaml
@@ -125,6 +125,42 @@ tests:
           path: spec.template.spec.containers[0].args
           content: --leader-elect=false
 
+  # --- replicas > 1 requires leader election ---
+  - it: fails when replicas > 1 and leader election is disabled
+    set:
+      replicas: 2
+      leaderElection:
+        enabled: false
+    template: templates/deployment.yaml
+    asserts:
+      - failedTemplate:
+          errorMessage: "replicas > 1 requires leaderElection.enabled=true"
+
+  - it: renders multiple replicas with leader election enabled
+    set:
+      replicas: 3
+      leaderElection:
+        enabled: true
+    template: templates/deployment.yaml
+    asserts:
+      - equal:
+          path: spec.replicas
+          value: 3
+      - contains:
+          path: spec.template.spec.containers[0].args
+          content: --leader-elect=true
+
+  - it: renders zero replicas with leader election disabled
+    set:
+      replicas: 0
+      leaderElection:
+        enabled: false
+    template: templates/deployment.yaml
+    asserts:
+      - equal:
+          path: spec.replicas
+          value: 0
+
   # --- podDisruptionBudget ---
   - it: renders no PDB by default
     template: templates/poddisruptionbudget.yaml
diff --git a/charts/superset-operator/values.yaml 
b/charts/superset-operator/values.yaml
index f7f9f2c..fddef08 100644
--- a/charts/superset-operator/values.yaml
+++ b/charts/superset-operator/values.yaml
@@ -39,7 +39,7 @@ serviceAccount:
   annotations: {}
 
 leaderElection:
-  # -- Enable leader election so only one replica is active at a time.
+  # -- Enable leader election so only one replica is active at a time. 
Required when `replicas > 1`.
   enabled: true
 
 # -- Operator log verbosity (`--zap-log-level`). Leave empty for the default 
(`info`).
diff --git a/docs/reference/releases.md b/docs/reference/releases.md
index 265b41f..7fa53ff 100644
--- a/docs/reference/releases.md
+++ b/docs/reference/releases.md
@@ -30,6 +30,7 @@ This page tracks notable changes in Apache Superset 
Kubernetes Operator releases
 
 ### Changed
 
+- **Helm chart requires leader election for multiple replicas.** Rendering now 
fails when `replicas` is greater than 1 and `leaderElection.enabled` is 
`false`. Replicas are active/standby behind the [leader election 
Lease](https://kubernetes.io/docs/concepts/architecture/leases/#leader-election);
 without it every replica reconciles the same `Superset` resources and races on 
Jobs, drains, and status. Existing releases with that combination fail `helm 
upgrade` until leader election is enab [...]
 - Valkey's default port is now applied at runtime, aligning it with the 
existing structured-metastore behavior, instead of being stored by CRD 
defaulting. Resources that omit both `valkey.port` and `valkey.portFrom` 
therefore no longer materialize `port: 6379`, while generated configuration 
continues to use port 6379. This permits `portFrom` without a defaulted literal 
conflicting at admission 
([#369](https://github.com/apache/superset-kubernetes-operator/pull/369)).
 - Kubernetes support now covers the three newest `kind`-published minor 
versions instead of two. CI tests Kubernetes 1.37, 1.36, and 1.35 natively, 
with the experimental `next` lane disabled again 
([#317](https://github.com/apache/superset-kubernetes-operator/pull/317)).
 

Reply via email to