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

jedcunningham pushed a commit to branch v2-2-test
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit c836e71b2f39e069ae880eb7a2eacfb420672fd6
Author: Bas Harenslak <[email protected]>
AuthorDate: Thu Dec 16 00:54:31 2021 +0100

    Bugfix: Deepcopying Kubernetes Secrets attributes causing issues (#20318)
    
    Encountered a nasty bug where somebody basically implemented their own 
KubernetesPodSensor, which failed after more than one attempt when using 
mode="poke" + a volume + a secret.
    
    Root cause turned out to be in `secret.attach_to_pod()`. In here, a volume 
and volumemount is created to mount the secret. A deepcopy() is made of the 
given Pod spec. In order to avoid appending to None, there is this line: 
`cp_pod.spec.volumes = pod.spec.volumes or []`. In case a volume is set on the 
Pod spec, a reference is created to the original pod spec volumes, which in 
turn was a reference to `self.volumes`. As a result, each secret resulted in a 
volume added to `self.volumes`, [...]
    
    This PR references the deepcopied object instead, and creates a new list if 
pod.spec.volumes is None.
    
    Co-authored-by: Bas Harenslak <[email protected]>
    (cherry picked from commit 2409760694b668213a111712bb1162884c23dd2d)
---
 airflow/kubernetes/secret.py | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/airflow/kubernetes/secret.py b/airflow/kubernetes/secret.py
index 20ed27b..1ca2611 100644
--- a/airflow/kubernetes/secret.py
+++ b/airflow/kubernetes/secret.py
@@ -91,20 +91,28 @@ class Secret(K8SModel):
     def attach_to_pod(self, pod: k8s.V1Pod) -> k8s.V1Pod:
         """Attaches to pod"""
         cp_pod = copy.deepcopy(pod)
+
         if self.deploy_type == 'volume':
             volume, volume_mount = self.to_volume_secret()
-            cp_pod.spec.volumes = pod.spec.volumes or []
+            if cp_pod.spec.volumes is None:
+                cp_pod.spec.volumes = []
             cp_pod.spec.volumes.append(volume)
-            cp_pod.spec.containers[0].volume_mounts = 
pod.spec.containers[0].volume_mounts or []
+            if cp_pod.spec.containers[0].volume_mounts is None:
+                cp_pod.spec.containers[0].volume_mounts = []
             cp_pod.spec.containers[0].volume_mounts.append(volume_mount)
+
         if self.deploy_type == 'env' and self.key is not None:
             env = self.to_env_secret()
-            cp_pod.spec.containers[0].env = cp_pod.spec.containers[0].env or []
+            if cp_pod.spec.containers[0].env is None:
+                cp_pod.spec.containers[0].env = []
             cp_pod.spec.containers[0].env.append(env)
+
         if self.deploy_type == 'env' and self.key is None:
             env_from = self.to_env_from_secret()
-            cp_pod.spec.containers[0].env_from = 
cp_pod.spec.containers[0].env_from or []
+            if cp_pod.spec.containers[0].env_from is None:
+                cp_pod.spec.containers[0].env_from = []
             cp_pod.spec.containers[0].env_from.append(env_from)
+
         return cp_pod
 
     def __eq__(self, other):

Reply via email to