From 40b74cefb511f675ef2e05ee39be38571bfaceea Mon Sep 17 00:00:00 2001 From: Arksine Date: Thu, 17 Dec 2020 06:16:30 -0500 Subject: [PATCH] update_manager: refresh the local git repo state when a status refresh is requested Signed-off-by: Eric Callahan --- moonraker/plugins/update_manager.py | 65 +++++++++++++++++------------ 1 file changed, 39 insertions(+), 26 deletions(-) diff --git a/moonraker/plugins/update_manager.py b/moonraker/plugins/update_manager.py index bfcd8f3..9171a81 100644 --- a/moonraker/plugins/update_manager.py +++ b/moonraker/plugins/update_manager.py @@ -11,6 +11,7 @@ import sys import shutil import zipfile import io +import asyncio import tornado.gen from tornado.ioloop import IOLoop from tornado.httpclient import AsyncHTTPClient, HTTPRequest @@ -44,11 +45,10 @@ class UpdateManager: self.server = config.get_server() AsyncHTTPClient.configure(None, defaults=dict(user_agent="Moonraker")) self.http_client = AsyncHTTPClient() - sw_version = config['system_args'].get('software_version') + env = sys.executable self.updaters = { "system": PackageUpdater(self), - "moonraker": GitUpdater(self, "moonraker", MOONRAKER_PATH, - sw_version, sys.executable) + "moonraker": GitUpdater(self, "moonraker", MOONRAKER_PATH, env) } self.current_update = None client_repo = config.get("client_repo", None) @@ -86,14 +86,14 @@ class UpdateManager: logging.info("No valid klippy info received") return kpath = kinfo['klipper_path'] - kversion = kinfo['software_version'] env = kinfo['python_path'] - self.updaters['klipper'] = GitUpdater( - self, "klipper", kpath, kversion, env) + self.updaters['klipper'] = GitUpdater(self, "klipper", kpath, env) - async def _check_versions(self): + async def _refresh_git_repo_state(self): for updater in self.updaters.values(): - await updater.check_remote_version() + ret = updater.refresh_update_state() + if asyncio.iscoroutine(ret): + await ret async def _handle_update_request(self, web_request): app = web_request.get_endpoint().split("/")[-1] @@ -114,7 +114,7 @@ class UpdateManager: async def _handle_status_request(self, web_request): if web_request.get_boolean('refresh', False): - await self._check_versions() + await self._refresh_git_repo_state() vinfo = {} for name, updater in self.updaters.items(): if hasattr(updater, "get_update_status"): @@ -184,7 +184,7 @@ class UpdateManager: class GitUpdater: - def __init__(self, umgr, name, path, ver, env): + def __init__(self, umgr, name, path, env): self.server = umgr.server self.execute_cmd = umgr.execute_cmd self.execute_cmd_with_response = umgr.execute_cmd_with_response @@ -194,14 +194,8 @@ class GitUpdater: self.repo_path = path self.env = env self.version = self.cur_hash = self.remote_hash = "?" - self.is_valid = False - self.is_dirty = ver.endswith("dirty") - tag_version = "?" - ver_match = re.match(r"v\d+\.\d+\.\d-\d+", ver) - if ver_match: - tag_version = ver_match.group() - self.version = tag_version - IOLoop.current().spawn_callback(self._init_repo) + self.is_valid = self.is_dirty = False + IOLoop.current().spawn_callback(self.refresh_update_state) def _get_version_info(self): ver_path = os.path.join(self.repo_path, "scripts/version.txt") @@ -239,7 +233,7 @@ class GitUpdater: logging.debug(log_msg) self.notify_update_response(log_msg) - async def _init_repo(self): + async def refresh_update_state(self): self.is_valid = False self.cur_hash = "?" try: @@ -249,10 +243,20 @@ class GitUpdater: f"git -C {self.repo_path} remote get-url origin") hash = await self.execute_cmd_with_response( f"git -C {self.repo_path} rev-parse HEAD") + repo_version = await self.execute_cmd_with_response( + f"git -C {self.repo_path} describe --always " + "--tags --long --dirty") except Exception: self._log_exc("Error retreiving git info") return + self.is_dirty = repo_version.endswith("dirty") + tag_version = "?" + ver_match = re.match(r"v\d+\.\d+\.\d-\d+", repo_version) + if ver_match: + tag_version = ver_match.group() + self.version = tag_version + if not branch.startswith("fatal:"): self.cur_hash = hash if branch == "master": @@ -267,7 +271,7 @@ class GitUpdater: else: self._log_info("Git repo not on master branch") else: - self._log_info(f"Invalid git repo at path '{self.repo_path}''") + self._log_info(f"Invalid git repo at path '{self.repo_path}'") try: await self.check_remote_version() except Exception: @@ -400,7 +404,9 @@ class PackageUpdater: self.execute_cmd = umgr.execute_cmd self.notify_update_response = umgr.notify_update_response - async def check_remote_version(self): + def refresh_update_state(self): + # TODO: We should be able to determine if packages need to be + # updated here pass async def update(self, *args): @@ -422,17 +428,24 @@ class ClientUpdater: self.name = self.repo.split("/")[-1] self.path = path self.version = self.remote_version = self.dl_url = "?" + self._get_local_version() + logging.info(f"\nInitializing Client Updater: '{self.name}'," + f"\nversion: {self.version}" + f"\npath: {self.path}") + IOLoop.current().spawn_callback(self.refresh_update_state) + + def _get_local_version(self): version_path = os.path.join(self.path, ".version") if os.path.isfile(os.path.join(self.path, ".version")): with open(version_path, "r") as f: v = f.read() self.version = v.strip() - logging.info(f"\nInitializing repo '{self.name}'," - f"\nversion: {self.version}" - f"\npath: {self.path}") - IOLoop.current().spawn_callback(self.check_remote_version) - async def check_remote_version(self): + async def refresh_update_state(self): + # Local state + self._get_local_version() + + # Remote state url = f"https://api.github.com/repos/{self.repo}/releases/latest" try: result = await self.github_request(url)