From 7ca08f9b306bcba82e193691a281b092154ee42f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Gaillard?= Date: Sun, 22 Mar 2026 12:01:15 +0100 Subject: [PATCH] feat(instance_manager): add interactive stopping of Klipper instances (#784) * feat(instance_manager): add interactive stopping of Klipper instances with user confirmation * fix(instance_utils): remove unnecessary 'self' parameter from stop_klipper_instances_interactively function * refactor(tmc_autotune): replace internal stop function with direct call to stop_klipper_instances_interactively --- .../tmc_autotune/tmc_autotune_extension.py | 45 ++----------------- kiauh/utils/instance_utils.py | 41 +++++++++++++++++ 2 files changed, 45 insertions(+), 41 deletions(-) diff --git a/kiauh/extensions/tmc_autotune/tmc_autotune_extension.py b/kiauh/extensions/tmc_autotune/tmc_autotune_extension.py index de9621a..6422299 100644 --- a/kiauh/extensions/tmc_autotune/tmc_autotune_extension.py +++ b/kiauh/extensions/tmc_autotune/tmc_autotune_extension.py @@ -30,7 +30,7 @@ from utils.config_utils import add_config_section, remove_config_section from utils.fs_utils import check_file_exist, create_symlink, run_remove_routines from utils.git_utils import git_clone_wrapper, git_pull_wrapper from utils.input_utils import get_confirm -from utils.instance_utils import get_instances +from utils.instance_utils import get_instances, stop_klipper_instances_interactively from utils.sys_utils import check_python_version @@ -84,7 +84,7 @@ class TmcAutotuneExtension(BaseExtension): kl_instances = get_instances(Klipper) - if not self._stop_klipper_instances_interactively( + if not stop_klipper_instances_interactively( kl_instances, "installation of TMC Autotune" ): return @@ -172,7 +172,7 @@ class TmcAutotuneExtension(BaseExtension): kl_instances = get_instances(Klipper) - if not self._stop_klipper_instances_interactively( + if not stop_klipper_instances_interactively( kl_instances, "update of TMC Autotune" ): return @@ -210,7 +210,7 @@ class TmcAutotuneExtension(BaseExtension): kl_instances = get_instances(Klipper) - if not self._stop_klipper_instances_interactively( + if not stop_klipper_instances_interactively( kl_instances, "removal of TMC Autotune" ): return @@ -345,40 +345,3 @@ class TmcAutotuneExtension(BaseExtension): "Klipper TMC Autotune successfully removed from Moonraker update manager(s)!" ) - def _stop_klipper_instances_interactively( - self, kl_instances: List[Klipper], operation_name: str = "operation" - ) -> bool: - """ - Interactively stops all active Klipper instances, warning the user that ongoing prints will be disrupted. - - :param kl_instances: List of Klipper instances to stop. - :param operation_name: Optional name of the operation being performed (for user messaging). Do NOT capitalize. - :return: True if instances were stopped or no instances found, False if operation was aborted. - """ - - if not kl_instances: - Logger.print_warn("No instances found, skipping instance stopping.") - return True - - Logger.print_dialog( - DialogType.ATTENTION, - [ - "Do NOT continue if there are ongoing prints running", - f"All Klipper instances will be restarted during the {operation_name} and " - "ongoing prints WILL FAIL.", - ], - ) - stop_klipper = get_confirm( - question=f"Stop Klipper now and proceed with {operation_name}?", - default_choice=False, - allow_go_back=True, - ) - - if stop_klipper: - InstanceManager.stop_all(kl_instances) - return True - else: - Logger.print_warn( - f"{operation_name.capitalize()} aborted due to user request." - ) - return False diff --git a/kiauh/utils/instance_utils.py b/kiauh/utils/instance_utils.py index 2056256..b516d39 100644 --- a/kiauh/utils/instance_utils.py +++ b/kiauh/utils/instance_utils.py @@ -12,8 +12,12 @@ import re from pathlib import Path from typing import List +from components.klipper.klipper import Klipper from core.constants import SYSTEMD from core.instance_manager.base_instance import SUFFIX_BLACKLIST +from core.instance_manager.instance_manager import InstanceManager +from core.logger import DialogType, Logger +from utils.input_utils import get_confirm from utils.instance_type import InstanceType @@ -56,3 +60,40 @@ def get_instance_suffix(name: str, file_path: Path) -> str: # otherwise there is and hyphen left, and we return the part after the hyphen suffix = file_path.stem[len(name) :] return suffix[1:] if suffix else "" + + +def stop_klipper_instances_interactively( + kl_instances: List[Klipper], operation_name: str = "operation" +) -> bool: + """ + Interactively stops all active Klipper instances, warning the user that ongoing prints will be disrupted. + + :param kl_instances: List of Klipper instances to stop. + :param operation_name: Optional name of the operation being performed (for user messaging). Do NOT capitalize. + :return: True if instances were stopped or no instances found, False if operation was aborted. + """ + + if not kl_instances: + Logger.print_warn("No instances found, skipping instance stopping.") + return True + + Logger.print_dialog( + DialogType.ATTENTION, + [ + "Do NOT continue if there are ongoing prints running", + f"All Klipper instances will be restarted during the {operation_name} and " + "ongoing prints WILL FAIL.", + ], + ) + stop_klipper = get_confirm( + question=f"Stop Klipper now and proceed with {operation_name}?", + default_choice=False, + allow_go_back=True, + ) + + if stop_klipper: + InstanceManager.stop_all(kl_instances) + return True + else: + Logger.print_warn(f"{operation_name.capitalize()} aborted due to user request.") + return False