Skip to content

Commit

Permalink
ds-identify: fake dmidecode support on OpenBSD (#4654)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
igalic committed Dec 9, 2023
1 parent f244632 commit f380cda
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 17 deletions.
34 changes: 22 additions & 12 deletions tests/unittests/test_ds_identify.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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"""
Expand All @@ -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
Expand Down Expand Up @@ -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"}],
Expand Down Expand Up @@ -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": ""},
],
Expand Down
31 changes: 26 additions & 5 deletions tools/ds-identify
Original file line number Diff line number Diff line change
Expand Up @@ -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 || {
Expand All @@ -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"
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit f380cda

Please sign in to comment.