From 9e20f1454da874b1ea81e08ff853f24615cbe055 Mon Sep 17 00:00:00 2001 From: Zack Cerza Date: Thu, 25 Sep 2014 09:38:52 -0600 Subject: [PATCH] Add 'lsb_release -a' parsing back to remote.OS It can now parse either that or /etc/os-release, and remote.Remote will attempt the latter first. Signed-off-by: Zack Cerza --- teuthology/orchestra/remote.py | 141 ++++++++++++------ teuthology/orchestra/test/test_integration.py | 2 - teuthology/orchestra/test/test_remote.py | 110 +++++++++----- 3 files changed, 166 insertions(+), 87 deletions(-) diff --git a/teuthology/orchestra/remote.py b/teuthology/orchestra/remote.py index de9c25352b..06336726d4 100644 --- a/teuthology/orchestra/remote.py +++ b/teuthology/orchestra/remote.py @@ -250,9 +250,14 @@ class Remote(object): @property def os(self): if not hasattr(self, '_os'): - os_info = self.run(args=['cat', '/etc/os-release'], - stdout=StringIO(), stderr=StringIO()) - self._os = OS(os_info.stdout.getvalue().strip()) + proc = self.run(args=['cat', '/etc/os-release'], stdout=StringIO(), + stderr=StringIO(), check_status=False) + if proc.exitstatus == 0: + self._os = OS.from_os_release(proc.stdout.getvalue().strip()) + else: + proc = self.run(args=['lsb_release', '-a'], stdout=StringIO(), + stderr=StringIO()) + self._os = OS.from_lsb_release(proc.stdout.getvalue().strip()) return self._os @property @@ -277,8 +282,8 @@ class Remote(object): node['name'] = self.hostname node['user'] = self.user node['arch'] = self.arch - node['os_type'] = self.os.id - node['os_version'] = self.os.version_id + node['os_type'] = self.os.name + node['os_version'] = self.os.version node['ssh_pub_key'] = self.host_key node['up'] = True return node @@ -286,56 +291,94 @@ class Remote(object): class OS(object): """ - Parse /etc/os-release and populate attributes - - Given output like: - NAME="Ubuntu" - VERSION="12.04.4 LTS, Precise Pangolin" - ID=ubuntu - ID_LIKE=debian - PRETTY_NAME="Ubuntu precise (12.04.4 LTS)" - VERSION_ID="12.04" - - Attributes will be: - name = 'Ubuntu' - version = '12.04.4 LTS, Precise Pangolin' - id = 'ubuntu' - id_like = 'debian' - pretty_name = 'Ubuntu precise (12.04.4 LTS)' - version_id = '12.04' - Additionally, we set the package type: - package_type = 'deb' + Class that parses either /etc/os-release or the output of 'lsb_release -a' + and provides OS name and version information. + + Must be initialized with OS.from_lsb_release or OS.from_os_release """ - __slots__ = ['_os_release_str', 'name', 'version', 'id', 'id_like', - 'pretty_name', 'version_id', 'package_type'] - - _deb_distros = ('debian') - _rpm_distros = ('fedora', 'rhel', 'rhel fedora', 'suse') - - def __init__(self, os_release_str): - self._os_release_str = os_release_str.strip() - self.name = self._get_value('NAME') - self.version = self._get_value('VERSION') - self.id = self._get_value('ID') - self.id_like = self._get_value('ID_LIKE') - self.pretty_name = self._get_value('PRETTY_NAME') - self.version_id = self._get_value('VERSION_ID') - - if self.id_like in self._deb_distros: - self.package_type = "deb" - elif self.id_like in self._rpm_distros: - self.package_type = "rpm" - - def _get_value(self, name): - regex = '^%s=(.+)' % name - match = re.search(regex, self._os_release_str, flags=re.M) + __slots__ = ['name', 'version', 'package_type'] + + _deb_distros = ('debian', 'ubuntu') + _rpm_distros = ('fedora', 'rhel', 'centos', 'suse') + + def __init__(self): + pass + + @classmethod + def from_lsb_release(cls, lsb_release_str): + """ + Parse /etc/os-release and populate attributes + + Given output like: + Distributor ID: Ubuntu + Description: Ubuntu 12.04.4 LTS + Release: 12.04 + Codename: precise + + Attributes will be: + name = 'ubuntu' + version = '12.04' + Additionally, we set the package type: + package_type = 'deb' + """ + obj = cls() + str_ = lsb_release_str.strip() + name = obj._get_value(str_, 'Distributor ID') + if name == 'RedHatEnterpriseServer': + name = 'rhel' + obj.name = name.lower() + + obj.version = obj._get_value(str_, 'Release') + + if obj.name in cls._deb_distros: + obj.package_type = "deb" + elif obj.name in cls._rpm_distros: + obj.package_type = "rpm" + + return obj + + @classmethod + def from_os_release(cls, os_release_str): + """ + Parse /etc/os-release and populate attributes + + Given output like: + NAME="Ubuntu" + VERSION="12.04.4 LTS, Precise Pangolin" + ID=ubuntu + ID_LIKE=debian + PRETTY_NAME="Ubuntu precise (12.04.4 LTS)" + VERSION_ID="12.04" + + Attributes will be: + name = 'ubuntu' + version = '12.04' + Additionally, we set the package type: + package_type = 'deb' + """ + obj = cls() + str_ = os_release_str.strip() + obj.name = cls._get_value(str_, 'ID').lower() + obj.version = cls._get_value(str_, 'VERSION_ID') + + if obj.name in cls._deb_distros: + obj.package_type = "deb" + elif obj.name in cls._rpm_distros: + obj.package_type = "rpm" + + return obj + + @staticmethod + def _get_value(str_, name): + regex = '^%s[:=](.+)' % name + match = re.search(regex, str_, flags=re.M) if match: - return match.groups()[0].strip('"\'') + return match.groups()[0].strip(' \t"\'') return '' def __str__(self): - return " ".join([self.id, self.version_id]).strip() + return " ".join([self.name, self.version]).strip() def getShortName(name): diff --git a/teuthology/orchestra/test/test_integration.py b/teuthology/orchestra/test/test_integration.py index c4731e5c95..6d45b28bc4 100644 --- a/teuthology/orchestra/test/test_integration.py +++ b/teuthology/orchestra/test/test_integration.py @@ -77,6 +77,4 @@ class TestIntegration(): def test_os(self): rem = remote.Remote(HOST) assert rem.os.name - assert rem.os.id assert rem.os.version - assert rem.os.version_id diff --git a/teuthology/orchestra/test/test_remote.py b/teuthology/orchestra/test/test_remote.py index cca5bc3300..128b3f2a0d 100644 --- a/teuthology/orchestra/test/test_remote.py +++ b/teuthology/orchestra/test/test_remote.py @@ -141,7 +141,7 @@ class TestRemote(object): class TestDistribution(object): - str_centos = dedent(""" + str_centos_7_os_release = dedent(""" NAME="CentOS Linux" VERSION="7 (Core)" ID="centos" @@ -154,7 +154,14 @@ class TestDistribution(object): BUG_REPORT_URL="https://bugs.centos.org/" """) - str_debian = dedent(""" + str_debian_7_lsb_release = dedent(""" + Distributor ID: Debian + Description: Debian GNU/Linux 7.1 (wheezy) + Release: 7.1 + Codename: wheezy + """) + + str_debian_7_os_release = dedent(""" PRETTY_NAME="Debian GNU/Linux 7 (wheezy)" NAME="Debian GNU/Linux" VERSION_ID="7" @@ -166,7 +173,14 @@ class TestDistribution(object): BUG_REPORT_URL="http://bugs.debian.org/" """) - str_ubuntu = dedent(""" + str_ubuntu_12_04_lsb_release = dedent(""" + Distributor ID: Ubuntu + Description: Ubuntu 12.04.4 LTS + Release: 12.04 + Codename: precise + """) + + str_ubuntu_12_04_os_release = dedent(""" NAME="Ubuntu" VERSION="12.04.4 LTS, Precise Pangolin" ID=ubuntu @@ -175,7 +189,23 @@ class TestDistribution(object): VERSION_ID="12.04" """) - str_rhel = dedent(""" + str_rhel_6_4_lsb_release = dedent(""" + LSB Version: :base-4.0-amd64:base-4.0-noarch:core-4.0-amd64:core-4.0-noarch:graphics-4.0-amd64:graphics-4.0-noarch:printing-4.0-amd64:printing-4.0-noarch + Distributor ID: RedHatEnterpriseServer + Description: Red Hat Enterprise Linux Server release 6.4 (Santiago) + Release: 6.4 + Codename: Santiago + """) + + str_rhel_7_lsb_release = dedent(""" + LSB Version: :core-4.1-amd64:core-4.1-noarch:cxx-4.1-amd64:cxx-4.1-noarch:desktop-4.1-amd64:desktop-4.1-noarch:languages-4.1-amd64:languages-4.1-noarch:printing-4.1-amd64:printing-4.1-noarch + Distributor ID: RedHatEnterpriseServer + Description: Red Hat Enterprise Linux Server release 7.0 (Maipo) + Release: 7.0 + Codename: Maipo + """) + + str_rhel_7_os_release = dedent(""" NAME="Red Hat Enterprise Linux Server" VERSION="7.0 (Maipo)" ID="rhel" @@ -193,42 +223,50 @@ class TestDistribution(object): REDHAT_SUPPORT_PRODUCT_VERSION=7.0 """) - def test_centos(self): - os = remote.OS(self.str_centos) - assert os.name == 'CentOS Linux' - assert os.version == '7 (Core)' - assert os.id == 'centos' - assert os.id_like == 'rhel fedora' - assert os.pretty_name == 'CentOS Linux 7 (Core)' - assert os.version_id == '7' + def test_centos_7_os_release(self): + os = remote.OS.from_os_release(self.str_centos_7_os_release) + assert os.name == 'centos' + assert os.version == '7' assert os.package_type == 'rpm' - def test_debian(self): - os = remote.OS(self.str_debian) - assert os.name == 'Debian GNU/Linux' - assert os.version == '7 (wheezy)' - assert os.id == 'debian' - assert os.id_like == '' - assert os.pretty_name == 'Debian GNU/Linux 7 (wheezy)' - assert os.version_id == '7' + def test_debian_7_lsb_release(self): + os = remote.OS.from_lsb_release(self.str_debian_7_lsb_release) + assert os.name == 'debian' + assert os.version == '7.1' assert os.package_type == 'deb' - def test_ubuntu(self): - os = remote.OS(self.str_ubuntu) - assert os.name == 'Ubuntu' - assert os.version == '12.04.4 LTS, Precise Pangolin' - assert os.id == 'ubuntu' - assert os.id_like == 'debian' - assert os.pretty_name == 'Ubuntu precise (12.04.4 LTS)' - assert os.version_id == '12.04' + def test_debian_7_os_release(self): + os = remote.OS.from_os_release(self.str_debian_7_os_release) + assert os.name == 'debian' + assert os.version == '7' assert os.package_type == 'deb' - def test_rhel(self): - os = remote.OS(self.str_rhel) - assert os.name == 'Red Hat Enterprise Linux Server' - assert os.version == '7.0 (Maipo)' - assert os.id == 'rhel' - assert os.id_like == 'fedora' - assert os.pretty_name == 'Red Hat Enterprise Linux Server 7.0 (Maipo)' - assert os.version_id == '7.0' + def test_ubuntu_12_04_lsb_release(self): + os = remote.OS.from_lsb_release(self.str_ubuntu_12_04_lsb_release) + assert os.name == 'ubuntu' + assert os.version == '12.04' + assert os.package_type == 'deb' + + def test_ubuntu_12_04_os_release(self): + os = remote.OS.from_os_release(self.str_ubuntu_12_04_os_release) + assert os.name == 'ubuntu' + assert os.version == '12.04' + assert os.package_type == 'deb' + + def test_rhel_6_4_lsb_release(self): + os = remote.OS.from_lsb_release(self.str_rhel_6_4_lsb_release) + assert os.name == 'rhel' + assert os.version == '6.4' + assert os.package_type == 'rpm' + + def test_rhel_7_lsb_release(self): + os = remote.OS.from_lsb_release(self.str_rhel_7_lsb_release) + assert os.name == 'rhel' + assert os.version == '7.0' + assert os.package_type == 'rpm' + + def test_rhel_7_os_release(self): + os = remote.OS.from_os_release(self.str_rhel_7_os_release) + assert os.name == 'rhel' + assert os.version == '7.0' assert os.package_type == 'rpm' -- 2.39.5