diff --git a/framework/python/src/api/api.py b/framework/python/src/api/api.py index f332bad74..745303701 100644 --- a/framework/python/src/api/api.py +++ b/framework/python/src/api/api.py @@ -20,6 +20,7 @@ from json import JSONDecodeError import os import psutil +import requests import threading import uvicorn @@ -34,6 +35,8 @@ DEVICE_TEST_MODULES_KEY = "test_modules" DEVICES_PATH = "/usr/local/testrun/local/devices" +LATEST_RELEASE_CHECK = "https://api.github.com/repos/google/testrun/releases/latest" + class Api: """Provide REST endpoints to manage Testrun""" @@ -55,6 +58,8 @@ def __init__(self, test_run): methods=["POST"]) self._router.add_api_route("/system/status", self.get_status) + self._router.add_api_route("/system/version", self.get_version) + # Deprecated: /history will be removed in version 1.1 self._router.add_api_route("/history", self.get_reports) @@ -206,6 +211,46 @@ async def stop_test_run(self): async def get_status(self): return self._test_run.get_session().to_json() + async def get_version(self, response: Response): + json_response = {} + + # Obtain the current version + current_version = self._session.get_version() + + # Check if current version was able to be obtained + if current_version is None: + response.status_code = 500 + return self._generate_msg(False, "Could not fetch current version") + + # Set the installed version + json_response["installed_version"] = current_version + + # Check latest version number from GitHub API + version_check = requests.get(LATEST_RELEASE_CHECK, timeout=5) + + # Check OK response was received + if version_check.status_code != 200: + response.status_code = 500 + return self._generate_msg(False, "Failed to fetch latest version") + + # Extract version number from response, removing the leading 'v' + latest_version_no = version_check.json()["name"].strip("v") + LOGGER.debug(f"Latest version available is {latest_version_no}") + + # Craft JSON response + json_response["latest_version"] = latest_version_no + json_response["latest_version_url"] = version_check.json()["html_url"] + + # String comparison between current and latest version + if latest_version_no > current_version: + json_response["update_available"] = True + LOGGER.debug("An update is available") + else: + json_response["update_available"] = False + LOGGER.debug("The latest version is installed") + + return json_response + async def get_reports(self): LOGGER.debug("Received reports list request") return self._session.get_all_reports() diff --git a/framework/python/src/common/session.py b/framework/python/src/common/session.py index dd9a50b59..feb4fb60f 100644 --- a/framework/python/src/common/session.py +++ b/framework/python/src/common/session.py @@ -42,6 +42,10 @@ def __init__(self, config_file): self._runtime_params = [] self._device_repository = [] self._total_tests = 0 + + self._version = None + self._load_version() + self._config_file = config_file self._config = self._get_default_config() self._load_config() @@ -120,6 +124,17 @@ def _load_config(self): LOGGER.debug(self._config) + def _load_version(self): + version_cmd = util.run_command('dpkg-query --showformat=\'${Version}\' --show testrun') + + if version_cmd: + version = version_cmd[0] + LOGGER.info(f'Running Testrun version {version}') + self._version = version + + def get_version(self): + return self._version + def _save_config(self): with open(self._config_file, 'w', encoding='utf-8') as f: f.write(json.dumps(self._config, indent=2))