update_manager: support internal updaters

Signed-off-by:  Eric Callahan <arksine.code@gmail.com>
This commit is contained in:
Eric Callahan 2025-01-17 10:59:39 -05:00
parent 1117890327
commit ff2571180c
7 changed files with 49 additions and 38 deletions

View File

@ -31,7 +31,6 @@ from typing import (
if TYPE_CHECKING:
from ...confighelper import ConfigHelper
from ..klippy_connection import KlippyConnection as Klippy
from .update_manager import CommandHelper
from ..machine import Machine
from ..file_manager.file_manager import FileManager
@ -39,10 +38,8 @@ DISTRO_ALIASES = [distro.id()]
DISTRO_ALIASES.extend(distro.like().split())
class AppDeploy(BaseDeploy):
def __init__(
self, config: ConfigHelper, cmd_helper: CommandHelper, prefix: str
) -> None:
super().__init__(config, cmd_helper, prefix=prefix)
def __init__(self, config: ConfigHelper, prefix: str) -> None:
super().__init__(config, prefix=prefix)
self.config = config
type_choices = {str(t): t for t in AppType.valid_types()}
self.type = config.getchoice("type", type_choices)

View File

@ -16,13 +16,14 @@ if TYPE_CHECKING:
from .update_manager import CommandHelper
class BaseDeploy:
def __init__(self,
config: ConfigHelper,
cmd_helper: CommandHelper,
name: Optional[str] = None,
prefix: str = "",
cfg_hash: Optional[str] = None
) -> None:
cmd_helper: CommandHelper
def __init__(
self,
config: ConfigHelper,
name: Optional[str] = None,
prefix: str = "",
cfg_hash: Optional[str] = None
) -> None:
if name is None:
name = self.parse_name(config)
self.name = name
@ -30,8 +31,7 @@ class BaseDeploy:
prefix = f"{prefix} {self.name}: "
self.prefix = prefix
self.server = config.get_server()
self.cmd_helper = cmd_helper
self.refresh_interval = cmd_helper.get_refresh_interval()
self.refresh_interval = self.cmd_helper.get_refresh_interval()
refresh_interval = config.getint('refresh_interval', None)
if refresh_interval is not None:
self.refresh_interval = refresh_interval * 60 * 60
@ -47,6 +47,10 @@ class BaseDeploy:
name = name[7:]
return name
@staticmethod
def set_command_helper(cmd_helper: CommandHelper) -> None:
BaseDeploy.cmd_helper = cmd_helper
async def initialize(self) -> Dict[str, Any]:
umdb = self.cmd_helper.get_umdb()
storage: Dict[str, Any] = await umdb.get(self.name, {})

View File

@ -30,8 +30,8 @@ if TYPE_CHECKING:
from ..http_client import HttpClient
class GitDeploy(AppDeploy):
def __init__(self, config: ConfigHelper, cmd_helper: CommandHelper) -> None:
super().__init__(config, cmd_helper, "Git Repo")
def __init__(self, config: ConfigHelper) -> None:
super().__init__(config, "Git Repo")
self._configure_path(config)
self._configure_virtualenv(config)
self._configure_dependencies(config)
@ -49,7 +49,7 @@ class GitDeploy(AppDeploy):
"a minimum of 8 characters."
)
self.repo = GitRepo(
cmd_helper, self.path, self.name, self.origin, self.moved_origin,
self.cmd_helper, self.path, self.name, self.origin, self.moved_origin,
self.primary_branch, self.channel, pinned_commit
)

View File

@ -28,7 +28,6 @@ if TYPE_CHECKING:
from ...confighelper import ConfigHelper
from ...utils.source_info import PackageInfo
from ...components.file_manager.file_manager import FileManager
from .update_manager import CommandHelper
class PackageSource(Enum):
PIP = 0
@ -37,8 +36,8 @@ class PackageSource(Enum):
class PythonDeploy(AppDeploy):
def __init__(self, config: ConfigHelper, cmd_helper: CommandHelper) -> None:
super().__init__(config, cmd_helper, "Python Package")
def __init__(self, config: ConfigHelper) -> None:
super().__init__(config, "Python Package")
self._configure_virtualenv(config)
if self.virtualenv is None:
raise config.error(

View File

@ -35,12 +35,9 @@ if TYPE_CHECKING:
class PackageDeploy(BaseDeploy):
def __init__(self,
config: ConfigHelper,
cmd_helper: CommandHelper
) -> None:
super().__init__(config, cmd_helper, "system", "", "")
cmd_helper.set_package_updater(self)
def __init__(self, config: ConfigHelper) -> None:
super().__init__(config, "system", "", "")
self.cmd_helper.set_package_updater(self)
self.use_packagekit = config.getboolean("enable_packagekit", True)
self.available_packages: List[str] = []

View File

@ -87,20 +87,21 @@ class UpdateManager:
" in 'refresh_window' cannot be the same.")
self.cmd_helper = CommandHelper(config, self.get_updaters)
BaseDeploy.set_command_helper(self.cmd_helper)
self.updaters: Dict[str, BaseDeploy] = {}
if config.getboolean('enable_system_updates', True):
self.updaters['system'] = PackageDeploy(config, self.cmd_helper)
self.updaters['system'] = PackageDeploy(config)
mcfg = self.app_config["moonraker"]
kcfg = self.app_config["klipper"]
mclass = get_deploy_class(mcfg.get("type"), BaseDeploy)
self.updaters['moonraker'] = mclass(mcfg, self.cmd_helper)
self.updaters['moonraker'] = mclass(mcfg)
kclass = BaseDeploy
if (
os.path.exists(kcfg.get("path")) and
os.path.exists(kcfg.get("env"))
):
kclass = get_deploy_class(kcfg.get("type"), BaseDeploy)
self.updaters['klipper'] = kclass(kcfg, self.cmd_helper)
self.updaters['klipper'] = kclass(kcfg)
# TODO: The below check may be removed when invalid config options
# raise a config error.
@ -129,7 +130,7 @@ class UpdateManager:
self.server.add_warning(
f"Invalid type '{client_type}' for section [{section}]")
else:
self.updaters[name] = deployer(cfg, self.cmd_helper)
self.updaters[name] = deployer(cfg)
except Exception as e:
self.server.add_warning(
f"[update_manager]: Failed to load extension {name}: {e}",
@ -204,6 +205,24 @@ class UpdateManager:
self._handle_auto_refresh, self.event_loop.get_loop_time()
)
def register_updater(self, name: str, config: Dict[str, str]) -> None:
if name in self.updaters:
raise self.server.error(f"Updater {name} already registered")
cfg = self.app_config.read_supplemental_dict({name: config})
updater_type = cfg.get("type")
updater_cls = get_deploy_class(updater_type, None)
if updater_cls is None:
raise self.server.error(f"Invalid type '{updater_type}'")
self.updaters[name] = updater_cls(cfg)
async def refresh_updater(self, updater_name: str, force: bool = False) -> None:
if updater_name not in self.updaters:
return
async with self.cmd_request_lock:
updater = self.updaters[updater_name]
if updater.needs_refresh() or force:
await updater.refresh()
def _set_klipper_repo(self) -> None:
if self.klippy_identified_evt is not None:
self.klippy_identified_evt.set()
@ -224,7 +243,7 @@ class UpdateManager:
kcfg.set_option("type", str(app_type))
notify = not isinstance(kupdater, AppDeploy)
kclass = get_deploy_class(app_type, BaseDeploy)
coro = self._update_klipper_repo(kclass(kcfg, self.cmd_helper), notify)
coro = self._update_klipper_repo(kclass(kcfg), notify)
self.event_loop.create_task(coro)
async def _update_klipper_repo(self, updater: BaseDeploy, notify: bool) -> None:

View File

@ -27,16 +27,11 @@ from typing import (
)
if TYPE_CHECKING:
from ...confighelper import ConfigHelper
from .update_manager import CommandHelper
from ..file_manager.file_manager import FileManager
class ZipDeploy(AppDeploy):
def __init__(
self,
config: ConfigHelper,
cmd_helper: CommandHelper
) -> None:
super().__init__(config, cmd_helper, "Zip Application")
def __init__(self, config: ConfigHelper) -> None:
super().__init__(config, "Zip Application")
self._configure_path(config, False)
if self.type == AppType.ZIP:
self._configure_virtualenv(config)