[Libvirt-cim] [PATCH] [TEST] Use python-lxml instead of PyXML
Chip Vincent
cvincent at linux.vnet.ibm.com
Sat Dec 24 01:55:25 UTC 2011
Pushed.
On 12/05/2011 11:24 AM, Eduardo Lima (Etrunko) wrote:
> From: Eduardo Lima (Etrunko)<eblima at br.ibm.com>
>
> PyXML is a legacy python XML library which won't work with recent versions of
> python unless you patch the code. The following link describes the problem:
>
> http://stackoverflow.com/questions/4953600/pyxml-on-ubuntu
>
> In summary, when trying to install PyXML with easy_install, you get an error
> because it tries to use 'as' which is a reserved keyword introduced in python
> 2.5.
>
> This patch removes dependency of PyXML in favor of python-lxml, which provides
> bindings to the very complete and fast libxml2:
>
> http://lxml.de/intro.html
>
> Signed-off-by: Eduardo Lima (Etrunko)<eblima at br.ibm.com>
> ---
> suites/libvirt-cim/cimtest/FilterList/helper.py | 8 +--
> .../12_referenced_config.py | 14 +---
> .../24_define_sys_features.py | 6 +-
> suites/libvirt-cim/lib/XenKvmLib/test_xml.py | 27 +++---
> suites/libvirt-cim/lib/XenKvmLib/vxml.py | 95 ++++++++++----------
> 5 files changed, 69 insertions(+), 81 deletions(-)
>
> diff --git a/suites/libvirt-cim/cimtest/FilterList/helper.py b/suites/libvirt-cim/cimtest/FilterList/helper.py
> index 138f941..9ae2f62 100644
> --- a/suites/libvirt-cim/cimtest/FilterList/helper.py
> +++ b/suites/libvirt-cim/cimtest/FilterList/helper.py
> @@ -35,11 +35,7 @@ from XenKvmLib.vxml import get_class
> import VirtLib
> from VirtLib.utils import run_remote
>
> -try:
> - from xml.etree import cElementTree as ElementTree
> -except:
> - from xml.etree import ElementTree
> -
> +from lxml import etree
>
> class BaseTestObject(object):
>
> @@ -247,7 +243,7 @@ class FilterListTest(BaseTestObject):
>
> # Remove all unecessary spaces and new lines
> _xml = "".join([a.strip() for a in out.split("\n") if a])
> - return ElementTree.fromstring(_xml)
> + return etree.fromstring(_xml)
> # libvirt_filter_dumpxml
>
> def libvirt_entries_in_filter_lists(self):
> diff --git a/suites/libvirt-cim/cimtest/VirtualSystemManagementService/12_referenced_config.py b/suites/libvirt-cim/cimtest/VirtualSystemManagementService/12_referenced_config.py
> index 7af65fd..24b47e9 100644
> --- a/suites/libvirt-cim/cimtest/VirtualSystemManagementService/12_referenced_config.py
> +++ b/suites/libvirt-cim/cimtest/VirtualSystemManagementService/12_referenced_config.py
> @@ -102,20 +102,8 @@ def setup_second_guest(ip, virt, cxml2, ref):
> return PASS, "define"
>
> def get_dom_disk_src(xml, ip):
> - disk_list = []
> -
> xml.dumpxml(ip)
> - myxml = xml.get_formatted_xml()
> -
> - lines = myxml.splitlines()
> - for l in lines:
> - if l.find("source file=") != -1:
> - disk = l.split('=')[1]
> - disk = disk.lstrip('\'')
> - disk = disk.rstrip('\'/>')
> - disk_list.append(disk)
> -
> - return disk_list
> + return xml.xdoc.xpath("/domain/devices/disk/source/@file")
>
> @do_main(sup_types)
> def main():
> diff --git a/suites/libvirt-cim/cimtest/VirtualSystemManagementService/24_define_sys_features.py b/suites/libvirt-cim/cimtest/VirtualSystemManagementService/24_define_sys_features.py
> index 9716cd1..42c59ec 100644
> --- a/suites/libvirt-cim/cimtest/VirtualSystemManagementService/24_define_sys_features.py
> +++ b/suites/libvirt-cim/cimtest/VirtualSystemManagementService/24_define_sys_features.py
> @@ -48,13 +48,13 @@ def main():
>
> cxml.dumpxml(options.ip)
>
> - if cxml.xml_get_pae() == None:
> + if cxml.xml_get_pae() is None:
> raise Exception("Failed to set pae for dom: %s" % default_dom)
>
> - if cxml.xml_get_acpi() == None:
> + if cxml.xml_get_acpi() is None:
> raise Exception("Failed to set acpi for dom: %s" % default_dom)
>
> - if cxml.xml_get_apic() == None:
> + if cxml.xml_get_apic() is None:
> raise Exception("Failed to set apic for dom: %s" % default_dom)
>
> status = PASS
> diff --git a/suites/libvirt-cim/lib/XenKvmLib/test_xml.py b/suites/libvirt-cim/lib/XenKvmLib/test_xml.py
> index 033275b..b32ae4c 100755
> --- a/suites/libvirt-cim/lib/XenKvmLib/test_xml.py
> +++ b/suites/libvirt-cim/lib/XenKvmLib/test_xml.py
> @@ -29,8 +29,7 @@ import os
> import sys
> import random
> from VirtLib import utils
> -from xml import xpath
> -from xml.dom import minidom, Node
> +from lxml import etree
> from CimTest.Globals import logger
> from XenKvmLib.test_doms import set_uuid, create_vnet
> from VirtLib.live import available_bridges
> @@ -212,22 +211,26 @@ def dumpxml(name, server, virt="Xen"):
> return o
>
> def get_value_xpath(xmlStr, xpathStr):
> - xmldoc = minidom.parseString(xmlStr)
> - nodes = xpath.Evaluate(xpathStr, xmldoc.documentElement)
> + xmldoc = etree.fromstring(xmlStr)
> + nodes = xmldoc.xpath(xpathStr)
>
> if len(nodes) != 1:
> raise LookupError('Zero or multiple xpath results found!')
>
> node = nodes[0]
> - if node.nodeType == Node.ATTRIBUTE_NODE:
> - return node.value
> - if node.nodeType == Node.TEXT_NODE:
> - return node.toxml()
> - if node.nodeType == Node.ELEMENT_NODE:
> + ret = ''
> +
> + if etree.iselement(node):
> + ret = node.text
> + for child in node:
> + ret = ret + child.text
> + elif isinstance(node, str):
> + ret = node
> +
> + if ret is None:
> ret = ''
> - for child in node.childNodes:
> - ret = ret + child.toxml()
> - return ret
> +
> + return ret
>
> def xml_get_dom_name(xmlStr):
> return get_value_xpath(xmlStr,
> diff --git a/suites/libvirt-cim/lib/XenKvmLib/vxml.py b/suites/libvirt-cim/lib/XenKvmLib/vxml.py
> index 15859c1..51a4166 100644
> --- a/suites/libvirt-cim/lib/XenKvmLib/vxml.py
> +++ b/suites/libvirt-cim/lib/XenKvmLib/vxml.py
> @@ -34,15 +34,10 @@ import sys
> import random
> import platform
> import tempfile
> -from time import sleep
> import pywbem
> -from xml.dom import minidom, Node
> -from xml import xpath
>
> -try:
> - from xml.etree import cElementTree as ElementTree
> -except:
> - from xml.etree import ElementTree
> +from lxml import etree
> +from time import sleep
>
> from VirtLib import utils, live
> from XenKvmLib.xm_virt_util import get_bridge_from_network_xml, bootloader, \
> @@ -64,35 +59,37 @@ class XMLClass:
> xdoc = None
>
> def __init__(self):
> - self.xdoc = minidom.Document()
> self.refresh()
>
> def __str__(self):
> return self.xml_string
>
> def refresh(self):
> - self.xml_string = self.xdoc.toxml()
> + if self.xdoc is not None:
> + self.xml_string = etree.tostring(self.xdoc)
>
> def get_node(self, ixpath):
> - node_list = xpath.Evaluate(ixpath, self.xdoc.documentElement)
> + if self.xdoc is None:
> + return None
> +
> + node_list = self.xdoc.xpath(ixpath)
> if len(node_list) != 1:
> raise LookupError('Zero or multiple nodes found for XPath' + ixpath)
> return node_list[0]
> +
> def add_sub_node(self, parent, node_name, text_cdata=None, **attrs):
> if isinstance(parent, basestring):
> pnode = self.get_node(parent)
> else:
> pnode = parent
>
> - node = self.xdoc.createElement(node_name)
> -
> - for key in attrs.keys():
> - node.setAttribute(key, str(attrs[key]))
> -
> - if text_cdata is not None:
> - node.appendChild(self.xdoc.createTextNode(str(text_cdata)))
> + if pnode is None:
> + self.xdoc = etree.Element(node_name, **attrs)
> + node = self.xdoc
> + else:
> + node = etree.SubElement(pnode, node_name, **attrs)
>
> - pnode.appendChild(node)
> + node.text = str(text_cdata)
> self.refresh()
>
> return node
> @@ -103,13 +100,7 @@ class XMLClass:
> else:
> pnode = parent
>
> - for cnode in pnode.childNodes:
> - pnode.removeChild(cnode)
> - cnode.unlink()
> -
> - if text_cdata is not None:
> - pnode.appendChild(self.xdoc.createTextNode(str(text_cdata)))
> -
> + pnode.text = str(text_cdata)
> self.refresh()
>
> def set_attributes(self, node, **attrs):
> @@ -118,8 +109,8 @@ class XMLClass:
> else:
> pnode = node
>
> - for key in attrs.keys():
> - pnode.setAttribute(key, str(attrs[key]))
> + for key, val in attrs.items():
> + pnode.set(key, val)
>
> self.refresh()
>
> @@ -127,7 +118,7 @@ class XMLClass:
> '''Don't use this to define domain.
> Extra newline in the text node fails libvirt
> '''
> - return self.xdoc.toprettyxml()
> + return etree.tostring(self.xdoc, pretty_print=True)
>
> def get_value_xpath(self, xpathStr):
> try:
> @@ -136,15 +127,19 @@ class XMLClass:
> logger.info('Zero or multiple node found')
> return None
>
> - if node.nodeType == Node.ATTRIBUTE_NODE:
> - return node.value
> - if node.nodeType == Node.TEXT_NODE:
> - return node.toxml()
> - if node.nodeType == Node.ELEMENT_NODE:
> + ret = ''
> +
> + if etree.iselement(node):
> + ret = node.text
> + for child in node:
> + ret = ret + child.text
> + elif isinstance(node, basestring):
> + ret = node
> +
> + if ret is None:
> ret = ''
> - for child in node.childNodes:
> - ret = ret + child.toxml()
> - return ret
> +
> + return ret
>
>
> class Virsh:
> @@ -220,7 +215,7 @@ class NetXML(Virsh, XMLClass):
>
> def _parse_net_dumpxml(_xml):
> try:
> - root = ElementTree.fromstring(_xml)
> + root = etree.fromstring(_xml)
> ip_element = root.find("ip")
> return ip_element.get("address")
> except:
> @@ -247,7 +242,7 @@ class NetXML(Virsh, XMLClass):
> return None
> else:
> self.xml_string = net_xml
> - self.xdoc = minidom.parseString(self.xml_string)
> + self.xdoc = etree.fromstring(self.xml_string)
> return
>
> network = self.add_sub_node(self.xdoc, 'network')
> @@ -337,7 +332,7 @@ class PoolXML(Virsh, XMLClass):
> return None
> else:
> self.xml_string = disk_xml
> - self.xdoc = minidom.parseString(self.xml_string)
> + self.xdoc = etree.fromstring(self.xml_string)
> return
>
> pool = self.add_sub_node(self.xdoc, 'pool', type='dir')
> @@ -547,8 +542,9 @@ class VirtXML(Virsh, XMLClass):
> cmd = 'virsh -c %s dumpxml %s 2>/dev/null' % (self.vuri, self.dname)
> s, o = utils.run_remote(ip, cmd)
> if s == 0:
> - self.xml_string = o
> - self.xdoc = minidom.parseString(self.xml_string)
> + o = "".join([i.strip() for i in o.split("\n") if i])
> + self.xdoc = etree.fromstring(o)
> + self.refresh()
>
> def _set_emulator(self, emu):
> self.add_sub_node('/domain/devices', 'emulator', emu)
> @@ -562,7 +558,7 @@ class VirtXML(Virsh, XMLClass):
> # pick the 1st virtual bridge
> br = br_list[0]
> interface = self.get_node('/domain/devices/interface')
> - interface.setAttribute('type', 'bridge')
> + interface.set('type', 'bridge')
> self.add_sub_node(interface, 'source', bridge=br)
>
> return br
> @@ -570,20 +566,25 @@ class VirtXML(Virsh, XMLClass):
> def _set_vbridge(self, ip, virt_type, net_name):
> vbr = get_bridge_from_network_xml(net_name, ip, virt=virt_type)
>
> - interface = self.get_node('/domain/devices/interface')
> - interface.setAttribute('type', 'bridge')
> - self.add_sub_node(interface, 'source', bridge=vbr)
> + if vbr is not None:
> + interface = self.get_node('/domain/devices/interface')
> + interface.set('type', 'bridge')
> + self.add_sub_node(interface, 'source', bridge=vbr)
>
> return vbr
>
> def set_interface_details(self, devices, net_mac, net_type, net_name,
> virt_type):
> interface = self.add_sub_node(devices, 'interface', type=net_type)
> - self.add_sub_node(interface, 'mac', address=net_mac)
> +
> + if net_mac:
> + self.add_sub_node(interface, 'mac', address=net_mac)
> +
> if net_type == 'bridge':
> self._set_vbridge(CIM_IP, virt_type, net_name)
> elif net_type == 'network':
> - self.add_sub_node(interface, 'source', network=net_name)
> + if net_name:
> + self.add_sub_node(interface, 'source', network=net_name)
> elif net_type == 'ethernet':
> pass
> elif net_type == 'user':
--
Chip Vincent
Open Virtualization
IBM Linux Technology Center
cvincent at linux.vnet.ibm.com
More information about the Libvirt-cim
mailing list