mirror of
https://github.com/dw-0/kiauh.git
synced 2025-12-25 16:53:36 +05:00
feat: add system upgrades
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
This commit is contained in:
@@ -9,7 +9,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import textwrap
|
import textwrap
|
||||||
from typing import Callable, Type
|
from typing import Callable, List, Type
|
||||||
|
|
||||||
from components.crowsnest.crowsnest import get_crowsnest_status, update_crowsnest
|
from components.crowsnest.crowsnest import get_crowsnest_status, update_crowsnest
|
||||||
from components.klipper.klipper_setup import update_klipper
|
from components.klipper.klipper_setup import update_klipper
|
||||||
@@ -48,8 +48,14 @@ from utils.constants import (
|
|||||||
COLOR_YELLOW,
|
COLOR_YELLOW,
|
||||||
RESET_FORMAT,
|
RESET_FORMAT,
|
||||||
)
|
)
|
||||||
from utils.logger import Logger
|
from utils.input_utils import get_confirm
|
||||||
|
from utils.logger import DialogType, Logger
|
||||||
from utils.spinner import Spinner
|
from utils.spinner import Spinner
|
||||||
|
from utils.sys_utils import (
|
||||||
|
get_upgradable_packages,
|
||||||
|
update_system_package_lists,
|
||||||
|
upgrade_system_packages,
|
||||||
|
)
|
||||||
from utils.types import ComponentStatus
|
from utils.types import ComponentStatus
|
||||||
|
|
||||||
|
|
||||||
@@ -60,6 +66,9 @@ class UpdateMenu(BaseMenu):
|
|||||||
super().__init__()
|
super().__init__()
|
||||||
self.previous_menu: Type[BaseMenu] | None = previous_menu
|
self.previous_menu: Type[BaseMenu] | None = previous_menu
|
||||||
|
|
||||||
|
self.packages: List[str] = []
|
||||||
|
self.package_count: int = 0
|
||||||
|
|
||||||
self.klipper_local = self.klipper_remote = ""
|
self.klipper_local = self.klipper_remote = ""
|
||||||
self.moonraker_local = self.moonraker_remote = ""
|
self.moonraker_local = self.moonraker_remote = ""
|
||||||
self.mainsail_local = self.mainsail_remote = ""
|
self.mainsail_local = self.mainsail_remote = ""
|
||||||
@@ -108,7 +117,7 @@ class UpdateMenu(BaseMenu):
|
|||||||
}
|
}
|
||||||
|
|
||||||
def print_menu(self) -> None:
|
def print_menu(self) -> None:
|
||||||
spinner = Spinner()
|
spinner = Spinner("Loading update menu, please wait")
|
||||||
spinner.start()
|
spinner.start()
|
||||||
|
|
||||||
self._fetch_update_status()
|
self._fetch_update_status()
|
||||||
@@ -118,6 +127,15 @@ class UpdateMenu(BaseMenu):
|
|||||||
header = " [ Update Menu ] "
|
header = " [ Update Menu ] "
|
||||||
color = COLOR_GREEN
|
color = COLOR_GREEN
|
||||||
count = 62 - len(color) - len(RESET_FORMAT)
|
count = 62 - len(color) - len(RESET_FORMAT)
|
||||||
|
|
||||||
|
sysupgrades: str = "No upgrades available."
|
||||||
|
padding = 29
|
||||||
|
if self.package_count > 0:
|
||||||
|
sysupgrades = (
|
||||||
|
f"{COLOR_GREEN}{self.package_count} upgrades available!{RESET_FORMAT}"
|
||||||
|
)
|
||||||
|
padding = 38
|
||||||
|
|
||||||
menu = textwrap.dedent(
|
menu = textwrap.dedent(
|
||||||
f"""
|
f"""
|
||||||
╔═══════════════════════════════════════════════════════╗
|
╔═══════════════════════════════════════════════════════╗
|
||||||
@@ -143,7 +161,7 @@ class UpdateMenu(BaseMenu):
|
|||||||
║ 9) Crowsnest │ {self.crowsnest_local:<22} │ {self.crowsnest_remote:<22} ║
|
║ 9) Crowsnest │ {self.crowsnest_local:<22} │ {self.crowsnest_remote:<22} ║
|
||||||
║ 10) OctoEverywhere │ {self.octoeverywhere_local:<22} │ {self.octoeverywhere_remote:<22} ║
|
║ 10) OctoEverywhere │ {self.octoeverywhere_local:<22} │ {self.octoeverywhere_remote:<22} ║
|
||||||
║ ├───────────────┴───────────────╢
|
║ ├───────────────┴───────────────╢
|
||||||
║ 11) System │ ║
|
║ 11) System │ {sysupgrades:^{padding}} ║
|
||||||
╟───────────────────────┴───────────────────────────────╢
|
╟───────────────────────┴───────────────────────────────╢
|
||||||
"""
|
"""
|
||||||
)[1:]
|
)[1:]
|
||||||
@@ -192,7 +210,8 @@ class UpdateMenu(BaseMenu):
|
|||||||
if self._check_is_installed("octoeverywhere"):
|
if self._check_is_installed("octoeverywhere"):
|
||||||
update_octoeverywhere()
|
update_octoeverywhere()
|
||||||
|
|
||||||
def upgrade_system_packages(self, **kwargs) -> None: ...
|
def upgrade_system_packages(self, **kwargs) -> None:
|
||||||
|
self._run_system_updates()
|
||||||
|
|
||||||
def _fetch_update_status(self) -> None:
|
def _fetch_update_status(self) -> None:
|
||||||
self._set_status_data("klipper", get_klipper_status)
|
self._set_status_data("klipper", get_klipper_status)
|
||||||
@@ -210,6 +229,10 @@ class UpdateMenu(BaseMenu):
|
|||||||
self._set_status_data("crowsnest", get_crowsnest_status)
|
self._set_status_data("crowsnest", get_crowsnest_status)
|
||||||
self._set_status_data("octoeverywhere", get_octoeverywhere_status)
|
self._set_status_data("octoeverywhere", get_octoeverywhere_status)
|
||||||
|
|
||||||
|
update_system_package_lists(silent=True)
|
||||||
|
self.packages = get_upgradable_packages()
|
||||||
|
self.package_count = len(self.packages)
|
||||||
|
|
||||||
def _format_local_status(self, local_version, remote_version) -> str:
|
def _format_local_status(self, local_version, remote_version) -> str:
|
||||||
color = COLOR_RED
|
color = COLOR_RED
|
||||||
if not local_version:
|
if not local_version:
|
||||||
@@ -246,3 +269,25 @@ class UpdateMenu(BaseMenu):
|
|||||||
Logger.print_info(f"{name.capitalize()} is not installed! Skipped ...")
|
Logger.print_info(f"{name.capitalize()} is not installed! Skipped ...")
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def _run_system_updates(self) -> None:
|
||||||
|
if not self.packages:
|
||||||
|
Logger.print_info("No system upgrades available!")
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
pkgs: str = ", ".join(self.packages)
|
||||||
|
Logger.print_dialog(
|
||||||
|
DialogType.CUSTOM,
|
||||||
|
["The following packages will be upgraded:", "\n\n", pkgs],
|
||||||
|
custom_title="UPGRADABLE SYSTEM UPDATES",
|
||||||
|
padding_top=0,
|
||||||
|
padding_bottom=0,
|
||||||
|
)
|
||||||
|
if not get_confirm("Continue?"):
|
||||||
|
return
|
||||||
|
Logger.print_status("Upgrading system packages ...")
|
||||||
|
upgrade_system_packages(self.packages)
|
||||||
|
except Exception as e:
|
||||||
|
Logger.print_error(f"Error upgrading system packages:\n{e}")
|
||||||
|
raise
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import time
|
|||||||
import urllib.error
|
import urllib.error
|
||||||
import urllib.request
|
import urllib.request
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from subprocess import DEVNULL, PIPE, CalledProcessError, Popen, run
|
from subprocess import DEVNULL, PIPE, CalledProcessError, Popen, check_output, run
|
||||||
from typing import List, Literal, Set
|
from typing import List, Literal, Set
|
||||||
|
|
||||||
from utils.constants import SYSTEMD
|
from utils.constants import SYSTEMD
|
||||||
@@ -219,6 +219,25 @@ def update_system_package_lists(silent: bool, rls_info_change=False) -> None:
|
|||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
def get_upgradable_packages() -> List[str]:
|
||||||
|
"""
|
||||||
|
Reads all system packages that can be upgraded.
|
||||||
|
:return: A list of package names available for upgrade
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
command = ["apt", "list", "--upgradable"]
|
||||||
|
output: str = check_output(command, stderr=DEVNULL, text=True, encoding="utf-8")
|
||||||
|
pkglist = []
|
||||||
|
for line in output.split("\n"):
|
||||||
|
if "/" not in line:
|
||||||
|
continue
|
||||||
|
pkg = line.split("/")[0]
|
||||||
|
pkglist.append(pkg)
|
||||||
|
return pkglist
|
||||||
|
except CalledProcessError as e:
|
||||||
|
raise Exception(f"Error reading upgradable packages: {e}")
|
||||||
|
|
||||||
|
|
||||||
def check_package_install(packages: Set[str]) -> List[str]:
|
def check_package_install(packages: Set[str]) -> List[str]:
|
||||||
"""
|
"""
|
||||||
Checks the system for installed packages |
|
Checks the system for installed packages |
|
||||||
@@ -252,12 +271,29 @@ def install_system_packages(packages: List[str]) -> None:
|
|||||||
command.append(pkg)
|
command.append(pkg)
|
||||||
run(command, stderr=PIPE, check=True)
|
run(command, stderr=PIPE, check=True)
|
||||||
|
|
||||||
Logger.print_ok("Packages installed successfully.")
|
Logger.print_ok("Packages successfully installed.")
|
||||||
except CalledProcessError as e:
|
except CalledProcessError as e:
|
||||||
Logger.print_error(f"Error installing packages:\n{e.stderr.decode()}")
|
Logger.print_error(f"Error installing packages:\n{e.stderr.decode()}")
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade_system_packages(packages: List[str]) -> None:
|
||||||
|
"""
|
||||||
|
Updates a list of system packages |
|
||||||
|
:param packages: List of system package names
|
||||||
|
:return: None
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
command = ["sudo", "apt-get", "upgrade", "-y"]
|
||||||
|
for pkg in packages:
|
||||||
|
command.append(pkg)
|
||||||
|
run(command, stderr=PIPE, check=True)
|
||||||
|
|
||||||
|
Logger.print_ok("Packages successfully upgraded.")
|
||||||
|
except CalledProcessError as e:
|
||||||
|
raise Exception(f"Error upgrading packages:\n{e.stderr.decode()}")
|
||||||
|
|
||||||
|
|
||||||
# this feels hacky and not quite right, but for now it works
|
# this feels hacky and not quite right, but for now it works
|
||||||
# see: https://stackoverflow.com/questions/166506/finding-local-ip-addresses-using-pythons-stdlib
|
# see: https://stackoverflow.com/questions/166506/finding-local-ip-addresses-using-pythons-stdlib
|
||||||
def get_ipv4_addr() -> str:
|
def get_ipv4_addr() -> str:
|
||||||
|
|||||||
Reference in New Issue
Block a user