Compare commits

..

2 Commits

Author SHA1 Message Date
asvdvl
39d3b0702a Merge 3d7e865409 into c8f713c00e 2025-04-12 08:07:10 +02:00
asvdvl
3d7e865409 Enable fluidd ipv6 support 2025-03-04 13:40:03 +03:00
16 changed files with 200 additions and 218 deletions

View File

@@ -126,7 +126,7 @@ def create_example_moonraker_conf(
scp.read_file(target) scp.read_file(target)
trusted_clients: List[str] = [ trusted_clients: List[str] = [
f" {'.'.join(ip)}\n", f" {'.'.join(ip)}\n",
*scp.getvals("authorization", "trusted_clients"), *scp.getval("authorization", "trusted_clients"),
] ]
scp.set_option("server", "port", str(port)) scp.set_option("server", "port", str(port))

View File

@@ -102,7 +102,6 @@ def install_client(
section=f"update_manager {client.name}", section=f"update_manager {client.name}",
instances=mr_instances, instances=mr_instances,
options=[ options=[
("persistent_files", ["config.json"]),
("type", "web"), ("type", "web"),
("channel", "stable"), ("channel", "stable"),
("repo", str(client.repo_path)), ("repo", str(client.repo_path)),

View File

@@ -119,7 +119,7 @@ def enable_mainsail_remotemode() -> None:
with open(c_json, "r") as f: with open(c_json, "r") as f:
config_data = json.load(f) config_data = json.load(f)
if config_data["instancesDB"] == "browser" or config_data["instancesDB"] == "json": if config_data["instancesDB"] == "browser":
Logger.print_info("Remote mode already configured. Skipped ...") Logger.print_info("Remote mode already configured. Skipped ...")
return return

View File

@@ -8,15 +8,14 @@
# ======================================================================= # # ======================================================================= #
from __future__ import annotations from __future__ import annotations
import shutil
from dataclasses import dataclass, field from dataclasses import dataclass, field
from typing import Any, Callable, List, TypeVar from typing import Any, List
from components.klipper import KLIPPER_REPO_URL
from components.moonraker import MOONRAKER_REPO_URL
from core.backup_manager.backup_manager import BackupManager from core.backup_manager.backup_manager import BackupManager
from core.logger import DialogType, Logger from core.logger import DialogType, Logger
from core.submodules.simple_config_parser.src.simple_config_parser.simple_config_parser import ( from core.submodules.simple_config_parser.src.simple_config_parser.simple_config_parser import (
NoOptionError,
NoSectionError,
SimpleConfigParser, SimpleConfigParser,
) )
from utils.input_utils import get_confirm from utils.input_utils import get_confirm
@@ -27,7 +26,13 @@ from kiauh import PROJECT_ROOT
DEFAULT_CFG = PROJECT_ROOT.joinpath("default.kiauh.cfg") DEFAULT_CFG = PROJECT_ROOT.joinpath("default.kiauh.cfg")
CUSTOM_CFG = PROJECT_ROOT.joinpath("kiauh.cfg") CUSTOM_CFG = PROJECT_ROOT.joinpath("kiauh.cfg")
T = TypeVar("T")
class NoValueError(Exception):
"""Raised when a required value is not defined for an option"""
def __init__(self, section: str, option: str):
msg = f"Missing value for option '{option}' in section '{section}'"
super().__init__(msg)
class InvalidValueError(Exception): class InvalidValueError(Exception):
@@ -72,7 +77,6 @@ class WebUiSettings:
# noinspection PyMethodMayBeStatic # noinspection PyMethodMayBeStatic
class KiauhSettings: class KiauhSettings:
__instance = None __instance = None
__initialized = False
def __new__(cls, *args, **kwargs) -> "KiauhSettings": def __new__(cls, *args, **kwargs) -> "KiauhSettings":
if cls.__instance is None: if cls.__instance is None:
@@ -90,10 +94,11 @@ class KiauhSettings:
return getattr(self, item) return getattr(self, item)
def __init__(self) -> None: def __init__(self) -> None:
if not hasattr(self, "__initialized"):
self.__initialized = False
if self.__initialized: if self.__initialized:
return return
self.__initialized = True self.__initialized = True
self.config = SimpleConfigParser() self.config = SimpleConfigParser()
self.kiauh = AppSettings() self.kiauh = AppSettings()
self.klipper = KlipperSettings() self.klipper = KlipperSettings()
@@ -101,9 +106,8 @@ class KiauhSettings:
self.mainsail = WebUiSettings() self.mainsail = WebUiSettings()
self.fluidd = WebUiSettings() self.fluidd = WebUiSettings()
self.__read_config_set_internal_state() self._load_config()
# todo: refactor this, at least rename to something else!
def get(self, section: str, option: str) -> str | int | bool: def get(self, section: str, option: str) -> str | int | bool:
""" """
Get a value from the settings state by providing the section and option name as Get a value from the settings state by providing the section and option name as
@@ -121,175 +125,139 @@ class KiauhSettings:
raise raise
def save(self) -> None: def save(self) -> None:
self.__write_internal_state_to_cfg() self._set_config_options_state()
self.__read_config_set_internal_state() self.config.write_file(CUSTOM_CFG)
self._load_config()
def __read_config_set_internal_state(self) -> None: def _load_config(self) -> None:
if not CUSTOM_CFG.exists() and not DEFAULT_CFG.exists(): if not CUSTOM_CFG.exists() and not DEFAULT_CFG.exists():
Logger.print_dialog( self.__kill()
DialogType.ERROR,
[ cfg = CUSTOM_CFG if CUSTOM_CFG.exists() else DEFAULT_CFG
"No KIAUH configuration file found! Please make sure you have at least " self.config.read_file(cfg)
"one of the following configuration files in KIAUH's root directory:",
"● default.kiauh.cfg", needs_migration = self._check_deprecated_repo_config()
"● kiauh.cfg", if needs_migration:
], self._prompt_migration_dialog()
) return
else:
# Only validate if no migration was needed
self._validate_cfg()
self.__set_internal_state()
def _validate_cfg(self) -> None:
def __err_and_kill(error: str) -> None:
Logger.print_error(f"Error validating kiauh.cfg: {error}")
kill() kill()
# copy default config to custom config if it does not exist try:
if not CUSTOM_CFG.exists(): self._validate_bool("kiauh", "backup_before_update")
shutil.copyfile(DEFAULT_CFG, CUSTOM_CFG)
self.config.read_file(CUSTOM_CFG) self._validate_repositories("klipper", "repositories")
self._validate_repositories("moonraker", "repositories")
# check if there are deprecated repo_url and branch options in the kiauh.cfg self._validate_int("mainsail", "port")
if self._check_deprecated_repo_config(): self._validate_bool("mainsail", "unstable_releases")
self._prompt_migration_dialog()
self.__set_internal_state() self._validate_int("fluidd", "port")
self._validate_bool("fluidd", "unstable_releases")
def __set_internal_state(self) -> None: except ValueError:
# parse Kiauh options err = f"Invalid value for option '{self._v_option}' in section '{self._v_section}'"
self.kiauh.backup_before_update = self.__read_from_cfg( __err_and_kill(err)
"kiauh", except NoSectionError:
"backup_before_update", err = f"Missing section '{self._v_section}' in config file"
self.config.getboolean, __err_and_kill(err)
False, except NoOptionError:
) err = f"Missing option '{self._v_option}' in section '{self._v_section}'"
__err_and_kill(err)
except NoValueError:
err = f"Missing value for option '{self._v_option}' in section '{self._v_section}'"
__err_and_kill(err)
# parse Klipper options def _validate_bool(self, section: str, option: str) -> None:
self.klipper.use_python_binary = self.__read_from_cfg( self._v_section, self._v_option = (section, option)
"klipper", (bool(self.config.getboolean(section, option)))
"use_python_binary",
self.config.getval,
None,
True,
)
kl_repos: List[str] = self.__read_from_cfg(
"klipper",
"repositories",
self.config.getvals,
[KLIPPER_REPO_URL],
)
self.klipper.repositories = self.__set_repo_state("klipper", kl_repos)
# parse Moonraker options def _validate_int(self, section: str, option: str) -> None:
self.moonraker.use_python_binary = self.__read_from_cfg( self._v_section, self._v_option = (section, option)
"moonraker", int(self.config.getint(section, option))
"use_python_binary",
self.config.getval,
None,
True,
)
self.moonraker.optional_speedups = self.__read_from_cfg(
"moonraker",
"optional_speedups",
self.config.getboolean,
True,
)
mr_repos: List[str] = self.__read_from_cfg(
"moonraker",
"repositories",
self.config.getvals,
[MOONRAKER_REPO_URL],
)
self.moonraker.repositories = self.__set_repo_state("moonraker", mr_repos)
# parse Mainsail options def _validate_str(self, section: str, option: str) -> None:
self.mainsail.port = self.__read_from_cfg( self._v_section, self._v_option = (section, option)
"mainsail", v = self.config.getval(section, option)
"port",
self.config.getint,
80,
)
self.mainsail.unstable_releases = self.__read_from_cfg(
"mainsail",
"unstable_releases",
self.config.getboolean,
False,
)
# parse Fluidd options if not v:
self.fluidd.port = self.__read_from_cfg( raise ValueError
"fluidd",
"port",
self.config.getint,
80,
)
self.fluidd.unstable_releases = self.__read_from_cfg(
"fluidd",
"unstable_releases",
self.config.getboolean,
False,
)
def __check_option_exists( def _validate_repositories(self, section: str, option: str) -> None:
self, section: str, option: str, fallback: Any, silent: bool = False self._v_section, self._v_option = (section, option)
) -> bool: repos = self.config.getval(section, option)
has_section = self.config.has_section(section) if not repos:
has_option = self.config.has_option(section, option) raise NoValueError(section, option)
if not (has_section and has_option):
if not silent:
Logger.print_warn(
f"Option '{option}' in section '{section}' not defined. Falling back to '{fallback}'."
)
return False
return True
def __read_bool_from_cfg(
self,
section: str,
option: str,
fallback: bool | None = None,
silent: bool = False,
) -> bool | None:
if not self.__check_option_exists(section, option, fallback, silent):
return fallback
return self.config.getboolean(section, option, fallback)
def __read_from_cfg(
self,
section: str,
option: str,
getter: Callable[[str, str, T | None], T],
fallback: T = None,
silent: bool = False,
) -> T:
if not self.__check_option_exists(section, option, fallback, silent):
return fallback
return getter(section, option, fallback)
def __set_repo_state(self, section: str, repos: List[str]) -> List[Repository]:
_repos: List[Repository] = []
for repo in repos: for repo in repos:
if repo.strip().startswith("#") or repo.strip().startswith(";"):
continue
try: try:
if repo.strip().startswith("#") or repo.strip().startswith(";"):
continue
if "," in repo: if "," in repo:
url, branch = repo.strip().split(",") url, branch = repo.strip().split(",")
if not url:
if not branch: raise InvalidValueError(section, option, repo)
branch = "master"
else: else:
url = repo.strip() url = repo.strip()
if not url:
raise InvalidValueError(section, option, repo)
except ValueError:
raise InvalidValueError(section, option, repo)
def __set_internal_state(self) -> None:
self.kiauh.backup_before_update = self.config.getboolean(
"kiauh", "backup_before_update"
)
self.moonraker.optional_speedups = self.config.getboolean(
"moonraker", "optional_speedups", True
)
kl_repos = self.config.getval("klipper", "repositories")
self.klipper.repositories = self.__set_repo_state(kl_repos)
mr_repos = self.config.getval("moonraker", "repositories")
self.moonraker.repositories = self.__set_repo_state(mr_repos)
self.klipper.use_python_binary = self.config.getval(
"klipper", "use_python_binary", None
)
self.moonraker.use_python_binary = self.config.getval(
"moonraker", "use_python_binary", None
)
self.mainsail.port = self.config.getint("mainsail", "port")
self.mainsail.unstable_releases = self.config.getboolean(
"mainsail", "unstable_releases"
)
self.fluidd.port = self.config.getint("fluidd", "port")
self.fluidd.unstable_releases = self.config.getboolean(
"fluidd", "unstable_releases"
)
def __set_repo_state(self, repos: List[str]) -> List[Repository]:
_repos: List[Repository] = []
for repo in repos:
if repo.strip().startswith("#") or repo.strip().startswith(";"):
continue
if "," in repo:
url, branch = repo.strip().split(",")
if not branch:
branch = "master" branch = "master"
else:
# url must not be empty otherwise it's considered url = repo.strip()
# as an unrecoverable, invalid configuration branch = "master"
if not url: _repos.append(Repository(url.strip(), branch.strip()))
raise InvalidValueError(section, "repositories", repo)
_repos.append(Repository(url.strip(), branch.strip()))
except InvalidValueError as e:
Logger.print_error(f"Error parsing kiauh.cfg: {e}")
kill()
return _repos return _repos
def __write_internal_state_to_cfg(self) -> None: def _set_config_options_state(self) -> None:
"""Updates the config with current settings, preserving values that haven't been modified""" """Updates the config with current settings, preserving values that haven't been modified"""
if self.kiauh.backup_before_update is not None: if self.kiauh.backup_before_update is not None:
self.config.set_option( self.config.set_option(
@@ -327,8 +295,6 @@ class KiauhSettings:
"fluidd", "unstable_releases", str(self.fluidd.unstable_releases) "fluidd", "unstable_releases", str(self.fluidd.unstable_releases)
) )
self.config.write_file(CUSTOM_CFG)
def _check_deprecated_repo_config(self) -> bool: def _check_deprecated_repo_config(self) -> bool:
# repo_url and branch are deprecated - 2025.03.23 # repo_url and branch are deprecated - 2025.03.23
for section in ["klipper", "moonraker"]: for section in ["klipper", "moonraker"]:
@@ -340,23 +306,22 @@ class KiauhSettings:
def _prompt_migration_dialog(self) -> None: def _prompt_migration_dialog(self) -> None:
migration_1: List[str] = [ migration_1: List[str] = [
"Options 'repo_url' and 'branch' are now combined into a 'repositories' option.", "The old 'repo_url' and 'branch' options are now combined under 'repositories'.",
"\n\n", "\n\n",
"● Old format:", "Example format:",
" [klipper]", "[klipper]",
" repo_url: https://github.com/Klipper3d/klipper", "repositories:",
" branch: master", " https://github.com/Klipper3d/klipper, master",
"\n\n", "\n\n",
"● New format:", "[moonraker]",
" [klipper]", "repositories:",
" repositories:", " https://github.com/Arksine/moonraker, master",
" https://github.com/Klipper3d/klipper, master",
] ]
Logger.print_dialog( Logger.print_dialog(
DialogType.ATTENTION, DialogType.ATTENTION,
[ [
"Deprecated kiauh.cfg configuration found!", "Deprecated repository configuration found!",
"KAIUH can now attempt to automatically migrate the configuration.", "KAIUH can now attempt to automatically migrate your configuration.",
"\n\n", "\n\n",
*migration_1, *migration_1,
], ],
@@ -367,7 +332,7 @@ class KiauhSettings:
Logger.print_dialog( Logger.print_dialog(
DialogType.ERROR, DialogType.ERROR,
[ [
"Please update the configuration file manually.", "Please update your configuration file manually.",
], ],
center_content=True, center_content=True,
) )
@@ -408,7 +373,23 @@ class KiauhSettings:
self.config.write_file(CUSTOM_CFG) self.config.write_file(CUSTOM_CFG)
self.config.read_file(CUSTOM_CFG) # reload config self.config.read_file(CUSTOM_CFG) # reload config
# Validate the migrated config
self._validate_cfg()
self.__set_internal_state()
except Exception as e: except Exception as e:
Logger.print_error(f"Error migrating configuration: {e}") Logger.print_error(f"Error migrating configuration: {e}")
Logger.print_error("Please migrate manually.") Logger.print_error("Please migrate manually.")
kill() kill()
def __kill(self) -> None:
Logger.print_dialog(
DialogType.ERROR,
[
"No KIAUH configuration file found! Please make sure you have at least "
"one of the following configuration files in KIAUH's root directory:",
"● default.kiauh.cfg",
"● kiauh.cfg",
],
)
kill()

View File

@@ -314,7 +314,9 @@ class SimpleConfigParser:
elements.pop(i) elements.pop(i)
break break
def getval(self, section: str, option: str, fallback: str | _UNSET = _UNSET) -> str: def getval(
self, section: str, option: str, fallback: str | _UNSET = _UNSET
) -> str | List[str]:
""" """
Return the value of the given option in the given section Return the value of the given option in the given section
@@ -327,34 +329,22 @@ class SimpleConfigParser:
if option not in self.get_options(section): if option not in self.get_options(section):
raise NoOptionError(option, section) raise NoOptionError(option, section)
# Find the option in the elements list
for element in self.config[section]["elements"]: for element in self.config[section]["elements"]:
if element["type"] is LineType.OPTION.value and element["name"] == option: if element["type"] in [LineType.OPTION.value, LineType.OPTION_BLOCK.value] and element["name"] == option:
return str(element["value"].strip().replace("\n", "")) raw_value = element["value"]
return "" if isinstance(raw_value, str) and raw_value.endswith("\n"):
return raw_value[:-1].strip()
except (NoSectionError, NoOptionError): elif isinstance(raw_value, list):
if fallback is _UNSET: values: List[str] = []
raise for i, val in enumerate(raw_value):
return fallback val = val.strip().strip("\n")
if len(val) < 1:
def getvals(self, section: str, option: str, fallback: List[str] | _UNSET = _UNSET) -> List[str]: continue
""" values.append(val.strip())
Return the values of the given multi-line option in the given section return values
return str(raw_value)
If the key is not found and 'fallback' is provided, it is used as raise NoOptionError(option, section)
a fallback value.
"""
try:
if section not in self.get_sections():
raise NoSectionError(section)
if option not in self.get_options(section):
raise NoOptionError(option, section)
for element in self.config[section]["elements"]:
if element["type"] is LineType.OPTION_BLOCK.value and element["name"] == option:
return [val.strip() for val in element["value"] if val.strip()]
return []
except (NoSectionError, NoOptionError): except (NoSectionError, NoOptionError):
if fallback is _UNSET: if fallback is _UNSET:
raise raise

View File

@@ -51,7 +51,7 @@ def test_getval(parser):
assert parser.getval("section_2", "option_2") == "value_2" assert parser.getval("section_2", "option_2") == "value_2"
# test multiline option values # test multiline option values
ml_val = parser.getvals("section number 5", "multi_option") ml_val = parser.getval("section number 5", "multi_option")
assert isinstance(ml_val, list) assert isinstance(ml_val, list)
assert len(ml_val) > 0 assert len(ml_val) > 0
@@ -164,7 +164,7 @@ def test_set_new_option(parser):
assert parser.getval("new_section", "very_new_option") == "very_new_value" assert parser.getval("new_section", "very_new_option") == "very_new_value"
parser.set_option("section_2", "array_option", ["value_1", "value_2", "value_3"]) parser.set_option("section_2", "array_option", ["value_1", "value_2", "value_3"])
assert parser.getvals("section_2", "array_option") == [ assert parser.getval("section_2", "array_option") == [
"value_1", "value_1",
"value_2", "value_2",
"value_3", "value_3",

View File

@@ -11,7 +11,7 @@ from __future__ import annotations
import shutil import shutil
import tempfile import tempfile
from pathlib import Path from pathlib import Path
from typing import List, Tuple, Union from typing import List, Tuple
from core.logger import Logger from core.logger import Logger
from core.submodules.simple_config_parser.src.simple_config_parser.simple_config_parser import ( from core.submodules.simple_config_parser.src.simple_config_parser.simple_config_parser import (
@@ -19,7 +19,7 @@ from core.submodules.simple_config_parser.src.simple_config_parser.simple_config
) )
from utils.instance_type import InstanceType from utils.instance_type import InstanceType
ConfigOption = Tuple[str, Union[str, List[str]]] ConfigOption = Tuple[str, str]
def add_config_section( def add_config_section(

View File

@@ -184,6 +184,9 @@ def install_python_requirements(target: Path, requirements: Path) -> None:
:return: None :return: None
""" """
try: try:
# always update pip before installing requirements
update_python_pip(target)
Logger.print_status("Installing Python requirements ...") Logger.print_status("Installing Python requirements ...")
command = [ command = [
target.joinpath("bin/pip").as_posix(), target.joinpath("bin/pip").as_posix(),
@@ -193,7 +196,7 @@ def install_python_requirements(target: Path, requirements: Path) -> None:
] ]
result = run(command, stderr=PIPE, text=True) result = run(command, stderr=PIPE, text=True)
if result.returncode != 0: if result.returncode != 0 or result.stderr:
Logger.print_error(f"{result.stderr}", False) Logger.print_error(f"{result.stderr}", False)
raise VenvCreationFailedException("Installing Python requirements failed!") raise VenvCreationFailedException("Installing Python requirements failed!")
@@ -213,6 +216,9 @@ def install_python_packages(target: Path, packages: List[str]) -> None:
:return: None :return: None
""" """
try: try:
# always update pip before installing requirements
update_python_pip(target)
Logger.print_status("Installing Python requirements ...") Logger.print_status("Installing Python requirements ...")
command = [ command = [
target.joinpath("bin/pip").as_posix(), target.joinpath("bin/pip").as_posix(),
@@ -222,7 +228,7 @@ def install_python_packages(target: Path, packages: List[str]) -> None:
command.append(pkg) command.append(pkg)
result = run(command, stderr=PIPE, text=True) result = run(command, stderr=PIPE, text=True)
if result.returncode != 0: if result.returncode != 0 or result.stderr:
Logger.print_error(f"{result.stderr}", False) Logger.print_error(f"{result.stderr}", False)
raise VenvCreationFailedException("Installing Python requirements failed!") raise VenvCreationFailedException("Installing Python requirements failed!")

View File

@@ -2,7 +2,7 @@
requires-python = ">=3.8" requires-python = ">=3.8"
[project.optional-dependencies] [project.optional-dependencies]
dev=["ruff", "pyright"] dev=["ruff", "mypy"]
[tool.ruff] [tool.ruff]
required-version = ">=0.9.10" required-version = ">=0.9.10"
@@ -20,3 +20,14 @@ quote-style = "double"
[tool.ruff.lint] [tool.ruff.lint]
extend-select = ["I"] extend-select = ["I"]
[tool.mypy]
python_version = "3.8"
platform = "linux"
# strict = true # TODO: enable this once everything is else is handled
check_untyped_defs = true
ignore_missing_imports = true
warn_redundant_casts = true
warn_unused_ignores = true
warn_return_any = true
warn_unreachable = true

View File

@@ -1,6 +0,0 @@
{
"pythonVersion": "3.8",
"pythonPlatform": "Linux",
"typeCheckingMode": "standard",
"venvPath": "./.kiauh-env"
}

View File

@@ -1,2 +0,0 @@
ruff (>=0.9.10)
pyright

View File

@@ -2,6 +2,7 @@
server { server {
listen 80; listen 80;
listen [::]:80;
access_log /var/log/nginx/fluidd-access.log; access_log /var/log/nginx/fluidd-access.log;
error_log /var/log/nginx/fluidd-error.log; error_log /var/log/nginx/fluidd-error.log;

View File

@@ -280,6 +280,7 @@ function create_klipper_virtualenv() {
status_msg "Installing $("python${python_version}" -V) virtual environment..." status_msg "Installing $("python${python_version}" -V) virtual environment..."
if virtualenv -p "python${python_version}" "${KLIPPY_ENV}"; then if virtualenv -p "python${python_version}" "${KLIPPY_ENV}"; then
(( python_version == 3 )) && "${KLIPPY_ENV}"/bin/pip install -U pip
"${KLIPPY_ENV}"/bin/pip install -r "${KLIPPER_DIR}"/scripts/klippy-requirements.txt "${KLIPPY_ENV}"/bin/pip install -r "${KLIPPER_DIR}"/scripts/klippy-requirements.txt
else else
log_error "failure while creating python3 klippy-env" log_error "failure while creating python3 klippy-env"

View File

@@ -126,7 +126,7 @@ function update_klipperscreen() {
git checkout -f master && ok_msg "Checkout successfull" git checkout -f master && ok_msg "Checkout successfull"
if [[ $(md5sum "${KLIPPERSCREEN_DIR}/scripts/KlipperScreen-requirements.txt" | cut -d " " -f1) != "${old_md5}" ]]; then if [[ $(md5sum "${KLIPPERSCREEN_DIR}/scripts/KlipperScreen-requirements.txt" | cut -d " " -f1) != "${old_md5}" ]]; then
status_msg "New dependencies detected..." status_msg "New dependecies detected..."
"${KLIPPERSCREEN_ENV}"/bin/pip install -r "${KLIPPERSCREEN_DIR}/scripts/KlipperScreen-requirements.txt" "${KLIPPERSCREEN_ENV}"/bin/pip install -r "${KLIPPERSCREEN_DIR}/scripts/KlipperScreen-requirements.txt"
ok_msg "Dependencies have been installed!" ok_msg "Dependencies have been installed!"
fi fi

View File

@@ -133,7 +133,7 @@ function update_mobileraker() {
git checkout -f main && ok_msg "Checkout successfull" git checkout -f main && ok_msg "Checkout successfull"
if [[ $(md5sum "${MOBILERAKER_DIR}/scripts/mobileraker-requirements.txt" | cut -d " " -f1) != "${old_md5}" ]]; then if [[ $(md5sum "${MOBILERAKER_DIR}/scripts/mobileraker-requirements.txt" | cut -d " " -f1) != "${old_md5}" ]]; then
status_msg "New dependencies detected..." status_msg "New dependecies detected..."
"${MOBILERAKER_ENV}"/bin/pip install -r "${MOBILERAKER_DIR}/scripts/mobileraker-requirements.txt" "${MOBILERAKER_ENV}"/bin/pip install -r "${MOBILERAKER_DIR}/scripts/mobileraker-requirements.txt"
ok_msg "Dependencies have been installed!" ok_msg "Dependencies have been installed!"
fi fi

View File

@@ -336,6 +336,7 @@ function create_moonraker_virtualenv() {
[[ -d ${MOONRAKER_ENV} ]] && rm -rf "${MOONRAKER_ENV}" [[ -d ${MOONRAKER_ENV} ]] && rm -rf "${MOONRAKER_ENV}"
if virtualenv -p /usr/bin/python3 "${MOONRAKER_ENV}"; then if virtualenv -p /usr/bin/python3 "${MOONRAKER_ENV}"; then
"${MOONRAKER_ENV}"/bin/pip install -U pip
"${MOONRAKER_ENV}"/bin/pip install -r "${MOONRAKER_DIR}/scripts/moonraker-requirements.txt" "${MOONRAKER_ENV}"/bin/pip install -r "${MOONRAKER_DIR}/scripts/moonraker-requirements.txt"
else else
log_error "failure while creating python3 moonraker-env" log_error "failure while creating python3 moonraker-env"