[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