Fix Xen DomU detection in grains

Current code has two issues:
 - Parses dmesg for "xen:" messages. This will only work when initial kernel
   messages are still available via dmesg. After some uptime other messages
   (e.g. OOM) will have evicted the initial boot messages from the ringbuffer.
   This leads to the weird situation that a grain changes depending on uptime.
 - Checks if /sys/bus/xen/drivers/xenconsole is a file to verify it's running
   under Xen. Unfortunately, this path is not a file but a directory.

This change swaps the order, first check for xenconsole being a directory, then
run dmesg as a fallback.

Unit tests are updated correctly to cover this case.
Drive-By: Correct docstring for xen tests. These have nothing to do with Ubuntu
          Xenial
Drive-By: Fix indentation error in tests
This commit is contained in:
Andreas Thienemann 2020-11-22 11:01:50 +01:00 committed by Gareth J. Greenaway
parent 7fb811d771
commit e58d28285c
3 changed files with 16 additions and 10 deletions

1
changelog/59001.fixed Normal file
View file

@ -0,0 +1 @@
Fix Xen DomU virt detection in grains for long running machines.

View file

@ -1019,11 +1019,12 @@ def _virtual(osdata):
# Tested on Fedora 10 / 2.6.27.30-170.2.82 with xen
# Tested on Fedora 15 / 2.6.41.4-1 without running xen
elif isdir("/sys/bus/xen"):
if "xen:" in __salt__["cmd.run"]("dmesg").lower():
grains["virtual_subtype"] = "Xen PV DomU"
elif os.path.isfile("/sys/bus/xen/drivers/xenconsole"):
if os.path.isdir("/sys/bus/xen/drivers/xenconsole"):
# An actual DomU will have the xenconsole driver
grains["virtual_subtype"] = "Xen PV DomU"
elif "xen:" in __salt__["cmd.run"]("dmesg").lower():
# Fallback to parsing dmesg, might not be successful
grains["virtual_subtype"] = "Xen PV DomU"
# If a Dom0 or DomU was detected, obviously this is xen
if "dom" in grains.get("virtual_subtype", "").lower():
grains["virtual"] = "xen"

View file

@ -1235,16 +1235,20 @@ class CoreGrainsTestCase(TestCase, LoaderModuleMockMixin):
@skipIf(not salt.utils.platform.is_linux(), "System is not Linux")
def test_xen_virtual(self):
"""
Test if OS grains are parsed correctly in Ubuntu Xenial Xerus
Test if OS grains are parsed correctly for Xen hypervisors
"""
with patch.multiple(
os.path,
isdir=MagicMock(side_effect=lambda x: x == "/sys/bus/xen"),
isfile=MagicMock(
side_effect=lambda x: x == "/sys/bus/xen/drivers/xenconsole"
isdir=MagicMock(
side_effect=lambda x: x
in ["/sys/bus/xen", "/sys/bus/xen/drivers/xenconsole"]
),
):
with patch.dict(core.__salt__, {"cmd.run": MagicMock(return_value="")}):
with patch.dict(
core.__salt__, {"cmd.run": MagicMock(return_value="")}
), patch.dict(
core.__salt__, {"cmd.run_all": MagicMock(return_value={"retcode": 0})}
):
log.debug("Testing Xen")
self.assertEqual(
core._virtual({"kernel": "Linux"}).get("virtual_subtype"),
@ -1466,8 +1470,8 @@ class CoreGrainsTestCase(TestCase, LoaderModuleMockMixin):
def _check_type(key, value, ip4_empty, ip6_empty):
"""
check type and other checks
"""
check type and other checks
"""
assert isinstance(value, list)
if "4" in key: