From f7230984f658c48b9a9af13e844a335c3736e904 Mon Sep 17 00:00:00 2001 From: Guillaume Abrioux Date: Wed, 1 Feb 2017 16:05:14 +0100 Subject: [PATCH] ceph-detect-init: Add docker detection if running `ceph-detect-init` from a container, the given output is the reference from the hosting system. This patch add the capability of detecting if the tool is being run inside a container. Signed-off-by: Guillaume Abrioux --- .../ceph_detect_init/__init__.py | 17 +++++++++ .../ceph_detect_init/docker/__init__.py | 3 ++ src/ceph-detect-init/tests/test_all.py | 37 +++++++++++++++++++ 3 files changed, 57 insertions(+) create mode 100644 src/ceph-detect-init/ceph_detect_init/docker/__init__.py diff --git a/src/ceph-detect-init/ceph_detect_init/__init__.py b/src/ceph-detect-init/ceph_detect_init/__init__.py index b431616cedfc..aad3eee5a77a 100644 --- a/src/ceph-detect-init/ceph_detect_init/__init__.py +++ b/src/ceph-detect-init/ceph_detect_init/__init__.py @@ -23,6 +23,8 @@ from ceph_detect_init import rhel from ceph_detect_init import suse from ceph_detect_init import gentoo from ceph_detect_init import freebsd +from ceph_detect_init import docker +import os import logging import platform @@ -69,6 +71,7 @@ def _get_distro(distro, use_rhceph=False): 'funtoo': gentoo, 'exherbo': gentoo, 'freebsd': freebsd, + 'docker': docker, } if distro == 'redhat' and use_rhceph: @@ -94,6 +97,20 @@ def _normalized_distro_name(distro): def platform_information(): """detect platform information from remote host.""" + try: + file_name = '/proc/self/cgroup' + with open(file_name, 'r') as f: + lines = f.readlines() + for line in lines: + if "docker" in line.split(':')[2]: + return ('docker', 'docker', 'docker') + except Exception as err: + logging.debug("platform_information: ", + "Error while opening %s : %s" % (file_name, err)) + + if os.path.isfile('/.dockerenv'): + return ('docker', 'docker', 'docker') + if platform.system() == 'Linux': linux_distro = platform.linux_distribution( supported_dists=platform._supported_dists + ('alpine', 'arch')) diff --git a/src/ceph-detect-init/ceph_detect_init/docker/__init__.py b/src/ceph-detect-init/ceph_detect_init/docker/__init__.py new file mode 100644 index 000000000000..30e838eeb83b --- /dev/null +++ b/src/ceph-detect-init/ceph_detect_init/docker/__init__.py @@ -0,0 +1,3 @@ +def choose_init(): + """Returns 'none' because we are running in a container""" + return 'none' diff --git a/src/ceph-detect-init/tests/test_all.py b/src/ceph-detect-init/tests/test_all.py index a81ec980843a..d2733c32957c 100644 --- a/src/ceph-detect-init/tests/test_all.py +++ b/src/ceph-detect-init/tests/test_all.py @@ -34,6 +34,7 @@ from ceph_detect_init import rhel from ceph_detect_init import suse from ceph_detect_init import gentoo from ceph_detect_init import freebsd +from ceph_detect_init import docker logging.basicConfig(format='%(asctime)s %(levelname)s %(message)s', level=logging.DEBUG) @@ -50,6 +51,9 @@ class TestCephDetectInit(testtools.TestCase): def test_freebsd(self): self.assertEqual('bsdrc', freebsd.choose_init()) + def test_docker(self): + self.assertEqual('none', docker.choose_init()) + def test_centos(self): with mock.patch('ceph_detect_init.centos.release', '7.0'): @@ -262,6 +266,39 @@ class TestCephDetectInit(testtools.TestCase): self.assertEqual(('debian', 'sid/jessie', 'sid'), ceph_detect_init.platform_information()) + @mock.patch('platform.linux_distribution') + def test_platform_information_container(self, mock_linux_dist): + import sys + if sys.version_info >= (3, 0): + mocked_fn = 'builtins.open' + else: + mocked_fn = '__builtin__.open' + + with mock.patch(mocked_fn, + mock.mock_open(read_data="""1:name=systemd:/system.slice \ + /docker-39cc1fb.scope"""), + create=True) as m: + self.assertEqual(('docker', + 'docker', + 'docker'), + ceph_detect_init.platform_information(),) + m.assert_called_once_with('/proc/self/cgroup', 'r') + + with mock.patch(mocked_fn, mock.mock_open(), create=True) as m: + m.side_effect = IOError() + mock_linux_dist.return_value = ('Red Hat Enterprise Linux Server', + '7.3', 'Maipo') + # Just run the code to validate the code won't raise IOError + ceph_detect_init.platform_information() + + with mock.patch('os.path.isfile', mock.MagicMock()) as m: + m.return_value = True + self.assertEqual(('docker', + 'docker', + 'docker'), + ceph_detect_init.platform_information(),) + m.assert_called_once_with('/.dockerenv') + @mock.patch('platform.system', lambda: 'FreeBSD') def test_platform_information_freebsd(self): with mock.patch.multiple('platform', -- 2.47.3