summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSoren Hansen <soren@linux2go.dk>2011-11-10 10:58:08 +0100
committerSoren Hansen <soren@linux2go.dk>2011-11-10 13:35:54 +0100
commit41b4af111d4f80f51e79aeebc643ace60dee54f8 (patch)
tree5a97ef1e21595d14eac7b3730e68d4405f3b205e
parent6c0fd03fc3e4f30ca6d1e7d55e83d7a325fae447 (diff)
downloadnova-41b4af111d4f80f51e79aeebc643ace60dee54f8.tar.gz
nova-41b4af111d4f80f51e79aeebc643ace60dee54f8.tar.xz
nova-41b4af111d4f80f51e79aeebc643ace60dee54f8.zip
Replace libvirt driver's use of libxml2 with ElementTree
libxml2 has been rather awkward as a dependency, and ElementTree is in the standard library, so this replaces all use of libxml2 with ElementTree instead. Change-Id: Ib99983d5b04cc9f899584bfd4335fa9f7ece3c40
-rw-r--r--nova/tests/test_libvirt.py9
-rw-r--r--nova/virt/libvirt/connection.py132
2 files changed, 50 insertions, 91 deletions
diff --git a/nova/tests/test_libvirt.py b/nova/tests/test_libvirt.py
index d0ca361ad..72ba84d7f 100644
--- a/nova/tests/test_libvirt.py
+++ b/nova/tests/test_libvirt.py
@@ -51,13 +51,6 @@ except ImportError:
libvirt = None
-try:
- import libxml2
- connection.libxml2 = libxml2
-except ImportError:
- libxml2 = None
-
-
FLAGS = flags.FLAGS
LOG = logging.getLogger('nova.tests.test_libvirt')
@@ -243,7 +236,7 @@ class FakeVolumeDriver(object):
def missing_libvirt():
- return libvirt is None or libxml2 is None
+ return libvirt is None
class LibvirtConnTestCase(test.TestCase):
diff --git a/nova/virt/libvirt/connection.py b/nova/virt/libvirt/connection.py
index a8a5caa01..28e351771 100644
--- a/nova/virt/libvirt/connection.py
+++ b/nova/virt/libvirt/connection.py
@@ -74,7 +74,6 @@ from nova.virt.libvirt import netutils
libvirt = None
-libxml2 = None
Template = None
@@ -155,11 +154,8 @@ def get_connection(read_only):
# Cheetah is separate because the unit tests want to load Cheetah,
# but not libvirt.
global libvirt
- global libxml2
if libvirt is None:
libvirt = __import__('libvirt')
- if libxml2 is None:
- libxml2 = __import__('libxml2')
_late_load_cheetah()
return LibvirtConnection(read_only)
@@ -399,22 +395,15 @@ class LibvirtConnection(driver.ComputeDriver):
def _get_disk_xml(self, xml, device):
"""Returns the xml for the disk mounted at device"""
try:
- doc = libxml2.parseDoc(xml)
+ doc = ElementTree.fromstring(xml)
except Exception:
return None
- ctx = doc.xpathNewContext()
- try:
- ret = ctx.xpathEval('/domain/devices/disk')
- for node in ret:
- for child in node.children:
- if child.name == 'target':
- if child.prop('dev') == device:
- return str(node)
- finally:
- if ctx is not None:
- ctx.xpathFreeContext()
- if doc is not None:
- doc.freeDoc()
+ ret = doc.findall('./devices/disk')
+ for node in ret:
+ for child in node.getchildren():
+ if child.tag == 'target':
+ if child.get('dev') == device:
+ return ElementTree.tostring(node)
@exception.wrap_exception()
def detach_volume(self, connection_info, instance_name, mountpoint):
@@ -1285,37 +1274,29 @@ class LibvirtConnection(driver.ComputeDriver):
Returns a list of all block devices for this domain.
"""
domain = self._lookup_by_name(instance_name)
- # TODO(devcamcar): Replace libxml2 with etree.
xml = domain.XMLDesc(0)
doc = None
try:
- doc = libxml2.parseDoc(xml)
+ doc = ElementTree.fromstring(xml)
except Exception:
return []
- ctx = doc.xpathNewContext()
disks = []
- try:
- ret = ctx.xpathEval('/domain/devices/disk')
+ ret = doc.findall('./devices/disk')
- for node in ret:
- devdst = None
+ for node in ret:
+ devdst = None
- for child in node.children:
- if child.name == 'target':
- devdst = child.prop('dev')
+ for child in node.children:
+ if child.name == 'target':
+ devdst = child.prop('dev')
- if devdst is None:
- continue
+ if devdst is None:
+ continue
- disks.append(devdst)
- finally:
- if ctx is not None:
- ctx.xpathFreeContext()
- if doc is not None:
- doc.freeDoc()
+ disks.append(devdst)
return disks
@@ -1326,37 +1307,29 @@ class LibvirtConnection(driver.ComputeDriver):
Returns a list of all network interfaces for this instance.
"""
domain = self._lookup_by_name(instance_name)
- # TODO(devcamcar): Replace libxml2 with etree.
xml = domain.XMLDesc(0)
doc = None
try:
- doc = libxml2.parseDoc(xml)
+ doc = ElementTree.fromstring(xml)
except Exception:
return []
- ctx = doc.xpathNewContext()
interfaces = []
- try:
- ret = ctx.xpathEval('/domain/devices/interface')
+ ret = doc.findall('./devices/interface')
- for node in ret:
- devdst = None
+ for node in ret:
+ devdst = None
- for child in node.children:
- if child.name == 'target':
- devdst = child.prop('dev')
+ for child in node.children:
+ if child.name == 'target':
+ devdst = child.prop('dev')
- if devdst is None:
- continue
+ if devdst is None:
+ continue
- interfaces.append(devdst)
- finally:
- if ctx is not None:
- ctx.xpathFreeContext()
- if doc is not None:
- doc.freeDoc()
+ interfaces.append(devdst)
return interfaces
@@ -1488,8 +1461,8 @@ class LibvirtConnection(driver.ComputeDriver):
"""
xml = self._conn.getCapabilities()
- xml = libxml2.parseDoc(xml)
- nodes = xml.xpathEval('//host/cpu')
+ xml = ElementTree.fromstring(xml)
+ nodes = xml.findall('.//host/cpu')
if len(nodes) != 1:
reason = _("'<cpu>' must be 1, but %d\n") % len(nodes)
reason += xml.serialize()
@@ -1497,38 +1470,36 @@ class LibvirtConnection(driver.ComputeDriver):
cpu_info = dict()
- arch_nodes = xml.xpathEval('//host/cpu/arch')
+ arch_nodes = xml.findall('.//host/cpu/arch')
if arch_nodes:
- cpu_info['arch'] = arch_nodes[0].getContent()
+ cpu_info['arch'] = arch_nodes[0].text
- model_nodes = xml.xpathEval('//host/cpu/model')
+ model_nodes = xml.findall('.//host/cpu/model')
if model_nodes:
- cpu_info['model'] = model_nodes[0].getContent()
+ cpu_info['model'] = model_nodes[0].text
- vendor_nodes = xml.xpathEval('//host/cpu/vendor')
+ vendor_nodes = xml.findall('.//host/cpu/vendor')
if vendor_nodes:
- cpu_info['vendor'] = vendor_nodes[0].getContent()
+ cpu_info['vendor'] = vendor_nodes[0].text
- topology_nodes = xml.xpathEval('//host/cpu/topology')
+ topology_nodes = xml.findall('.//host/cpu/topology')
topology = dict()
if topology_nodes:
- topology_node = topology_nodes[0].get_properties()
- while topology_node:
- name = topology_node.get_name()
- topology[name] = topology_node.getContent()
- topology_node = topology_node.get_next()
+ topology_node = topology_nodes[0]
keys = ['cores', 'sockets', 'threads']
- tkeys = topology.keys()
+ tkeys = topology_node.keys()
if set(tkeys) != set(keys):
ks = ', '.join(keys)
reason = _("topology (%(topology)s) must have %(ks)s")
raise exception.InvalidCPUInfo(reason=reason % locals())
+ for key in keys:
+ topology[key] = topology_node.get(key)
- feature_nodes = xml.xpathEval('//host/cpu/feature')
+ feature_nodes = xml.findall('.//host/cpu/feature')
features = list()
for nodes in feature_nodes:
- features.append(nodes.get_properties().getContent())
+ features.append(nodes.get('name'))
cpu_info['topology'] = topology
cpu_info['features'] = features
@@ -1889,26 +1860,21 @@ class LibvirtConnection(driver.ComputeDriver):
virt_dom = self._lookup_by_name(instance_ref.name)
xml = virt_dom.XMLDesc(0)
- doc = libxml2.parseDoc(xml)
- disk_nodes = doc.xpathEval('//devices/disk')
- path_nodes = doc.xpathEval('//devices/disk/source')
- driver_nodes = doc.xpathEval('//devices/disk/driver')
+ doc = ElementTree.fromstring(xml)
+ disk_nodes = doc.findall('.//devices/disk')
+ path_nodes = doc.findall('.//devices/disk/source')
+ driver_nodes = doc.findall('.//devices/disk/driver')
for cnt, path_node in enumerate(path_nodes):
- disk_type = disk_nodes[cnt].get_properties().getContent()
- path = path_node.get_properties().getContent()
+ disk_type = disk_nodes[cnt].get('type')
+ path = path_node.get('file')
if disk_type != 'file':
LOG.debug(_('skipping %(path)s since it looks like volume') %
locals())
continue
- # In case of libvirt.xml, disk type can be obtained
- # by the below statement.
- # -> disk_type = driver_nodes[cnt].get_properties().getContent()
- # but this xml is generated by kvm, format is slightly different.
- disk_type = \
- driver_nodes[cnt].get_properties().get_next().getContent()
+ disk_type = driver_nodes[cnt].get('type')
if disk_type == 'raw':
size = int(os.path.getsize(path))
backing_file = ""