commit 7e24a094b71d19c6ec7c6ae047e9a79a0e3ffc46 Author: Radek Novacek rnovacek@redhat.com Date: Wed Nov 5 10:46:28 2014 +0100
libvirt: treat remote libvirt as hypervisor
manager/manager.py | 2 +- tests/test_subscriptionmanager.py | 1 + virt/__init__.py | 2 +- virt/esx/esx.py | 2 +- virt/hyperv/hyperv.py | 2 +- virt/libvirtd/libvirtd.py | 33 ++++++++++++++++++++++++++++++--- virt/rhevm/rhevm.py | 2 +- virt/vdsm/vdsm.py | 7 +++++-- virt/virt.py | 15 +++++++++------ virtwho.py | 16 ++++++++-------- 10 files changed, 58 insertions(+), 24 deletions(-) --- diff --git a/manager/manager.py b/manager/manager.py index f8ed382..27a246d 100644 --- a/manager/manager.py +++ b/manager/manager.py @@ -27,7 +27,7 @@ class Manager(object): def sendVirtGuests(self, domains): raise NotImplementedError()
- def hypervisorCheckIn(self, owner, env, mapping, type=None): + def hypervisorCheckIn(self, config, mapping, type=None): raise NotImplementedError()
@classmethod diff --git a/tests/test_subscriptionmanager.py b/tests/test_subscriptionmanager.py index 35e1665..512d2f5 100644 --- a/tests/test_subscriptionmanager.py +++ b/tests/test_subscriptionmanager.py @@ -10,6 +10,7 @@ from base import TestBase
from config import Config from manager.subscriptionmanager import SubscriptionManager +from virt import Virt
import rhsm.config import rhsm.certificate diff --git a/virt/__init__.py b/virt/__init__.py index aebc492..23979a9 100644 --- a/virt/__init__.py +++ b/virt/__init__.py @@ -1,3 +1,3 @@
-from virt import Virt, DirectVirt, HypervisorVirt, VirtError, Domain +from virt import Virt, VirtError, Domain diff --git a/virt/esx/esx.py b/virt/esx/esx.py index cdca920..743887b 100644 --- a/virt/esx/esx.py +++ b/virt/esx/esx.py @@ -108,7 +108,7 @@ def get_search_filter_spec(client, begin_entity, property_spec): return pfs
-class Esx(virt.HypervisorVirt): +class Esx(virt.Virt): CONFIG_TYPE = "esx"
def __init__(self, logger, config): diff --git a/virt/hyperv/hyperv.py b/virt/hyperv/hyperv.py index 8b48c46..3302ea1 100644 --- a/virt/hyperv/hyperv.py +++ b/virt/hyperv/hyperv.py @@ -175,7 +175,7 @@ class HyperVAuthFailed(HyperVException): pass
-class HyperV(virt.HypervisorVirt): +class HyperV(virt.Virt): CONFIG_TYPE = "hyperv"
def __init__(self, logger, config): diff --git a/virt/libvirtd/libvirtd.py b/virt/libvirtd/libvirtd.py index 60fdb32..a45c2bf 100644 --- a/virt/libvirtd/libvirtd.py +++ b/virt/libvirtd/libvirtd.py @@ -26,6 +26,12 @@ import urlparse
import virt
+# Import XML parser +try: + from elementtree import ElementTree +except ImportError: + from xml.etree import ElementTree +
class VirEventLoopThread(threading.Thread): def __init__(self, logger, *args, **kwargs): @@ -126,7 +132,7 @@ def libvirt_cred_request(credentials, config): return 0
-class Libvirtd(virt.DirectVirt): +class Libvirtd(virt.Virt): """ Class for interacting with libvirt. """ CONFIG_TYPE = "libvirt"
@@ -135,8 +141,12 @@ class Libvirtd(virt.DirectVirt): self.logger = logger self.config = config self.registerEvents = registerEvents + self._host_uuid = None libvirt.registerErrorHandler(lambda ctx, error: None, None)
+ def isHypervisor(self): + return bool(self.config.server) + def _get_url(self): if self.config.server: scheme = username = netloc = path = None @@ -188,9 +198,13 @@ class Libvirtd(virt.DirectVirt):
def listDomains(self): """ Get list of all domains. """ - domains = [] self._connect() + domains = self._listDomains() + self.virt.close() + return domains
+ def _listDomains(self): + domains = [] try: # Active domains for domainID in self.virt.listDomainsID(): @@ -209,9 +223,22 @@ class Libvirtd(virt.DirectVirt): except libvirt.libvirtError, e: self.virt.close() raise virt.VirtError(str(e)) - self.virt.close() return domains
+ def _remote_host_uuid(self): + if self._host_uuid is None: + xml = ElementTree.fromstring(self.virt.getCapabilities()) + self._host_uuid = xml.find('host/uuid').text + return self._host_uuid + + def getHostGuestMapping(self): + self._connect() + mapping = { + self._remote_host_uuid(): self._listDomains() + } + self.virt.close() + return mapping + def canMonitor(self): return True
diff --git a/virt/rhevm/rhevm.py b/virt/rhevm/rhevm.py index a4069fb..8bb540e 100644 --- a/virt/rhevm/rhevm.py +++ b/virt/rhevm/rhevm.py @@ -32,7 +32,7 @@ except ImportError: from xml.etree import ElementTree
-class RhevM(virt.HypervisorVirt): +class RhevM(virt.Virt): CONFIG_TYPE = "rhevm"
def __init__(self, logger, config): diff --git a/virt/vdsm/vdsm.py b/virt/vdsm/vdsm.py index af0c797..e1e9a47 100644 --- a/virt/vdsm/vdsm.py +++ b/virt/vdsm/vdsm.py @@ -26,14 +26,14 @@ import xmlrpclib from ConfigParser import SafeConfigParser, NoSectionError, NoOptionError import subprocess
-from virt import DirectVirt +from virt import Virt
class VdsmError(Exception): pass
-class Vdsm(DirectVirt): +class Vdsm(Virt): CONFIG_TYPE = "vdsm"
def __init__(self, logger, config): @@ -42,6 +42,9 @@ class Vdsm(DirectVirt): self._readConfig("/etc/vdsm/vdsm.conf") self.connect()
+ def isHypervisor(self): + return False + def _readConfig(self, configName): parser = SafeConfigParser() parser.read(configName) diff --git a/virt/virt.py b/virt/virt.py index 288d800..8d1de05 100644 --- a/virt/virt.py +++ b/virt/virt.py @@ -59,9 +59,8 @@ class Virt(object): import hyperv
for subcls in cls.__subclasses__(): - for subsubcls in subcls.__subclasses__(): - if config.type == subsubcls.CONFIG_TYPE: - return subsubcls(logger, config) + if config.type == subcls.CONFIG_TYPE: + return subcls(logger, config) raise KeyError("Invalid config type: %s" % config.type)
def canMonitor(self): @@ -79,12 +78,16 @@ class Virt(object): """ raise NotImplementedError()
+ def isHypervisor(self): + """ + Return True if the virt instance represents hypervisor and the guests + should be obtained by using getHostGuestMapping method. Otherwise + plain listDomains will be used + """ + return True
-class DirectVirt(Virt): def listDomains(self): raise NotImplementedError()
- -class HypervisorVirt(Virt): def getHostGuestMapping(self): raise NotImplementedError() diff --git a/virtwho.py b/virtwho.py index 783bad8..d474d5c 100644 --- a/virtwho.py +++ b/virtwho.py @@ -107,8 +107,9 @@ class VirtWho(object): retry - Should be True on first run, False on second. return - True if sending is successful, False otherwise """ + virt = Virt.fromConfig(self.logger, config) try: - virtualGuests = self._readGuests(config) + virtualGuests = self._readGuests(virt) except (KeyboardInterrupt, SystemExit): raise except Exception, e: @@ -122,7 +123,7 @@ class VirtWho(object): return False
try: - self._sendGuests(config, virtualGuests) + self._sendGuests(virt, virtualGuests) except (KeyboardInterrupt, SystemExit): raise except Exception, e: @@ -137,21 +138,20 @@ class VirtWho(object): return False return True
- def _readGuests(self, config): - virt = Virt.fromConfig(self.logger, config) + def _readGuests(self, virt): if not self.options.oneshot and virt.canMonitor(): virt.startMonitoring(self.sync_event) - if config.type not in ["esx", "rhevm", "hyperv"]: + if not virt.isHypervisor(): return virt.listDomains() else: return virt.getHostGuestMapping()
- def _sendGuests(self, config, virtualGuests): + def _sendGuests(self, virt, virtualGuests): manager = Manager.fromOptions(self.logger, self.options) - if config.type not in ["esx", "rhevm", "hyperv"]: + if not virt.isHypervisor(): manager.sendVirtGuests(virtualGuests) else: - result = manager.hypervisorCheckIn(config, virtualGuests) + result = manager.hypervisorCheckIn(virt.config, virtualGuests)
# Show the result of hypervisorCheckIn for fail in result['failedUpdate']:
virt-who-devel@lists.fedorahosted.org