RBD: Fix containerized detection

Our detection mechanism of when we are running containerized has false
positives, so we are not also checking /proc/1/mounts to see if the root
directory is mounted from /var/lib/, which is the case when running
containerized.

Change-Id: Icad0340a9f805b59a5cddd7526a1efbb24ab652e
Closes-Bug: #1885302
This commit is contained in:
Gorka Eguileor 2020-06-26 18:03:11 +02:00
parent c8e59f5d97
commit 669235b8ab
3 changed files with 72 additions and 1 deletions

View File

@ -183,6 +183,23 @@ class RBDConnector(connectors.rbd.RBDConnector):
else:
self._execute('mkdir', '-p', '-m0755', path, run_as_root=True)
@staticmethod
def _in_container():
if os.stat('/proc').st_dev <= 4:
return False
# When running containerized / is /var/lib/docker when running in
# Docker /var/lib/containers when running in Podman, and /var/lib/lxc
# when in LXC
with open('/proc/1/mounts', 'r') as f:
for line in f.readlines():
data = line.split(' ', 2)
if data[1] == '/':
return '/var/lib/' in data[2]
# Just in case, say we are
LOG.warning("Couldn't detect if running on container, assuming we are")
return True
def _setup_class(self):
try:
self._execute('which', 'rbd')
@ -192,7 +209,7 @@ class RBDConnector(connectors.rbd.RBDConnector):
RBDConnector.im_root = os.getuid() == 0
# Check if we are running containerized
RBDConnector.containerized = os.stat('/proc').st_dev > 4
RBDConnector.containerized = self._in_container()
# Don't check again to speed things on following connections
RBDConnector._setup_rbd_class = lambda *args: None

View File

@ -31,6 +31,54 @@ class TestRBDConnector(base.BaseTest):
self.connector.containerized = False
self.connector._setup_rbd_class = lambda *args: None
@mock.patch.object(nos_brick, 'open')
@mock.patch('os.stat')
def test__in_container_stat(self, mock_stat, mock_open):
mock_stat.return_value.st_dev = 4
res = self.connector._in_container()
self.assertFalse(res)
mock_stat.assert_called_once_with('/proc')
mock_open.assert_not_called()
@mock.patch.object(nos_brick, 'open')
@mock.patch('os.stat')
def test__in_container_mounts_no_container(self, mock_stat, mock_open):
mock_stat.return_value.st_dev = 5
mock_read = mock_open.return_value.__enter__.return_value.readlines
mock_read.return_value = [
'sysfs /sys sysfs rw,seclabel,nosuid,nodev,noexec,relatime 0 0',
'proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0',
'/dev/mapper/fedora_think2-root / ext4 rw,seclabel,relatime 0 0',
'selinuxfs /sys/fs/selinux selinuxfs rw,relatime 0 0',
]
res = self.connector._in_container()
self.assertFalse(res)
mock_stat.assert_called_once_with('/proc')
mock_open.assert_called_once_with('/proc/1/mounts', 'r')
mock_read.assert_called_once_with()
@mock.patch.object(nos_brick.LOG, 'warning')
@mock.patch.object(nos_brick, 'open')
@mock.patch('os.stat')
def test__in_container_mounts_in_container(self, mock_stat, mock_open,
mock_warning):
mock_stat.return_value.st_dev = 5
mock_read = mock_open.return_value.__enter__.return_value.readlines
mock_read.return_value = [
'sysfs /sys sysfs rw,seclabel,nosuid,nodev,noexec,relatime 0 0',
'proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0',
'overlay / overlay rw,lowerdir=/var/lib/containers/...',
'selinuxfs /sys/fs/selinux selinuxfs rw,relatime 0 0',
]
res = self.connector._in_container()
self.assertTrue(res)
mock_stat.assert_called_once_with('/proc')
mock_open.assert_called_once_with('/proc/1/mounts', 'r')
mock_read.assert_called_once_with()
mock_warning.assert_not_called()
@mock.patch.object(nos_brick.RBDConnector, '_get_rbd_args')
@mock.patch.object(nos_brick.RBDConnector, '_execute')
@mock.patch('os.path.exists', return_value=True)

View File

@ -0,0 +1,6 @@
---
fixes:
- |
Fix cases where our detection of when we are running containerized is not
very reliable for the RBD driver.
(Bug #1885302).