Change in vdsm[master]: caps: move os-related information to osinfo module

mpolednik at redhat.com mpolednik at redhat.com
Wed Mar 9 12:42:27 UTC 2016


Martin Polednik has uploaded a new change for review.

Change subject: caps: move os-related information to osinfo module
......................................................................

caps: move os-related information to osinfo module

As a part of ongoing effort to strip caps.py the 'trashbin of VDSM
capabilities' title, this patch moves functionality related to OS
(packages, kdump support, selinux) etc. to VDSM library, module osinfo.

This is mostly raw move, cleanups within osinfo will be added further
in the patch series.

Change-Id: Iae6f1f7683e0f5acf7ed77082ac9f69203cbcf6b
Signed-off-by: Martin Polednik <mpolednik at redhat.com>
---
M lib/vdsm/Makefile.am
A lib/vdsm/osinfo.py
M tests/vmTests.py
M vdsm.spec.in
M vdsm/caps.py
M vdsm/virt/vm.py
6 files changed, 249 insertions(+), 220 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/42/54542/1

diff --git a/lib/vdsm/Makefile.am b/lib/vdsm/Makefile.am
index dd86ba3..72c81ad 100644
--- a/lib/vdsm/Makefile.am
+++ b/lib/vdsm/Makefile.am
@@ -48,6 +48,7 @@
 	machinetype.py \
 	netconfpersistence.py \
 	numa.py \
+	osinfo.py \
 	panic.py \
 	password.py \
 	ppc64HardwareInfo.py \
diff --git a/lib/vdsm/osinfo.py b/lib/vdsm/osinfo.py
new file mode 100644
index 0000000..0c3765a
--- /dev/null
+++ b/lib/vdsm/osinfo.py
@@ -0,0 +1,235 @@
+#
+# Copyright 2016 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+#
+# Refer to the README and COPYING files for full details of the license
+#
+from __future__ import absolute_import
+
+import itertools
+import glob
+import linecache
+import logging
+import time
+import os
+
+from vdsm import utils
+
+# For debian systems we can use python-apt if available
+try:
+    import apt
+    python_apt = True
+except ImportError:
+    python_apt = False
+
+# For systems without rpm support
+try:
+    import rpm
+except ImportError:
+    pass
+
+try:
+    from gluster.api import GLUSTER_RPM_PACKAGES
+    from gluster.api import GLUSTER_DEB_PACKAGES
+    glusterEnabled = True
+except ImportError:
+    glusterEnabled = False
+
+
+class OSName:
+    UNKNOWN = 'unknown'
+    OVIRT = 'oVirt Node'
+    RHEL = 'RHEL'
+    FEDORA = 'Fedora'
+    RHEVH = 'RHEV Hypervisor'
+    DEBIAN = 'Debian'
+    POWERKVM = 'PowerKVM'
+
+
+class KdumpStatus(object):
+    UNKNOWN = -1
+    DISABLED = 0
+    ENABLED = 1
+
+
+def getKdumpStatus():
+    try:
+        # check if kdump service is running
+        with open('/sys/kernel/kexec_crash_loaded', 'r') as f:
+            kdumpStatus = int(f.read().strip('\n'))
+
+        if kdumpStatus == KdumpStatus.ENABLED:
+            # check if fence_kdump is configured
+            kdumpStatus = KdumpStatus.DISABLED
+            with open('/etc/kdump.conf', 'r') as f:
+                for line in f:
+                    if line.startswith('fence_kdump_nodes'):
+                        kdumpStatus = KdumpStatus.ENABLED
+                        break
+    except (IOError, OSError, ValueError):
+        kdumpStatus = KdumpStatus.UNKNOWN
+        logging.debug(
+            'Error detecting fence_kdump configuration status',
+            exc_info=True,
+        )
+    return kdumpStatus
+
+
+ at utils.memoized
+def _getos():
+    if os.path.exists('/etc/rhev-hypervisor-release'):
+        return OSName.RHEVH
+    elif glob.glob('/etc/ovirt-node-*-release'):
+        return OSName.OVIRT
+    elif os.path.exists('/etc/fedora-release'):
+        return OSName.FEDORA
+    elif os.path.exists('/etc/redhat-release'):
+        return OSName.RHEL
+    elif os.path.exists('/etc/debian_version'):
+        return OSName.DEBIAN
+    elif os.path.exists('/etc/ibm_powerkvm-release'):
+        return OSName.POWERKVM
+    else:
+        return OSName.UNKNOWN
+
+
+def _parse_node_version(path):
+    data = {}
+    with open(path) as f:
+        for line in f:
+            try:
+                key, value = [kv.strip() for kv in line.split('=', 1)]
+            except ValueError:
+                continue
+
+    return data.get('VERSION', ''), data.get('RELEASE', '')
+
+
+ at utils.memoized
+def osversion():
+    version = release = ''
+
+    osname = getos()
+    try:
+        if osname == OSName.RHEVH or osname == OSName.OVIRT:
+            version, release = _parse_node_version('/etc/default/version')
+        elif osname == OSName.DEBIAN:
+            version = linecache.getline('/etc/debian_version', 1).strip("\n")
+            release = ""  # Debian just has a version entry
+        else:
+            if osname == OSName.POWERKVM:
+                release_path = '/etc/ibm_powerkvm-release'
+            else:
+                release_path = '/etc/redhat-release'
+
+            ts = rpm.TransactionSet()
+            for er in ts.dbMatch('basenames', release_path):
+                version = er['version']
+                release = er['release']
+    except:
+        logging.error('failed to find version/release', exc_info=True)
+
+    return dict(release=release, version=version, name=osname)
+
+
+def getSELinux():
+    selinux = dict()
+    selinux['mode'] = str(utils.get_selinux_enforce_mode())
+
+    return selinux
+
+
+def getKeyPackages():
+    def kernelDict():
+        try:
+            ret = os.uname()
+            ver, rel = ret[2].split('-', 1)
+        except:
+            logging.error('kernel release not found', exc_info=True)
+            ver, rel = '0', '0'
+        try:
+            t = ret[3].split()[2:]
+            del t[4]  # Delete timezone
+            t = time.mktime(time.strptime(' '.join(t)))
+        except:
+            logging.error('kernel build time not found', exc_info=True)
+            t = '0'
+        return dict(version=ver, release=rel, buildtime=t)
+
+    pkgs = {'kernel': kernelDict()}
+
+    if getos() in (OSName.RHEVH, OSName.OVIRT, OSName.FEDORA, OSName.RHEL,
+                   OSName.POWERKVM):
+        KEY_PACKAGES = {
+            'glusterfs-cli': ('glusterfs-cli',),
+            'librbd1': ('librbd1',),
+            'libvirt': ('libvirt', 'libvirt-daemon-kvm'),
+            'mom': ('mom',),
+            'qemu-img': ('qemu-img', 'qemu-img-rhev', 'qemu-img-ev'),
+            'qemu-kvm': ('qemu-kvm', 'qemu-kvm-rhev', 'qemu-kvm-ev'),
+            'spice-server': ('spice-server',),
+            'vdsm': ('vdsm',),
+        }
+
+        if glusterEnabled:
+            KEY_PACKAGES.update(GLUSTER_RPM_PACKAGES)
+
+        try:
+            ts = rpm.TransactionSet()
+
+            for pkg, names in KEY_PACKAGES.iteritems():
+                try:
+                    mi = itertools.chain(*[ts.dbMatch('name', name)
+                                           for name in names]).next()
+                except StopIteration:
+                    logging.debug("rpm package %s not found",
+                                  KEY_PACKAGES[pkg])
+                else:
+                    pkgs[pkg] = {
+                        'version': mi['version'],
+                        'release': mi['release'],
+                        'buildtime': mi['buildtime'],
+                    }
+        except:
+            logging.error('', exc_info=True)
+
+    elif getos() == OSName.DEBIAN and python_apt:
+        KEY_PACKAGES = {
+            'glusterfs-cli': 'glusterfs-cli',
+            'librbd1': 'librbd1',
+            'libvirt': 'libvirt0',
+            'mom': 'mom',
+            'qemu-img': 'qemu-utils',
+            'qemu-kvm': 'qemu-kvm',
+            'spice-server': 'libspice-server1',
+            'vdsm': 'vdsmd',
+        }
+
+        if glusterEnabled:
+            KEY_PACKAGES.update(GLUSTER_DEB_PACKAGES)
+
+        cache = apt.Cache()
+
+        for pkg in KEY_PACKAGES:
+            try:
+                deb_pkg = KEY_PACKAGES[pkg]
+                ver = cache[deb_pkg].installed.version
+                # Debian just offers a version
+                pkgs[pkg] = dict(version=ver, release="", buildtime="")
+            except:
+                logging.error('', exc_info=True)
+
+    return pkgs
diff --git a/tests/vmTests.py b/tests/vmTests.py
index d67c467..a6c807b 100644
--- a/tests/vmTests.py
+++ b/tests/vmTests.py
@@ -51,6 +51,7 @@
 from vdsm import constants
 from vdsm import cpuarch
 from vdsm import define
+from vdsm import osinfo
 from vdsm import password
 from vdsm import response
 from testlib import VdsmTestCase as TestCaseBase
@@ -513,7 +514,7 @@
             self.assertEquals(cm.exception.args[0], exceptionMsg)
 
     @MonkeyPatch(cpuarch, 'effective', lambda: cpuarch.X86_64)
-    @MonkeyPatch(caps, 'osversion', lambda: {
+    @MonkeyPatch(osinfo, 'osversion', lambda: {
         'release': '1', 'version': '18', 'name': 'Fedora'})
     @MonkeyPatch(constants, 'SMBIOS_MANUFACTURER', 'oVirt')
     @MonkeyPatch(constants, 'SMBIOS_OSNAME', 'oVirt Node')
diff --git a/vdsm.spec.in b/vdsm.spec.in
index 2643679..329a415 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -1139,6 +1139,7 @@
 %{python_sitelib}/%{vdsm_name}/network/sourceroutethread.py*
 %{python_sitelib}/%{vdsm_name}/network/utils.py*
 %{python_sitelib}/%{vdsm_name}/numa.py*
+%{python_sitelib}/%{vdsm_name}/osinfo.py*
 %{python_sitelib}/%{vdsm_name}/password.py*
 %{python_sitelib}/%{vdsm_name}/panic.py*
 %{python_sitelib}/%{vdsm_name}/ppc64HardwareInfo.py*
diff --git a/vdsm/caps.py b/vdsm/caps.py
index 3820d1e..fbb9508 100644
--- a/vdsm/caps.py
+++ b/vdsm/caps.py
@@ -20,12 +20,8 @@
 
 """Collect host capabilities"""
 
-import itertools
 import os
 import logging
-import time
-import linecache
-import glob
 import xml.etree.ElementTree as ET
 from distutils.version import LooseVersion
 
@@ -41,54 +37,17 @@
 from vdsm import machinetype
 from vdsm import netinfo
 from vdsm import numa
+from vdsm import osinfo
 from vdsm import host
 from vdsm import utils
 import storage.hba
 import storage.iscsi
 from virt import vmdevices
 
-# For debian systems we can use python-apt if available
-try:
-    import apt
-    python_apt = True
-except ImportError:
-    python_apt = False
-
-# For systems without rpm support
-try:
-    import rpm
-except ImportError:
-    pass
-
-PAGE_SIZE_BYTES = os.sysconf('SC_PAGESIZE')
-
-try:
-    from gluster.api import GLUSTER_RPM_PACKAGES
-    from gluster.api import GLUSTER_DEB_PACKAGES
-    from gluster.api import glusterAdditionalFeatures
-    _glusterEnabled = True
-except ImportError:
-    _glusterEnabled = False
-
-
-class OSName:
-    UNKNOWN = 'unknown'
-    OVIRT = 'oVirt Node'
-    RHEL = 'RHEL'
-    FEDORA = 'Fedora'
-    RHEVH = 'RHEV Hypervisor'
-    DEBIAN = 'Debian'
-    POWERKVM = 'PowerKVM'
-
-
 RNG_SOURCES = {'random': '/dev/random',
                'hwrng': '/dev/hwrng'}
 
-
-class KdumpStatus(object):
-    UNKNOWN = -1
-    DISABLED = 0
-    ENABLED = 1
+PAGE_SIZE_BYTES = os.sysconf('SC_PAGESIZE')
 
 
 def _getFreshCapsXMLStr():
@@ -164,93 +123,6 @@
     return True
 
 
-def _getKdumpStatus():
-    try:
-        # check if kdump service is running
-        with open('/sys/kernel/kexec_crash_loaded', 'r') as f:
-            kdumpStatus = int(f.read().strip('\n'))
-
-        if kdumpStatus == KdumpStatus.ENABLED:
-            # check if fence_kdump is configured
-            kdumpStatus = KdumpStatus.DISABLED
-            with open('/etc/kdump.conf', 'r') as f:
-                for line in f:
-                    if line.startswith('fence_kdump_nodes'):
-                        kdumpStatus = KdumpStatus.ENABLED
-                        break
-    except (IOError, OSError, ValueError):
-        kdumpStatus = KdumpStatus.UNKNOWN
-        logging.debug(
-            'Error detecting fence_kdump configuration status',
-            exc_info=True,
-        )
-    return kdumpStatus
-
-
- at utils.memoized
-def getos():
-    if os.path.exists('/etc/rhev-hypervisor-release'):
-        return OSName.RHEVH
-    elif glob.glob('/etc/ovirt-node-*-release'):
-        return OSName.OVIRT
-    elif os.path.exists('/etc/fedora-release'):
-        return OSName.FEDORA
-    elif os.path.exists('/etc/redhat-release'):
-        return OSName.RHEL
-    elif os.path.exists('/etc/debian_version'):
-        return OSName.DEBIAN
-    elif os.path.exists('/etc/ibm_powerkvm-release'):
-        return OSName.POWERKVM
-    else:
-        return OSName.UNKNOWN
-
-
-def _parse_node_version(path):
-    data = {}
-    with open(path) as f:
-        for line in f:
-            try:
-                key, value = [kv.strip() for kv in line.split('=', 1)]
-            except ValueError:
-                continue
-
-    return data.get('VERSION', ''), data.get('RELEASE', '')
-
-
- at utils.memoized
-def osversion():
-    version = release = ''
-
-    osname = getos()
-    try:
-        if osname == OSName.RHEVH or osname == OSName.OVIRT:
-            version, release = _parse_node_version('/etc/default/version')
-        elif osname == OSName.DEBIAN:
-            version = linecache.getline('/etc/debian_version', 1).strip("\n")
-            release = ""  # Debian just has a version entry
-        else:
-            if osname == OSName.POWERKVM:
-                release_path = '/etc/ibm_powerkvm-release'
-            else:
-                release_path = '/etc/redhat-release'
-
-            ts = rpm.TransactionSet()
-            for er in ts.dbMatch('basenames', release_path):
-                version = er['version']
-                release = er['release']
-    except:
-        logging.error('failed to find version/release', exc_info=True)
-
-    return dict(release=release, version=version, name=osname)
-
-
-def _getSELinux():
-    selinux = dict()
-    selinux['mode'] = str(utils.get_selinux_enforce_mode())
-
-    return selinux
-
-
 def get():
     caps = {}
     cpu_topology = numa.cpu_topology()
@@ -281,9 +153,9 @@
     except:
         logging.debug('not reporting hooks', exc_info=True)
 
-    caps['operatingSystem'] = osversion()
+    caps['operatingSystem'] = osinfo.osversion()
     caps['uuid'] = host.uuid()
-    caps['packages2'] = _getKeyPackages()
+    caps['packages2'] = osinfo.getKeyPackages()
     caps['emulatedMachines'] = machinetype.emulated_machines(
         cpuarch.effective())
     try:
@@ -319,17 +191,18 @@
     caps['numaNodeDistance'] = dict(numa.distances())
     caps['autoNumaBalancing'] = numa.autonuma_status()
 
-    caps['selinux'] = _getSELinux()
+    caps['selinux'] = osinfo.getSELinux()
 
     liveSnapSupported = _getLiveSnapshotSupport(cpuarch.effective())
     if liveSnapSupported is not None:
         caps['liveSnapshot'] = str(liveSnapSupported).lower()
     caps['liveMerge'] = str(getLiveMergeSupport()).lower()
-    caps['kdumpStatus'] = _getKdumpStatus()
+    caps['kdumpStatus'] = osinfo.getKdumpStatus()
 
     caps['hostdevPassthrough'] = str(hostdev.is_supported()).lower()
     caps['additionalFeatures'] = []
-    if _glusterEnabled:
+    if osinfo.glusterEnabled:
+        from gluster.api import glusterAdditionalFeatures
         caps['additionalFeatures'].extend(glusterAdditionalFeatures())
     return caps
 
@@ -370,86 +243,3 @@
                             ' libvirt from the virt-preview repository')
 
     return dsaversion.version_info
-
-
-def _getKeyPackages():
-    def kernelDict():
-        try:
-            ret = os.uname()
-            ver, rel = ret[2].split('-', 1)
-        except:
-            logging.error('kernel release not found', exc_info=True)
-            ver, rel = '0', '0'
-        try:
-            t = ret[3].split()[2:]
-            del t[4]  # Delete timezone
-            t = time.mktime(time.strptime(' '.join(t)))
-        except:
-            logging.error('kernel build time not found', exc_info=True)
-            t = '0'
-        return dict(version=ver, release=rel, buildtime=t)
-
-    pkgs = {'kernel': kernelDict()}
-
-    if getos() in (OSName.RHEVH, OSName.OVIRT, OSName.FEDORA, OSName.RHEL,
-                   OSName.POWERKVM):
-        KEY_PACKAGES = {
-            'glusterfs-cli': ('glusterfs-cli',),
-            'librbd1': ('librbd1',),
-            'libvirt': ('libvirt', 'libvirt-daemon-kvm'),
-            'mom': ('mom',),
-            'qemu-img': ('qemu-img', 'qemu-img-rhev', 'qemu-img-ev'),
-            'qemu-kvm': ('qemu-kvm', 'qemu-kvm-rhev', 'qemu-kvm-ev'),
-            'spice-server': ('spice-server',),
-            'vdsm': ('vdsm',),
-        }
-
-        if _glusterEnabled:
-            KEY_PACKAGES.update(GLUSTER_RPM_PACKAGES)
-
-        try:
-            ts = rpm.TransactionSet()
-
-            for pkg, names in KEY_PACKAGES.iteritems():
-                try:
-                    mi = itertools.chain(*[ts.dbMatch('name', name)
-                                           for name in names]).next()
-                except StopIteration:
-                    logging.debug("rpm package %s not found",
-                                  KEY_PACKAGES[pkg])
-                else:
-                    pkgs[pkg] = {
-                        'version': mi['version'],
-                        'release': mi['release'],
-                        'buildtime': mi['buildtime'],
-                    }
-        except:
-            logging.error('', exc_info=True)
-
-    elif getos() == OSName.DEBIAN and python_apt:
-        KEY_PACKAGES = {
-            'glusterfs-cli': 'glusterfs-cli',
-            'librbd1': 'librbd1',
-            'libvirt': 'libvirt0',
-            'mom': 'mom',
-            'qemu-img': 'qemu-utils',
-            'qemu-kvm': 'qemu-kvm',
-            'spice-server': 'libspice-server1',
-            'vdsm': 'vdsmd',
-        }
-
-        if _glusterEnabled:
-            KEY_PACKAGES.update(GLUSTER_DEB_PACKAGES)
-
-        cache = apt.Cache()
-
-        for pkg in KEY_PACKAGES:
-            try:
-                deb_pkg = KEY_PACKAGES[pkg]
-                ver = cache[deb_pkg].installed.version
-                # Debian just offers a version
-                pkgs[pkg] = dict(version=ver, release="", buildtime="")
-            except:
-                logging.error('', exc_info=True)
-
-    return pkgs
diff --git a/vdsm/virt/vm.py b/vdsm/virt/vm.py
index d292fd1..ffd1aa8 100644
--- a/vdsm/virt/vm.py
+++ b/vdsm/virt/vm.py
@@ -44,6 +44,7 @@
 from vdsm import hostdev
 from vdsm import libvirtconnection
 from vdsm import netinfo
+from vdsm import osinfo
 from vdsm import qemuimg
 from vdsm import response
 from vdsm import supervdsm
@@ -1634,7 +1635,7 @@
         domxml.appendOs(use_serial_console=(serial_console is not None))
 
         if cpuarch.is_x86(self.arch):
-            osd = caps.osversion()
+            osd = osinfo.osversion()
 
             osVersion = osd.get('version', '') + '-' + osd.get('release', '')
             serialNumber = self.conf.get('serial', host.uuid())


-- 
To view, visit https://gerrit.ovirt.org/54542
To unsubscribe, visit https://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Iae6f1f7683e0f5acf7ed77082ac9f69203cbcf6b
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Martin Polednik <mpolednik at redhat.com>


More information about the vdsm-patches mailing list