mirror of
https://github.com/virt-manager/virt-manager.git
synced 2025-09-07 17:44:17 +03:00
xmlbuilder: Support clear()ing an object in place
This gives friendly XML output via virt-xml for clearxml=yes + extra options: the XML block is editted in place, rather than removed and with the newchanges appended
This commit is contained in:
@@ -1,20 +1,12 @@
|
|||||||
<feature policy="require" name="xtpr"/>
|
|
||||||
<feature policy="require" name="acpi"/>
|
<feature policy="require" name="acpi"/>
|
||||||
</cpu>
|
</cpu>
|
||||||
- <clock offset="utc">
|
<clock offset="utc">
|
||||||
- <timer name="rtc" tickpolicy="catchup"/>
|
- <timer name="rtc" tickpolicy="catchup"/>
|
||||||
- <timer name="pit" tickpolicy="delay"/>
|
- <timer name="pit" tickpolicy="delay"/>
|
||||||
- <timer name="hpet" present="no"/>
|
- <timer name="hpet" present="no"/>
|
||||||
- </clock>
|
</clock>
|
||||||
<on_poweroff>destroy</on_poweroff>
|
<on_poweroff>destroy</on_poweroff>
|
||||||
<on_reboot>restart</on_reboot>
|
<on_reboot>restart</on_reboot>
|
||||||
<on_crash>restart</on_crash>
|
|
||||||
@@
|
|
||||||
</panic>
|
|
||||||
</devices>
|
|
||||||
<seclabel type="dynamic" model="selinux" relabel="yes"/>
|
|
||||||
+ <clock offset="utc"/>
|
|
||||||
</domain>
|
|
||||||
|
|
||||||
Domain 'test-for-virtxml' defined successfully.
|
Domain 'test-for-virtxml' defined successfully.
|
||||||
Changes will take effect after the next domain shutdown.
|
Changes will take effect after the next domain shutdown.
|
@@ -17,16 +17,10 @@
|
|||||||
- <feature policy="require" name="ds_cpl"/>
|
- <feature policy="require" name="ds_cpl"/>
|
||||||
- <feature policy="require" name="xtpr"/>
|
- <feature policy="require" name="xtpr"/>
|
||||||
- <feature policy="require" name="acpi"/>
|
- <feature policy="require" name="acpi"/>
|
||||||
- </cpu>
|
+ <cpu mode="host-passthrough">
|
||||||
|
</cpu>
|
||||||
<clock offset="utc">
|
<clock offset="utc">
|
||||||
<timer name="rtc" tickpolicy="catchup"/>
|
<timer name="rtc" tickpolicy="catchup"/>
|
||||||
<timer name="pit" tickpolicy="delay"/>
|
|
||||||
@@
|
|
||||||
</panic>
|
|
||||||
</devices>
|
|
||||||
<seclabel type="dynamic" model="selinux" relabel="yes"/>
|
|
||||||
+ <cpu mode="host-passthrough"/>
|
|
||||||
</domain>
|
|
||||||
|
|
||||||
Domain 'test-for-virtxml' defined successfully.
|
Domain 'test-for-virtxml' defined successfully.
|
||||||
Changes will take effect after the next domain shutdown.
|
Changes will take effect after the next domain shutdown.
|
@@ -1028,17 +1028,27 @@ class VirtCLIParser(object):
|
|||||||
|
|
||||||
def __init_global_params(self):
|
def __init_global_params(self):
|
||||||
def set_clearxml_cb(opts, inst, cliname, val):
|
def set_clearxml_cb(opts, inst, cliname, val):
|
||||||
ignore = opts = cliname
|
ignore = opts
|
||||||
|
ignore = cliname
|
||||||
if not self.objclass and not self.clear_attr:
|
if not self.objclass and not self.clear_attr:
|
||||||
raise RuntimeError("Don't know how to clearxml --%s" %
|
raise RuntimeError("Don't know how to clearxml --%s" %
|
||||||
self.cli_arg_name)
|
self.cli_arg_name)
|
||||||
if val is not True:
|
if val is not True:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
clear_inst = inst
|
||||||
if self.clear_attr:
|
if self.clear_attr:
|
||||||
getattr(inst, self.clear_attr).clear()
|
clear_inst = getattr(inst, self.clear_attr)
|
||||||
else:
|
|
||||||
inst.clear()
|
# If there's any opts remaining, leave the root stub element
|
||||||
|
# in place, so virt-xml updates are done in place.
|
||||||
|
#
|
||||||
|
# So --edit --cpu clearxml=yes should remove the entire <cpu>
|
||||||
|
# block. But --edit --cpu clearxml=yes,model=foo should leave
|
||||||
|
# a <cpu> stub in place, so that it gets model=foo in place,
|
||||||
|
# otherwise the newly created cpu block gets appened to the
|
||||||
|
# end of the domain XML, which gives an ugly diff
|
||||||
|
clear_inst.clear(leave_stub=bool(opts.opts))
|
||||||
|
|
||||||
self.set_param(None, "clearxml",
|
self.set_param(None, "clearxml",
|
||||||
setter_cb=set_clearxml_cb, is_onoff=True)
|
setter_cb=set_clearxml_cb, is_onoff=True)
|
||||||
|
@@ -312,9 +312,9 @@ SUPPORT_CONN_MEM_STATS_PERIOD = _make(
|
|||||||
function="virDomain.setMemoryStatsPeriod",
|
function="virDomain.setMemoryStatsPeriod",
|
||||||
version="1.1.1", hv_version={"qemu": 0})
|
version="1.1.1", hv_version={"qemu": 0})
|
||||||
SUPPORT_CONN_SPICE_GL = _make(version="1.3.3",
|
SUPPORT_CONN_SPICE_GL = _make(version="1.3.3",
|
||||||
hv_version={"qemu": "2.5.92", "test": 0})
|
hv_version={"qemu": "2.7.92", "test": 0})
|
||||||
SUPPORT_CONN_VIDEO_VIRTIO_ACCEL3D = _make(version="1.3.0",
|
SUPPORT_CONN_VIDEO_VIRTIO_ACCEL3D = _make(version="1.3.0",
|
||||||
hv_version={"qemu": "2.5.0", "test": 0})
|
hv_version={"qemu": "2.7.0", "test": 0})
|
||||||
|
|
||||||
|
|
||||||
# This is for disk <driver name=qemu>. xen supports this, but it's
|
# This is for disk <driver name=qemu>. xen supports this, but it's
|
||||||
|
@@ -38,6 +38,10 @@ _trackprops = bool("VIRTINST_TEST_SUITE" in os.environ)
|
|||||||
_allprops = []
|
_allprops = []
|
||||||
_seenprops = []
|
_seenprops = []
|
||||||
|
|
||||||
|
# Convenience global to prevent _remove_xpath_node from unlinking the
|
||||||
|
# top relavtive node in certain cases
|
||||||
|
_top_node = None
|
||||||
|
|
||||||
|
|
||||||
class _DocCleanupWrapper(object):
|
class _DocCleanupWrapper(object):
|
||||||
def __init__(self, doc):
|
def __init__(self, doc):
|
||||||
@@ -224,17 +228,17 @@ def _remove_xpath_node(ctx, xpath, dofree=True):
|
|||||||
if not is_orig:
|
if not is_orig:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
if node == root_node or node == _top_node:
|
||||||
|
# Don't unlink the root node, since it's spread out to all
|
||||||
|
# child objects and it ends up wreaking havoc.
|
||||||
|
break
|
||||||
|
|
||||||
# Look for preceding whitespace and remove it
|
# Look for preceding whitespace and remove it
|
||||||
white = node.get_prev()
|
white = node.get_prev()
|
||||||
if white and white.type == "text" and not white.content.count("<"):
|
if white and white.type == "text" and not white.content.count("<"):
|
||||||
white.unlinkNode()
|
white.unlinkNode()
|
||||||
white.freeNode()
|
white.freeNode()
|
||||||
|
|
||||||
if node == root_node:
|
|
||||||
# Don't unlink the root node, since it's spread out to all
|
|
||||||
# child objects and it ends up wreaking havoc.
|
|
||||||
break
|
|
||||||
|
|
||||||
node.unlinkNode()
|
node.unlinkNode()
|
||||||
if dofree:
|
if dofree:
|
||||||
node.freeNode()
|
node.freeNode()
|
||||||
@@ -836,17 +840,28 @@ class XMLBuilder(object):
|
|||||||
finally:
|
finally:
|
||||||
self._finish_get_xml(data)
|
self._finish_get_xml(data)
|
||||||
|
|
||||||
def clear(self):
|
def clear(self, leave_stub=False):
|
||||||
"""
|
"""
|
||||||
Wipe out all properties of the object
|
Wipe out all properties of the object
|
||||||
|
|
||||||
|
:param leave_stub: if True, don't unlink the top stub node,
|
||||||
|
see virtinst/cli usage for an explanation
|
||||||
"""
|
"""
|
||||||
|
global _top_node
|
||||||
|
old_top_node = _top_node
|
||||||
|
try:
|
||||||
|
if leave_stub:
|
||||||
|
_top_node = _get_xpath_node(self._xmlstate.xml_ctx,
|
||||||
|
self.get_root_xpath())
|
||||||
props = self._all_xml_props().values()
|
props = self._all_xml_props().values()
|
||||||
props += self._all_child_props().values()
|
props += self._all_child_props().values()
|
||||||
for prop in props:
|
for prop in props:
|
||||||
prop.clear(self)
|
prop.clear(self)
|
||||||
|
finally:
|
||||||
|
_top_node = old_top_node
|
||||||
|
|
||||||
is_child = bool(re.match("^.*\[\d+\]$", self.get_root_xpath()))
|
is_child = bool(re.match("^.*\[\d+\]$", self.get_root_xpath()))
|
||||||
if is_child:
|
if is_child or leave_stub:
|
||||||
# User requested to clear an object that is the child of
|
# User requested to clear an object that is the child of
|
||||||
# another object (xpath ends in [1] etc). We can't fully remove
|
# another object (xpath ends in [1] etc). We can't fully remove
|
||||||
# the node in that case, since then the xmlbuilder object is
|
# the node in that case, since then the xmlbuilder object is
|
||||||
@@ -855,6 +870,7 @@ class XMLBuilder(object):
|
|||||||
node = _get_xpath_node(self._xmlstate.xml_ctx,
|
node = _get_xpath_node(self._xmlstate.xml_ctx,
|
||||||
self.get_root_xpath())
|
self.get_root_xpath())
|
||||||
indent = 2 * self.get_root_xpath().count("/")
|
indent = 2 * self.get_root_xpath().count("/")
|
||||||
|
if node:
|
||||||
node.setContent("\n" + (indent * " "))
|
node.setContent("\n" + (indent * " "))
|
||||||
else:
|
else:
|
||||||
_remove_xpath_node(self._xmlstate.xml_ctx,
|
_remove_xpath_node(self._xmlstate.xml_ctx,
|
||||||
|
Reference in New Issue
Block a user