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

jscheffl 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 c85246ce9bf Add missing support for:  securityContexts and 
containerLifecycleHooks (#60677)
c85246ce9bf is described below

commit c85246ce9bffbcd4d52e674e266086351dd94315
Author: Henry Chen <[email protected]>
AuthorDate: Wed Feb 25 06:34:20 2026 +0800

    Add missing support for:  securityContexts and containerLifecycleHooks 
(#60677)
    
    * keep consistency
    
    * support kerberos init securityContext/lifecycle in workers
---
 chart/files/pod-template-file.kubernetes-helm-yaml |   6 ++
 chart/templates/workers/worker-deployment.yaml     |   6 ++
 .../airflow_aux/test_pod_template_file.py          | 102 +++++++++++++++++++++
 .../tests/helm_tests/airflow_core/test_worker.py   |  59 ++++++++++++
 .../helm_tests/airflow_core/test_worker_sets.py    | 102 +++++++++++++++++++++
 .../helm_tests/security/test_security_context.py   |  43 +++++++++
 6 files changed, 318 insertions(+)

diff --git a/chart/files/pod-template-file.kubernetes-helm-yaml 
b/chart/files/pod-template-file.kubernetes-helm-yaml
index 51d2c50e63c..05be0e210db 100644
--- a/chart/files/pod-template-file.kubernetes-helm-yaml
+++ b/chart/files/pod-template-file.kubernetes-helm-yaml
@@ -24,6 +24,8 @@
 {{- $securityContext := include "airflowPodSecurityContext" (list 
.Values.workers.kubernetes .Values.workers .Values) }}
 {{- $containerSecurityContextKerberosSidecar := include 
"containerSecurityContext" (list .Values.workers.kerberosSidecar .Values) }}
 {{- $containerLifecycleHooksKerberosSidecar := or 
.Values.workers.kerberosSidecar.containerLifecycleHooks 
.Values.containerLifecycleHooks }}
+{{- $containerSecurityContextKerberosInitContainer := include 
"containerSecurityContext" (list 
.Values.workers.kubernetes.kerberosInitContainer 
.Values.workers.kerberosInitContainer .Values) }}
+{{- $containerLifecycleHooksKerberosInitContainer := or 
.Values.workers.kubernetes.kerberosInitContainer.containerLifecycleHooks 
.Values.workers.kerberosInitContainer.containerLifecycleHooks 
.Values.containerLifecycleHooks }}
 {{- $containerSecurityContext := include "containerSecurityContext" (list 
.Values.workers.kubernetes .Values.workers .Values) }}
 {{- $containerLifecycleHooks := or .Values.workers.containerLifecycleHooks 
.Values.containerLifecycleHooks }}
 {{- $safeToEvict := dict "cluster-autoscaler.kubernetes.io/safe-to-evict" 
(.Values.workers.safeToEvict | toString) }}
@@ -57,6 +59,10 @@ spec:
     - name: kerberos-init
       image: {{ template "airflow_image" . }}
       imagePullPolicy: {{ .Values.images.airflow.pullPolicy }}
+      securityContext: {{ $containerSecurityContextKerberosInitContainer | 
nindent 8 }}
+      {{- if $containerLifecycleHooksKerberosInitContainer }}
+      lifecycle: {{- tpl (toYaml 
$containerLifecycleHooksKerberosInitContainer) . | nindent 8 }}
+      {{- end }}
       args: ["kerberos", "-o"]
       resources: {{- toYaml 
(.Values.workers.kubernetes.kerberosInitContainer.resources | default 
.Values.workers.kerberosInitContainer.resources) | nindent 8 }}
       volumeMounts:
diff --git a/chart/templates/workers/worker-deployment.yaml 
b/chart/templates/workers/worker-deployment.yaml
index 1ae802555c5..93e7efcdb7e 100644
--- a/chart/templates/workers/worker-deployment.yaml
+++ b/chart/templates/workers/worker-deployment.yaml
@@ -48,6 +48,8 @@
 {{- $containerSecurityContextWaitForMigrations := include 
"containerSecurityContext" (list .Values.workers.waitForMigrations .Values) }}
 {{- $containerSecurityContextLogGroomerSidecar := include 
"containerSecurityContext" (list .Values.workers.logGroomerSidecar .Values) }}
 {{- $containerSecurityContextKerberosSidecar := include 
"containerSecurityContext" (list .Values.workers.kerberosSidecar .Values) }}
+{{- $containerSecurityContextKerberosInitContainer := include 
"containerSecurityContext" (list .Values.workers.kerberosInitContainer .Values) 
}}
+{{- $containerLifecycleHooksKerberosInitContainer := or 
.Values.workers.kerberosInitContainer.containerLifecycleHooks 
.Values.containerLifecycleHooks }}
 {{- $containerLifecycleHooks := or .Values.workers.containerLifecycleHooks 
.Values.containerLifecycleHooks }}
 {{- $containerLifecycleHooksLogGroomerSidecar := or 
.Values.workers.logGroomerSidecar.containerLifecycleHooks 
.Values.containerLifecycleHooks }}
 {{- $containerLifecycleHooksKerberosSidecar := or 
.Values.workers.kerberosSidecar.containerLifecycleHooks 
.Values.containerLifecycleHooks }}
@@ -180,6 +182,10 @@ spec:
         {{- if and (semverCompare ">=2.8.0" .Values.airflowVersion) 
.Values.workers.kerberosInitContainer.enabled }}
         - name: kerberos-init
           image: {{ template "airflow_image" . }}
+          securityContext: {{ $containerSecurityContextKerberosInitContainer | 
nindent 12 }}
+          {{- if $containerLifecycleHooksKerberosInitContainer }}
+          lifecycle: {{- tpl (toYaml 
$containerLifecycleHooksKerberosInitContainer) . | nindent 12 }}
+          {{- end }}
           imagePullPolicy: {{ .Values.images.airflow.pullPolicy }}
           args: ["kerberos", "-o"]
           resources: {{- toYaml 
.Values.workers.kerberosInitContainer.resources | nindent 12 }}
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 b9678ada1e5..bfce878fcd0 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
@@ -1384,3 +1384,105 @@ class TestPodTemplateFile:
                 "memory": "4Mi",
             },
         }
+
+    @pytest.mark.parametrize(
+        "workers_values",
+        [
+            {
+                "kerberosInitContainer": {
+                    "enabled": True,
+                    "securityContexts": {"container": {"runAsUser": 2000}},
+                }
+            },
+            {
+                "kubernetes": {
+                    "kerberosInitContainer": {
+                        "enabled": True,
+                        "securityContexts": {"container": {"runAsUser": 2000}},
+                    }
+                }
+            },
+            {
+                "kerberosInitContainer": {
+                    "enabled": True,
+                    "securityContexts": {"container": {"runAsUser": 1000}},
+                },
+                "kubernetes": {
+                    "kerberosInitContainer": {
+                        "enabled": True,
+                        "securityContexts": {"container": {"runAsUser": 2000}},
+                    }
+                },
+            },
+        ],
+    )
+    def test_kerberos_init_container_security_context(self, workers_values):
+        docs = render_chart(
+            values={
+                "workers": workers_values,
+            },
+            show_only=["templates/pod-template-file.yaml"],
+            chart_dir=self.temp_chart_dir,
+        )
+
+        assert jmespath.search(
+            "spec.initContainers[?name=='kerberos-init'] | 
[0].securityContext", docs[0]
+        ) == {"runAsUser": 2000}
+
+    @pytest.mark.parametrize(
+        ("workers_values", "expected"),
+        [
+            (
+                {
+                    "kerberosInitContainer": {
+                        "enabled": True,
+                        "containerLifecycleHooks": {"postStart": {"exec": 
{"command": ["echo", "base"]}}},
+                    }
+                },
+                {"postStart": {"exec": {"command": ["echo", "base"]}}},
+            ),
+            (
+                {
+                    "kubernetes": {
+                        "kerberosInitContainer": {
+                            "enabled": True,
+                            "containerLifecycleHooks": {
+                                "postStart": {"exec": {"command": ["echo", 
"kubernetes"]}}
+                            },
+                        }
+                    }
+                },
+                {"postStart": {"exec": {"command": ["echo", "kubernetes"]}}},
+            ),
+            (
+                {
+                    "kerberosInitContainer": {
+                        "enabled": True,
+                        "containerLifecycleHooks": {"preStop": {"exec": 
{"command": ["echo", "base"]}}},
+                    },
+                    "kubernetes": {
+                        "kerberosInitContainer": {
+                            "enabled": True,
+                            "containerLifecycleHooks": {
+                                "postStart": {"exec": {"command": ["echo", 
"kubernetes"]}}
+                            },
+                        }
+                    },
+                },
+                {"postStart": {"exec": {"command": ["echo", "kubernetes"]}}},
+            ),
+        ],
+    )
+    def test_kerberos_init_container_lifecycle_hooks(self, workers_values, 
expected):
+        docs = render_chart(
+            values={
+                "workers": workers_values,
+            },
+            show_only=["templates/pod-template-file.yaml"],
+            chart_dir=self.temp_chart_dir,
+        )
+
+        assert (
+            jmespath.search("spec.initContainers[?name=='kerberos-init'] | 
[0].lifecycle", docs[0])
+            == expected
+        )
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 9d02691aad3..a8b93bb5f2e 100644
--- a/helm-tests/tests/helm_tests/airflow_core/test_worker.py
+++ b/helm-tests/tests/helm_tests/airflow_core/test_worker.py
@@ -1050,6 +1050,65 @@ class TestWorker:
             },
         }
 
+    @pytest.mark.parametrize(
+        ("workers_values", "expected"),
+        [
+            (
+                {
+                    "kerberosInitContainer": {
+                        "enabled": True,
+                        "containerLifecycleHooks": {"postStart": {"exec": 
{"command": ["echo", "base"]}}},
+                    }
+                },
+                {"postStart": {"exec": {"command": ["echo", "base"]}}},
+            ),
+            (
+                {
+                    "celery": {
+                        "kerberosInitContainer": {
+                            "enabled": True,
+                            "containerLifecycleHooks": {
+                                "postStart": {"exec": {"command": ["echo", 
"celery"]}}
+                            },
+                        }
+                    }
+                },
+                {"postStart": {"exec": {"command": ["echo", "celery"]}}},
+            ),
+            (
+                {
+                    "kerberosInitContainer": {
+                        "enabled": True,
+                        "containerLifecycleHooks": {"postStart": {"exec": 
{"command": ["echo", "base"]}}},
+                    },
+                    "celery": {
+                        "kerberosInitContainer": {
+                            "enabled": True,
+                            "containerLifecycleHooks": {
+                                "postStart": {"exec": {"command": ["echo", 
"celery"]}}
+                            },
+                        }
+                    },
+                },
+                {"postStart": {"exec": {"command": ["echo", "celery"]}}},
+            ),
+        ],
+    )
+    def test_kerberos_init_container_lifecycle_hooks(self, workers_values, 
expected):
+        docs = render_chart(
+            values={
+                "workers": workers_values,
+            },
+            show_only=["templates/workers/worker-deployment.yaml"],
+        )
+
+        assert (
+            jmespath.search(
+                "spec.template.spec.initContainers[?name=='kerberos-init'] | 
[0].lifecycle", docs[0]
+            )
+            == expected
+        )
+
     @pytest.mark.parametrize(
         ("airflow_version", "expected_arg"),
         [
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 44188918d70..1434094172a 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
@@ -841,6 +841,108 @@ class TestWorkerSets:
             "limits": {"cpu": "3m", "memory": "4Mi"},
         }
 
+    @pytest.mark.parametrize(
+        "values",
+        [
+            {
+                "celery": {
+                    "enableDefault": False,
+                    "sets": [
+                        {
+                            "name": "test",
+                            "kerberosInitContainer": {
+                                "enabled": True,
+                                "securityContexts": {
+                                    "container": {"runAsUser": 10},
+                                },
+                            },
+                        }
+                    ],
+                }
+            },
+            {
+                "kerberosInitContainer": {
+                    "securityContexts": {
+                        "container": {"allowPrivilegeEscalation": False},
+                    }
+                },
+                "celery": {
+                    "enableDefault": False,
+                    "sets": [
+                        {
+                            "name": "test",
+                            "kerberosInitContainer": {
+                                "enabled": True,
+                                "securityContexts": {
+                                    "container": {"runAsUser": 10},
+                                },
+                            },
+                        }
+                    ],
+                },
+            },
+        ],
+    )
+    def test_overwrite_kerberos_init_container_security_context(self, values):
+        docs = render_chart(
+            values={"workers": values},
+            show_only=["templates/workers/worker-deployment.yaml"],
+        )
+
+        assert jmespath.search(
+            "spec.template.spec.initContainers[?name=='kerberos-init'] | 
[0].securityContext", docs[0]
+        ) == {"runAsUser": 10}
+
+    @pytest.mark.parametrize(
+        "values",
+        [
+            {
+                "celery": {
+                    "enableDefault": False,
+                    "sets": [
+                        {
+                            "name": "test",
+                            "kerberosInitContainer": {
+                                "enabled": True,
+                                "containerLifecycleHooks": {
+                                    "postStart": {"exec": {"command": ["echo", 
"{{ .Release.Name }}"]}},
+                                },
+                            },
+                        }
+                    ],
+                }
+            },
+            {
+                "kerberosInitContainer": {
+                    "containerLifecycleHooks": {"preStop": {"exec": 
{"command": ["echo", "test"]}}}
+                },
+                "celery": {
+                    "enableDefault": False,
+                    "sets": [
+                        {
+                            "name": "test",
+                            "kerberosInitContainer": {
+                                "enabled": True,
+                                "containerLifecycleHooks": {
+                                    "postStart": {"exec": {"command": ["echo", 
"{{ .Release.Name }}"]}},
+                                },
+                            },
+                        }
+                    ],
+                },
+            },
+        ],
+    )
+    def test_overwrite_kerberos_init_container_lifecycle_hooks(self, values):
+        docs = render_chart(
+            values={"workers": values},
+            show_only=["templates/workers/worker-deployment.yaml"],
+        )
+
+        assert jmespath.search(
+            "spec.template.spec.initContainers[?name=='kerberos-init'] | 
[0].lifecycle", docs[0]
+        ) == {"postStart": {"exec": {"command": ["echo", "release-name"]}}}
+
     def test_overwrite_container_lifecycle_hooks(self):
         docs = render_chart(
             values={
diff --git a/helm-tests/tests/helm_tests/security/test_security_context.py 
b/helm-tests/tests/helm_tests/security/test_security_context.py
index 916365e155e..1738520702a 100644
--- a/helm-tests/tests/helm_tests/security/test_security_context.py
+++ b/helm-tests/tests/helm_tests/security/test_security_context.py
@@ -632,6 +632,49 @@ class TestSecurityContext:
 
         assert ctx_value == 
jmespath.search("spec.template.spec.containers[2].securityContext", docs[0])
 
+    @pytest.mark.parametrize(
+        "workers_values",
+        [
+            {
+                "kerberosInitContainer": {
+                    "enabled": True,
+                    "securityContexts": {"container": {"runAsUser": 2000}},
+                }
+            },
+            {
+                "celery": {
+                    "kerberosInitContainer": {
+                        "enabled": True,
+                        "securityContexts": {"container": {"runAsUser": 2000}},
+                    }
+                }
+            },
+            {
+                "kerberosInitContainer": {
+                    "enabled": True,
+                    "securityContexts": {"container": {"runAsUser": 1000}},
+                },
+                "celery": {
+                    "kerberosInitContainer": {
+                        "enabled": True,
+                        "securityContexts": {"container": {"runAsUser": 2000}},
+                    }
+                },
+            },
+        ],
+    )
+    def test_worker_kerberos_init_container_security_context(self, 
workers_values):
+        docs = render_chart(
+            values={
+                "workers": workers_values,
+            },
+            show_only=["templates/workers/worker-deployment.yaml"],
+        )
+
+        assert jmespath.search(
+            "spec.template.spec.initContainers[?name=='kerberos-init'] | 
[0].securityContext", docs[0]
+        ) == {"runAsUser": 2000}
+
     # Test securityContexts for the wait-for-migrations init containers
     def test_wait_for_migrations_init_container_setting_airflow_2(self):
         ctx_value = {"allowPrivilegeEscalation": False}

Reply via email to