diff options
| -rw-r--r-- | cloudinit/tests/test_util.py | 78 | ||||
| -rw-r--r-- | cloudinit/util.py | 39 | ||||
| -rwxr-xr-x | setup.py | 17 | 
3 files changed, 127 insertions, 7 deletions
| diff --git a/cloudinit/tests/test_util.py b/cloudinit/tests/test_util.py index 3c05a437..17853fc7 100644 --- a/cloudinit/tests/test_util.py +++ b/cloudinit/tests/test_util.py @@ -3,11 +3,12 @@  """Tests for cloudinit.util"""  import logging -from textwrap import dedent +import platform  import cloudinit.util as util  from cloudinit.tests.helpers import CiTestCase, mock +from textwrap import dedent  LOG = logging.getLogger(__name__) @@ -16,6 +17,29 @@ MOUNT_INFO = [      '153 68 254:0 / /home rw,relatime shared:101 - xfs /dev/sda2 rw,attr2'  ] +OS_RELEASE_SLES = dedent("""\ +    NAME="SLES"\n +    VERSION="12-SP3"\n +    VERSION_ID="12.3"\n +    PRETTY_NAME="SUSE Linux Enterprise Server 12 SP3"\n +    ID="sles"\nANSI_COLOR="0;32"\n +    CPE_NAME="cpe:/o:suse:sles:12:sp3"\n +""") + +OS_RELEASE_UBUNTU = dedent("""\ +    NAME="Ubuntu"\n +    VERSION="16.04.3 LTS (Xenial Xerus)"\n +    ID=ubuntu\n +    ID_LIKE=debian\n +    PRETTY_NAME="Ubuntu 16.04.3 LTS"\n +    VERSION_ID="16.04"\n +    HOME_URL="http://www.ubuntu.com/"\n +    SUPPORT_URL="http://help.ubuntu.com/"\n +    BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"\n +    VERSION_CODENAME=xenial\n +    UBUNTU_CODENAME=xenial\n +""") +  class FakeCloud(object): @@ -261,4 +285,56 @@ class TestUdevadmSettle(CiTestCase):          self.assertRaises(util.ProcessExecutionError, util.udevadm_settle) +@mock.patch('os.path.exists') +class TestGetLinuxDistro(CiTestCase): + +    @classmethod +    def os_release_exists(self, path): +        """Side effect function""" +        if path == '/etc/os-release': +            return 1 + +    @mock.patch('cloudinit.util.load_file') +    def test_get_linux_distro_quoted_name(self, m_os_release, m_path_exists): +        """Verify we get the correct name if the os-release file has +        the distro name in quotes""" +        m_os_release.return_value = OS_RELEASE_SLES +        m_path_exists.side_effect = TestGetLinuxDistro.os_release_exists +        dist = util.get_linux_distro() +        self.assertEqual(('sles', '12.3', platform.machine()), dist) + +    @mock.patch('cloudinit.util.load_file') +    def test_get_linux_distro_bare_name(self, m_os_release, m_path_exists): +        """Verify we get the correct name if the os-release file does not +        have the distro name in quotes""" +        m_os_release.return_value = OS_RELEASE_UBUNTU +        m_path_exists.side_effect = TestGetLinuxDistro.os_release_exists +        dist = util.get_linux_distro() +        self.assertEqual(('ubuntu', '16.04', platform.machine()), dist) + +    @mock.patch('platform.dist') +    def test_get_linux_distro_no_data(self, m_platform_dist, m_path_exists): +        """Verify we get no information if os-release does not exist""" +        m_platform_dist.return_value = ('', '', '') +        m_path_exists.return_value = 0 +        dist = util.get_linux_distro() +        self.assertEqual(('', '', ''), dist) + +    @mock.patch('platform.dist') +    def test_get_linux_distro_no_impl(self, m_platform_dist, m_path_exists): +        """Verify we get an empty tuple when no information exists and +        Exceptions are not propagated""" +        m_platform_dist.side_effect = Exception() +        m_path_exists.return_value = 0 +        dist = util.get_linux_distro() +        self.assertEqual(('', '', ''), dist) + +    @mock.patch('platform.dist') +    def test_get_linux_distro_plat_data(self, m_platform_dist, m_path_exists): +        """Verify we get the correct platform information""" +        m_platform_dist.return_value = ('foo', '1.1', 'aarch64') +        m_path_exists.return_value = 0 +        dist = util.get_linux_distro() +        self.assertEqual(('foo', '1.1', 'aarch64'), dist) +  # vi: ts=4 expandtab diff --git a/cloudinit/util.py b/cloudinit/util.py index 6ea6ca76..d9b61cfe 100644 --- a/cloudinit/util.py +++ b/cloudinit/util.py @@ -576,6 +576,39 @@ def get_cfg_option_int(yobj, key, default=0):      return int(get_cfg_option_str(yobj, key, default=default)) +def get_linux_distro(): +    distro_name = '' +    distro_version = '' +    if os.path.exists('/etc/os-release'): +        os_release = load_file('/etc/os-release') +        for line in os_release.splitlines(): +            if line.strip().startswith('ID='): +                distro_name = line.split('=')[-1] +                distro_name = distro_name.replace('"', '') +            if line.strip().startswith('VERSION_ID='): +                # Lets hope for the best that distros stay consistent ;) +                distro_version = line.split('=')[-1] +                distro_version = distro_version.replace('"', '') +    else: +        dist = ('', '', '') +        try: +            # Will be removed in 3.7 +            dist = platform.dist()  # pylint: disable=W1505 +        except Exception: +            pass +        finally: +            found = None +            for entry in dist: +                if entry: +                    found = 1 +            if not found: +                LOG.warning('Unable to determine distribution, template ' +                            'expansion may have unexpected results') +        return dist + +    return (distro_name, distro_version, platform.machine()) + +  def system_info():      info = {          'platform': platform.platform(), @@ -583,19 +616,19 @@ def system_info():          'release': platform.release(),          'python': platform.python_version(),          'uname': platform.uname(), -        'dist': platform.dist(),  # pylint: disable=W1505 +        'dist': get_linux_distro()      }      system = info['system'].lower()      var = 'unknown'      if system == "linux":          linux_dist = info['dist'][0].lower() -        if linux_dist in ('centos', 'fedora', 'debian'): +        if linux_dist in ('centos', 'debian', 'fedora', 'rhel', 'suse'):              var = linux_dist          elif linux_dist in ('ubuntu', 'linuxmint', 'mint'):              var = 'ubuntu'          elif linux_dist == 'redhat':              var = 'rhel' -        elif linux_dist == 'suse': +        elif linux_dist in ('opensuse', 'sles'):              var = 'suse'          else:              var = 'linux' @@ -25,7 +25,7 @@ from distutils.errors import DistutilsArgError  import subprocess  RENDERED_TMPD_PREFIX = "RENDERED_TEMPD" - +VARIANT = None  def is_f(p):      return os.path.isfile(p) @@ -114,10 +114,20 @@ def render_tmpl(template):      atexit.register(shutil.rmtree, tmpd)      bname = os.path.basename(template).rstrip(tmpl_ext)      fpath = os.path.join(tmpd, bname) -    tiny_p([sys.executable, './tools/render-cloudcfg', template, fpath]) +    if VARIANT: +        tiny_p([sys.executable, './tools/render-cloudcfg', '--variant', +            VARIANT, template, fpath]) +    else: +        tiny_p([sys.executable, './tools/render-cloudcfg', template, fpath])      # return path relative to setup.py      return os.path.join(os.path.basename(tmpd), bname) +# User can set the variant for template rendering +if '--distro' in sys.argv: +    idx = sys.argv.index('--distro') +    VARIANT = sys.argv[idx+1] +    del sys.argv[idx+1] +    sys.argv.remove('--distro')  INITSYS_FILES = {      'sysvinit': [f for f in glob('sysvinit/redhat/*') if is_f(f)], @@ -260,7 +270,7 @@ requirements = read_requires()  setuptools.setup(      name='cloud-init',      version=get_version(), -    description='EC2 initialisation magic', +    description='Cloud instance initialisation magic',      author='Scott Moser',      author_email='scott.moser@canonical.com',      url='http://launchpad.net/cloud-init/', @@ -277,4 +287,5 @@ setuptools.setup(      }  ) +  # vi: ts=4 expandtab | 
