refactor: create moonraker instances based on klipper instances

Signed-off-by: Dominik Willner <th33xitus@gmail.com>
This commit is contained in:
dw-0
2024-08-20 20:22:01 +02:00
parent fe0bfc5376
commit ea991644cd
5 changed files with 52 additions and 34 deletions

View File

@@ -32,7 +32,6 @@ from core.logger import Logger
class Klipper(BaseInstance): class Klipper(BaseInstance):
klipper_dir: Path = KLIPPER_DIR klipper_dir: Path = KLIPPER_DIR
env_dir: Path = KLIPPER_ENV_DIR env_dir: Path = KLIPPER_ENV_DIR
log_file_name = KLIPPER_LOG_NAME
cfg_file: Path | None = None cfg_file: Path | None = None
serial: Path | None = None serial: Path | None = None
uds: Path | None = None uds: Path | None = None
@@ -42,6 +41,7 @@ class Klipper(BaseInstance):
def __post_init__(self) -> None: def __post_init__(self) -> None:
super().__post_init__() super().__post_init__()
self.log_file_name = KLIPPER_LOG_NAME
self.cfg_file = self.cfg_dir.joinpath(KLIPPER_CFG_NAME) self.cfg_file = self.cfg_dir.joinpath(KLIPPER_CFG_NAME)
self.serial = self.comms_dir.joinpath(KLIPPER_SERIAL_NAME) self.serial = self.comms_dir.joinpath(KLIPPER_SERIAL_NAME)
self.uds = self.comms_dir.joinpath(KLIPPER_UDS_NAME) self.uds = self.comms_dir.joinpath(KLIPPER_UDS_NAME)

View File

@@ -33,7 +33,6 @@ from core.submodules.simple_config_parser.src.simple_config_parser.simple_config
class Moonraker(BaseInstance): class Moonraker(BaseInstance):
moonraker_dir: Path = MOONRAKER_DIR moonraker_dir: Path = MOONRAKER_DIR
env_dir: Path = MOONRAKER_ENV_DIR env_dir: Path = MOONRAKER_ENV_DIR
log_file_name = MOONRAKER_LOG_NAME
cfg_file: Path | None = None cfg_file: Path | None = None
port: int | None = None port: int | None = None
backup_dir: Path | None = None backup_dir: Path | None = None
@@ -45,6 +44,7 @@ class Moonraker(BaseInstance):
def __post_init__(self) -> None: def __post_init__(self) -> None:
super().__post_init__() super().__post_init__()
self.log_file_name = MOONRAKER_LOG_NAME
self.cfg_file = self.cfg_dir.joinpath(MOONRAKER_CFG_NAME) self.cfg_file = self.cfg_dir.joinpath(MOONRAKER_CFG_NAME)
self.port = self._get_port() self.port = self._get_port()
self.backup_dir = self.data_dir.joinpath("backup") self.backup_dir = self.data_dir.joinpath("backup")

View File

@@ -31,6 +31,7 @@ from components.moonraker.moonraker_dialogs import print_moonraker_overview
from components.moonraker.moonraker_utils import ( from components.moonraker.moonraker_utils import (
backup_moonraker_dir, backup_moonraker_dir,
create_example_moonraker_conf, create_example_moonraker_conf,
moonraker_factory,
) )
from components.webui_client.client_utils import ( from components.webui_client.client_utils import (
enable_mainsail_remotemode, enable_mainsail_remotemode,
@@ -50,6 +51,7 @@ from utils.input_utils import (
from utils.sys_utils import ( from utils.sys_utils import (
check_python_version, check_python_version,
cmd_sysctl_manage, cmd_sysctl_manage,
cmd_sysctl_service,
create_python_venv, create_python_venv,
install_python_requirements, install_python_requirements,
parse_packages_from_file, parse_packages_from_file,
@@ -61,14 +63,12 @@ def install_moonraker() -> None:
return return
klipper_list: List[Klipper] = InstanceManager(Klipper).instances klipper_list: List[Klipper] = InstanceManager(Klipper).instances
mr_im = InstanceManager(Moonraker) moonraker_list: List[Moonraker] = InstanceManager(Moonraker).instances
moonraker_list: List[Moonraker] = mr_im.instances instances: List[Moonraker] = []
instance_names = []
selected_option: str | Klipper selected_option: str | Klipper
if len(klipper_list) == 0: if len(klipper_list) == 1:
instance_names.append(klipper_list[0].suffix) instances.append(moonraker_factory(klipper_list[0]))
else: else:
print_moonraker_overview( print_moonraker_overview(
klipper_list, klipper_list,
@@ -87,12 +87,12 @@ def install_moonraker() -> None:
return return
if selected_option == "a": if selected_option == "a":
instance_names.extend([k.suffix for k in klipper_list]) instances.extend([moonraker_factory(k) for k in klipper_list])
else: else:
klipper_instance: Klipper | None = options.get(selected_option) klipper_instance: Klipper | None = options.get(selected_option)
if klipper_instance is None: if klipper_instance is None:
raise Exception("Error selecting instance!") raise Exception("Error selecting instance!")
instance_names.append(klipper_instance.suffix) instances.append(moonraker_factory(klipper_instance))
create_example_cfg = get_confirm("Create example moonraker.conf?") create_example_cfg = get_confirm("Create example moonraker.conf?")
@@ -102,26 +102,23 @@ def install_moonraker() -> None:
install_moonraker_polkit() install_moonraker_polkit()
used_ports_map = {m.suffix: m.port for m in moonraker_list} used_ports_map = {m.suffix: m.port for m in moonraker_list}
for name in instance_names: for instance in instances:
current_instance = Moonraker(suffix=name) instance.create()
cmd_sysctl_service(instance.service_file_path.name, "enable")
mr_im.current_instance = current_instance
mr_im.create_instance()
mr_im.enable_instance()
if create_example_cfg: if create_example_cfg:
# if a webclient and/or it's config is installed, patch # if a webclient and/or it's config is installed, patch
# its update section to the config # its update section to the config
clients = get_existing_clients() clients = get_existing_clients()
create_example_moonraker_conf(current_instance, used_ports_map, clients) create_example_moonraker_conf(instance, used_ports_map, clients)
mr_im.start_instance() cmd_sysctl_service(instance.service_file_path.name, "start")
cmd_sysctl_manage("daemon-reload") cmd_sysctl_manage("daemon-reload")
# if mainsail is installed, and we installed # if mainsail is installed, and we installed
# multiple moonraker instances, we enable mainsails remote mode # multiple moonraker instances, we enable mainsails remote mode
if MainsailData().client_dir.exists() and len(mr_im.instances) > 1: if MainsailData().client_dir.exists() and len(moonraker_list) > 1:
enable_mainsail_remotemode() enable_mainsail_remotemode()
except Exception as e: except Exception as e:

View File

@@ -10,9 +10,11 @@
import shutil import shutil
from typing import Dict, List, Optional from typing import Dict, List, Optional
from components.klipper.klipper import Klipper
from components.moonraker import ( from components.moonraker import (
MODULE_PATH, MODULE_PATH,
MOONRAKER_BACKUP_DIR, MOONRAKER_BACKUP_DIR,
MOONRAKER_CFG_NAME,
MOONRAKER_DB_BACKUP_DIR, MOONRAKER_DB_BACKUP_DIR,
MOONRAKER_DEFAULT_PORT, MOONRAKER_DEFAULT_PORT,
MOONRAKER_DIR, MOONRAKER_DIR,
@@ -33,6 +35,25 @@ from utils.sys_utils import (
) )
def moonraker_factory(klipper_instance: Klipper) -> Moonraker:
"""Create a new Moonraker instance from a Klipper instance."""
instance: Moonraker = Moonraker(suffix=klipper_instance.suffix)
instance.is_legacy_instance = klipper_instance.is_legacy_instance
instance.data_dir = klipper_instance.data_dir
instance.data_dir_name = klipper_instance.data_dir_name
instance.cfg_dir = klipper_instance.cfg_dir
instance.cfg_file = instance.cfg_dir.joinpath(MOONRAKER_CFG_NAME)
instance.log_dir = klipper_instance.log_dir
instance.sysd_dir = klipper_instance.sysd_dir
instance.comms_dir = klipper_instance.comms_dir
instance.gcodes_dir = klipper_instance.gcodes_dir
instance.db_dir = instance.data_dir.joinpath("database")
instance.backup_dir = instance.data_dir.joinpath("backup")
instance.certs_dir = instance.data_dir.joinpath("certs")
return instance
def get_moonraker_status() -> ComponentStatus: def get_moonraker_status() -> ComponentStatus:
return get_install_status(MOONRAKER_DIR, MOONRAKER_ENV_DIR, Moonraker) return get_install_status(MOONRAKER_DIR, MOONRAKER_ENV_DIR, Moonraker)

View File

@@ -35,10 +35,12 @@ class BaseInstance(ABC):
log_file_name: str = "" log_file_name: str = ""
def __post_init__(self) -> None: def __post_init__(self) -> None:
self._set_data_dir()
self._set_is_legacy_instance()
self._set_service_file_path() self._set_service_file_path()
self._set_data_dir()
if self.data_dir is not None: if self.data_dir is not None:
self.data_dir_name = self.data_dir.name
self._set_is_legacy_instance()
self.cfg_dir = self.data_dir.joinpath("config") self.cfg_dir = self.data_dir.joinpath("config")
self.log_dir = self.data_dir.joinpath("logs") self.log_dir = self.data_dir.joinpath("logs")
self.comms_dir = self.data_dir.joinpath("comms") self.comms_dir = self.data_dir.joinpath("comms")
@@ -112,13 +114,15 @@ class BaseInstance(ABC):
else: else:
self.data_dir = Path.home().joinpath(f"printer_{self.suffix}_data") self.data_dir = Path.home().joinpath(f"printer_{self.suffix}_data")
if self.service_file_path is not None and self.service_file_path.exists(): if self.service_file_path and self.service_file_path.exists():
with open(self.service_file_path, "r") as service_file: with open(self.service_file_path, "r") as service_file:
service_content = service_file.read() lines = service_file.readlines()
pattern = re.compile("^EnvironmentFile=(.+)(/systemd/.+\.env)") for line in lines:
match = re.search(pattern, service_content) pattern = r"^EnvironmentFile=(.+)(/systemd/.+\.env)"
if match: match = re.search(pattern, line)
self.data_dir = Path(match.group(1)) if match:
self.data_dir = Path(match.group(1))
break
def _set_service_file_path(self) -> None: def _set_service_file_path(self) -> None:
from utils.common import convert_camelcase_to_kebabcase from utils.common import convert_camelcase_to_kebabcase
@@ -130,11 +134,7 @@ class BaseInstance(ABC):
self.service_file_path = SYSTEMD.joinpath(f"{name}.service") self.service_file_path = SYSTEMD.joinpath(f"{name}.service")
def _set_is_legacy_instance(self) -> None: def _set_is_legacy_instance(self) -> None:
if ( legacy_pattern = r"^(?!printer)(.+)_data"
self.suffix != "" match = re.search(legacy_pattern, self.data_dir_name)
and not self.data_dir_name.startswith("printer_") if match and self.suffix != "":
and not self.data_dir_name.endswith("_data")
):
self.is_legacy_instance = True self.is_legacy_instance = True
else:
self.is_legacy_instance = False