From bc613ad4089a3c67a93bdbf420255a1b7fe6fe22 Mon Sep 17 00:00:00 2001 From: Pritam Ghanghas Date: Mon, 6 Mar 2023 18:41:53 +0530 Subject: [PATCH] fix: Use proc/cpuinfo for hardware serial #496 --- hw_diag/utilities/balena_migration.py | 8 +------ hw_diag/utilities/hardware.py | 30 +++++++++++++++++++++++++-- hw_diag/utilities/system_metrics.py | 17 ++++++++++----- 3 files changed, 41 insertions(+), 14 deletions(-) diff --git a/hw_diag/utilities/balena_migration.py b/hw_diag/utilities/balena_migration.py index b97da565..fb99c8b6 100644 --- a/hw_diag/utilities/balena_migration.py +++ b/hw_diag/utilities/balena_migration.py @@ -3,7 +3,7 @@ import subprocess import requests from hw_diag.utilities.osutils import balena_boot_partition -from hw_diag.utilities.hardware import get_serial_number +from hw_diag.utilities.hardware import fetch_serial_number from hw_diag.utilities.balena_supervisor import BalenaSupervisor from hm_pyhelper.logger import get_logger from typing import Dict, Union @@ -101,12 +101,6 @@ def update_config(old_config) -> Union[Dict, None]: return new_config -def fetch_serial_number() -> Union[str, None]: - diag = {} - get_serial_number(diag) - return diag.get("serial_number") - - def read_config() -> Dict: # read only mount would have been great but that isn't # possible as the fs is mounted in host os as rw. diff --git a/hw_diag/utilities/hardware.py b/hw_diag/utilities/hardware.py index 31ba9792..300bcbcd 100644 --- a/hw_diag/utilities/hardware.py +++ b/hw_diag/utilities/hardware.py @@ -1,6 +1,7 @@ import re import dbus import psutil +from typing import Union from urllib.parse import urlparse from hm_pyhelper.logger import get_logger from hm_pyhelper.miner_param import get_public_keys_rust @@ -240,6 +241,12 @@ def detect_ecc(diagnostics): logging.error(e) +def fetch_serial_number() -> Union[str, None]: + diag = {} + get_serial_number(diag) + return diag.get("serial_number") + + def get_serial_number(diagnostics): """ input: @@ -251,8 +258,13 @@ def get_serial_number(diagnostics): Writes the received value to the dictionary """ try: - serial_number = open("/proc/device-tree/serial-number").readline() \ - .rstrip('\x00') + cpuinfo = load_cpu_info() + serial_number = "" + if "serial" in cpuinfo: + serial_number = cpuinfo["serial"] + else: + serial_number = open("/proc/device-tree/serial-number").readline() \ + .rstrip('\x00') except FileNotFoundError as e: raise e except PermissionError as e: @@ -261,6 +273,20 @@ def get_serial_number(diagnostics): diagnostics["serial_number"] = serial_number +def load_cpu_info() -> dict: + ''' + returns /proc/cpuinfo as dict, keys are case-insensitive + ''' + with open("/proc/cpuinfo", "r") as f: + cpuinfo = {} + lines = f.readlines() + for line in lines: + pair = line.split(":") + if len(pair) == 2: + cpuinfo[pair[0].strip().lower()] = pair[1].strip() + return cpuinfo + + @retry(Exception, tries=5, delay=5, max_delay=15, backoff=2, logger=logging) def lora_module_test(): """ diff --git a/hw_diag/utilities/system_metrics.py b/hw_diag/utilities/system_metrics.py index 5c802b86..f37785ed 100644 --- a/hw_diag/utilities/system_metrics.py +++ b/hw_diag/utilities/system_metrics.py @@ -1,6 +1,7 @@ from typing import Dict, Any import logging import os +from hw_diag.utilities.hardware import fetch_serial_number from hw_diag.utilities.balena_supervisor import BalenaSupervisor @@ -48,11 +49,17 @@ def read_proc_file(file_path: str, default_value: str) -> Any: def get_serial_number() -> str: + ''' + returns a valid serial number or empty string if none can + be determined. No exceptions. + ''' try: - with open("/proc/device-tree/serial-number", 'r') as f: - return f.readline().rstrip('\x00') + serial_number = fetch_serial_number() + if not serial_number: + serial_number = "" + return serial_number except Exception as e: - log.warning(f"can't read serial number {e}") + log.error(f"failed to get serial number {e}") return "" @@ -74,10 +81,10 @@ def get_network_statistics(interface_list=['wlan0', 'eth0']) -> Dict: stats[iface_name] = { "rx_errors": int( read_proc_file(f"/sys/class/net/{iface_name}/statistics/rx_errors", "0") - ), + ), "tx_errors": int( read_proc_file(f"/sys/class/net/{iface_name}/statistics/tx_errors", "0") - ) + ) } return stats