Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions airflow/executors/kubernetes_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -370,17 +370,17 @@ def delete_pod(self, pod_id: str, namespace: str) -> None:
if e.status != 404:
raise

def patch_pod_executor_done(self, *, pod_id: str, namespace: str):
def patch_pod_executor_done(self, *, pod_name: str, namespace: str):
"""Add a "done" annotation to ensure we don't continually adopt pods"""
self.log.debug("Patching pod %s in namespace %s to mark it as done", pod_id, namespace)
self.log.debug("Patching pod %s in namespace %s to mark it as done", pod_name, namespace)
try:
self.kube_client.patch_namespaced_pod(
name=pod_id,
name=pod_name,
namespace=namespace,
body={"metadata": {"labels": {POD_EXECUTOR_DONE_KEY: "True"}}},
)
except ApiException as e:
self.log.info("Failed to patch pod %s with done annotation. Reason: %s", pod_id, e)
self.log.info("Failed to patch pod %s with done annotation. Reason: %s", pod_name, e)

def sync(self) -> None:
"""
Expand Down Expand Up @@ -761,7 +761,7 @@ def _change_state(self, key: TaskInstanceKey, state: str | None, pod_id: str, na
self.kube_scheduler.delete_pod(pod_id, namespace)
self.log.info("Deleted pod: %s in namespace %s", str(key), str(namespace))
else:
self.kube_scheduler.patch_pod_executor_done(pod_id=pod_id, namespace=namespace)
self.kube_scheduler.patch_pod_executor_done(pod_name=pod_id, namespace=namespace)
self.log.info("Patched pod %s in namespace %s to mark it as done", str(key), str(namespace))

try:
Expand Down
11 changes: 7 additions & 4 deletions tests/executors/test_kubernetes_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -545,21 +545,24 @@ def test_change_state_success(self, mock_delete_pod, mock_get_kube_client, mock_

@mock.patch("airflow.executors.kubernetes_executor.KubernetesJobWatcher")
@mock.patch("airflow.executors.kubernetes_executor.get_kube_client")
@mock.patch("airflow.executors.kubernetes_executor.AirflowKubernetesScheduler.delete_pod")
@mock.patch("airflow.executors.kubernetes_executor.AirflowKubernetesScheduler")
def test_change_state_failed_no_deletion(
self, mock_delete_pod, mock_get_kube_client, mock_kubernetes_job_watcher
self, mock_kubescheduler, mock_get_kube_client, mock_kubernetes_job_watcher
):
mock_delete_pod = mock_kubescheduler.return_value.delete_pod
mock_patch_pod = mock_kubescheduler.return_value.patch_pod_executor_done
executor = self.kubernetes_executor
executor.kube_config.delete_worker_pods = False
executor.kube_config.delete_worker_pods_on_failure = False
executor.start()
try:
key = ("dag_id", "task_id", "run_id", "try_number3")
executor.running = {key}
executor._change_state(key, State.FAILED, "pod_id", "default")
executor._change_state(key, State.FAILED, "pod_id", "test-namespace")
assert executor.event_buffer[key][0] == State.FAILED
assert executor.running == set()
mock_delete_pod.assert_not_called()
mock_patch_pod.assert_called_once_with(pod_name="pod_id", namespace="test-namespace")
finally:
executor.end()

Expand Down Expand Up @@ -606,7 +609,7 @@ def test_change_state_skip_pod_deletion(
assert executor.event_buffer[key][0] == State.SUCCESS
assert executor.running == set()
mock_delete_pod.assert_not_called()
mock_patch_pod.assert_called_once_with(pod_id="pod_id", namespace="test-namespace")
mock_patch_pod.assert_called_once_with(pod_name="pod_id", namespace="test-namespace")
finally:
executor.end()

Expand Down