From 24e433a8de119ef5e2a6a9843dd72bcbcb6cbc59 Mon Sep 17 00:00:00 2001 From: Cole Robinson Date: Wed, 17 Jul 2013 17:11:18 -0400 Subject: [PATCH] CPU: Convert to new style XML props --- tests/cli-test-xml/compare/kvm-f14-url.xml | 52 ++-- tests/cli-test-xml/compare/w2k3-cdrom.xml | 6 +- tests/xmlconfig-xml/boot-cpuset.xml | 6 +- tests/xmlparse-xml/change-guest-out.xml | 4 +- .../xmlparse-xml/change-minimal-guest-out.xml | 2 +- tests/xmlparse.py | 2 +- virtinst/CPU.py | 234 +++++------------- virtinst/VirtualDevice.py | 2 +- virtinst/xmlbuilder.py | 28 +-- 9 files changed, 111 insertions(+), 225 deletions(-) diff --git a/tests/cli-test-xml/compare/kvm-f14-url.xml b/tests/cli-test-xml/compare/kvm-f14-url.xml index 3410e5e73..5e3f8b2c3 100644 --- a/tests/cli-test-xml/compare/kvm-f14-url.xml +++ b/tests/cli-test-xml/compare/kvm-f14-url.xml @@ -16,19 +16,19 @@ core2duo Intel - - - - - - - - - - - - - + + + + + + + + + + + + + destroy @@ -70,19 +70,19 @@ core2duo Intel - - - - - - - - - - - - - + + + + + + + + + + + + + destroy diff --git a/tests/cli-test-xml/compare/w2k3-cdrom.xml b/tests/cli-test-xml/compare/w2k3-cdrom.xml index a4a896d4e..ea04f8789 100644 --- a/tests/cli-test-xml/compare/w2k3-cdrom.xml +++ b/tests/cli-test-xml/compare/w2k3-cdrom.xml @@ -12,7 +12,7 @@ - + @@ -50,7 +50,7 @@ - + @@ -88,7 +88,7 @@ - + diff --git a/tests/xmlconfig-xml/boot-cpuset.xml b/tests/xmlconfig-xml/boot-cpuset.xml index 3fb10dbd5..0e119b7a1 100644 --- a/tests/xmlconfig-xml/boot-cpuset.xml +++ b/tests/xmlconfig-xml/boot-cpuset.xml @@ -12,12 +12,12 @@ - + footest Intel - - + + destroy diff --git a/tests/xmlparse-xml/change-guest-out.xml b/tests/xmlparse-xml/change-guest-out.xml index 322311b7d..3b4df2e36 100644 --- a/tests/xmlparse-xml/change-guest-out.xml +++ b/tests/xmlparse-xml/change-guest-out.xml @@ -20,8 +20,8 @@ qemu64 qemuvendor - - + + destroy diff --git a/tests/xmlparse-xml/change-minimal-guest-out.xml b/tests/xmlparse-xml/change-minimal-guest-out.xml index c9df30abb..1821aaa9b 100644 --- a/tests/xmlparse-xml/change-minimal-guest-out.xml +++ b/tests/xmlparse-xml/change-minimal-guest-out.xml @@ -25,6 +25,6 @@ foobar - + diff --git a/tests/xmlparse.py b/tests/xmlparse.py index 02a306add..387e1ac33 100644 --- a/tests/xmlparse.py +++ b/tests/xmlparse.py @@ -161,7 +161,7 @@ class XMLParseTest(unittest.TestCase): check("sockets", 4, 4) check = self._make_checker(guest.cpu.features[0]) - check("name", "x2apic", "foofeat") + check("name", "x2apic") check("policy", "force", "disable") guest.cpu.remove_feature(guest.cpu.features[1]) guest.cpu.add_feature("addfeature") diff --git a/virtinst/CPU.py b/virtinst/CPU.py index 07ddd4f60..59e86b07c 100644 --- a/virtinst/CPU.py +++ b/virtinst/CPU.py @@ -22,12 +22,6 @@ from virtinst.xmlbuilder import XMLBuilder, XMLProperty import libxml2 -def _int_or_none(val): - if val is None: - return None - return int(val) - - class CPUFeature(XMLBuilder): """ Class for generating child XML @@ -35,40 +29,35 @@ class CPUFeature(XMLBuilder): POLICIES = ["force", "require", "optional", "disable", "forbid"] - def __init__(self, conn, parsexml=None, parsexmlnode=None): - XMLBuilder.__init__(self, conn, parsexml, - parsexmlnode) + _XML_PROP_ORDER = ["_xmlname", "policy"] + _XML_ROOT_NAME = "cpu" + _XML_XPATH_RELATIVE = True + _XML_INDENT = 4 - self._name = None - self._policy = None + def __init__(self, conn, name, parsexml=None, parsexmlnode=None): + XMLBuilder.__init__(self, conn, parsexml, parsexmlnode) - if self._is_parse(): - return + self._name = name + self._xmlname = name def _get_name(self): - return self._name - def _set_name(self, val): - self._name = val - name = XMLProperty(_get_name, _set_name, - xpath="./@name") + return self._xmlname + name = property(_get_name) - def _get_policy(self): - return self._policy - def _set_policy(self, val): - self._policy = val - policy = XMLProperty(_get_policy, _set_policy, - xpath="./@policy") + def _name_xpath(self): + return "./cpu/feature[@name='%s']/@name" % self._name + _xmlname = XMLProperty(name="feature name", + xml_get_xpath=_name_xpath, + xml_set_xpath=_name_xpath) + def _policy_xpath(self): + return "./cpu/feature[@name='%s']/@policy" % self._name + policy = XMLProperty(name="feature policy", + xml_get_xpath=_policy_xpath, + xml_set_xpath=_policy_xpath) - def _get_xml_config(self): - if not self.name: - return "" - - xml = " XML """ - _dumpxml_xpath = "/domain/cpu" - MATCHS = ["minimum", "exact", "strict"] + _dumpxml_xpath = "/domain/cpu" + _XML_ROOT_NAME = "cpu" + _XML_INDENT = 2 + _XML_XPATH_RELATIVE = True + _XML_PROP_ORDER = ["mode", "match", "model", "vendor", + "sockets", "cores", "threads"] + def __init__(self, conn, parsexml=None, parsexmlnode=None): - self._model = None - self._match = None - self._vendor = None - self._mode = None self._features = [] - - self._sockets = None - self._cores = None - self._threads = None - - XMLBuilder.__init__(self, conn, parsexml, - parsexmlnode) - if self._is_parse(): - return + self._XML_SUB_ELEMENTS = self._XML_SUB_ELEMENTS + ["_features"] + XMLBuilder.__init__(self, conn, parsexml, parsexmlnode) def _parsexml(self, xml, node): XMLBuilder._parsexml(self, xml, node) @@ -102,89 +85,25 @@ class CPU(XMLBuilder): for node in self._xml_node.children: if node.name != "feature": continue - feature = CPUFeature(self.conn, parsexmlnode=node) + if not node.prop("name"): + continue + feature = CPUFeature(self.conn, node.prop("name"), + parsexmlnode=self._xml_node) self._features.append(feature) + def add_feature(self, name, policy="require"): + feature = CPUFeature(self.conn, name, parsexmlnode=self._xml_node) + feature.policy = policy + self._features.append(feature) + + def remove_feature(self, feature): + self._features.remove(feature) + feature.clear() + def _get_features(self): return self._features[:] features = property(_get_features) - def add_feature(self, name, policy="require"): - feature = CPUFeature(self.conn) - feature.name = name - feature.policy = policy - - if self._is_parse(): - xml = feature.get_xml_config() - node = libxml2.parseDoc(xml).children - feature.set_xml_node(node) - self._add_child_node("./cpu", node) - - self._features.append(feature) - - def remove_feature(self, feature): - if self._is_parse() and feature in self._features: - xpath = feature.get_xml_node_path() - if xpath: - self._remove_child_xpath(xpath) - - self._features.remove(feature) - - - def _get_model(self): - return self._model - def _set_model(self, val): - if val: - self.mode = "custom" - if val and not self.match: - self.match = "exact" - self._model = val - model = XMLProperty(_get_model, _set_model, - xpath="./cpu/model") - - def _get_match(self): - return self._match - def _set_match(self, val): - self._match = val - match = XMLProperty(_get_match, _set_match, - xpath="./cpu/@match") - - def _get_vendor(self): - return self._vendor - def _set_vendor(self, val): - self._vendor = val - vendor = XMLProperty(_get_vendor, _set_vendor, - xpath="./cpu/vendor") - - def _get_mode(self): - return self._mode - def _set_mode(self, val): - self._mode = val - mode = XMLProperty(_get_mode, _set_mode, - xpath="./cpu/@mode") - - # Topology properties - def _get_sockets(self): - return self._sockets - def _set_sockets(self, val): - self._sockets = _int_or_none(val) - sockets = XMLProperty(_get_sockets, _set_sockets, is_int=True, - xpath="./cpu/topology/@sockets") - - def _get_cores(self): - return self._cores - def _set_cores(self, val): - self._cores = _int_or_none(val) - cores = XMLProperty(_get_cores, _set_cores, is_int=True, - xpath="./cpu/topology/@cores") - - def _get_threads(self): - return self._threads - def _set_threads(self, val): - self._threads = _int_or_none(val) - threads = XMLProperty(_get_threads, _set_threads, is_int=True, - xpath="./cpu/topology/@threads") - def clear_attrs(self): self.match = None self.mode = None @@ -259,56 +178,23 @@ class CPU(XMLBuilder): return - def _get_topology_xml(self): - xml = "" - if self.sockets: - xml += " sockets='%s'" % self.sockets - if self.cores: - xml += " cores='%s'" % self.cores - if self.threads: - xml += " threads='%s'" % self.threads - if not xml: - return "" - return " \n" % xml + ################## + # XML properties # + ################## - def _get_feature_xml(self): - xml = "" - for feature in self._features: - xml += feature.get_xml_config() + "\n" - return xml - - def _get_xml_config(self): - top_xml = self._get_topology_xml() - feature_xml = self._get_feature_xml() - mode_xml = "" - match_xml = "" - if self.match: - match_xml = " match='%s'" % self.match - xml = "" - - if self.model == "host-passthrough": - self.mode = "host-passthrough" - mode_xml = " mode='%s'" % self.mode - xml += " " % mode_xml - return xml - else: + def _set_model(self, val): + if val: self.mode = "custom" - mode_xml = " mode='%s'" % self.mode + if not self.match: + self.match = "exact" + return val + model = XMLProperty(xpath="./cpu/model", set_converter=_set_model) - if not (self.model or top_xml or feature_xml): - return "" + match = XMLProperty(xpath="./cpu/@match") + vendor = XMLProperty(xpath="./cpu/vendor") + mode = XMLProperty(xpath="./cpu/@mode") - # Simple topology XML mode - xml += " \n" % (mode_xml, match_xml) - if self.model: - xml += " %s\n" % self.model - if self.vendor: - xml += " %s\n" % self.vendor - if top_xml: - xml += top_xml - if feature_xml: - xml += feature_xml - - xml += " " - return xml + sockets = XMLProperty(xpath="./cpu/topology/@sockets", is_int=True) + cores = XMLProperty(xpath="./cpu/topology/@cores", is_int=True) + threads = XMLProperty(xpath="./cpu/topology/@threads", is_int=True) diff --git a/virtinst/VirtualDevice.py b/virtinst/VirtualDevice.py index bf7a9cc55..c97562d70 100644 --- a/virtinst/VirtualDevice.py +++ b/virtinst/VirtualDevice.py @@ -132,7 +132,7 @@ class VirtualDeviceAddress(XMLBuilder): _XML_ROOT_NAME = "address" _XML_INDENT = 0 - _XML_XPATH_RELATIVE = True + #_XML_XPATH_RELATIVE = True _XML_PROP_ORDER = ["type", "domain", "bus", "slot", "function"] def set_addrstr(self, addrstr): diff --git a/virtinst/xmlbuilder.py b/virtinst/xmlbuilder.py index 1b5d9a81f..fa6d22fb8 100644 --- a/virtinst/xmlbuilder.py +++ b/virtinst/xmlbuilder.py @@ -378,7 +378,8 @@ class XMLProperty(property): if not xpath.startswith(root): raise RuntimeError("%s: xpath did not start with root=%s" % (str(self), root)) - return "." + xpath[len(root):] + ret = "." + xpath[len(root):] + return ret def _xpath_list_for_setter(self, xpath, setval, nodelist): @@ -696,21 +697,18 @@ class XMLBuilder(object): else: ret = _sanitize_libxml_xml(node.serialize()) else: - try: - self._xml_fixup_relative_xpath = self._XML_XPATH_RELATIVE - xmlstub = self._make_xml_stub(fail=False) - ret = self._get_xml_config(*args, **kwargs) - if ret is None: - return None - ret = self._add_parse_bits(ret) + xmlstub = self._make_xml_stub(fail=False) + ret = self._get_xml_config(*args, **kwargs) + if ret is None: + return None + ret = self._add_parse_bits(ret) - for propname in self._XML_SUB_ELEMENTS: - ret = getattr(self, propname)._add_parse_bits(ret) + for propname in self._XML_SUB_ELEMENTS: + for prop in util.listify(getattr(self, propname)): + ret = prop._add_parse_bits(ret) - if ret == xmlstub: - ret = "" - finally: - self._xml_fixup_relative_xpath = False + if ret == xmlstub: + ret = "" return self._cleanup_xml(ret) @@ -852,6 +850,7 @@ class XMLBuilder(object): origproporder = self._proporder[:] origpropstore = self._propstore.copy() try: + self._xml_fixup_relative_xpath = self._XML_XPATH_RELATIVE return self._do_add_parse_bits(xml) finally: self._xml_root_doc = None @@ -859,3 +858,4 @@ class XMLBuilder(object): self._xml_ctx = None self._proporder = origproporder self._propstore = origpropstore + self._xml_fixup_relative_xpath = False