From 4645e8c97578b57e8a2d44b15df5ceb76e2db20b Mon Sep 17 00:00:00 2001 From: Daniel Markstedt Date: Tue, 15 Nov 2022 22:28:27 -0800 Subject: [PATCH] Display hardware info in footer; close open file handlers; better error handling (#989) * Expose hardware info in env string * Improve error handling for get_properties_by_drive_name * Verbose uname parameters. * Close open file in introspect method * Add error handling for when no drive name was matched with props in the database --- python/common/src/rascsi/sys_cmds.py | 48 ++++++++++++++++++++++------ python/web/src/templates/base.html | 2 +- python/web/src/web.py | 42 ++++++++++++++++-------- python/web/src/web_utils.py | 20 ++++++------ 4 files changed, 78 insertions(+), 34 deletions(-) diff --git a/python/common/src/rascsi/sys_cmds.py b/python/common/src/rascsi/sys_cmds.py index ab2a0863..c6beddf5 100644 --- a/python/common/src/rascsi/sys_cmds.py +++ b/python/common/src/rascsi/sys_cmds.py @@ -7,6 +7,7 @@ from subprocess import run from shutil import disk_usage from re import findall, match from socket import socket, gethostname, AF_INET, SOCK_DGRAM +from pathlib import Path from rascsi.common_settings import SHELL_ERROR @@ -37,9 +38,9 @@ class SysCmds: ra_git_version = "" try: - pi_version = ( + os_version = ( subprocess.run( - ["uname", "-a"], + ["uname", "--kernel-name", "--kernel-release", "--machine"], capture_output=True, check=True, ) @@ -48,9 +49,35 @@ class SysCmds: ) except subprocess.CalledProcessError as error: logging.warning(SHELL_ERROR, " ".join(error.cmd), error.stderr.decode("utf-8")) - pi_version = "?" + os_version = "Unknown OS" - return {"git": ra_git_version, "env": pi_version} + PROC_MODEL_PATH = "/proc/device-tree/model" + SYS_VENDOR_PATH = "/sys/devices/virtual/dmi/id/sys_vendor" + SYS_PROD_PATH = "/sys/devices/virtual/dmi/id/product_name" + # First we try to get the Pi model + if Path(PROC_MODEL_PATH).is_file(): + try: + with open(PROC_MODEL_PATH, "r") as open_file: + hardware = open_file.read().rstrip() + except (IOError, ValueError, EOFError, TypeError) as error: + logging.error(str(error)) + # As a fallback, look for PC vendor information + elif Path(SYS_VENDOR_PATH).is_file() and Path(SYS_PROD_PATH).is_file(): + hardware = "" + try: + with open(SYS_VENDOR_PATH, "r") as open_file: + hardware = open_file.read().rstrip() + " " + except (IOError, ValueError, EOFError, TypeError) as error: + logging.error(str(error)) + try: + with open(SYS_PROD_PATH, "r") as open_file: + hardware = hardware + open_file.read().rstrip() + except (IOError, ValueError, EOFError, TypeError) as error: + logging.error(str(error)) + else: + hardware = "Unknown Device" + + return {"git": ra_git_version, "env": f"{hardware}, {os_version}" } @staticmethod def running_proc(daemon): @@ -114,15 +141,18 @@ class SysCmds: Will introspect file_path for the existance of re_term and return True if found, False if not found """ + result = False try: ifile = open(file_path, "r", encoding="ISO-8859-1") + for line in ifile: + if match(re_term, line): + result = True + break except (IOError, ValueError, EOFError, TypeError) as error: logging.error(str(error)) - return False - for line in ifile: - if match(re_term, line): - return True - return False + finally: + ifile.close() + return result # pylint: disable=broad-except @staticmethod diff --git a/python/web/src/templates/base.html b/python/web/src/templates/base.html index cce8a30a..09249238 100644 --- a/python/web/src/templates/base.html +++ b/python/web/src/templates/base.html @@ -129,7 +129,7 @@ {{ _("RaSCSI Reloaded version: ") }}{{ env["version"] }} {{ env["running_env"]["git"][:7] }}
- {{ _("Pi environment: ") }}{{ env["running_env"]["env"] }} + {{ _("Hardware and OS: ") }}{{ env["running_env"]["env"] }}
diff --git a/python/web/src/web.py b/python/web/src/web.py index e290a838..cc9dbf5c 100644 --- a/python/web/src/web.py +++ b/python/web/src/web.py @@ -361,6 +361,12 @@ def drive_create(): drive_name ) + if not properties: + return response( + error=True, + message=_("No properties data for drive %(drive_name)s", drive_name=drive_name), + ) + # Creating the image file process = file_cmd.create_new_image( file_name, @@ -398,6 +404,13 @@ def drive_cdrom(): APP.config["RASCSI_DRIVE_PROPERTIES"], drive_name ) + + if not properties: + return response( + error=True, + message=_("No properties data for drive %(drive_name)s", drive_name=drive_name), + ) + process = file_cmd.write_drive_properties(file_name, properties) process = ReturnCodeMapper.add_msg(process) if process["status"]: @@ -1007,21 +1020,22 @@ def create_file(): APP.config["RASCSI_DRIVE_PROPERTIES"], drive_name ) - prop_file_name = f"{full_file_name}.{PROPERTIES_SUFFIX}" - process = file_cmd.write_drive_properties(prop_file_name, properties) - process = ReturnCodeMapper.add_msg(process) - if not process["status"]: - return response(error=True, message=process["msg"]) + if properties: + prop_file_name = f"{full_file_name}.{PROPERTIES_SUFFIX}" + process = file_cmd.write_drive_properties(prop_file_name, properties) + process = ReturnCodeMapper.add_msg(process) + if not process["status"]: + return response(error=True, message=process["msg"]) - return response( - status_code=201, - message=_( - "Image file with properties created: %(file_name)s%(drive_format)s", - file_name=full_file_name, - drive_format=message_postfix, - ), - image=full_file_name, - ) + return response( + status_code=201, + message=_( + "Image file with properties created: %(file_name)s%(drive_format)s", + file_name=full_file_name, + drive_format=message_postfix, + ), + image=full_file_name, + ) return response( status_code=201, diff --git a/python/web/src/web_utils.py b/python/web/src/web_utils.py index 855ba331..a1db8b3a 100644 --- a/python/web/src/web_utils.py +++ b/python/web/src/web_utils.py @@ -189,19 +189,19 @@ def get_properties_by_drive_name(drives, drive_name): """ drives.sort(key=lambda item: item.get("name")) - drive_props = None for drive in drives: if drive["name"] == drive_name: - drive_props = drive + return { + "file_type": drive["file_type"], + "vendor": drive["vendor"], + "product": drive["product"], + "revision": drive["revision"], + "block_size": drive["block_size"], + "size": drive["size"], + } - return { - "file_type": drive_props["file_type"], - "vendor": drive_props["vendor"], - "product": drive_props["product"], - "revision": drive_props["revision"], - "block_size": drive_props["block_size"], - "size": drive_props["size"], - } + logging.error("Properties for drive '%s' does not exist in database", drive_name) + return False def auth_active(group): """