From a159d081ef765ab4b5c9fa2a49f6640275a93318 Mon Sep 17 00:00:00 2001 From: Alputer Date: Mon, 18 Nov 2024 11:51:36 +0100 Subject: [PATCH] fix(sessions): get the session status from the pod state (#611) Closes reanahub/reana-ui#408 --- reana_workflow_controller/k8s.py | 46 +++++++++++++++++++++ reana_workflow_controller/rest/workflows.py | 11 ++++- 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/reana_workflow_controller/k8s.py b/reana_workflow_controller/k8s.py index 5661f2c5..68cf30ab 100644 --- a/reana_workflow_controller/k8s.py +++ b/reana_workflow_controller/k8s.py @@ -477,3 +477,49 @@ def delete_dask_dashboard_ingress(cluster_name, workflow_id): plural="middlewares", name=f"replacepath-{workflow_id}", ) + + +def get_pod_status(pod_name, namespace="default"): + """Check the status of a Pod in the given namespace.""" + try: + # Use the correct client for CoreV1Api + pod = current_k8s_corev1_api_client.read_namespaced_pod( + name=pod_name, namespace=namespace + ) + + # Check the pod phase + pod_phase = pod.status.phase + if pod_phase == "Running": + return "Running" + elif pod_phase == "Pending": + return "Pending" + elif pod_phase == "Failed": + return "Failed" + elif pod_phase == "Succeeded": + return "Succeeded" + else: + return f"Unknown status: {pod_phase}" + except ApiException as e: + if e.status == 404: + print(f"Pod {pod_name} not found in namespace {namespace}.") + return "Not Found" + else: + print(f"Exception when checking pod status: {e}") + return "Error" + + +def check_pod_by_prefix(pod_name_prefix, namespace="default"): + """Check if there is a Pod in the given namespace whose name starts with the specified prefix. We assume that there exists 0 or 1 pod with a given prefix.""" + try: + pods = current_k8s_corev1_api_client.list_namespaced_pod(namespace=namespace) + + for pod in pods.items: + if pod.metadata.name.startswith(pod_name_prefix): + if pod.status.phase == "Running": + return "Running" + else: + return "Not Ready" + + return "Not Found" + except ApiException as e: + return f"Error: {e.reason}" diff --git a/reana_workflow_controller/rest/workflows.py b/reana_workflow_controller/rest/workflows.py index 1ee83fa1..30b03d3a 100644 --- a/reana_workflow_controller/rest/workflows.py +++ b/reana_workflow_controller/rest/workflows.py @@ -22,6 +22,7 @@ from webargs import fields, validate from webargs.flaskparser import use_args, use_kwargs from reana_commons.config import WORKFLOW_TIME_FORMAT +from reana_commons.utils import build_unique_component_name from reana_db.database import Session from reana_db.models import RunStatus, User, UserWorkflow, Workflow, WorkflowResource from reana_db.utils import ( @@ -48,6 +49,8 @@ use_paginate_args, ) +from reana_workflow_controller.k8s import check_pod_by_prefix + START = "start" STOP = "stop" DELETED = "deleted" @@ -398,7 +401,13 @@ def get_workflows(args, paginate=None): # noqa if int_session: workflow_response["session_type"] = int_session.type_.name workflow_response["session_uri"] = int_session.path - workflow_response["session_status"] = int_session.status.name + int_session_pod_name_prefix = build_unique_component_name( + "run-session", int_session.workflow[0].id_ + ) + workflow_response["session_status"] = check_pod_by_prefix( + pod_name_prefix=int_session_pod_name_prefix + ) + # Skip workflow if type is interactive and there is no session elif type_ == "interactive": continue