update_manager: refresh the local git repo state when a status refresh is requested

Signed-off-by:  Eric Callahan <arksine.code@gmail.com>
This commit is contained in:
Arksine 2020-12-17 06:16:30 -05:00
parent 20d27b0be6
commit 40b74cefb5
1 changed files with 39 additions and 26 deletions

View File

@ -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)