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:
parent
c8e59f5d97
commit
669235b8ab
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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).
|
Loading…
Reference in New Issue