mirror of
https://github.com/virt-manager/virt-manager.git
synced 2025-01-24 02:04:13 +03:00
xmlbuilder: Allow classes to specify order of certain xml elements
This will save us some test case churn. As an example, we now do auto building of disk <target> XML and it doesn't alter things. Without this bus and target are often swapped.
This commit is contained in:
parent
154bad0184
commit
2cea517823
@ -23,17 +23,17 @@
|
||||
<devices>
|
||||
<emulator>/usr/bin/test-hv</emulator>
|
||||
<disk type="file" device="disk">
|
||||
<driver cache="writeback" io="threads"/>
|
||||
<source file="/default-pool/UPPER"/>
|
||||
<target dev="hda" bus="ide"/>
|
||||
<shareable/>
|
||||
<serial>WD-WMAP9A966149</serial>
|
||||
<driver cache="writeback" io="threads"/>
|
||||
</disk>
|
||||
<disk type="file" device="disk">
|
||||
<driver error_policy="enospace"/>
|
||||
<source file="/tmp/__virtinst_cli_new1.img"/>
|
||||
<target dev="hdb" bus="ide"/>
|
||||
<readonly/>
|
||||
<driver error_policy="enospace"/>
|
||||
</disk>
|
||||
<disk type="block" device="cdrom">
|
||||
<target dev="sda" bus="sata"/>
|
||||
@ -110,17 +110,17 @@
|
||||
<devices>
|
||||
<emulator>/usr/bin/test-hv</emulator>
|
||||
<disk type="file" device="disk">
|
||||
<driver cache="writeback" io="threads"/>
|
||||
<source file="/default-pool/UPPER"/>
|
||||
<target dev="hda" bus="ide"/>
|
||||
<shareable/>
|
||||
<serial>WD-WMAP9A966149</serial>
|
||||
<driver cache="writeback" io="threads"/>
|
||||
</disk>
|
||||
<disk type="file" device="disk">
|
||||
<driver error_policy="enospace"/>
|
||||
<source file="/tmp/__virtinst_cli_new1.img"/>
|
||||
<target dev="hdb" bus="ide"/>
|
||||
<readonly/>
|
||||
<driver error_policy="enospace"/>
|
||||
</disk>
|
||||
<disk type="block" device="cdrom">
|
||||
<target dev="sda" bus="sata"/>
|
||||
|
@ -157,6 +157,7 @@ def read_file(filename):
|
||||
def diff_compare(actual_out, filename=None, expect_out=None):
|
||||
"""Compare passed string output to contents of filename"""
|
||||
if not expect_out:
|
||||
#file(filename, "w").write(actual_out)
|
||||
expect_out = read_file(filename)
|
||||
|
||||
diff = "".join(difflib.unified_diff(expect_out.splitlines(1),
|
||||
|
@ -388,10 +388,14 @@ class VirtualDisk(VirtualDevice):
|
||||
except Exception, e:
|
||||
raise ValueError(_("Couldn't lookup volume object: %s" % str(e)))
|
||||
|
||||
_DEFAULT_SENTINEL = -1234
|
||||
|
||||
_XMLELEMENTORDER = ["driver", "source", "target"]
|
||||
_XMLPROPORDER = ["target", "bus"]
|
||||
|
||||
def __init__(self, conn, parsexml=None, parsexmlnode=None):
|
||||
VirtualDevice.__init__(self, conn, parsexml, parsexmlnode)
|
||||
|
||||
self._DEFAULT_SENTINEL = -1234
|
||||
self._device = self.DEVICE_DISK
|
||||
self._type = self._DEFAULT_SENTINEL
|
||||
self._driverName = self._DEFAULT_SENTINEL
|
||||
@ -756,8 +760,6 @@ class VirtualDisk(VirtualDevice):
|
||||
if path is not None:
|
||||
ret += " <source %s='%s'/>\n" % (typeattr, path)
|
||||
|
||||
ret += " <target dev='%s'/>\n" % (self.target)
|
||||
|
||||
addr = self.indent(self.address.get_xml_config(), 6)
|
||||
if addr:
|
||||
ret += addr
|
||||
|
@ -521,6 +521,12 @@ class XMLBuilder(object):
|
||||
xml += " " * level + l + "\n"
|
||||
return xml
|
||||
|
||||
# Specify a list of tag values here and we will arrange them when
|
||||
# outputing XML. They will be put before every other element. This
|
||||
# is strictly to keep test suite happy.
|
||||
_XMLELEMENTORDER = []
|
||||
_XMLPROPORDER = []
|
||||
|
||||
_dumpxml_xpath = "."
|
||||
def __init__(self, conn, parsexml=None, parsexmlnode=None):
|
||||
"""
|
||||
@ -596,10 +602,20 @@ class XMLBuilder(object):
|
||||
if not self._propstore or self._is_parse():
|
||||
return xml
|
||||
|
||||
do_order = []
|
||||
proporder = self._proporder[:]
|
||||
propstore = self._propstore.copy()
|
||||
|
||||
for key in self._XMLPROPORDER:
|
||||
if key in proporder:
|
||||
proporder.remove(key)
|
||||
do_order.append(key)
|
||||
proporder = do_order + proporder
|
||||
|
||||
try:
|
||||
self._parsexml(xml, None)
|
||||
for key in self._proporder[:]:
|
||||
setattr(self, key, self._propstore[key])
|
||||
for key in proporder:
|
||||
setattr(self, key, propstore[key])
|
||||
ret = self.get_xml_config()
|
||||
for c in xml:
|
||||
if c != " ":
|
||||
@ -627,6 +643,37 @@ class XMLBuilder(object):
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def _order_xml_elements(self, xml):
|
||||
# This whole thing is reeeally hacky but it saves us some
|
||||
# unittest churn.
|
||||
if not self._XMLELEMENTORDER:
|
||||
return xml
|
||||
|
||||
split = xml.splitlines()
|
||||
if len(split) < 3:
|
||||
return xml
|
||||
|
||||
head = split[0]
|
||||
end = split[-1]
|
||||
split = split[1:-1]
|
||||
|
||||
baseindent = 0
|
||||
for i in head:
|
||||
if i != " ":
|
||||
break
|
||||
baseindent += 1
|
||||
|
||||
neworder = []
|
||||
for prio in reversed(self._XMLELEMENTORDER):
|
||||
tag = "%s<%s " % ((baseindent + 2) * " ", prio)
|
||||
for idx in range(len(split)):
|
||||
if split[idx].startswith(tag):
|
||||
neworder.insert(0, split.pop(idx))
|
||||
break
|
||||
neworder += split
|
||||
|
||||
return "\n".join([head] + neworder + [end])
|
||||
|
||||
def get_xml_config(self, *args, **kwargs):
|
||||
"""
|
||||
Construct and return object xml
|
||||
@ -637,7 +684,10 @@ class XMLBuilder(object):
|
||||
if self._xml_ctx:
|
||||
node = _get_xpath_node(self._xml_ctx, self._dumpxml_xpath)
|
||||
if not node:
|
||||
return ""
|
||||
return _sanitize_libxml_xml(node.serialize())
|
||||
ret = ""
|
||||
else:
|
||||
ret = _sanitize_libxml_xml(node.serialize())
|
||||
else:
|
||||
ret = self._get_xml_config(*args, **kwargs)
|
||||
|
||||
return self._get_xml_config(*args, **kwargs)
|
||||
return self._order_xml_elements(ret)
|
||||
|
Loading…
x
Reference in New Issue
Block a user