Skip to content

Commit

Permalink
feat(ds-identify): Don't run unnecessary systemd-detect-virt
Browse files Browse the repository at this point in the history
Running systemd-detect-virt is expensive and, on systemd >=251, unnecessary.

The environment variable SYSTEMD_VIRTUALIZATION contains the virtualization
type that we currently manually get from systemd-detect-virt.

Update tests to exercise this code path.

https://www.freedesktop.org/software/systemd/man/latest/systemd.generator.html#Environment
  • Loading branch information
holmanb committed Mar 5, 2024
1 parent 2ba7fdf commit c44d938
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 12 deletions.
34 changes: 26 additions & 8 deletions tests/unittests/test_ds_identify.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,19 +96,19 @@

MOCK_VIRT_IS_CONTAINER_OTHER = {
"name": "detect_virt",
"RET": "container-other",
"RET": "container:container-other",
"ret": 0,
}
MOCK_NOT_LXD_DATASOURCE = {"name": "dscheck_LXD", "ret": 1}
MOCK_VIRT_IS_KVM = {"name": "detect_virt", "RET": "kvm", "ret": 0}
MOCK_VIRT_IS_KVM = {"name": "detect_virt", "RET": "vm:kvm", "ret": 0}
# qemu support for LXD is only for host systems > 5.10 kernel as lxd
# passed `hv_passthrough` which causes systemd < v.251 to misinterpret CPU
# as "qemu" instead of "kvm"
MOCK_VIRT_IS_KVM_QEMU = {"name": "detect_virt", "RET": "qemu", "ret": 0}
MOCK_VIRT_IS_VMWARE = {"name": "detect_virt", "RET": "vmware", "ret": 0}
MOCK_VIRT_IS_KVM_QEMU = {"name": "detect_virt", "RET": "vm:qemu", "ret": 0}
MOCK_VIRT_IS_VMWARE = {"name": "detect_virt", "RET": "vm:vmware", "ret": 0}
# currenty' SmartOS hypervisor "bhyve" is unknown by systemd-detect-virt.
MOCK_VIRT_IS_VM_OTHER = {"name": "detect_virt", "RET": "vm-other", "ret": 0}
MOCK_VIRT_IS_XEN = {"name": "detect_virt", "RET": "xen", "ret": 0}
MOCK_VIRT_IS_VM_OTHER = {"name": "detect_virt", "RET": "vm:vm-other", "ret": 0}
MOCK_VIRT_IS_XEN = {"name": "detect_virt", "RET": "vm:xen", "ret": 0}
MOCK_VIRT_IS_WSL = {"name": "detect_virt", "RET": "wsl", "ret": 0}
MOCK_UNAME_IS_PPC64 = {"name": "uname", "out": UNAME_PPC64EL, "ret": 0}
MOCK_UNAME_IS_FREEBSD = {"name": "uname", "out": UNAME_FREEBSD, "ret": 0}
Expand Down Expand Up @@ -189,6 +189,15 @@ def call(

def write_mock(data):
ddata = {"out": None, "err": None, "ret": 0, "RET": None}

# Don't mock when SYSTEMD_VIRTUALIZATION would be set to a value.
# When no virtualization is detected, the call path would currently
# fall back to calling systemd-detect-virt, which we currently mock
# out at the function call to `detect_virt()`. Continue mocking
# that code path. One day when systemd 250 is no longer supported
# we can simplify this code and not mock `detect_virt()` at all.
if "detect_virt" == data["name"] and "none" != data["RET"]:
return ""
ddata.update(data)
for k in ddata.keys():
if ddata[k] is None:
Expand Down Expand Up @@ -246,9 +255,18 @@ def write_mock(data):
with open(wrap, "w") as fp:
fp.write("\n".join(head + mocklines + endlines) + "\n")

detect_virt = None
for mock in [*mocks, *default_mocks]:
if "detect_virt" == mock["name"]:
detect_virt = mock["RET"]
break
rc = 0
try:
out, err = subp.subp(["sh", "-c", ". %s" % wrap], capture=True)
out, err = subp.subp(
["sh", "-c", ". %s" % wrap],
update_env={"SYSTEMD_VIRTUALIZATION": detect_virt},
capture=True,
)
except subp.ProcessExecutionError as e:
rc = e.exit_code
out = e.stdout
Expand Down Expand Up @@ -1270,7 +1288,7 @@ def _print_run_output(rc, out, err, cfg, files):
},
"Ec2-hvm": {
"ds": "Ec2",
"mocks": [{"name": "detect_virt", "RET": "kvm", "ret": 0}],
"mocks": [{"name": "detect_virt", "RET": "vm:kvm", "ret": 0}],
"files": {
P_PRODUCT_SERIAL: "ec23aef5-54be-4843-8d24-8c819f88453e\n",
P_PRODUCT_UUID: "EC23AEF5-54BE-4843-8D24-8C819F88453E\n",
Expand Down
13 changes: 9 additions & 4 deletions tools/ds-identify
Original file line number Diff line number Diff line change
Expand Up @@ -437,10 +437,15 @@ cached() {
detect_virt() {
local virt="${UNAVAILABLE}" r="" out=""
if [ -d /run/systemd ]; then
out=$(systemd-detect-virt 2>&1)
r=$?
if [ $r -eq 0 ] || { [ $r -ne 0 ] && [ "$out" = "none" ]; }; then
virt="$out"
if [ -n "$SYSTEMD_VIRTUALIZATION" ]; then
virt=${SYSTEMD_VIRTUALIZATION#*:}
else
# required for compatibility with systemd version <251
out=$(systemd-detect-virt 2>&1)
r=$?
if [ $r -eq 0 ] || { [ $r -ne 0 ] && [ "$out" = "none" ]; }; then
virt="$out"
fi
fi
elif command -v virt-what >/dev/null 2>&1; then
# Map virt-what's names to those systemd-detect-virt that
Expand Down

0 comments on commit c44d938

Please sign in to comment.