diff --git a/Lib/test/pythoninfo.py b/Lib/test/pythoninfo.py index 77204f5aa0ae38..c9e81660758313 100644 --- a/Lib/test/pythoninfo.py +++ b/Lib/test/pythoninfo.py @@ -16,6 +16,15 @@ def normalize_text(text): return text.strip() +def read_first_line(filename): + # Get the first line of a text file and strip trailing spaces + try: + with open(filename, encoding="utf-8") as fp: + return fp.readline().rstrip() + except OSError: + return '' + + class PythonInfo: def __init__(self): self.info = {} @@ -994,14 +1003,9 @@ def collect_fips(info_add): if _hashlib is not None: call_func(info_add, 'fips.openssl_fips_mode', _hashlib, 'get_fips_mode') - try: - with open("/proc/sys/crypto/fips_enabled", encoding="utf-8") as fp: - line = fp.readline().rstrip() - - if line: - info_add('fips.linux_crypto_fips_enabled', line) - except OSError: - pass + fips_enabled = read_first_line("/proc/sys/crypto/fips_enabled") + if fips_enabled: + info_add('fips.linux_crypto_fips_enabled', fips_enabled) def collect_tempfile(info_add): @@ -1019,6 +1023,49 @@ def collect_libregrtest_utils(info_add): info_add('libregrtests.build_info', ' '.join(utils.get_build_info())) +def linux_get_uptime(): + # Use CLOCK_BOOTTIME if available + import time + try: + return time.clock_gettime(time.CLOCK_BOOTTIME) + except (AttributeError, OSError): + pass + + # Otherwise, parse the first member of /proc/uptime + uptime = read_first_line("/proc/uptime") + if not uptime: + return + try: + parts = uptime.split() + if not parts: + return + return float(parts[0]) + except ValueError: + return + + +def collect_linux(info_add): + boot_id = read_first_line("/proc/sys/kernel/random/boot_id") + if boot_id: + info_add('linux.boot_id', boot_id) + + # https://www.freedesktop.org/software/systemd/man/latest/machine-id.html + machine_id = read_first_line("/etc/machine-id") + if machine_id: + info_add('linux.machine_id', machine_id) + + uptime = linux_get_uptime() + if uptime is not None: + # truncate microseconds + uptime = int(uptime) + try: + import datetime + uptime = str(datetime.timedelta(seconds=uptime)) + except ImportError: + uptime = f'{uptime} sec' + info_add('linux.uptime', uptime) + + def collect_info(info): error = False info_add = info.add @@ -1059,6 +1106,7 @@ def collect_info(info): collect_windows, collect_zlib, collect_libregrtest_utils, + collect_linux, # Collecting from tests should be last as they have side effects. collect_test_socket,