]> git-server-git.apps.pok.os.sepia.ceph.com Git - teuthology.git/commitdiff
Add caching lsb_release parser
authorZack Cerza <zack@cerza.org>
Thu, 5 Jun 2014 21:50:24 +0000 (16:50 -0500)
committerZack Cerza <zack.cerza@inktank.com>
Thu, 11 Sep 2014 21:12:51 +0000 (15:12 -0600)
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 <zack.cerza@inktank.com>
teuthology/orchestra/remote.py
teuthology/orchestra/test/test_integration.py
teuthology/orchestra/test/test_remote.py

index 12b5f11226ceded62a551bc1b619f1942e44634c..6d683657299e5b08d17d6bd4c60e24ea4d22cc76 100644 (file)
@@ -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):
     """
index 4b761bb8684ae3a66f0416fb96de91b8d55f992e..2722c86aea5559e71734f96300e3d4bf6d7a8ef2 100644 (file)
@@ -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
index b79cd176972c795c34064a153dea85ec283701d6..a2a32676d772bbe751e9a3cf95e6fd1141d204ed 100644 (file)
@@ -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'