From f380cda9d55121994a6631543446975668c49a51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mina=20Gali=C4=87?= Date: Fri, 1 Dec 2023 22:46:40 +0000 Subject: [PATCH] ds-identify: fake dmidecode support on OpenBSD (#4654) use sysctl's hw hierarchy, because it contains pretty much all we use from dmidecode. Unlike dmidecode, we don't need to set `kern.allowkmem=1` for this to work. Extend tests to cover uname & sysctl DMI changes. Sponsored by: The FreeBSD Foundation --- tests/unittests/test_ds_identify.py | 34 +++++++++++++++++++---------- tools/ds-identify | 31 +++++++++++++++++++++----- 2 files changed, 48 insertions(+), 17 deletions(-) diff --git a/tests/unittests/test_ds_identify.py b/tests/unittests/test_ds_identify.py index ca206fb5a77..a871943cbb3 100644 --- a/tests/unittests/test_ds_identify.py +++ b/tests/unittests/test_ds_identify.py @@ -19,17 +19,17 @@ ) UNAME_MYSYS = ( - "Linux bart 4.4.0-62-generic #83-Ubuntu " - "SMP Wed Jan 18 14:10:15 UTC 2017 x86_64 GNU/Linux" + "Linux 4.4.0-62-generic #83-Ubuntu SMP Wed Jan 18 14:10:15 UTC 2017 x86_64" ) UNAME_PPC64EL = ( - "Linux diamond 4.4.0-83-generic #106-Ubuntu SMP " + "Linux 4.4.0-83-generic #106-Ubuntu SMP " "Mon Jun 26 17:53:54 UTC 2017 " - "ppc64le ppc64le ppc64le GNU/Linux" + "ppc64le ppc64le ppc64le" ) UNAME_FREEBSD = ( - "FreeBSD fbsd12-1 12.1-RELEASE-p10 FreeBSD 12.1-RELEASE-p10 GENERIC amd64" + "FreeBSD 12.1-RELEASE-p10 FreeBSD 12.1-RELEASE-p10 GENERIC amd64" ) +UNAME_OPENBSD = "OpenBSD GENERIC.MP#1397 amd64" BLKID_EFI_ROOT = """ DEVNAME=/dev/sda1 @@ -246,6 +246,7 @@ MOCK_VIRT_IS_XEN = {"name": "detect_virt", "RET": "xen", "ret": 0} MOCK_UNAME_IS_PPC64 = {"name": "uname", "out": UNAME_PPC64EL, "ret": 0} MOCK_UNAME_IS_FREEBSD = {"name": "uname", "out": UNAME_FREEBSD, "ret": 0} +MOCK_UNAME_IS_OPENBSD = {"name": "uname", "out": UNAME_OPENBSD, "ret": 0} shell_true = 0 shell_false = 1 @@ -434,11 +435,8 @@ def test_wb_print_variables(self): "KERNEL_CMDLINE", "VIRT", "UNAME_KERNEL_NAME", - "UNAME_KERNEL_RELEASE", "UNAME_KERNEL_VERSION", "UNAME_MACHINE", - "UNAME_NODENAME", - "UNAME_OPERATING_SYSTEM", "DSNAME", "DSLIST", "MODE", @@ -1062,6 +1060,7 @@ class TestBSDNoSys(DsIdentifyBase): """Test *BSD code paths FreeBSD doesn't have /sys so we use kenv(1) here. + OpenBSD uses sysctl(8). Other BSD systems fallback to dmidecode(8). BSDs also doesn't have systemd-detect-virt(8), so we use sysctl(8) to query kern.vm_guest, and optionally map it""" @@ -1073,6 +1072,13 @@ def test_dmi_kenv(self): """ self._test_ds_found("Hetzner-kenv") + def test_dmi_sysctl(self): + """Test that sysctl(8) works on systems which don't have /sys + + This will be used on OpenBSD systems. + """ + self._test_ds_found("Hetzner-sysctl") + def test_dmi_dmidecode(self): """Test that dmidecode(8) works on systems which don't have /sys @@ -1616,6 +1622,13 @@ def _print_run_output(rc, out, err, cfg, files): {"name": "get_kenv_field", "ret": 0, "RET": "Hetzner"}, ], }, + "Hetzner-sysctl": { + "ds": "Hetzner", + "mocks": [ + MOCK_UNAME_IS_OPENBSD, + {"name": "get_sysctl_field", "ret": 0, "RET": "Hetzner"}, + ], + }, "Hetzner-dmidecode": { "ds": "Hetzner", "mocks": [{"name": "dmi_decode", "ret": 0, "RET": "Hetzner"}], @@ -1766,10 +1779,7 @@ def _print_run_output(rc, out, err, cfg, files): { "name": "uname", "ret": 0, - "out": ( - "Linux d43da87a-daca-60e8-e6d4-d2ed372662a3 4.3.0 " - "BrandZ virtual linux x86_64 GNU/Linux" - ), + "out": ("Linux BrandZ virtual linux x86_64"), }, {"name": "blkid", "ret": 2, "out": ""}, ], diff --git a/tools/ds-identify b/tools/ds-identify index 97aa9511bc0..7a051935378 100755 --- a/tools/ds-identify +++ b/tools/ds-identify @@ -210,6 +210,27 @@ get_kenv_field() { _RET="$val" } +get_sysctl_field() { + local sys_field="$1" sysctl_field="" val="" + command -v sysctl >/dev/null 2>&1 || { + warn "No sysctl program. Cannot read $sys_field." + return 1 + } + case "$sys_field" in + chassis_vendor) sysctl_field='hw.vendor';; + chassis_serial) sysctl_field='hw.type';; + chassis_version) sysctl_field='hw.uuid';; + sys_vendor) sysctl_field='hw.vendor';; + product_name) sysctl_field='hw.product';; + product_serial) sysctl_field='hw.uuid';; + product_uuid) sysctl_field='hw.uuid';; + *) error "Unknown field $sys_field. Cannot call sysctl." + return 1;; + esac + val=$(sysctl -nq "$sysctl_field" 2>/dev/null) || return 1 + _RET="$val" +} + dmi_decode() { local sys_field="$1" dmi_field="" val="" command -v dmidecode >/dev/null 2>&1 || { @@ -235,6 +256,9 @@ get_dmi_field() { if [ "$DI_UNAME_KERNEL_NAME" = "FreeBSD" -o "$DI_UNAME_KERNEL_NAME" = "Dragonfly" ]; then get_kenv_field "$1" || _RET="$ERROR" return $? + elif [ "$DI_UNAME_KERNEL_NAME" = "OpenBSD" ]; then + get_sysctl_field "$1" || _RET="$ERROR" + return $? fi local path="${PATH_SYS_CLASS_DMI_ID}/$1" @@ -521,11 +545,8 @@ read_uname_info() { # uname is tricky to parse as it outputs always in a given order # independent of option order. kernel-version is known to have spaces. # 1 -s kernel-name - # 2 -n nodename - # 3 -r kernel-release - # 4.. -v kernel-version(whitespace) - # N-2 -m machine - # N-1 -o operating-system + # 2.. -v kernel-version(whitespace) + # N-1 -m machine cached "${DI_UNAME_CMD_OUT}" && return local out="${1:-}" ret=0 buf="" if [ -z "$out" ]; then