update_manager: make application package updates generic
This ignores an attempt to update packages if system updates are disabled and opens the possibility for supporting updates for other linux distributions. Signed-off-by: Eric Callahan <arksine.code@gmail.com>
This commit is contained in:
parent
74630f933a
commit
b6cd19d6ef
|
@ -194,18 +194,13 @@ class AppDeploy(BaseDeploy):
|
||||||
return prev_hash != cur_hash
|
return prev_hash != cur_hash
|
||||||
|
|
||||||
async def _install_packages(self, package_list: List[str]) -> None:
|
async def _install_packages(self, package_list: List[str]) -> None:
|
||||||
pkgs = " ".join(package_list)
|
|
||||||
apt_cmd = self.cmd_helper.get_system_update_command()
|
|
||||||
self.notify_status("Installing system dependencies...")
|
self.notify_status("Installing system dependencies...")
|
||||||
# Install packages with apt-get
|
# Install packages with apt-get
|
||||||
try:
|
try:
|
||||||
await self.cmd_helper.run_cmd(
|
await self.cmd_helper.install_packages(
|
||||||
f"{apt_cmd} update", timeout=300., notify=True)
|
package_list, timeout=3600., notify=True)
|
||||||
await self.cmd_helper.run_cmd(
|
|
||||||
f"{apt_cmd} install --yes {pkgs}", timeout=3600.,
|
|
||||||
notify=True)
|
|
||||||
except Exception:
|
except Exception:
|
||||||
self.log_exc("Error updating packages via apt-get")
|
self.log_exc("Error updating packages")
|
||||||
return
|
return
|
||||||
|
|
||||||
async def _update_virtualenv(self,
|
async def _update_virtualenv(self,
|
||||||
|
|
|
@ -53,7 +53,6 @@ SUPPLEMENTAL_CFG_PATH = os.path.join(
|
||||||
os.path.dirname(__file__), "update_manager.conf")
|
os.path.dirname(__file__), "update_manager.conf")
|
||||||
KLIPPER_DEFAULT_PATH = os.path.expanduser("~/klipper")
|
KLIPPER_DEFAULT_PATH = os.path.expanduser("~/klipper")
|
||||||
KLIPPER_DEFAULT_EXEC = os.path.expanduser("~/klippy-env/bin/python")
|
KLIPPER_DEFAULT_EXEC = os.path.expanduser("~/klippy-env/bin/python")
|
||||||
APT_CMD = "sudo DEBIAN_FRONTEND=noninteractive apt-get"
|
|
||||||
|
|
||||||
# Check To see if Updates are necessary each hour
|
# Check To see if Updates are necessary each hour
|
||||||
UPDATE_REFRESH_INTERVAL_MS = 3600000
|
UPDATE_REFRESH_INTERVAL_MS = 3600000
|
||||||
|
@ -452,6 +451,7 @@ class CommandHelper:
|
||||||
shell_cmd: SCMDComp = self.server.lookup_component('shell_command')
|
shell_cmd: SCMDComp = self.server.lookup_component('shell_command')
|
||||||
self.scmd_error = shell_cmd.error
|
self.scmd_error = shell_cmd.error
|
||||||
self.build_shell_command = shell_cmd.build_shell_command
|
self.build_shell_command = shell_cmd.build_shell_command
|
||||||
|
self.pkg_updater: Optional[PackageDeploy] = None
|
||||||
|
|
||||||
AsyncHTTPClient.configure(None, defaults=dict(user_agent="Moonraker"))
|
AsyncHTTPClient.configure(None, defaults=dict(user_agent="Moonraker"))
|
||||||
self.http_client = AsyncHTTPClient()
|
self.http_client = AsyncHTTPClient()
|
||||||
|
@ -495,6 +495,9 @@ class CommandHelper:
|
||||||
def is_update_busy(self) -> bool:
|
def is_update_busy(self) -> bool:
|
||||||
return self.cur_update_app is not None
|
return self.cur_update_app is not None
|
||||||
|
|
||||||
|
def set_package_updater(self, updater: PackageDeploy) -> None:
|
||||||
|
self.pkg_updater = updater
|
||||||
|
|
||||||
def get_rate_limit_stats(self) -> Dict[str, Any]:
|
def get_rate_limit_stats(self) -> Dict[str, Any]:
|
||||||
return {
|
return {
|
||||||
'github_rate_limit': self.gh_rate_limit,
|
'github_rate_limit': self.gh_rate_limit,
|
||||||
|
@ -704,8 +707,13 @@ class CommandHelper:
|
||||||
self.server.send_event(
|
self.server.send_event(
|
||||||
"update_manager:update_response", notification)
|
"update_manager:update_response", notification)
|
||||||
|
|
||||||
def get_system_update_command(self) -> str:
|
async def install_packages(self,
|
||||||
return APT_CMD
|
package_list: List[str],
|
||||||
|
**kwargs
|
||||||
|
) -> None:
|
||||||
|
if self.pkg_updater is None:
|
||||||
|
return
|
||||||
|
await self.pkg_updater.install_packages(package_list, **kwargs)
|
||||||
|
|
||||||
def close(self) -> None:
|
def close(self) -> None:
|
||||||
self.http_client.close()
|
self.http_client.close()
|
||||||
|
@ -771,13 +779,17 @@ class StreamingDownload:
|
||||||
self.busy_evt.set()
|
self.busy_evt.set()
|
||||||
|
|
||||||
class PackageDeploy(BaseDeploy):
|
class PackageDeploy(BaseDeploy):
|
||||||
|
APT_CMD = "sudo DEBIAN_FRONTEND=noninteractive apt-get"
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
config: ConfigHelper,
|
config: ConfigHelper,
|
||||||
cmd_helper: CommandHelper
|
cmd_helper: CommandHelper
|
||||||
) -> None:
|
) -> None:
|
||||||
super().__init__(config, cmd_helper)
|
super().__init__(config, cmd_helper)
|
||||||
|
cmd_helper.set_package_updater(self)
|
||||||
self.available_packages: List[str] = []
|
self.available_packages: List[str] = []
|
||||||
self.refresh_evt: Optional[asyncio.Event] = None
|
self.refresh_evt: Optional[asyncio.Event] = None
|
||||||
|
# Initialze to current time so an update is not performed on init
|
||||||
|
self.last_apt_update_time: float = time.time()
|
||||||
self.mutex: asyncio.Lock = asyncio.Lock()
|
self.mutex: asyncio.Lock = asyncio.Lock()
|
||||||
|
|
||||||
async def refresh(self, fetch_packages: bool = True) -> None:
|
async def refresh(self, fetch_packages: bool = True) -> None:
|
||||||
|
@ -788,9 +800,7 @@ class PackageDeploy(BaseDeploy):
|
||||||
async with self.mutex:
|
async with self.mutex:
|
||||||
self.refresh_evt = asyncio.Event()
|
self.refresh_evt = asyncio.Event()
|
||||||
try:
|
try:
|
||||||
if fetch_packages:
|
await self._update_apt(force=fetch_packages)
|
||||||
await self.cmd_helper.run_cmd(
|
|
||||||
f"{APT_CMD} update", timeout=300., retries=3)
|
|
||||||
res = await self.cmd_helper.run_cmd_with_response(
|
res = await self.cmd_helper.run_cmd_with_response(
|
||||||
"apt list --upgradable", timeout=60.)
|
"apt list --upgradable", timeout=60.)
|
||||||
pkg_list = [p.strip() for p in res.split("\n") if p.strip()]
|
pkg_list = [p.strip() for p in res.split("\n") if p.strip()]
|
||||||
|
@ -809,18 +819,44 @@ class PackageDeploy(BaseDeploy):
|
||||||
|
|
||||||
async def update(self) -> None:
|
async def update(self) -> None:
|
||||||
async with self.mutex:
|
async with self.mutex:
|
||||||
|
if not self.available_packages:
|
||||||
|
return
|
||||||
self.cmd_helper.notify_update_response("Updating packages...")
|
self.cmd_helper.notify_update_response("Updating packages...")
|
||||||
try:
|
try:
|
||||||
|
await self._update_apt(force=True, notify=True)
|
||||||
await self.cmd_helper.run_cmd(
|
await self.cmd_helper.run_cmd(
|
||||||
f"{APT_CMD} update", timeout=300., notify=True)
|
f"{self.APT_CMD} upgrade --yes", timeout=3600.,
|
||||||
await self.cmd_helper.run_cmd(
|
notify=True)
|
||||||
f"{APT_CMD} upgrade --yes", timeout=3600., notify=True)
|
|
||||||
except Exception:
|
except Exception:
|
||||||
raise self.server.error("Error updating system packages")
|
raise self.server.error("Error updating system packages")
|
||||||
self.available_packages = []
|
self.available_packages = []
|
||||||
self.cmd_helper.notify_update_response(
|
self.cmd_helper.notify_update_response(
|
||||||
"Package update finished...", is_complete=True)
|
"Package update finished...", is_complete=True)
|
||||||
|
|
||||||
|
async def _update_apt(self,
|
||||||
|
force: bool = False,
|
||||||
|
notify: bool = False
|
||||||
|
) -> None:
|
||||||
|
curtime = time.time()
|
||||||
|
if force or curtime > self.last_apt_update_time + 3600.:
|
||||||
|
# Don't update if a request was done within the last hour
|
||||||
|
await self.cmd_helper.run_cmd(
|
||||||
|
f"{self.APT_CMD} update", timeout=300., notify=notify)
|
||||||
|
self.last_apt_update_time = time.time()
|
||||||
|
|
||||||
|
async def install_packages(self,
|
||||||
|
package_list: List[str],
|
||||||
|
**kwargs
|
||||||
|
) -> None:
|
||||||
|
timeout: float = kwargs.get('timeout', 300.)
|
||||||
|
retries: int = kwargs.get('retries', 3)
|
||||||
|
notify: bool = kwargs.get('notify', False)
|
||||||
|
pkgs = " ".join(package_list)
|
||||||
|
await self._update_apt(notify=notify)
|
||||||
|
await self.cmd_helper.run_cmd(
|
||||||
|
f"{self.APT_CMD} install --yes {pkgs}", timeout=timeout,
|
||||||
|
retries=retries, notify=notify)
|
||||||
|
|
||||||
def get_update_status(self) -> Dict[str, Any]:
|
def get_update_status(self) -> Dict[str, Any]:
|
||||||
return {
|
return {
|
||||||
'package_count': len(self.available_packages),
|
'package_count': len(self.available_packages),
|
||||||
|
|
Loading…
Reference in New Issue