-
Notifications
You must be signed in to change notification settings - Fork 16.4k
Added Istio support to KubernetesPodOperator #26739
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
b9d8a02
c9dd73d
3a8103d
c0d8166
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -215,6 +215,7 @@ def __init__( | |
| termination_grace_period: int | None = None, | ||
| configmaps: list[str] | None = None, | ||
| resources: dict[str, Any] | None = None, | ||
| istio_enabled: bool = False, | ||
| **kwargs, | ||
| ) -> None: | ||
|
|
||
|
|
@@ -287,6 +288,7 @@ def __init__( | |
| self.termination_grace_period = termination_grace_period | ||
| self.pod_request_obj: k8s.V1Pod | None = None | ||
| self.pod: k8s.V1Pod | None = None | ||
| self.istio_enabled = istio_enabled | ||
|
|
||
| def _render_nested_template_fields( | ||
| self, | ||
|
|
@@ -342,7 +344,7 @@ def _get_ti_pod_labels(context: Context | None = None, include_try_number: bool | |
|
|
||
| @cached_property | ||
| def pod_manager(self) -> PodManager: | ||
| return PodManager(kube_client=self.client) | ||
| return PodManager(kube_client=self.client, istio_enabled=self.istio_enabled) | ||
|
|
||
| def get_hook(self): | ||
| warnings.warn("get_hook is deprecated. Please use hook instead.", DeprecationWarning, stacklevel=2) | ||
|
|
@@ -453,7 +455,7 @@ def cleanup(self, pod: k8s.V1Pod, remote_pod: k8s.V1Pod): | |
| if not self.is_delete_operator_pod: | ||
| with _suppress(Exception): | ||
| self.patch_already_checked(remote_pod) | ||
| if pod_phase != PodPhase.SUCCEEDED: | ||
| if (not self.istio_enabled and pod_phase != PodPhase.SUCCEEDED) or (self.istio_enabled and pod_phase != PodPhase.SUCCEEDED and not self.pod_manager.container_is_succeeded(pod, 'base')): | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this expression can probably be simplified. i would try to do so. it's too hard to understand as it is. |
||
| if self.log_events_on_failure: | ||
| with _suppress(Exception): | ||
| for event in self.pod_manager.read_pod_events(pod).items: | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -84,6 +84,36 @@ def container_is_running(pod: V1Pod, container_name: str) -> bool: | |
| return container_status.state.running is not None | ||
|
|
||
|
|
||
| def container_is_completed(pod: V1Pod, container_name: str) -> bool: | ||
| """ | ||
| Examines V1Pod ``pod`` to determine whether ``container_name`` is completed. | ||
| If that container is present and completed, returns True. Returns False otherwise. | ||
| """ | ||
| container_statuses = pod.status.container_statuses if pod and pod.status else None | ||
| if not container_statuses: | ||
| return False | ||
| container_status = next(iter([x for x in container_statuses if x.name == container_name]), None) | ||
| if not container_status: | ||
| return False | ||
| return container_status.state.terminated is not None | ||
|
|
||
|
|
||
| def container_is_succeeded(pod: V1Pod, container_name: str) -> bool: | ||
| """ | ||
| Examines V1Pod ``pod`` to determine whether ``container_name`` is completed and succeeded. | ||
| If that container is present and completed and succeeded, returns True. Returns False otherwise. | ||
| """ | ||
| if not container_is_completed(pod, container_name): | ||
| return False | ||
| container_statuses = pod.status.container_statuses if pod and pod.status else None | ||
| if not container_statuses: | ||
| return False | ||
| container_status = next(iter([x for x in container_statuses if x.name == container_name]), None) | ||
| if not container_status: | ||
| return False | ||
| return container_status.state.terminated.exit_code == 0 | ||
|
Comment on lines
+87
to
+114
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. seems you are duplicating a lot of logic here. looks like you could pull out a |
||
|
|
||
|
|
||
| def get_container_termination_message(pod: V1Pod, container_name: str): | ||
| try: | ||
| container_statuses = pod.status.container_statuses | ||
|
|
@@ -112,6 +142,7 @@ def __init__( | |
| kube_client: client.CoreV1Api = None, | ||
| in_cluster: bool = True, | ||
| cluster_context: str | None = None, | ||
| istio_enabled: bool = False, | ||
| ): | ||
| """ | ||
| Creates the launcher. | ||
|
|
@@ -123,6 +154,7 @@ def __init__( | |
| super().__init__() | ||
| self._client = kube_client or get_kube_client(in_cluster=in_cluster, cluster_context=cluster_context) | ||
| self._watch = watch.Watch() | ||
| self.istio_enabled = istio_enabled | ||
|
|
||
| def run_pod_async(self, pod: V1Pod, **kwargs) -> V1Pod: | ||
| """Runs POD asynchronously""" | ||
|
|
@@ -272,6 +304,10 @@ def await_pod_completion(self, pod: V1Pod) -> V1Pod: | |
| remote_pod = self.read_pod(pod) | ||
| if remote_pod.status.phase in PodPhase.terminal_states: | ||
| break | ||
| if self.istio_enabled and remote_pod.status.phase == PodPhase.RUNNING and self.container_is_completed( | ||
| remote_pod, 'base' | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| ): | ||
| break | ||
| self.log.info('Pod %s has phase %s', pod.metadata.name, remote_pod.status.phase) | ||
| time.sleep(2) | ||
| return remote_pod | ||
|
|
@@ -306,6 +342,16 @@ def container_is_running(self, pod: V1Pod, container_name: str) -> bool: | |
| remote_pod = self.read_pod(pod) | ||
| return container_is_running(pod=remote_pod, container_name=container_name) | ||
|
|
||
| def container_is_completed(self, pod: V1Pod, container_name: str) -> bool: | ||
| """Reads pod and checks if container is completed""" | ||
| remote_pod = self.read_pod(pod) | ||
| return container_is_completed(pod=remote_pod, container_name=container_name) | ||
|
|
||
| def container_is_succeeded(self, pod: V1Pod, container_name: str) -> bool: | ||
| """Reads pod and checks if container is succeeded""" | ||
| remote_pod = self.read_pod(pod) | ||
| return container_is_succeeded(pod=remote_pod, container_name=container_name) | ||
|
|
||
| @tenacity.retry(stop=tenacity.stop_after_attempt(3), wait=tenacity.wait_exponential(), reraise=True) | ||
| def read_pod_logs( | ||
| self, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you will need to enable pre-commit locally see https://github.com/apache/airflow/blob/main/CONTRIBUTING.rst