From 6e6388d673d471f629e1313851adde133f145874 Mon Sep 17 00:00:00 2001 From: Eric Callahan Date: Sat, 6 Jan 2024 11:54:33 -0500 Subject: [PATCH] update_manager: fix race condition Previously the Klipper repo location can be changed outside of the lock. If the location of the Klipper path is moved while an autorefresh is occurring it is possible for Moonraker to call refresh and/or notify_update_refreshed before the repo has been initialized. This commit moves the re-assignment of the "klipper" updated inside the lock. In addition AppDeploy._is_valid is now defined in the __init__() method. Signed-off-by: Eric Callahan --- moonraker/components/update_manager/app_deploy.py | 1 + .../components/update_manager/update_manager.py | 12 ++++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/moonraker/components/update_manager/app_deploy.py b/moonraker/components/update_manager/app_deploy.py index 1c94417..2706697 100644 --- a/moonraker/components/update_manager/app_deploy.py +++ b/moonraker/components/update_manager/app_deploy.py @@ -76,6 +76,7 @@ class AppDeploy(BaseDeploy): f"option 'channel'. Type '{self.type}' supports the following " f"channels: {str_channels}. Falling back to channel '{self.channel}'" ) + self._is_valid: bool = False self.virtualenv: Optional[pathlib.Path] = None self.py_exec: Optional[pathlib.Path] = None self.pip_cmd: Optional[str] = None diff --git a/moonraker/components/update_manager/update_manager.py b/moonraker/components/update_manager/update_manager.py index caec8ef..dfed1ab 100644 --- a/moonraker/components/update_manager/update_manager.py +++ b/moonraker/components/update_manager/update_manager.py @@ -210,18 +210,18 @@ class UpdateManager: kcfg.set_option("path", kpath) kcfg.set_option("env", executable) kcfg.set_option("type", str(app_type)) - need_notification = not isinstance(kupdater, AppDeploy) + notify = not isinstance(kupdater, AppDeploy) kclass = get_deploy_class(app_type, BaseDeploy) - self.updaters['klipper'] = kclass(kcfg, self.cmd_helper) - coro = self._update_klipper_repo(need_notification) + coro = self._update_klipper_repo(kclass(kcfg, self.cmd_helper), notify) self.event_loop.create_task(coro) - async def _update_klipper_repo(self, notify: bool) -> None: + async def _update_klipper_repo(self, updater: BaseDeploy, notify: bool) -> None: async with self.cmd_request_lock: + self.updaters['klipper'] = updater umdb = self.cmd_helper.get_umdb() await umdb.pop('klipper', None) - await self.updaters['klipper'].initialize() - await self.updaters['klipper'].refresh() + await updater.initialize() + await updater.refresh() if notify: self.cmd_helper.notify_update_refreshed()