commit 6c76df43df047bb9eb1c01a6397d98e8bf1d7aed
Author: Radek Novacek <rnovacek(a)redhat.com>
Date: Tue Sep 13 16:14:57 2011 +0200
Add VDSM mode
vdsm.py | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
virt-who.py | 28 ++++++++++++---
2 files changed, 135 insertions(+), 5 deletions(-)
---
diff --git a/vdsm.py b/vdsm.py
new file mode 100644
index 0000000..aa029c1
--- /dev/null
+++ b/vdsm.py
@@ -0,0 +1,112 @@
+"""
+Module for accessing vdsm, part of virt-who
+
+Parts of this file is based on rhn-virtualization from spacewalk
+http://git.fedorahosted.org/git/?p=spacewalk.git;a=tree;f=client/tools/rhn-virtualization
+
+Copyright (C) 2011 Radek Novacek <rnovacek(a)redhat.com>
+
+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.
+"""
+
+import xmlrpclib
+from ConfigParser import SafeConfigParser, NoSectionError
+import subprocess
+
+class VdsmError(Exception):
+ pass
+
+class Domain:
+ """ Class for compatibility with libvirt Domain class. Only UUID
supported. """
+ def __init__(self, uuid):
+ self.uuid = uuid
+
+ def UUIDString(self):
+ return self.uuid
+
+ def __str__(self):
+ return self.uuid
+
+class VDSM:
+ def __init__(self, logger):
+ self.logger = logger
+ self._readConfig("/etc/vdsm/vdsm.conf")
+ self.connect()
+
+ def _readConfig(self, configName):
+ parser = SafeConfigParser()
+ parser.read(configName)
+ try:
+ self.ssl = parser.get("vars", "ssl").lower() in
["1", "true"]
+ if self.ssl:
+ self.trust_store_path = parser.get("vars",
"trust_store_path")
+ else:
+ self.trust_store_path = None
+ self.management_port = parser.get("addresses",
"management_port")
+ except NoSectionError, e:
+ raise VdsmError("Error in vdsm configuration file: %s" % str(e))
+
+ def _getLocalVdsName(self, tsPath):
+ p = subprocess.Popen(['/usr/bin/openssl', 'x509',
'-noout', '-subject', '-in',
+ '%s/certs/vdsmcert.pem' % tsPath], stdout=subprocess.PIPE,
close_fds=True)
+ out, err = p.communicate()
+ if p.returncode != 0:
+ return '0'
+ return out.split('=')[-1].strip()
+
+ def _secureConnect(self):
+ addr = self._getLocalVdsName(self.trust_store_path)
+
+ from M2Crypto.m2xmlrpclib import SSL_Transport
+ from M2Crypto import SSL
+
+ KEYFILE = self.trust_store_path + '/keys/vdsmkey.pem'
+ CERTFILE = self.trust_store_path + '/certs/vdsmcert.pem'
+ CACERT = self.trust_store_path + '/certs/cacert.pem'
+
+ ctx = SSL.Context('sslv3')
+
+ ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, 16)
+ ctx.load_verify_locations(CACERT)
+ ctx.load_cert(CERTFILE, KEYFILE)
+
+ return xmlrpclib.Server('https://%s:%s' % (addr, self.management_port),
SSL_Transport(ctx))
+
+ def connect(self):
+ if self.trust_store_path:
+ try:
+ self.server = self._secureConnect()
+ return
+ except Exception, e:
+ self.logger.exception(e)
+ # Try http version if ssl is off or fails
+ self.server = xmlrpclib.Server("http://localhost:%s" %
self.management_port)
+
+ def listDomains(self):
+ domains = []
+ response = self.server.list(True)
+ if response['status']['code'] != 0:
+ self.logger.error("Unable to list virtual machines: %s" %
response['status']['message'])
+ else:
+ for vm in response['vmList']:
+ domains.append(Domain(vm['vmId']))
+ return domains
+
+
+if __name__ == '__main__':
+ import logging
+ logger = logging.getLogger("rhsm-app." + __name__)
+ vdsm = VDSM(logger)
+ print vdsm.listDomains()
diff --git a/virt-who.py b/virt-who.py
index ddfc090..012794b 100644
--- a/virt-who.py
+++ b/virt-who.py
@@ -23,6 +23,7 @@ import os
import time
from virt import Virt, VirtError
+from vdsm import VDSM
from event import virEventLoopPureStart
from subscriptionmanager import SubscriptionManager
@@ -43,6 +44,8 @@ if __name__ == '__main__':
parser.add_option("-d", "--debug", action="store_true",
dest="debug", default=False, help="Enable debugging output")
parser.add_option("-b", "--background",
action="store_true", dest="background", default=False, help="Run
in the background and monitor virtual guests")
parser.add_option("-i", "--interval", type="int",
dest="interval", default=0, help="Acquire and send list of virtual guest
each N seconds")
+ parser.add_option("--libvirt", action="store_false",
dest="useVDSM", default=False, help="Use libvirt to list virtual guests
[default]")
+ parser.add_option("--vdsm", action="store_true",
dest="useVDSM", default=False, help="Use vdsm to list virtual
guests")
(options, args) = parser.parse_args()
@@ -69,6 +72,10 @@ if __name__ == '__main__':
except ValueError:
logger.warning("Interval is not number, ignoring")
+ env = os.getenv("VIRTWHO_VDSM", "0").strip().lower()
+ if env in ["1", "true"]:
+ options.useVDSM = True
+
if options.interval < 0:
logger.warning("Interval is not positive number, ignoring")
options.interval = 0
@@ -77,6 +84,10 @@ if __name__ == '__main__':
logger.warning("Interval and background options can't be used together,
using interval only")
options.background = False
+ if options.background and options.useVDSM:
+ logger.error("Unable to start in background in VDSM mode, use interval
instead")
+ sys.exit(4)
+
if options.background:
try:
pid = os.fork()
@@ -104,11 +115,18 @@ if __name__ == '__main__':
logger.error("Error in reading configuration file (/etc/rhsm/rhsm.conf):
%s" % e)
sys.exit(2)
- try:
- virt = Virt(logger)
- except VirtError, e:
- print e
- sys.exit(3)
+ if options.useVDSM:
+ try:
+ virt = VDSM(logger)
+ except Exception, e:
+ logger.exception(e)
+ sys.exit(3)
+ else:
+ try:
+ virt = Virt(logger)
+ except VirtError, e:
+ logger.exception(e)
+ sys.exit(3)
subscriptionManager.connect()
if options.background: