From cee3f659f9c50e93790447ddbb788e638042e639 Mon Sep 17 00:00:00 2001 From: Shashank Tippanavar <152605527+MightyShashank@users.noreply.github.com> Date: Sun, 23 Mar 2025 14:35:02 +0530 Subject: [PATCH 1/7] Update __init__.py Signed-off-by: Shashank Tippanavar <152605527+MightyShashank@users.noreply.github.com> --- ceph_devstack/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ceph_devstack/__init__.py b/ceph_devstack/__init__.py index c2c88d660..a0fca0cba 100644 --- a/ceph_devstack/__init__.py +++ b/ceph_devstack/__init__.py @@ -90,6 +90,8 @@ def parse_args(args: List[str]) -> argparse.Namespace: default=False, help="Leave the cluster running - and don't auto-schedule anything", ) + + subparsers.add_parser("show_log", help="Show test logs") subparsers.add_parser("remove", help="Destroy the cluster") subparsers.add_parser("start", help="Start the cluster") subparsers.add_parser("stop", help="Stop the cluster") From 254964ee64172da304d666e9bf416f5ffdbac48a Mon Sep 17 00:00:00 2001 From: Shashank Tippanavar <152605527+MightyShashank@users.noreply.github.com> Date: Sun, 23 Mar 2025 14:36:51 +0530 Subject: [PATCH 2/7] Update __init__.py Implementation of show_log Signed-off-by: Shashank Tippanavar <152605527+MightyShashank@users.noreply.github.com> --- ceph_devstack/resources/ceph/__init__.py | 46 ++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/ceph_devstack/resources/ceph/__init__.py b/ceph_devstack/resources/ceph/__init__.py index 95a8754e2..649a38f79 100644 --- a/ceph_devstack/resources/ceph/__init__.py +++ b/ceph_devstack/resources/ceph/__init__.py @@ -229,3 +229,49 @@ async def wait(self, container_name: str): return await container.wait() logger.error(f"Could not find container {container_name}") return 1 + + async def show_log(self): + home_dir = os.path.expanduser("~") + target_dir = os.path.join(home_dir, ".local", "share", "ceph-devstack", "archive") + run_directories_list = None + if os.path.exists(target_dir) and os.path.isdir(target_dir): + run_directories_list = os.listdir(target_dir) + else: + logger.error(f"Error: {target_dir} does not exist or is not a directory") + return 1 + def extract_timestamp(dir_name): + try: + parts = dir_name.split("-") + year, month, day_time = parts[1], parts[2], parts[3] + day, time = day_time.split("_") + timestamp = f"{year}-{month}-{day} {time}" + return datetime.strptime(timestamp, "%Y-%m-%d %H:%M:%S") + except Exception as e: + logger.error(f"Error extracting timestamp from {dir_name}: {e}") + return None + run_directories_list.sort(key=lambda dir: extract_timestamp(dir), reverse=True) + latest_directory = run_directories_list[0] if run_directories_list else None + try: + latest_directory = os.path.join(target_dir, latest_directory) + all_job_ids = [jobID for jobID in os.listdir(latest_directory) if os.path.isdir(os.path.join(latest_directory, jobID)) and jobID.isdigit()] + if not all_job_ids: + logger.info("No latest jobIDs") # We could add a feature to go to the "next" latest directory + else: + print("Available jobID to view log:", ", ".join(all_job_ids)) + while True: + selected_jobID = input("Select jobID to view corresponding log: ") + if selected_jobID in all_job_ids: + log_file_path = os.path.join(latest_directory, selected_jobID, "teuthology.log") + if os.path.exists(log_file_path) and os.path.isfile(log_file_path): + print("<------------teuthology.log contents------------> \n") + with open(log_file_path, "r") as file: + print(file.read()) + return 0 + else: + logger.error(f"Error: teuthology.log file not found in {os.path.join(latest_directory, selected_jobID)}") + return 1 + else: + logger.error(f"Error: {selected_jobID} is not a valid jobID") + return 0 + except Exception as e: + logger.error(f"Error: {e}") From 0f97b34828fef4bbc6813d5f916168625b0f1512 Mon Sep 17 00:00:00 2001 From: Shashank Tippanavar <152605527+MightyShashank@users.noreply.github.com> Date: Sun, 23 Mar 2025 16:14:23 +0530 Subject: [PATCH 3/7] Update __init__.py Update __init__.py to include option for --filepath flag Signed-off-by: Shashank Tippanavar <152605527+MightyShashank@users.noreply.github.com> --- ceph_devstack/__init__.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/ceph_devstack/__init__.py b/ceph_devstack/__init__.py index a0fca0cba..aa07d39fb 100644 --- a/ceph_devstack/__init__.py +++ b/ceph_devstack/__init__.py @@ -91,7 +91,14 @@ def parse_args(args: List[str]) -> argparse.Namespace: help="Leave the cluster running - and don't auto-schedule anything", ) - subparsers.add_parser("show_log", help="Show test logs") + parser_show_log = subparsers.add_parser("show_log", help="Show test logs") + parser_show_log.add_argument( + "-f", + "--filepath", + action="store_true", + default=False, + help="Output just the full path of the logfile instead of its containers" + ) subparsers.add_parser("remove", help="Destroy the cluster") subparsers.add_parser("start", help="Start the cluster") subparsers.add_parser("stop", help="Stop the cluster") From 9af5959dc33758d6c4c885049925c4e403116be2 Mon Sep 17 00:00:00 2001 From: Shashank Tippanavar <152605527+MightyShashank@users.noreply.github.com> Date: Sun, 23 Mar 2025 16:16:32 +0530 Subject: [PATCH 4/7] Update cli.py Updated cli.py to include option for calling show-log Signed-off-by: Shashank Tippanavar <152605527+MightyShashank@users.noreply.github.com> --- ceph_devstack/cli.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ceph_devstack/cli.py b/ceph_devstack/cli.py index b3116f94d..8aa0215c6 100644 --- a/ceph_devstack/cli.py +++ b/ceph_devstack/cli.py @@ -36,6 +36,8 @@ async def run(): return elif args.command == "wait": return await obj.wait(container_name=args.container) + elif args.command == "show-log": + return await obj.show_log(filepath=args.filepath) else: await obj.apply(args.command) return 0 From acc527d5ea6a6d34add9f3a7b7cecb2317e5481c Mon Sep 17 00:00:00 2001 From: Shashank Tippanavar <152605527+MightyShashank@users.noreply.github.com> Date: Sun, 23 Mar 2025 16:20:33 +0530 Subject: [PATCH 5/7] Update show-log implementation Signed-off-by: Shashank Tippanavar <152605527+MightyShashank@users.noreply.github.com> --- ceph_devstack/resources/ceph/__init__.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/ceph_devstack/resources/ceph/__init__.py b/ceph_devstack/resources/ceph/__init__.py index 649a38f79..10221e19f 100644 --- a/ceph_devstack/resources/ceph/__init__.py +++ b/ceph_devstack/resources/ceph/__init__.py @@ -2,6 +2,7 @@ import contextlib import os import tempfile +from datetime import datetime from collections import OrderedDict from subprocess import CalledProcessError @@ -230,7 +231,7 @@ async def wait(self, container_name: str): logger.error(f"Could not find container {container_name}") return 1 - async def show_log(self): + async def show_log(self, filepath: bool = False): home_dir = os.path.expanduser("~") target_dir = os.path.join(home_dir, ".local", "share", "ceph-devstack", "archive") run_directories_list = None @@ -262,11 +263,14 @@ def extract_timestamp(dir_name): selected_jobID = input("Select jobID to view corresponding log: ") if selected_jobID in all_job_ids: log_file_path = os.path.join(latest_directory, selected_jobID, "teuthology.log") - if os.path.exists(log_file_path) and os.path.isfile(log_file_path): + if os.path.exists(log_file_path) and os.path.isfile(log_file_path) and not filepath: print("<------------teuthology.log contents------------> \n") with open(log_file_path, "r") as file: print(file.read()) return 0 + elif filepath: + logger.info(f"{log_file_path}") + return 0 else: logger.error(f"Error: teuthology.log file not found in {os.path.join(latest_directory, selected_jobID)}") return 1 @@ -275,3 +279,4 @@ def extract_timestamp(dir_name): return 0 except Exception as e: logger.error(f"Error: {e}") + From 145c030dad9a9007c8827bcbe5bbeac4dce57d94 Mon Sep 17 00:00:00 2001 From: Shashank Tippanavar <152605527+MightyShashank@users.noreply.github.com> Date: Sun, 23 Mar 2025 16:27:50 +0530 Subject: [PATCH 6/7] Updated show-log command Signed-off-by: Shashank Tippanavar <152605527+MightyShashank@users.noreply.github.com> --- ceph_devstack/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ceph_devstack/__init__.py b/ceph_devstack/__init__.py index aa07d39fb..81314c70e 100644 --- a/ceph_devstack/__init__.py +++ b/ceph_devstack/__init__.py @@ -91,13 +91,13 @@ def parse_args(args: List[str]) -> argparse.Namespace: help="Leave the cluster running - and don't auto-schedule anything", ) - parser_show_log = subparsers.add_parser("show_log", help="Show test logs") + parser_show_log = subparsers.add_parser("show-log", help="Show test logs") parser_show_log.add_argument( "-f", "--filepath", action="store_true", default=False, - help="Output just the full path of the logfile instead of its containers" + help="Output just the full path of the logfile instead of its content" ) subparsers.add_parser("remove", help="Destroy the cluster") subparsers.add_parser("start", help="Start the cluster") From 9113182ca68f259da3e4c9b8d2d525ddea943636 Mon Sep 17 00:00:00 2001 From: Shashank Tippanavar <152605527+MightyShashank@users.noreply.github.com> Date: Sun, 23 Mar 2025 16:51:27 +0530 Subject: [PATCH 7/7] Updated show-log implementation to handle multiple jobs Signed-off-by: Shashank Tippanavar <152605527+MightyShashank@users.noreply.github.com> --- ceph_devstack/resources/ceph/__init__.py | 47 ++++++++++++++++-------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/ceph_devstack/resources/ceph/__init__.py b/ceph_devstack/resources/ceph/__init__.py index 10221e19f..b7505f38e 100644 --- a/ceph_devstack/resources/ceph/__init__.py +++ b/ceph_devstack/resources/ceph/__init__.py @@ -258,24 +258,39 @@ def extract_timestamp(dir_name): if not all_job_ids: logger.info("No latest jobIDs") # We could add a feature to go to the "next" latest directory else: - print("Available jobID to view log:", ", ".join(all_job_ids)) - while True: - selected_jobID = input("Select jobID to view corresponding log: ") - if selected_jobID in all_job_ids: - log_file_path = os.path.join(latest_directory, selected_jobID, "teuthology.log") - if os.path.exists(log_file_path) and os.path.isfile(log_file_path) and not filepath: - print("<------------teuthology.log contents------------> \n") - with open(log_file_path, "r") as file: - print(file.read()) - return 0 - elif filepath: - logger.info(f"{log_file_path}") - return 0 + if(len(all_job_ids)>1): + print("ALERT: Multiple jobIDs found: ", ", ".join(all_job_ids)) + while True: + selected_jobID = input("Select jobID to view corresponding log: ") + if selected_jobID in all_job_ids: + log_file_path = os.path.join(latest_directory, selected_jobID, "teuthology.log") + if os.path.exists(log_file_path) and os.path.isfile(log_file_path) and not filepath: + print("<-----------teuthology.log contents----------->") + with open(log_file_path, "r") as file: + print(file.read()) + return 0 + elif filepath: + logger.info(f"{log_file_path}") + return 0 + else: + logger.error(f"Error: teuthology.log file not found in {os.path.join(latest_directory, selected_jobID)}") + return 1 else: - logger.error(f"Error: teuthology.log file not found in {os.path.join(latest_directory, selected_jobID)}") - return 1 + logger.error(f"Error: {selected_jobID} is not a valid jobID") + else: + selected_jobID = all_job_ids[0] + log_file_path = os.path.join(latest_directory, selected_jobID, "teuthology.log") + if os.path.exists(log_file_path) and os.path.isfile(log_file_path) and not filepath: + print("<-----------teuthology.log contents----------->") + with open(log_file_path, "r") as file: + print(file.read()) + return 0 + elif filepath: + logger.info(f"{log_file_path}") + return 0 else: - logger.error(f"Error: {selected_jobID} is not a valid jobID") + logger.error(f"Error: teuthology.log file not found in {os.path.join(latest_directory, selected_jobID)}") + return 1 return 0 except Exception as e: logger.error(f"Error: {e}")