From: Zack Cerza Date: Thu, 5 Jun 2014 21:50:24 +0000 (-0500) Subject: Add caching lsb_release parser X-Git-Tag: 1.1.0~1177 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=959353415598cb8a6a3c20c0d0cc80d0c97cfcc1;p=teuthology.git Add caching lsb_release parser In far too many places do we remotely exec lsb_release in some form, then parse the output. In shifting to a more stable interface between teuthology and its tasks, this seemed important to me. Remote objects now have a 'distro' property that, when first accessed, calls 'lsb_release -a' remotely and parses the results. I've included tests and documentation. Signed-off-by: Zack Cerza --- diff --git a/teuthology/orchestra/remote.py b/teuthology/orchestra/remote.py index 12b5f1122..6d6836572 100644 --- a/teuthology/orchestra/remote.py +++ b/teuthology/orchestra/remote.py @@ -237,6 +237,62 @@ class Remote(object): self._sftp_get_file(remote_temp_path, to_path) self.remove(remote_temp_path) + @property + def distro(self): + if not hasattr(self, '_distro'): + lsb_info = self.run(args=['lsb_release', '-a'], stdout=StringIO(), + stderr=StringIO()) + self._distro = Distribution(lsb_info.stdout.getvalue().strip()) + return self._distro + + +class Distribution(object): + """ + Parse 'lsb_release -a' output and populate attributes + + Given output like: + Distributor ID: Ubuntu + Description: Ubuntu 12.04.4 LTS + Release: 12.04 + Codename: precise + + Attributes will be: + distributor = 'Ubuntu' + description = 'Ubuntu 12.04.4 LTS' + release = '12.04' + codename = 'precise' + Additionally, a few convenience attributes will be set: + name = 'ubuntu' + package_type = 'deb' + """ + + __slots__ = ['_lsb_release_str', '__expr', 'distributor', 'description', + 'release', 'codename', 'name', 'package_type'] + + def __init__(self, lsb_release_str): + self._lsb_release_str = lsb_release_str.strip() + self.distributor = self._get_match("Distributor ID:\s*(.*)") + self.name = self.distributor.lower() + self.description = self._get_match("Description:\s*(.*)") + self.release = self._get_match("Release:\s*(.*)") + self.codename = self._get_match("Codename:\s*(.*)") + + if self.distributor in ['Ubuntu', 'Debian']: + self.package_type = "deb" + elif self.distributor in ['CentOS', 'Fedora', 'RedHatEnterpriseServer', + 'openSUSE project', 'SUSE LINUX']: + self.package_type = "rpm" + + def _get_match(self, regex): + match = re.search(regex, self._lsb_release_str) + if match: + return match.groups()[0] + return '' + + def __str__(self): + return " ".join([self.distributor, self.release, + self.codename]).strip() + def getShortName(name): """ diff --git a/teuthology/orchestra/test/test_integration.py b/teuthology/orchestra/test/test_integration.py index 4b761bb86..2722c86ae 100644 --- a/teuthology/orchestra/test/test_integration.py +++ b/teuthology/orchestra/test/test_integration.py @@ -4,7 +4,7 @@ monkey.patch_all() from cStringIO import StringIO import os -from .. import connection, run +from .. import connection, remote, run from .util import assert_raises from teuthology.exceptions import CommandCrashedError, ConnectionLostError @@ -73,3 +73,12 @@ class TestIntegration(): stdout=StringIO(), ) assert r.stdout.getvalue() == 'yup\n' + + def test_distro(self): + rem = remote.Remote(HOST) + assert rem.distro.distributor + assert rem.distro.name + assert rem.distro.description + assert rem.distro.release + assert rem.distro.codename + assert rem.distro.package_type diff --git a/teuthology/orchestra/test/test_remote.py b/teuthology/orchestra/test/test_remote.py index b79cd1769..a2a32676d 100644 --- a/teuthology/orchestra/test/test_remote.py +++ b/teuthology/orchestra/test/test_remote.py @@ -1,6 +1,8 @@ import fudge import fudge.inspector +from textwrap import dedent + from .. import remote from ..run import RemoteProcess @@ -54,3 +56,38 @@ class TestRemote(object): ) assert got is ret assert got.remote is r + + +class TestDistribution(object): + lsb_centos = 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: CentOS + Description: CentOS release 6.5 (Final) + Release: 6.5 + Codename: Final + """) + + lsb_ubuntu = dedent(""" + Distributor ID: Ubuntu + Description: Ubuntu 12.04.4 LTS + Release: 12.04 + Codename: precise + """) + + def test_centos(self): + d = remote.Distribution(self.lsb_centos) + assert d.distributor == 'CentOS' + assert d.description == 'CentOS release 6.5 (Final)' + assert d.release == '6.5' + assert d.codename == 'Final' + assert d.name == 'centos' + assert d.package_type == 'rpm' + + def test_ubuntu(self): + d = remote.Distribution(self.lsb_ubuntu) + assert d.distributor == 'Ubuntu' + assert d.description == 'Ubuntu 12.04.4 LTS' + assert d.release == '12.04' + assert d.codename == 'precise' + assert d.name == 'ubuntu' + assert d.package_type == 'deb'