Compare commits

..

1 Commits

Author SHA1 Message Date
dw-0
24ba2788de Merge e530c75307 into a929c6983d 2024-06-30 18:32:30 +02:00
15 changed files with 211 additions and 264 deletions

View File

@@ -13,24 +13,9 @@ from core.backup_manager import BACKUP_ROOT_DIR
MODULE_PATH = Path(__file__).resolve().parent
# names
KLIPPER_LOG_NAME = "klippy.log"
KLIPPER_CFG_NAME = "printer.cfg"
KLIPPER_SERIAL_NAME = "klippy.serial"
KLIPPER_UDS_NAME = "klippy.sock"
KLIPPER_ENV_FILE_NAME = "klipper.env"
KLIPPER_SERVICE_NAME = "klipper.service"
# directories
KLIPPER_DIR = Path.home().joinpath("klipper")
KLIPPER_ENV_DIR = Path.home().joinpath("klippy-env")
KLIPPER_BACKUP_DIR = BACKUP_ROOT_DIR.joinpath("klipper-backups")
# files
KLIPPER_REQ_FILE = KLIPPER_DIR.joinpath("scripts/klippy-requirements.txt")
KLIPPER_INSTALL_SCRIPT = KLIPPER_DIR.joinpath("scripts/install-ubuntu-22.04.sh")
KLIPPER_SERVICE_TEMPLATE = MODULE_PATH.joinpath(f"assets/{KLIPPER_SERVICE_NAME}")
KLIPPER_ENV_FILE_TEMPLATE = MODULE_PATH.joinpath(f"assets/{KLIPPER_ENV_FILE_NAME}")
KLIPPER_REQUIREMENTS_TXT = KLIPPER_DIR.joinpath("scripts/klippy-requirements.txt")
EXIT_KLIPPER_SETUP = "Exiting Klipper setup ..."

View File

@@ -8,21 +8,12 @@
# ======================================================================= #
from pathlib import Path
from subprocess import CalledProcessError, run
from subprocess import DEVNULL, CalledProcessError, run
from typing import List
from components.klipper import (
KLIPPER_CFG_NAME,
KLIPPER_DIR,
KLIPPER_ENV_DIR,
KLIPPER_ENV_FILE_NAME,
KLIPPER_ENV_FILE_TEMPLATE,
KLIPPER_LOG_NAME,
KLIPPER_SERIAL_NAME,
KLIPPER_SERVICE_TEMPLATE,
KLIPPER_UDS_NAME,
)
from components.klipper import KLIPPER_DIR, KLIPPER_ENV_DIR, MODULE_PATH
from core.instance_manager.base_instance import BaseInstance
from utils.constants import SYSTEMD
from utils.logger import Logger
@@ -36,10 +27,10 @@ class Klipper(BaseInstance):
super().__init__(instance_type=self, suffix=suffix)
self.klipper_dir: Path = KLIPPER_DIR
self.env_dir: Path = KLIPPER_ENV_DIR
self._cfg_file = self.cfg_dir.joinpath(KLIPPER_CFG_NAME)
self._log = self.log_dir.joinpath(KLIPPER_LOG_NAME)
self._serial = self.comms_dir.joinpath(KLIPPER_SERIAL_NAME)
self._uds = self.comms_dir.joinpath(KLIPPER_UDS_NAME)
self._cfg_file = self.cfg_dir.joinpath("printer.cfg")
self._log = self.log_dir.joinpath("klippy.log")
self._serial = self.comms_dir.joinpath("klippy.serial")
self._uds = self.comms_dir.joinpath("klippy.sock")
@property
def cfg_file(self) -> Path:
@@ -58,22 +49,23 @@ class Klipper(BaseInstance):
return self._uds
def create(self) -> None:
from utils.sys_utils import create_env_file, create_service_file
Logger.print_status("Creating new Klipper Instance ...")
service_template_path = MODULE_PATH.joinpath("assets/klipper.service")
service_file_name = self.get_service_file_name(extension=True)
service_file_target = SYSTEMD.joinpath(service_file_name)
env_template_file_path = MODULE_PATH.joinpath("assets/klipper.env")
env_file_target = self.sysd_dir.joinpath("klipper.env")
try:
self.create_folders()
create_service_file(
name=self.get_service_file_name(extension=True),
content=self._prep_service_file_content(),
)
create_env_file(
path=self.sysd_dir.joinpath(KLIPPER_ENV_FILE_NAME),
content=self._prep_env_file_content(),
self._write_service_file(
service_template_path,
service_file_target,
env_file_target,
)
self._write_env_file(env_template_file_path, env_file_target)
except CalledProcessError as e:
Logger.print_error(f"Error creating instance: {e}")
@@ -91,68 +83,80 @@ class Klipper(BaseInstance):
try:
command = ["sudo", "rm", "-f", service_file_path]
run(command, check=True)
self.delete_logfiles(KLIPPER_LOG_NAME)
self._delete_logfiles()
Logger.print_ok("Instance successfully removed!")
except CalledProcessError as e:
Logger.print_error(f"Error removing instance: {e}")
raise
def _prep_service_file_content(self) -> str:
template = KLIPPER_SERVICE_TEMPLATE
def _write_service_file(
self,
service_template_path: Path,
service_file_target: Path,
env_file_target: Path,
) -> None:
service_content = self._prep_service_file(
service_template_path, env_file_target
)
command = ["sudo", "tee", service_file_target]
run(
command,
input=service_content.encode(),
stdout=DEVNULL,
check=True,
)
Logger.print_ok(f"Service file created: {service_file_target}")
def _write_env_file(
self, env_template_file_path: Path, env_file_target: Path
) -> None:
env_file_content = self._prep_env_file(env_template_file_path)
with open(env_file_target, "w") as env_file:
env_file.write(env_file_content)
Logger.print_ok(f"Env file created: {env_file_target}")
def _prep_service_file(
self, service_template_path: Path, env_file_path: Path
) -> str:
try:
with open(template, "r") as template_file:
with open(service_template_path, "r") as template_file:
template_content = template_file.read()
except FileNotFoundError:
Logger.print_error(f"Unable to open {template} - File not found")
Logger.print_error(
f"Unable to open {service_template_path} - File not found"
)
raise
service_content = template_content.replace(
"%USER%",
self.user,
)
service_content = template_content.replace("%USER%", self.user)
service_content = service_content.replace(
"%KLIPPER_DIR%",
self.klipper_dir.as_posix(),
)
service_content = service_content.replace(
"%ENV%",
self.env_dir.as_posix(),
)
service_content = service_content.replace(
"%ENV_FILE%",
self.sysd_dir.joinpath(KLIPPER_ENV_FILE_NAME).as_posix(),
"%KLIPPER_DIR%", str(self.klipper_dir)
)
service_content = service_content.replace("%ENV%", str(self.env_dir))
service_content = service_content.replace("%ENV_FILE%", str(env_file_path))
return service_content
def _prep_env_file_content(self) -> str:
template = KLIPPER_ENV_FILE_TEMPLATE
def _prep_env_file(self, env_template_file_path: Path) -> str:
try:
with open(template, "r") as env_file:
with open(env_template_file_path, "r") as env_file:
env_template_file_content = env_file.read()
except FileNotFoundError:
Logger.print_error(f"Unable to open {template} - File not found")
Logger.print_error(
f"Unable to open {env_template_file_path} - File not found"
)
raise
env_file_content = env_template_file_content.replace(
"%KLIPPER_DIR%", self.klipper_dir.as_posix()
"%KLIPPER_DIR%", str(self.klipper_dir)
)
env_file_content = env_file_content.replace(
"%CFG%",
f"{self.cfg_dir}/{KLIPPER_CFG_NAME}",
"%CFG%", f"{self.cfg_dir}/printer.cfg"
)
env_file_content = env_file_content.replace(
"%SERIAL%",
self.serial.as_posix(),
)
env_file_content = env_file_content.replace(
"%LOG%",
self.log.as_posix(),
)
env_file_content = env_file_content.replace(
"%UDS%",
self.uds.as_posix(),
)
env_file_content = env_file_content.replace("%SERIAL%", str(self.serial))
env_file_content = env_file_content.replace("%LOG%", str(self.log))
env_file_content = env_file_content.replace("%UDS%", str(self.uds))
return env_file_content
def _delete_logfiles(self) -> None:
from utils.fs_utils import run_remove_routines
for log in list(self.log_dir.glob("klippy.log*")):
Logger.print_status(f"Remove '{log}'")
run_remove_routines(log)

View File

@@ -13,8 +13,7 @@ from components.klipper import (
EXIT_KLIPPER_SETUP,
KLIPPER_DIR,
KLIPPER_ENV_DIR,
KLIPPER_INSTALL_SCRIPT,
KLIPPER_REQ_FILE,
KLIPPER_REQUIREMENTS_TXT,
)
from components.klipper.klipper import Klipper
from components.klipper.klipper_utils import (
@@ -116,19 +115,21 @@ def setup_klipper_prerequesites() -> None:
# install klipper dependencies and create python virtualenv
try:
install_klipper_packages()
install_klipper_packages(KLIPPER_DIR)
create_python_venv(KLIPPER_ENV_DIR)
install_python_requirements(KLIPPER_ENV_DIR, KLIPPER_REQ_FILE)
install_python_requirements(KLIPPER_ENV_DIR, KLIPPER_REQUIREMENTS_TXT)
except Exception:
Logger.print_error("Error during installation of Klipper requirements!")
raise
def install_klipper_packages() -> None:
script = KLIPPER_INSTALL_SCRIPT
def install_klipper_packages(klipper_dir: Path) -> None:
script = klipper_dir.joinpath("scripts/install-debian.sh")
packages = parse_packages_from_file(script)
packages.append("python3-venv") # todo: remove once switched to virtualenv
packages = [pkg.replace("python-dev", "python3-dev") for pkg in packages]
packages.append("python3-venv")
# Add dfu-util for octopi-images
packages.append("dfu-util")
# Add dbus requirement for DietPi distro
if Path("/boot/dietpi/.version").exists():
packages.append("dbus")
@@ -159,9 +160,9 @@ def update_klipper() -> None:
git_pull_wrapper(repo=settings.klipper.repo_url, target_dir=KLIPPER_DIR)
# install possible new system packages
install_klipper_packages()
install_klipper_packages(KLIPPER_DIR)
# install possible new python dependencies
install_python_requirements(KLIPPER_ENV_DIR, KLIPPER_REQ_FILE)
install_python_requirements(KLIPPER_ENV_DIR, KLIPPER_REQUIREMENTS_TXT)
instance_manager.start_all_instance()

View File

@@ -9,19 +9,8 @@
from pathlib import Path
from core.backup_manager import BACKUP_ROOT_DIR
from utils.constants import SYSTEMD
# names
MOBILERAKER_REPO = "https://github.com/Clon1998/mobileraker_companion.git"
MOBILERAKER_UPDATER_SECTION_NAME = "update_manager mobileraker"
MOBILERAKER_LOG_NAME = "mobileraker.log"
# directories
MOBILERAKER_DIR = Path.home().joinpath("mobileraker_companion")
MOBILERAKER_BACKUP_DIR = BACKUP_ROOT_DIR.joinpath("mobileraker-backups")
# files
MOBILERAKER_ENV = Path.home().joinpath("mobileraker-env")
MOBILERAKER_INSTALL_SCRIPT = MOBILERAKER_DIR.joinpath("scripts/install.sh")
MOBILERAKER_REQ_FILE = MOBILERAKER_DIR.joinpath("scripts/mobileraker-requirements.txt")
MOBILERAKER_SERVICE_FILE = SYSTEMD.joinpath("mobileraker.service")
MOBILERAKER_BACKUP_DIR = BACKUP_ROOT_DIR.joinpath("mobileraker-backups")

View File

@@ -16,12 +16,7 @@ from components.mobileraker import (
MOBILERAKER_BACKUP_DIR,
MOBILERAKER_DIR,
MOBILERAKER_ENV,
MOBILERAKER_INSTALL_SCRIPT,
MOBILERAKER_LOG_NAME,
MOBILERAKER_REPO,
MOBILERAKER_REQ_FILE,
MOBILERAKER_SERVICE_FILE,
MOBILERAKER_UPDATER_SECTION_NAME,
)
from components.moonraker.moonraker import Moonraker
from core.backup_manager.backup_manager import BackupManager
@@ -29,6 +24,7 @@ from core.instance_manager.instance_manager import InstanceManager
from core.settings.kiauh_settings import KiauhSettings
from utils.common import check_install_dependencies, get_install_status
from utils.config_utils import add_config_section, remove_config_section
from utils.constants import SYSTEMD
from utils.fs_utils import remove_with_sudo
from utils.git_utils import (
git_clone_wrapper,
@@ -76,7 +72,8 @@ def install_mobileraker() -> None:
git_clone_wrapper(MOBILERAKER_REPO, MOBILERAKER_DIR)
try:
run(MOBILERAKER_INSTALL_SCRIPT.as_posix(), shell=True, check=True)
script = f"{MOBILERAKER_DIR}/scripts/install.sh"
run(script, shell=True, check=True)
if mr_instances:
patch_mobileraker_update_manager(mr_instances)
mr_im.restart_all_instance()
@@ -92,18 +89,19 @@ def install_mobileraker() -> None:
def patch_mobileraker_update_manager(instances: List[Moonraker]) -> None:
env_py = f"{MOBILERAKER_ENV}/bin/python"
add_config_section(
section=MOBILERAKER_UPDATER_SECTION_NAME,
section="update_manager mobileraker",
instances=instances,
options=[
("type", "git_repo"),
("path", MOBILERAKER_DIR.as_posix()),
("origin", MOBILERAKER_REPO),
("path", "mobileraker_companion"),
("orgin", MOBILERAKER_REPO),
("primary_branch", "main"),
("managed_services", "mobileraker"),
("env", f"{MOBILERAKER_ENV}/bin/python"),
("requirements", MOBILERAKER_REQ_FILE.as_posix()),
("install_script", MOBILERAKER_INSTALL_SCRIPT.as_posix()),
("env", env_py),
("requirements", "scripts/mobileraker-requirements.txt"),
("install_script", "scripts/install.sh"),
],
)
@@ -126,7 +124,8 @@ def update_mobileraker() -> None:
git_pull_wrapper(MOBILERAKER_REPO, MOBILERAKER_DIR)
install_python_requirements(MOBILERAKER_ENV, MOBILERAKER_REQ_FILE)
requirements = MOBILERAKER_DIR.joinpath("/scripts/mobileraker-requirements.txt")
install_python_requirements(MOBILERAKER_ENV, requirements)
cmd_sysctl_service("mobileraker", "start")
@@ -140,7 +139,7 @@ def get_mobileraker_status() -> ComponentStatus:
return get_install_status(
MOBILERAKER_DIR,
MOBILERAKER_ENV,
files=[MOBILERAKER_SERVICE_FILE],
files=[SYSTEMD.joinpath("mobileraker.service")],
)
@@ -161,11 +160,12 @@ def remove_mobileraker() -> None:
else:
Logger.print_warn("Mobileraker's companion environment not found!")
if MOBILERAKER_SERVICE_FILE.exists():
service = SYSTEMD.joinpath("mobileraker.service")
if service.exists():
Logger.print_status("Removing mobileraker service ...")
cmd_sysctl_service(MOBILERAKER_SERVICE_FILE, "stop")
cmd_sysctl_service(MOBILERAKER_SERVICE_FILE, "disable")
remove_with_sudo(MOBILERAKER_SERVICE_FILE)
cmd_sysctl_service(service, "stop")
cmd_sysctl_service(service, "disable")
remove_with_sudo(service)
cmd_sysctl_manage("daemon-reload")
cmd_sysctl_manage("reset-failed")
Logger.print_ok("Mobileraker's companion service successfully removed!")
@@ -173,7 +173,7 @@ def remove_mobileraker() -> None:
kl_im = InstanceManager(Klipper)
kl_instances: List[Klipper] = kl_im.instances
for instance in kl_instances:
logfile = instance.log_dir.joinpath(MOBILERAKER_LOG_NAME)
logfile = instance.log_dir.joinpath("mobileraker.log")
if logfile.exists():
Logger.print_status(f"Removing {logfile} ...")
Path(logfile).unlink()
@@ -185,7 +185,7 @@ def remove_mobileraker() -> None:
Logger.print_status(
"Removing Mobileraker's companion from update manager ..."
)
remove_config_section(MOBILERAKER_UPDATER_SECTION_NAME, mr_instances)
remove_config_section("update_manager mobileraker", mr_instances)
Logger.print_ok(
"Mobileraker's companion successfully removed from update manager!"
)
@@ -199,12 +199,12 @@ def remove_mobileraker() -> None:
def backup_mobileraker_dir() -> None:
bm = BackupManager()
bm.backup_directory(
MOBILERAKER_DIR.name,
"mobileraker_companion",
source=MOBILERAKER_DIR,
target=MOBILERAKER_BACKUP_DIR,
)
bm.backup_directory(
MOBILERAKER_ENV.name,
"mobileraker-env",
source=MOBILERAKER_ENV,
target=MOBILERAKER_BACKUP_DIR,
)

View File

@@ -13,21 +13,15 @@ from core.backup_manager import BACKUP_ROOT_DIR
MODULE_PATH = Path(__file__).resolve().parent
# names
MOONRAKER_CFG_NAME = "moonraker.conf"
MOONRAKER_LOG_NAME = "moonraker.log"
MOONRAKER_SERVICE_NAME = "moonraker.service"
MOONRAKER_DEFAULT_PORT = 7125
MOONRAKER_ENV_FILE_NAME = "moonraker.env"
# directories
MOONRAKER_DIR = Path.home().joinpath("moonraker")
MOONRAKER_ENV_DIR = Path.home().joinpath("moonraker-env")
MOONRAKER_BACKUP_DIR = BACKUP_ROOT_DIR.joinpath("moonraker-backups")
MOONRAKER_DB_BACKUP_DIR = BACKUP_ROOT_DIR.joinpath("moonraker-db-backups")
MOONRAKER_REQUIREMENTS_TXT = MOONRAKER_DIR.joinpath(
"scripts/moonraker-requirements.txt"
)
DEFAULT_MOONRAKER_PORT = 7125
# files
MOONRAKER_REQ_FILE = MOONRAKER_DIR.joinpath("scripts/moonraker-requirements.txt")
# introduced due to
# https://github.com/Arksine/moonraker/issues/349
# https://github.com/Arksine/moonraker/pull/346
@@ -35,8 +29,5 @@ POLKIT_LEGACY_FILE = Path("/etc/polkit-1/localauthority/50-local.d/10-moonraker.
POLKIT_FILE = Path("/etc/polkit-1/rules.d/moonraker.rules")
POLKIT_USR_FILE = Path("/usr/share/polkit-1/rules.d/moonraker.rules")
POLKIT_SCRIPT = Path.home().joinpath("moonraker/scripts/set-policykit-rules.sh")
MOONRAKER_SERVICE_TEMPLATE = MODULE_PATH.joinpath(f"assets/{MOONRAKER_SERVICE_NAME}")
MOONRAKER_ENV_FILE_TEMPLATE = MODULE_PATH.joinpath(f"assets/{MOONRAKER_ENV_FILE_NAME}")
EXIT_MOONRAKER_SETUP = "Exiting Moonraker setup ..."

View File

@@ -9,22 +9,15 @@
from __future__ import annotations
from pathlib import Path
from subprocess import CalledProcessError, run
from subprocess import DEVNULL, CalledProcessError, run
from typing import List
from components.moonraker import (
MOONRAKER_CFG_NAME,
MOONRAKER_DIR,
MOONRAKER_ENV_DIR,
MOONRAKER_ENV_FILE_NAME,
MOONRAKER_ENV_FILE_TEMPLATE,
MOONRAKER_LOG_NAME,
MOONRAKER_SERVICE_TEMPLATE,
)
from components.moonraker import MODULE_PATH, MOONRAKER_DIR, MOONRAKER_ENV_DIR
from core.instance_manager.base_instance import BaseInstance
from core.submodules.simple_config_parser.src.simple_config_parser.simple_config_parser import (
SimpleConfigParser,
)
from utils.constants import SYSTEMD
from utils.logger import Logger
@@ -38,13 +31,13 @@ class Moonraker(BaseInstance):
super().__init__(instance_type=self, suffix=suffix)
self.moonraker_dir: Path = MOONRAKER_DIR
self.env_dir: Path = MOONRAKER_ENV_DIR
self.cfg_file = self.cfg_dir.joinpath(MOONRAKER_CFG_NAME)
self.cfg_file = self.cfg_dir.joinpath("moonraker.conf")
self.port = self._get_port()
self.backup_dir = self.data_dir.joinpath("backup")
self.certs_dir = self.data_dir.joinpath("certs")
self._db_dir = self.data_dir.joinpath("database")
self._comms_dir = self.data_dir.joinpath("comms")
self.log = self.log_dir.joinpath(MOONRAKER_LOG_NAME)
self.log = self.log_dir.joinpath("moonraker.log")
@property
def db_dir(self) -> Path:
@@ -55,20 +48,23 @@ class Moonraker(BaseInstance):
return self._comms_dir
def create(self, create_example_cfg: bool = False) -> None:
from utils.sys_utils import create_env_file, create_service_file
Logger.print_status("Creating new Moonraker Instance ...")
service_template_path = MODULE_PATH.joinpath("assets/moonraker.service")
service_file_name = self.get_service_file_name(extension=True)
service_file_target = SYSTEMD.joinpath(service_file_name)
env_template_file_path = MODULE_PATH.joinpath("assets/moonraker.env")
env_file_target = self.sysd_dir.joinpath("moonraker.env")
try:
self.create_folders([self.backup_dir, self.certs_dir, self._db_dir])
create_service_file(
name=self.get_service_file_name(extension=True),
content=self._prep_service_file_content(),
)
create_env_file(
path=self.sysd_dir.joinpath(MOONRAKER_ENV_FILE_NAME),
content=self._prep_env_file_content(),
self._write_service_file(
service_template_path,
service_file_target,
env_file_target,
)
self._write_env_file(env_template_file_path, env_file_target)
except CalledProcessError as e:
Logger.print_error(f"Error creating instance: {e}")
@@ -86,59 +82,72 @@ class Moonraker(BaseInstance):
try:
command = ["sudo", "rm", "-f", service_file_path]
run(command, check=True)
self.delete_logfiles(MOONRAKER_LOG_NAME)
self._delete_logfiles()
Logger.print_ok("Instance successfully removed!")
except CalledProcessError as e:
Logger.print_error(f"Error removing instance: {e}")
raise
def _prep_service_file_content(self) -> str:
template = MOONRAKER_SERVICE_TEMPLATE
def _write_service_file(
self,
service_template_path: Path,
service_file_target: Path,
env_file_target: Path,
) -> None:
service_content = self._prep_service_file(
service_template_path, env_file_target
)
command = ["sudo", "tee", service_file_target]
run(
command,
input=service_content.encode(),
stdout=DEVNULL,
check=True,
)
Logger.print_ok(f"Service file created: {service_file_target}")
def _write_env_file(
self, env_template_file_path: Path, env_file_target: Path
) -> None:
env_file_content = self._prep_env_file(env_template_file_path)
with open(env_file_target, "w") as env_file:
env_file.write(env_file_content)
Logger.print_ok(f"Env file created: {env_file_target}")
def _prep_service_file(
self, service_template_path: Path, env_file_path: Path
) -> str:
try:
with open(template, "r") as template_file:
with open(service_template_path, "r") as template_file:
template_content = template_file.read()
except FileNotFoundError:
Logger.print_error(f"Unable to open {template} - File not found")
Logger.print_error(
f"Unable to open {service_template_path} - File not found"
)
raise
service_content = template_content.replace(
"%USER%",
self.user,
)
service_content = template_content.replace("%USER%", self.user)
service_content = service_content.replace(
"%MOONRAKER_DIR%",
self.moonraker_dir.as_posix(),
)
service_content = service_content.replace(
"%ENV%",
self.env_dir.as_posix(),
)
service_content = service_content.replace(
"%ENV_FILE%",
self.sysd_dir.joinpath(MOONRAKER_ENV_FILE_NAME).as_posix(),
"%MOONRAKER_DIR%", str(self.moonraker_dir)
)
service_content = service_content.replace("%ENV%", str(self.env_dir))
service_content = service_content.replace("%ENV_FILE%", str(env_file_path))
return service_content
def _prep_env_file_content(self) -> str:
template = MOONRAKER_ENV_FILE_TEMPLATE
def _prep_env_file(self, env_template_file_path: Path) -> str:
try:
with open(template, "r") as env_file:
with open(env_template_file_path, "r") as env_file:
env_template_file_content = env_file.read()
except FileNotFoundError:
Logger.print_error(f"Unable to open {template} - File not found")
Logger.print_error(
f"Unable to open {env_template_file_path} - File not found"
)
raise
env_file_content = env_template_file_content.replace(
"%MOONRAKER_DIR%",
self.moonraker_dir.as_posix(),
"%MOONRAKER_DIR%", str(self.moonraker_dir)
)
env_file_content = env_file_content.replace(
"%PRINTER_DATA%",
self.data_dir.as_posix(),
"%PRINTER_DATA%", str(self.data_dir)
)
return env_file_content
def _get_port(self) -> int | None:
@@ -150,3 +159,10 @@ class Moonraker(BaseInstance):
port = scp.getint("server", "port", fallback=None)
return port
def _delete_logfiles(self) -> None:
from utils.fs_utils import run_remove_routines
for log in list(self.log_dir.glob("moonraker.log*")):
Logger.print_status(f"Remove '{log}'")
run_remove_routines(log)

View File

@@ -15,7 +15,7 @@ from components.moonraker import (
EXIT_MOONRAKER_SETUP,
MOONRAKER_DIR,
MOONRAKER_ENV_DIR,
MOONRAKER_REQ_FILE,
MOONRAKER_REQUIREMENTS_TXT,
POLKIT_FILE,
POLKIT_LEGACY_FILE,
POLKIT_SCRIPT,
@@ -145,7 +145,7 @@ def setup_moonraker_prerequesites() -> None:
# install moonraker dependencies and create python virtualenv
install_moonraker_packages(MOONRAKER_DIR)
create_python_venv(MOONRAKER_ENV_DIR)
install_python_requirements(MOONRAKER_ENV_DIR, MOONRAKER_REQ_FILE)
install_python_requirements(MOONRAKER_ENV_DIR, MOONRAKER_REQUIREMENTS_TXT)
def install_moonraker_packages(moonraker_dir: Path) -> None:
@@ -206,11 +206,13 @@ def update_moonraker() -> None:
instance_manager = InstanceManager(Moonraker)
instance_manager.stop_all_instance()
git_pull_wrapper(repo=settings.moonraker.repo_url, target_dir=MOONRAKER_DIR)
git_pull_wrapper(
repo=settings.moonraker.repo_url, target_dir=MOONRAKER_DIR
)
# install possible new system packages
install_moonraker_packages(MOONRAKER_DIR)
# install possible new python dependencies
install_python_requirements(MOONRAKER_ENV_DIR, MOONRAKER_REQ_FILE)
install_python_requirements(MOONRAKER_ENV_DIR, MOONRAKER_REQUIREMENTS_TXT)
instance_manager.start_all_instance()

View File

@@ -11,10 +11,10 @@ import shutil
from typing import Dict, List, Optional
from components.moonraker import (
DEFAULT_MOONRAKER_PORT,
MODULE_PATH,
MOONRAKER_BACKUP_DIR,
MOONRAKER_DB_BACKUP_DIR,
MOONRAKER_DEFAULT_PORT,
MOONRAKER_DIR,
MOONRAKER_ENV_DIR,
)
@@ -68,7 +68,7 @@ def create_example_moonraker_conf(
# of moonraker-1 is 7125 and moonraker-3 is 7127 and there are moonraker.conf files for moonraker-1
# and moonraker-3 already. though, there does not seem to be a very reliable way of always assigning
# the correct port to each instance and the user will likely be required to correct the value manually.
port = max(ports) + 1 if ports else MOONRAKER_DEFAULT_PORT
port = max(ports) + 1 if ports else DEFAULT_MOONRAKER_PORT
else:
port = ports_map.get(instance.suffix)

View File

@@ -20,7 +20,7 @@ from components.webui_client.client_dialogs import (
)
from components.webui_client.client_utils import (
backup_client_config_data,
detect_client_cfg_conflict,
config_for_other_client_exist,
)
from core.instance_manager.instance_manager import InstanceManager
from core.settings.kiauh_settings import KiauhSettings
@@ -36,7 +36,7 @@ def install_client_config(client_data: BaseWebClient) -> None:
client_config: BaseWebClientConfig = client_data.client_config
display_name = client_config.display_name
if detect_client_cfg_conflict(client_data):
if config_for_other_client_exist(client_data.client):
Logger.print_info("Another Client-Config is already installed! Skipped ...")
return

View File

@@ -28,7 +28,7 @@ from components.webui_client.client_dialogs import (
)
from components.webui_client.client_utils import (
backup_mainsail_config_json,
detect_client_cfg_conflict,
config_for_other_client_exist,
enable_mainsail_remotemode,
restore_mainsail_config_json,
symlink_webui_nginx_log,
@@ -90,7 +90,7 @@ def install_client(client: BaseWebClient) -> None:
if (
kl_instances
and not client_config.config_dir.exists()
and not detect_client_cfg_conflict(client)
and not config_for_other_client_exist(client_to_ignore=client.client)
):
print_install_client_config_dialog(client)
question = f"Download the recommended {client_config.display_name}?"

View File

@@ -8,7 +8,7 @@
# ======================================================================= #
from __future__ import annotations
import json
import json # noqa: I001
import shutil
from pathlib import Path
from typing import List, get_args
@@ -16,9 +16,9 @@ from typing import List, get_args
from components.klipper.klipper import Klipper
from components.webui_client.base_data import (
BaseWebClient,
BaseWebClientConfig,
WebClientType,
)
from components.webui_client.fluidd_data import FluiddData
from components.webui_client.mainsail_data import MainsailData
from core.backup_manager.backup_manager import BackupManager
from core.settings.kiauh_settings import KiauhSettings
@@ -187,24 +187,30 @@ def get_existing_clients() -> List[BaseWebClient]:
return installed_clients
def detect_client_cfg_conflict(curr_client: BaseWebClient) -> bool:
def get_existing_client_config() -> List[BaseWebClient]:
clients = list(get_args(WebClientType))
installed_client_configs: List[BaseWebClient] = []
for client in clients:
c_config_data: BaseWebClientConfig = client.client_config
if c_config_data.config_dir.exists():
installed_client_configs.append(client)
return installed_client_configs
def config_for_other_client_exist(client_to_ignore: WebClientType) -> bool:
"""
Check if any other client configs are present on the system.
It is usually not harmful, but chances are they can conflict each other.
Multiple client configs are, at least, redundant to have them installed
:param curr_client: The client name to check for the conflict
:param client_to_ignore: The client name to ignore for the check
:return: True, if other client configs were found, else False
"""
mainsail_cfg_status: ComponentStatus = get_client_config_status(MainsailData())
fluidd_cfg_status: ComponentStatus = get_client_config_status(FluiddData())
clients = set([c.name for c in get_existing_client_config()])
clients = clients - {client_to_ignore.value}
if curr_client.client == WebClientType.MAINSAIL and fluidd_cfg_status.status == 2:
return True
if curr_client.client == WebClientType.FLUIDD and mainsail_cfg_status.status == 2:
return True
return False
return True if len(clients) > 0 else False
def get_download_url(base_url: str, client: BaseWebClient) -> str:

View File

@@ -18,6 +18,7 @@ from components.webui_client.base_data import (
WebClientConfigType,
WebClientType,
)
from components.webui_client.client_utils import get_download_url
from core.backup_manager import BACKUP_ROOT_DIR
@@ -46,8 +47,6 @@ class FluiddData(BaseWebClient):
@property
def download_url(self) -> str:
from components.webui_client.client_utils import get_download_url
return get_download_url(self.BASE_DL_URL, self)
@property

View File

@@ -14,7 +14,6 @@ from pathlib import Path
from typing import List, Optional
from utils.constants import CURRENT_USER, SYSTEMD
from utils.logger import Logger
class BaseInstance(ABC):
@@ -160,12 +159,3 @@ class BaseInstance(ABC):
return f"printer_{self._suffix}"
else:
return self._suffix
def delete_logfiles(self, log_name: str) -> None:
from utils.fs_utils import run_remove_routines
files = self.log_dir.iterdir()
logs = [f for f in files if f.name.startswith(log_name)]
for log in logs:
Logger.print_status(f"Remove '{log}'")
run_remove_routines(log)

View File

@@ -402,39 +402,3 @@ def log_process(process: Popen) -> None:
if process.poll() is not None:
break
def create_service_file(name: str, content: str) -> None:
"""
Creates a service file at the provided path with the provided content.
:param name: the name of the service file
:param content: the content of the service file
:return: None
"""
try:
run(
["sudo", "tee", SYSTEMD.joinpath(name)],
input=content.encode(),
stdout=DEVNULL,
check=True,
)
Logger.print_ok(f"Service file created: {SYSTEMD.joinpath(name)}")
except CalledProcessError as e:
Logger.print_error(f"Error creating service file: {e}")
raise
def create_env_file(path: Path, content: str) -> None:
"""
Creates an env file at the provided path with the provided content.
:param path: the path of the env file
:param content: the content of the env file
:return: None
"""
try:
with open(path, "w") as env_file:
env_file.write(content)
Logger.print_ok(f"Env file created: {path}")
except OSError as e:
Logger.print_error(f"Error creating env file: {e}")
raise