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

Miretpl pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/main by this push:
     new 7036d244b13 Fix Helm chart rendering an invalid label for multi-team 
executors (#72200)
7036d244b13 is described below

commit 7036d244b138463acc7849d5e38b419cd800e990
Author: KidAmnesiac1 <[email protected]>
AuthorDate: Wed Sep 2 23:59:57 2026 +0800

    Fix Helm chart rendering an invalid label for multi-team executors (#72200)
    
    The scheduler Deployment copies the executor value into a pod label and 
sanitises "," and ":" on the way through. Multi-team executor config uses ";" 
and "=" as its separators, and neither is legal in a Kubernetes label value, so 
a chart configured the documented multi-team way renders a label the API server 
rejects and the deploy fails outright.
    
    Why this is worth fixing rather than working around: multi-team executors 
are what the edge worker's --team-name flag depends on. EdgeExecutor stamps 
each edge_job row with its executor's team, and a worker started with 
--team-name only picks up jobs whose team matches. Without a per-team executor 
entry the jobs get stamped NULL, the worker sits there reporting it has no 
work, and the tasks stay queued.
    
    There isn't a good way around it from values.yaml. Quoting doesn't help, 
because the restriction is on the characters in the label rather than on the 
YAML. Setting config.core.executor instead is refused by the check in 
NOTES.txt. Overriding the label through .Values.labels does render, but it 
stamps the label on every object in the chart and breaks the migrations Job, 
whose pod template can't be changed in place.
    
    Sanitising ";" and "=" alongside the separators the chart already handles 
keeps the label legal while airflow.cfg still gets the real value.
    
    Co-authored-by: Przemysław Mirowski 
<[email protected]>
---
 .../templates/scheduler/scheduler-deployment.yaml  |  2 +-
 .../helm_tests/airflow_core/test_scheduler.py      | 23 ++++++++++++++++++++--
 2 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/chart/templates/scheduler/scheduler-deployment.yaml 
b/chart/templates/scheduler/scheduler-deployment.yaml
index 5775676b1d3..ad58ac1ec35 100644
--- a/chart/templates/scheduler/scheduler-deployment.yaml
+++ b/chart/templates/scheduler/scheduler-deployment.yaml
@@ -48,7 +48,7 @@ metadata:
     release: {{ .Release.Name }}
     chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
     heritage: {{ .Release.Service }}
-    executor: {{ .Values.executor | replace "," "-" | replace ":" "-" | trunc 
63 | trimSuffix "-" | trimSuffix ":" | trimSuffix "_" | trimSuffix "." | quote 
}}
+    executor: {{ .Values.executor | replace "," "-" | replace ":" "-" | 
replace ";" "-" | replace "=" "-" | trunc 63 | trimSuffix "-" | trimSuffix ":" 
| trimSuffix "_" | trimSuffix "." | quote }}
     {{- with .Values.labels }}
       {{- toYaml . | nindent 4 }}
     {{- end }}
diff --git a/chart/tests/helm_tests/airflow_core/test_scheduler.py 
b/chart/tests/helm_tests/airflow_core/test_scheduler.py
index 0322e273840..30ba62e6212 100644
--- a/chart/tests/helm_tests/airflow_core/test_scheduler.py
+++ b/chart/tests/helm_tests/airflow_core/test_scheduler.py
@@ -16,6 +16,8 @@
 # under the License.
 from __future__ import annotations
 
+import re
+
 import jmespath
 import pytest
 from chart_utils.helm_template_generator import render_chart
@@ -995,6 +997,20 @@ class TestSchedulerService:
             ("CeleryExecutor", "CeleryExecutor"),
             ("KubernetesExecutor", "KubernetesExecutor"),
             ("CeleryExecutor,KubernetesExecutor", 
"CeleryExecutor-KubernetesExecutor"),
+            (
+                "CeleryExecutor,harvest_exec:KubernetesExecutor",
+                "CeleryExecutor-harvest_exec-KubernetesExecutor",
+            ),
+            ("LocalExecutor;team_a=CeleryExecutor", 
"LocalExecutor-team_a-CeleryExecutor"),
+            (
+                
"LocalExecutor;team_a=CeleryExecutor;team_b=KubernetesExecutor",
+                
"LocalExecutor-team_a-CeleryExecutor-team_b-KubernetesExecutor",
+            ),
+            (
+                "airflow.providers.edge3.executors.EdgeExecutor;"
+                "team_b=airflow.providers.edge3.executors.EdgeExecutor",
+                
"airflow.providers.edge3.executors.EdgeExecutor-team_b-airflow.p",
+            ),
         ],
     )
     def test_should_add_executor_labels(self, executor, expected_label):
@@ -1005,8 +1021,11 @@ class TestSchedulerService:
             show_only=["templates/scheduler/scheduler-deployment.yaml"],
         )
 
-        assert "executor" in jmespath.search("metadata.labels", docs[0])
-        assert jmespath.search("metadata.labels", docs[0])["executor"] == 
expected_label
+        label = jmespath.search("metadata.labels", docs[0])["executor"]
+        assert label == expected_label
+        assert re.fullmatch(r"[A-Za-z0-9]([-A-Za-z0-9_.]{0,61}[A-Za-z0-9])?", 
label), (
+            f"{label!r} is not a valid Kubernetes label value"
+        )
 
     def test_ip_family_policy(self):
         docs = render_chart(

Reply via email to