def execute(self, context) -> Optional[str]: try: if self.in_cluster is not None: client = kube_client.get_kube_client( in_cluster=self.in_cluster, cluster_context=self.cluster_context, config_file=self.config_file) else: client = kube_client.get_kube_client( cluster_context=self.cluster_context, config_file=self.config_file) # Add combination of labels to uniquely identify a running pod labels = self.create_labels_for_pod(context) label_selector = self._get_pod_identifying_label_string(labels) pod_list = client.list_namespaced_pod( self.namespace, label_selector=label_selector) running_pods = [ pod for pod in pod_list.items if pod.status.phase == 'Running' ] if len(running_pods) > 1 and self.reattach_on_restart: raise AirflowException( 'More than one pod running with labels: ' '{label_selector}'.format(label_selector=label_selector)) launcher = pod_launcher.PodLauncher(kube_client=client, extract_xcom=self.do_xcom_push) if len(running_pods) == 1: try_numbers_match = self._try_numbers_match( context, running_pods[0]) final_state, result = self.handle_pod_overlap( labels, try_numbers_match, launcher, running_pods[0]) else: self.log.info("creating pod with labels %s and launcher %s", labels, launcher) final_state, _, result = self.create_new_pod_for_operator( labels, launcher) if final_state != State.SUCCESS: raise AirflowException( 'Pod returned a failure: {state}'.format( state=final_state)) return result except AirflowException as ex: raise AirflowException( 'Pod Launching failed: {error}'.format(error=ex))
def execute(self, context) -> Optional[str]: try: if self.in_cluster is not None: client = kube_client.get_kube_client( in_cluster=self.in_cluster, cluster_context=self.cluster_context, config_file=self.config_file, ) else: client = kube_client.get_kube_client( cluster_context=self.cluster_context, config_file=self.config_file ) self.pod = self.create_pod_request_obj() self.namespace = self.pod.metadata.namespace self.client = client # Add combination of labels to uniquely identify a running pod labels = self.create_labels_for_pod(context) label_selector = self._get_pod_identifying_label_string(labels) self.namespace = self.pod.metadata.namespace pod_list = client.list_namespaced_pod(self.namespace, label_selector=label_selector) if len(pod_list.items) > 1 and self.reattach_on_restart: raise AirflowException( f'More than one pod running with labels: {label_selector}' ) launcher = pod_launcher.PodLauncher(kube_client=client, extract_xcom=self.do_xcom_push) if len(pod_list.items) == 1: try_numbers_match = self._try_numbers_match(context, pod_list.items[0]) final_state, result = self.handle_pod_overlap( labels, try_numbers_match, launcher, pod_list.items[0] ) else: self.log.info("creating pod with labels %s and launcher %s", labels, launcher) final_state, _, result = self.create_new_pod_for_operator(labels, launcher) if final_state != State.SUCCESS: status = self.client.read_namespaced_pod(self.pod.metadata.name, self.namespace) raise AirflowException(f'Pod {self.pod.metadata.name} returned a failure: {status}') return result except AirflowException as ex: raise AirflowException(f'Pod Launching failed: {ex}')
def execute(self, context) -> Optional[str]: try: if self.in_cluster is not None: client = kube_client.get_kube_client(in_cluster=self.in_cluster, cluster_context=self.cluster_context, config_file=self.config_file) else: client = kube_client.get_kube_client(cluster_context=self.cluster_context, config_file=self.config_file) # Add combination of labels to uniquely identify a running pod labels = self.create_labels_for_pod(context) label_selector = self._get_pod_identifying_label_string(labels) pod_list = client.list_namespaced_pod(self.namespace, label_selector=label_selector) if len(pod_list.items) > 1: raise AirflowException( 'More than one pod running with labels: ' '{label_selector}'.format(label_selector=label_selector)) launcher = pod_launcher.PodLauncher(kube_client=client, extract_xcom=self.do_xcom_push) if len(pod_list.items) == 1 and \ self._try_numbers_do_not_match(context, pod_list.items[0]) and \ self.reattach_on_restart: self.log.info("found a running pod with labels %s but a different try_number" "Will attach to this pod and monitor instead of starting new one", labels) final_state, result = self.monitor_launched_pod(launcher, pod_list.items[0]) elif len(pod_list.items) == 1: self.log.info("found a running pod with labels %s." "Will monitor this pod instead of starting new one", labels) final_state, result = self.monitor_launched_pod(launcher, pod_list.items[0]) else: self.log.info("creating pod with labels %s and launcher %s", labels, launcher) final_state, _, result = self.create_new_pod_for_operator(labels, launcher) if final_state != State.SUCCESS: raise AirflowException( 'Pod returned a failure: {state}'.format(state=final_state)) return result except AirflowException as ex: raise AirflowException('Pod Launching failed: {error}'.format(error=ex))
def execute(self, context): try: if self.in_cluster is not None: client = kube_client.get_kube_client( in_cluster=self.in_cluster, cluster_context=self.cluster_context, config_file=self.config_file) else: client = kube_client.get_kube_client( cluster_context=self.cluster_context, config_file=self.config_file) if not (self.full_pod_spec or self.pod_template_file): # Add Airflow Version to the label # And a label to identify that pod is launched by KubernetesPodOperator self.labels.update({ 'airflow_version': airflow_version.replace('+', '-'), 'kubernetes_pod_operator': 'True', }) pod = pod_generator.PodGenerator( image=self.image, namespace=self.namespace, cmds=self.cmds, args=self.arguments, labels=self.labels, name=self.name, envs=self.env_vars, extract_xcom=self.do_xcom_push, image_pull_policy=self.image_pull_policy, node_selectors=self.node_selectors, annotations=self.annotations, affinity=self.affinity, image_pull_secrets=self.image_pull_secrets, service_account_name=self.service_account_name, hostnetwork=self.hostnetwork, tolerations=self.tolerations, configmaps=self.configmaps, security_context=self.security_context, dnspolicy=self.dnspolicy, schedulername=self.schedulername, init_containers=self.init_containers, restart_policy='Never', priority_class_name=self.priority_class_name, pod_template_file=self.pod_template_file, pod=self.full_pod_spec, ).gen_pod() pod = append_to_pod( pod, self.pod_runtime_info_envs + self.ports + self.resources + self.secrets + self.volumes + self.volume_mounts) self.pod = pod launcher = pod_launcher.PodLauncher(kube_client=client, extract_xcom=self.do_xcom_push) final_state, result = None, None try: (final_state, result) = launcher.run_pod( pod, startup_timeout=self.startup_timeout_seconds, get_logs=self.get_logs) finally: if final_state != State.SUCCESS: # Before deleting the pod we get events and status of the pod (events can be fetched # after pod deletion but not statuses. For consistency both are fetched before deletion. self._log_pod_events_on_failure(pod, launcher) self._log_pod_status_on_failure(pod, launcher) if self.is_delete_operator_pod: launcher.delete_pod(pod) if final_state != State.SUCCESS: if self.retry_only_on_pod_launching_failure: self.log.info( 'Task failure due to task image, avoiding retries and failing the task.' ) ti = context.get('task_instance') ti.error() raise AirflowException( 'Pod returned a failure: {state}'.format( state=final_state)) return result except AirflowException as ex: raise AirflowException( 'Pod Launching failed: {error}'.format(error=ex))
def execute(self, context): try: client = kube_client.get_kube_client( in_cluster=self.in_cluster, cluster_context=self.cluster_context, config_file=self.config_file) # Add Airflow Version to the label # And a label to identify that pod is launched by KubernetesPodOperator self.labels.update({ 'airflow_version': airflow_version.replace('+', '-'), 'kubernetes_pod_operator': 'True', }) pod = pod_generator.PodGenerator( image=self.image, namespace=self.namespace, cmds=self.cmds, args=self.arguments, labels=self.labels, name=self.name, envs=self.env_vars, extract_xcom=self.do_xcom_push, image_pull_policy=self.image_pull_policy, node_selectors=self.node_selectors, annotations=self.annotations, affinity=self.affinity, image_pull_secrets=self.image_pull_secrets, service_account_name=self.service_account_name, hostnetwork=self.hostnetwork, tolerations=self.tolerations, configmaps=self.configmaps, security_context=self.security_context, dnspolicy=self.dnspolicy, pod=self.full_pod_spec, ).gen_pod() pod = append_to_pod( pod, self.pod_runtime_info_envs + self.ports + self.resources + self.secrets + self.volumes + self.volume_mounts) self.pod = pod launcher = pod_launcher.PodLauncher(kube_client=client, extract_xcom=self.do_xcom_push) try: (final_state, result) = launcher.run_pod( pod, startup_timeout=self.startup_timeout_seconds, get_logs=self.get_logs) finally: if self.is_delete_operator_pod: launcher.delete_pod(pod) if final_state != State.SUCCESS: raise AirflowException( 'Pod returned a failure: {state}'.format( state=final_state)) return result except AirflowException as ex: raise AirflowException( 'Pod Launching failed: {error}'.format(error=ex))
def execute(self, context): try: client = kube_client.get_kube_client( in_cluster=self.in_cluster, cluster_context=self.cluster_context, config_file=self.config_file) gen = pod_generator.PodGenerator() for port in self.ports: gen.add_port(port) for mount in self.volume_mounts: gen.add_mount(mount) for volume in self.volumes: gen.add_volume(volume) pod = gen.make_pod( namespace=self.namespace, image=self.image, pod_id=self.name, cmds=self.cmds, arguments=self.arguments, labels=self.labels, ) pod.service_account_name = self.service_account_name pod.secrets = self.secrets pod.envs = self.env_vars pod.image_pull_policy = self.image_pull_policy pod.image_pull_secrets = self.image_pull_secrets pod.annotations = self.annotations pod.resources = self.resources pod.affinity = self.affinity pod.node_selectors = self.node_selectors pod.hostnetwork = self.hostnetwork pod.tolerations = self.tolerations pod.configmaps = self.configmaps pod.security_context = self.security_context pod.pod_runtime_info_envs = self.pod_runtime_info_envs pod.dnspolicy = self.dnspolicy launcher = pod_launcher.PodLauncher(kube_client=client, extract_xcom=self.do_xcom_push) try: (final_state, result) = launcher.run_pod( pod, startup_timeout=self.startup_timeout_seconds, logs_connection_timeout=self. logs_connection_timeout_seconds, get_logs=self.get_logs) finally: if self.is_delete_operator_pod: launcher.delete_pod(pod) if final_state != State.SUCCESS: raise AirflowException( 'Pod returned a failure: {state}'.format( state=final_state)) return result except AirflowException as ex: raise AirflowException( 'Pod Launching failed: {error}'.format(error=ex))