From 22852d8dd4906d4c874f9692d42d1a9cd0c88f0b Mon Sep 17 00:00:00 2001 From: Miretpl Date: Thu, 9 Apr 2026 22:15:25 +0200 Subject: [PATCH 1/2] Add workers.celery.topologySpreadConstraints & workers.kubernetes.topologySpreadConstraints --- .../pod-template-file.kubernetes-helm-yaml | 2 +- chart/templates/NOTES.txt | 8 +++ chart/values.schema.json | 20 +++++- chart/values.yaml | 8 +++ .../airflow_aux/test_pod_template_file.py | 45 +++++++++++-- .../helm_tests/airflow_core/test_worker.py | 64 ++++++++++++++++--- .../airflow_core/test_worker_sets.py | 26 ++++++++ 7 files changed, 156 insertions(+), 17 deletions(-) diff --git a/chart/files/pod-template-file.kubernetes-helm-yaml b/chart/files/pod-template-file.kubernetes-helm-yaml index 40aabae170362..66d9d7720f8d0 100644 --- a/chart/files/pod-template-file.kubernetes-helm-yaml +++ b/chart/files/pod-template-file.kubernetes-helm-yaml @@ -20,7 +20,7 @@ {{- $nodeSelector := or .Values.workers.kubernetes.nodeSelector .Values.workers.nodeSelector .Values.nodeSelector }} {{- $affinity := or .Values.workers.kubernetes.affinity .Values.workers.affinity .Values.affinity }} {{- $tolerations := or .Values.workers.kubernetes.tolerations .Values.workers.tolerations .Values.tolerations }} -{{- $topologySpreadConstraints := or .Values.workers.topologySpreadConstraints .Values.topologySpreadConstraints }} +{{- $topologySpreadConstraints := or .Values.workers.kubernetes.topologySpreadConstraints .Values.workers.topologySpreadConstraints .Values.topologySpreadConstraints }} {{- $securityContext := include "airflowPodSecurityContext" (list .Values.workers.kubernetes .Values.workers .Values) }} {{- $containerSecurityContextKerberosSidecar := include "containerSecurityContext" (list .Values.workers.kubernetes.kerberosSidecar .Values.workers.kerberosSidecar .Values) }} {{- $containerLifecycleHooksKerberosSidecar := or .Values.workers.kubernetes.kerberosSidecar.containerLifecycleHooks .Values.workers.kerberosSidecar.containerLifecycleHooks .Values.containerLifecycleHooks }} diff --git a/chart/templates/NOTES.txt b/chart/templates/NOTES.txt index bd92092a2d265..5273e167bad77 100644 --- a/chart/templates/NOTES.txt +++ b/chart/templates/NOTES.txt @@ -749,6 +749,14 @@ DEPRECATION WARNING: {{- end }} +{{- if not (empty .Values.workers.topologySpreadConstraints) }} + + DEPRECATION WARNING: + `workers.topologySpreadConstraints` has been renamed to `workers.celery.topologySpreadConstraints`/`workers.kubernetes.topologySpreadConstraints`. + Please change your values as support for the old name will be dropped in a future release. + +{{- end }} + {{- if not (empty .Values.workers.nodeSelector) }} DEPRECATION WARNING: diff --git a/chart/values.schema.json b/chart/values.schema.json index 555dc09410e61..997918f175c73 100644 --- a/chart/values.schema.json +++ b/chart/values.schema.json @@ -2372,7 +2372,7 @@ } }, "topologySpreadConstraints": { - "description": "Specify topology spread constraints for Airflow Celery worker pods and pods created with pod-template-file.", + "description": "Specify topology spread constraints for Airflow Celery worker pods and pods created with pod-template-file (deprecated, use ``workers.celery.topologySpreadConstraints`` and/or ``workers.kubernetes.topologySpreadConstraints`` instead).", "type": "array", "default": [], "items": { @@ -3451,6 +3451,15 @@ "$ref": "#/definitions/io.k8s.api.core.v1.Toleration" } }, + "topologySpreadConstraints": { + "description": "Specify topology spread constraints for Airflow Celery worker pods.", + "type": "array", + "default": [], + "items": { + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.TopologySpreadConstraint" + } + }, "hostAliases": { "description": "Specify HostAliases for Airflow Celery worker pods.", "items": { @@ -3966,6 +3975,15 @@ "$ref": "#/definitions/io.k8s.api.core.v1.Toleration" } }, + "topologySpreadConstraints": { + "description": "Specify topology spread constraints for pods created with pod-template-file.", + "type": "array", + "default": [], + "items": { + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.TopologySpreadConstraint" + } + }, "hostAliases": { "description": "Specify HostAliases for pods created with pod-template-file.", "items": { diff --git a/chart/values.yaml b/chart/values.yaml index 8255052131467..e662771f82d2f 100644 --- a/chart/values.yaml +++ b/chart/values.yaml @@ -1108,6 +1108,10 @@ workers: # (deprecated, use `workers.celery.tolerations` and/or `workers.kubernetes.tolerations` instead) tolerations: [] + # (deprecated, use + # `workers.celery.topologySpreadConstraints` and/or + # `workers.kubernetes.topologySpreadConstraints` + # instead) topologySpreadConstraints: [] # hostAliases to use in Airflow Celery worker pods and pods created with pod-template-file @@ -1496,6 +1500,8 @@ workers: tolerations: [] + topologySpreadConstraints: [] + # hostAliases to use in Airflow Celery worker pods # See: # https://kubernetes.io/docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases/ @@ -1666,6 +1672,8 @@ workers: tolerations: [] + topologySpreadConstraints: [] + # hostAliases to use in pods created with pod-template-file # See: # https://kubernetes.io/docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases/ diff --git a/helm-tests/tests/helm_tests/airflow_aux/test_pod_template_file.py b/helm-tests/tests/helm_tests/airflow_aux/test_pod_template_file.py index 6fbb87762e075..b003030725163 100644 --- a/helm-tests/tests/helm_tests/airflow_aux/test_pod_template_file.py +++ b/helm-tests/tests/helm_tests/airflow_aux/test_pod_template_file.py @@ -594,11 +594,41 @@ def test_workers_tolerations(self, workers_values): {"key": "dynamic-pods", "operator": "Equal", "value": "true", "effect": "NoSchedule"} ] - def test_workers_topology_spread_constraints(self): - docs = render_chart( - values={ - "executor": "KubernetesExecutor", - "workers": { + @pytest.mark.parametrize( + "workers_values", + [ + { + "topologySpreadConstraints": [ + { + "maxSkew": 1, + "topologyKey": "foo", + "whenUnsatisfiable": "ScheduleAnyway", + "labelSelector": {"matchLabels": {"tier": "airflow"}}, + } + ], + }, + { + "kubernetes": { + "topologySpreadConstraints": [ + { + "maxSkew": 1, + "topologyKey": "foo", + "whenUnsatisfiable": "ScheduleAnyway", + "labelSelector": {"matchLabels": {"tier": "airflow"}}, + } + ], + } + }, + { + "topologySpreadConstraints": [ + { + "maxSkew": 1, + "topologyKey": "not-me", + "whenUnsatisfiable": "ScheduleAnyway", + "labelSelector": {"matchLabels": {"tier": "airflow"}}, + } + ], + "kubernetes": { "topologySpreadConstraints": [ { "maxSkew": 1, @@ -609,6 +639,11 @@ def test_workers_topology_spread_constraints(self): ], }, }, + ], + ) + def test_workers_topology_spread_constraints(self, workers_values): + docs = render_chart( + values={"executor": "KubernetesExecutor", "workers": workers_values}, show_only=["templates/pod-template-file.yaml"], chart_dir=self.temp_chart_dir, ) diff --git a/helm-tests/tests/helm_tests/airflow_core/test_worker.py b/helm-tests/tests/helm_tests/airflow_core/test_worker.py index 5eb4b07733b2b..6c2a5a9ab40df 100644 --- a/helm-tests/tests/helm_tests/airflow_core/test_worker.py +++ b/helm-tests/tests/helm_tests/airflow_core/test_worker.py @@ -706,8 +706,60 @@ def test_tolerations(self, workers_values): {"key": "dynamic-pods", "operator": "Equal", "value": "true", "effect": "NoSchedule"} ] - def test_topology_spread_constraints(self): - expected_topology_spread_constraints = [ + @pytest.mark.parametrize( + "workers_values", + [ + { + "topologySpreadConstraints": [ + { + "maxSkew": 1, + "topologyKey": "foo", + "whenUnsatisfiable": "ScheduleAnyway", + "labelSelector": {"matchLabels": {"tier": "airflow"}}, + } + ] + }, + { + "celery": { + "topologySpreadConstraints": [ + { + "maxSkew": 1, + "topologyKey": "foo", + "whenUnsatisfiable": "ScheduleAnyway", + "labelSelector": {"matchLabels": {"tier": "airflow"}}, + } + ] + } + }, + { + "topologySpreadConstraints": [ + { + "maxSkew": 2, + "topologyKey": "not-me", + "whenUnsatisfiable": "ScheduleAnyway", + "labelSelector": {"matchLabels": {"airflow": "test"}}, + } + ], + "celery": { + "topologySpreadConstraints": [ + { + "maxSkew": 1, + "topologyKey": "foo", + "whenUnsatisfiable": "ScheduleAnyway", + "labelSelector": {"matchLabels": {"tier": "airflow"}}, + } + ] + }, + }, + ], + ) + def test_topology_spread_constraints(self, workers_values): + docs = render_chart( + values={"workers": workers_values}, + show_only=["templates/workers/worker-deployment.yaml"], + ) + + assert jmespath.search("spec.template.spec.topologySpreadConstraints", docs[0]) == [ { "maxSkew": 1, "topologyKey": "foo", @@ -715,14 +767,6 @@ def test_topology_spread_constraints(self): "labelSelector": {"matchLabels": {"tier": "airflow"}}, } ] - docs = render_chart( - values={"workers": {"topologySpreadConstraints": expected_topology_spread_constraints}}, - show_only=["templates/workers/worker-deployment.yaml"], - ) - - assert expected_topology_spread_constraints == jmespath.search( - "spec.template.spec.topologySpreadConstraints", docs[0] - ) @pytest.mark.parametrize( "workers_values", diff --git a/helm-tests/tests/helm_tests/airflow_core/test_worker_sets.py b/helm-tests/tests/helm_tests/airflow_core/test_worker_sets.py index 28fb480b9e7f7..50efb69dff172 100644 --- a/helm-tests/tests/helm_tests/airflow_core/test_worker_sets.py +++ b/helm-tests/tests/helm_tests/airflow_core/test_worker_sets.py @@ -2998,6 +2998,32 @@ def test_overwrite_tolerations(self, workers_values): ], }, }, + { + "celery": { + "enableDefault": False, + "topologySpreadConstraints": [ + { + "maxSkew": 1, + "topologyKey": "not-me", + "whenUnsatisfiable": "ScheduleAnyway", + "labelSelector": {"matchLabels": {"tier": "airflow"}}, + } + ], + "sets": [ + { + "name": "set1", + "topologySpreadConstraints": [ + { + "maxSkew": 1, + "topologyKey": "foo", + "whenUnsatisfiable": "ScheduleAnyway", + "labelSelector": {"matchLabels": {"tier": "airflow"}}, + } + ], + } + ], + }, + }, ], ) def test_overwrite_topology_spread_constraints(self, workers_values): From 19120ff98e2c427cac17230e07304c9afe09bfb1 Mon Sep 17 00:00:00 2001 From: Miretpl Date: Thu, 9 Apr 2026 22:20:10 +0200 Subject: [PATCH 2/2] Add newsfragment --- chart/newsfragments/64980.significant.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 chart/newsfragments/64980.significant.rst diff --git a/chart/newsfragments/64980.significant.rst b/chart/newsfragments/64980.significant.rst new file mode 100644 index 0000000000000..1fd365a31d0dd --- /dev/null +++ b/chart/newsfragments/64980.significant.rst @@ -0,0 +1 @@ +``workers.topologySpreadConstraints`` field is now deprecated in favor of ``workers.celery.topologySpreadConstraints`` and ``workers.kubernetes.topologySpreadConstraints``. Please update your configuration accordingly.