← Back to team overview

cloud-init-dev team mailing list archive

[Merge] ~smoser/cloud-init:bug/1701325-no-dmi-data-in-container into cloud-init:master

 

Scott Moser has proposed merging ~smoser/cloud-init:bug/1701325-no-dmi-data-in-container into cloud-init:master.

Commit message:
read_dmi_data: always return None when inside a container.

This fixes stacktrace and warning message that would be printed
to the log if running inside a container and read_dmi_data tried
to access a key that was not present.

In a container, the /sys/class/dmi/id data is not relevant to the
but to the host.  Additionally an unpriviledged container might see
strange behavior:
   # cd /sys/class/dmi/id/
   # id -u
   0
   # ls -l chassis_serial
   -r-------- 1 nobody nogroup 4096 Jun 29 16:49 chassis_serial
   # cat chassis_serial
   cat: /sys/class/dmi/id/chassis_serial: Permission denied

The solution here is to just always return None when running in a
container.

LP: #1701325



Requested reviews:
  cloud-init commiters (cloud-init-dev)
Related bugs:
  Bug #1701325 in cloud-init: "attempt to read dmi data can cause warning and stacktrace in logs in a container."
  https://bugs.launchpad.net/cloud-init/+bug/1701325

For more details, see:
https://code.launchpad.net/~smoser/cloud-init/+git/cloud-init/+merge/326546
-- 
Your team cloud-init commiters is requested to review the proposed merge of ~smoser/cloud-init:bug/1701325-no-dmi-data-in-container into cloud-init:master.
diff --git a/cloudinit/util.py b/cloudinit/util.py
index c93b6d7..b486e18 100644
--- a/cloudinit/util.py
+++ b/cloudinit/util.py
@@ -2397,6 +2397,10 @@ def read_dmi_data(key):
     """
     Wrapper for reading DMI data.
 
+    If running in a container return None.  This is because DMI data is
+    assumed to be not useful in a container as it does not represent the
+    container but rather the host.
+
     This will do the following (returning the first that produces a
     result):
         1) Use a mapping to translate `key` from dmidecode naming to
@@ -2407,6 +2411,9 @@ def read_dmi_data(key):
     If all of the above fail to find a value, None will be returned.
     """
 
+    if is_container():
+        return None
+
     syspath_value = _read_dmi_syspath(key)
     if syspath_value is not None:
         return syspath_value
diff --git a/tests/unittests/test_util.py b/tests/unittests/test_util.py
index a73fd26..4c59fcf 100644
--- a/tests/unittests/test_util.py
+++ b/tests/unittests/test_util.py
@@ -365,6 +365,10 @@ class TestReadDMIData(helpers.FilesystemMockingTestCase):
         self.addCleanup(shutil.rmtree, self.new_root)
         self.patchOS(self.new_root)
         self.patchUtils(self.new_root)
+        m = mock.patch("cloudinit.util.is_container", return_value=False)
+        m.start()
+        self.addCleanup(m.stop)
+        self._m_is_container = m
 
     def _create_sysfs_parent_directory(self):
         util.ensure_dir(os.path.join('sys', 'class', 'dmi', 'id'))
@@ -453,6 +457,13 @@ class TestReadDMIData(helpers.FilesystemMockingTestCase):
         self._create_sysfs_file(sysfs_key, dmi_value)
         self.assertEqual(expected, util.read_dmi_data(dmi_key))
 
+    def test_container_always_returns_none(self):
+        """In a container read_dmi_data should always return None."""
+        self._m_is_container.return_value = True
+        self.assertIsNone(util.read_dmi_data("system-product-name"))
+        self.assertIsNone(util.read_dmi_data("bogus"))
+
+
 
 class TestMultiLog(helpers.FilesystemMockingTestCase):