From 8eb573c5bd8f4a324a0db45a28965e38f1241c85 Mon Sep 17 00:00:00 2001 From: PreethamSanji Date: Sun, 12 Jul 2026 14:56:46 +0000 Subject: [PATCH] Support image digest in worker pod template image The pod_template_image helper only rendered repository:tag, ignoring digests, while airflow_image supports repository@digest with digest taking precedence over tag. Add images.pod_template.digest (falling back to defaultAirflowDigest) so worker pods can pin images by digest. Closes: #58625 --- chart/newsfragments/69776.bugfix.rst | 1 + chart/templates/_helpers.yaml | 9 ++++- .../airflow_aux/test_pod_template_file.py | 33 +++++++++++++++++++ chart/values.schema.json | 8 +++++ chart/values.yaml | 2 ++ 5 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 chart/newsfragments/69776.bugfix.rst diff --git a/chart/newsfragments/69776.bugfix.rst b/chart/newsfragments/69776.bugfix.rst new file mode 100644 index 0000000000000..9cc1ff37f37e1 --- /dev/null +++ b/chart/newsfragments/69776.bugfix.rst @@ -0,0 +1 @@ +Support image digest in the worker pod template image (``images.pod_template.digest``) diff --git a/chart/templates/_helpers.yaml b/chart/templates/_helpers.yaml index 2fefc497905d1..b069c38f97cc7 100644 --- a/chart/templates/_helpers.yaml +++ b/chart/templates/_helpers.yaml @@ -372,7 +372,14 @@ If release name contains chart name it will be used as a full name. {{- end }} {{- define "pod_template_image" -}} - {{- printf "%s:%s" (.Values.images.pod_template.repository | default .Values.defaultAirflowRepository) (.Values.images.pod_template.tag | default .Values.defaultAirflowTag) }} + {{- $repository := .Values.images.pod_template.repository | default .Values.defaultAirflowRepository -}} + {{- $tag := .Values.images.pod_template.tag | default .Values.defaultAirflowTag -}} + {{- $digest := .Values.images.pod_template.digest | default .Values.defaultAirflowDigest -}} + {{- if $digest }} + {{- printf "%s@%s" $repository $digest -}} + {{- else }} + {{- printf "%s:%s" $repository $tag -}} + {{- end }} {{- end }} {{/* This helper is used for airflow containers that do not need the users code */}} diff --git a/chart/tests/helm_tests/airflow_aux/test_pod_template_file.py b/chart/tests/helm_tests/airflow_aux/test_pod_template_file.py index 34d03fe7762d6..42a776b5fb628 100644 --- a/chart/tests/helm_tests/airflow_aux/test_pod_template_file.py +++ b/chart/tests/helm_tests/airflow_aux/test_pod_template_file.py @@ -356,6 +356,39 @@ def test_should_set_a_custom_image_in_pod_template(self): assert jmespath.search("spec.containers[0].imagePullPolicy", docs[0]) == "Always" assert jmespath.search("spec.containers[0].name", docs[0]) == "base" + @pytest.mark.parametrize( + ("expected_image", "tag", "digest"), + [ + ("dummy_image:user-tag", "user-tag", None), + ("dummy_image@user-digest", None, "user-digest"), + ("dummy_image@user-digest", "user-tag", "user-digest"), + ], + ) + def test_should_use_correct_pod_template_image(self, expected_image, tag, digest): + docs = render_chart( + values={ + "images": { + "pod_template": {"repository": "dummy_image", "tag": tag, "digest": digest}, + }, + }, + show_only=["templates/pod-template-file.yaml"], + chart_dir=self.temp_chart_dir, + ) + + assert jmespath.search("spec.containers[0].image", docs[0]) == expected_image + + def test_should_use_default_airflow_digest_in_pod_template(self): + docs = render_chart( + values={ + "defaultAirflowRepository": "test-repo", + "defaultAirflowDigest": "user-digest", + }, + show_only=["templates/pod-template-file.yaml"], + chart_dir=self.temp_chart_dir, + ) + + assert jmespath.search("spec.containers[0].image", docs[0]) == "test-repo@user-digest" + def test_mount_airflow_cfg(self): docs = render_chart( show_only=["templates/pod-template-file.yaml"], diff --git a/chart/values.schema.json b/chart/values.schema.json index 7eb865997c7b0..3513f073e126e 100644 --- a/chart/values.schema.json +++ b/chart/values.schema.json @@ -801,6 +801,14 @@ ], "default": null }, + "digest": { + "description": "The pod_template image digest. If set, it will override the tag. If ``config.kubernetes_executor.worker_container_repository`` and ``config.kubernetes_executor.worker_container_tag`` are set, the k8s executor will use those instead.", + "type": [ + "string", + "null" + ], + "default": null + }, "pullPolicy": { "description": "The pod_template image pull policy.", "type": "string", diff --git a/chart/values.yaml b/chart/values.yaml index 890f9976d970c..b73b6ed1bb4fa 100644 --- a/chart/values.yaml +++ b/chart/values.yaml @@ -89,6 +89,8 @@ images: # `config.kubernetes_executor.worker_container_tag` must be not set . repository: ~ tag: ~ + # Specifying digest takes precedence over tag. + digest: ~ pullPolicy: IfNotPresent flower: repository: ~