diff --git a/src/qlever/commands/stop.py b/src/qlever/commands/stop.py index 82225304..d2b74fcb 100644 --- a/src/qlever/commands/stop.py +++ b/src/qlever/commands/stop.py @@ -1,15 +1,40 @@ from __future__ import annotations - import re - import psutil - from qlever.command import QleverCommand from qlever.commands.status import StatusCommand from qlever.containerize import Containerize from qlever.log import log from qlever.util import show_process_info +# try to kill the given process, return true iff it was killed successfully. +# the process_info is used for logging. +def stop_process(proc, pinfo): + try: + proc.kill() + log.info(f"Killed process {pinfo['pid']}") + return True + except Exception as e: + log.error(f"Could not kill process with PID " + f"{pinfo['pid']} ({e}) ... try to kill it " + f"manually") + log.info("") + show_process_info(proc, "", show_heading=True) + return False + + +# try to stop and remove container. return True iff it was stopped +# successfully. Gives log info accordingly. +def stop_container(server_container): + for container_system in Containerize.supported_systems(): + if Containerize.stop_and_remove_container( + container_system, server_container): + log.info(f"{container_system.capitalize()} container with " + f"name \"{server_container}\" stopped " + f" and removed") + return True + return False + class StopCommand(QleverCommand): """ @@ -20,7 +45,7 @@ def __init__(self): pass def description(self) -> str: - return ("Stop QLever server for a given datasedataset or port") + return "Stop QLever server for a given datasedataset or port" def should_have_qleverfile(self) -> bool: return True @@ -54,46 +79,31 @@ def execute(self, args) -> bool: # First check if there is container running and if yes, stop and remove # it (unless the user has specified `--no-containers`). if not args.no_containers: - for container_system in Containerize.supported_systems(): - if Containerize.stop_and_remove_container( - container_system, args.server_container): - log.info(f"{container_system.capitalize()} container with " - f"name \"{args.server_container}\" stopped " - f" and removed") - return True + if stop_container(args.server_container): + return True # Check if there is a process running on the server port using psutil. - # # NOTE: On MacOS, some of the proc's returned by psutil.process_iter() # no longer exist when we try to access them, so we just skip them. for proc in psutil.process_iter(): try: pinfo = proc.as_dict( - attrs=['pid', 'username', 'create_time', - 'memory_info', 'cmdline']) + attrs=['pid', 'username', 'create_time', + 'memory_info', 'cmdline']) cmdline = " ".join(pinfo['cmdline']) except Exception as e: log.debug(f"Error getting process info: {e}") + return False if re.search(cmdline_regex, cmdline): log.info(f"Found process {pinfo['pid']} from user " f"{pinfo['username']} with command line: {cmdline}") log.info("") - try: - proc.kill() - log.info(f"Killed process {pinfo['pid']}") - except Exception as e: - log.error(f"Could not kill process with PID " - f"{pinfo['pid']} ({e}) ... try to kill it " - f"manually") - log.info("") - show_process_info(proc, "", show_heading=True) - return False - return True + return stop_process(proc, pinfo) # If no matching process found, show a message and the output of the # status command. message = "No matching process found" if args.no_containers else \ - "No matching process or container found" + "No matching process or container found" log.error(message) args.cmdline_regex = "^ServerMain.* -i [^ ]*" log.info("")