summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCole Robinson <crobinso@redhat.com>2014-01-25 15:44:14 -0500
committerCole Robinson <crobinso@redhat.com>2014-01-25 17:20:30 -0500
commit26737eb7d59c5eb8da6c8532a8cde90569fe98ae (patch)
tree2388ca306316d421bee931d8381d2beaf058619d
parent9f5a842a3ab2bea5ba2ff6eb60206b30a1ad8a22 (diff)
downloadvirt-manager-26737eb7d59c5eb8da6c8532a8cde90569fe98ae.tar.gz
virt-xml: Allow --option clearxml to clear all XML first
Needed for things like --cpu host-model,clearxml to easily clear all the previous state.
-rw-r--r--tests/cli-test-xml/compare/virtxml-edit-clear-clock.xml22
-rw-r--r--tests/cli-test-xml/compare/virtxml-edit-clear-cpu.xml36
-rw-r--r--tests/cli-test-xml/compare/virtxml-edit-clear-disk.xml17
-rw-r--r--tests/clitest.py7
-rw-r--r--virtinst/cli.py65
-rw-r--r--virtinst/connection.py2
6 files changed, 135 insertions, 14 deletions
diff --git a/tests/cli-test-xml/compare/virtxml-edit-clear-clock.xml b/tests/cli-test-xml/compare/virtxml-edit-clear-clock.xml
new file mode 100644
index 00000000..1e7f5adb
--- /dev/null
+++ b/tests/cli-test-xml/compare/virtxml-edit-clear-clock.xml
@@ -0,0 +1,22 @@
+--- Original XML
++++ Altered XML
+@@ -44,11 +44,6 @@
+ <feature policy="require" name="xtpr"/>
+ <feature policy="require" name="acpi"/>
+ </cpu>
+- <clock offset="utc">
+- <timer name="rtc" tickpolicy="catchup"/>
+- <timer name="pit" tickpolicy="delay"/>
+- <timer name="hpet" present="no"/>
+- </clock>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>restart</on_crash>
+@@ -303,4 +298,5 @@
+ </backend>
+ </rng>
+ </devices>
++ <clock offset="utc"/>
+ </domain>
+
+Domain 'test-many-devices' defined successfully. \ No newline at end of file
diff --git a/tests/cli-test-xml/compare/virtxml-edit-clear-cpu.xml b/tests/cli-test-xml/compare/virtxml-edit-clear-cpu.xml
new file mode 100644
index 00000000..e871c731
--- /dev/null
+++ b/tests/cli-test-xml/compare/virtxml-edit-clear-cpu.xml
@@ -0,0 +1,36 @@
+--- Original XML
++++ Altered XML
+@@ -27,23 +27,6 @@
+ <spinlocks state="on" retries="12287"/>
+ </hyperv>
+ </features>
+- <cpu mode="custom" match="exact">
+- <model fallback="allow">core2duo</model>
+- <vendor>Intel</vendor>
+- <feature policy="require" name="pbe"/>
+- <feature policy="require" name="tm2"/>
+- <feature policy="require" name="est"/>
+- <feature policy="require" name="ss"/>
+- <feature policy="require" name="ht"/>
+- <feature policy="require" name="ds"/>
+- <feature policy="require" name="lahf_lm"/>
+- <feature policy="require" name="tm"/>
+- <feature policy="require" name="cx16"/>
+- <feature policy="require" name="vmx"/>
+- <feature policy="require" name="ds_cpl"/>
+- <feature policy="require" name="xtpr"/>
+- <feature policy="require" name="acpi"/>
+- </cpu>
+ <clock offset="utc">
+ <timer name="rtc" tickpolicy="catchup"/>
+ <timer name="pit" tickpolicy="delay"/>
+@@ -303,4 +286,7 @@
+ </backend>
+ </rng>
+ </devices>
++ <cpu mode="custom" match="exact">
++ <model>host-passthrough</model>
++ </cpu>
+ </domain>
+
+Domain 'test-many-devices' defined successfully. \ No newline at end of file
diff --git a/tests/cli-test-xml/compare/virtxml-edit-clear-disk.xml b/tests/cli-test-xml/compare/virtxml-edit-clear-disk.xml
new file mode 100644
index 00000000..08c84ad7
--- /dev/null
+++ b/tests/cli-test-xml/compare/virtxml-edit-clear-disk.xml
@@ -0,0 +1,17 @@
+--- Original XML
++++ Altered XML
+@@ -54,10 +54,9 @@
+ <on_crash>restart</on_crash>
+ <devices>
+ <emulator>/usr/lib/xen/bin/qemu-dm</emulator>
+- <disk type="block" device="floppy">
+- <source dev="/dev/null"/>
++ <disk device="floppy">
++ <source file="/foo/bar"/>
+ <target dev="fda" bus="fdc"/>
+- <address type="drive" controller="0" bus="0" target="0" unit="0"/>
+ </disk>
+ <disk type="dir" device="floppy">
+ <source dir="/tmp"/>
+
+Domain 'test-many-devices' defined successfully. \ No newline at end of file
diff --git a/tests/clitest.py b/tests/clitest.py
index 8122479a..032bd106 100644
--- a/tests/clitest.py
+++ b/tests/clitest.py
@@ -799,6 +799,13 @@ c.add_compare("--edit target=hda --disk /dev/null", "virtxml-edit-select-disk-ta
c.add_compare("--edit /tmp/foobar2 --disk shareable=off,readonly=on", "virtxml-edit-select-disk-path")
c.add_compare("--edit mac=00:11:7f:33:44:55 --network target=nic55", "virtxml-edit-select-network-mac")
+c = vixml.add_category("edit clear", "--domain test-many-devices --print-diff --define")
+c.add_invalid("--edit --memory 200,clearxml") # clear isn't wired up for memory
+c.add_compare("--edit --cpu host-passthrough,clearxml", "virtxml-edit-clear-cpu")
+c.add_compare("--edit --clock offset=utc,clearxml", "virtxml-edit-clear-clock")
+c.add_compare("--edit --disk /foo/bar,target=fda,bus=fdc,device=floppy,clearxml", "virtxml-edit-clear-disk")
+
+
vimag = App("virt-image")
c = vimag.add_category("graphics", "--name test-image --boot 0 %(IMAGE_XML)s")
diff --git a/virtinst/cli.py b/virtinst/cli.py
index ecef5296..49a61143 100644
--- a/virtinst/cli.py
+++ b/virtinst/cli.py
@@ -967,8 +967,8 @@ def add_disk_option(stog):
class _VirtCLIArgument(object):
def __init__(self, attrname, cliname,
setter_cb=None, ignore_default=False,
- can_comma=False, is_list=False, is_onoff=False,
- aliases=None):
+ can_comma=False, aliases=None,
+ is_list=False, is_onoff=False, is_bool=False):
"""
A single subargument passed to compound command lines like --disk,
--network, etc.
@@ -986,22 +986,25 @@ class _VirtCLIArgument(object):
option string until it finds another known argument name:
everything prior to that argument name is considered part of
the value of this option, '=' included. Should be used sparingly.
+ @aliases: List of cli aliases. Useful if we want to change a property
+ name on the cli but maintain back compat.
@is_list: This value should be stored as a list, so multiple instances
are appended.
@is_onoff: The value expected on the cli is on/off or yes/no, convert
it to true/false.
- @aliases: List of cli aliases. Useful if we want to change a property
- name on the cli but maintain back compat.
+ @is_bool: This value shouldn't have an = component, so if it's present
+ on the command line, assume value is True
"""
self.attrname = attrname
self.cliname = cliname
self.setter_cb = setter_cb
self.can_comma = can_comma
- self.is_list = is_list
- self.is_onoff = is_onoff
self.ignore_default = ignore_default
self.aliases = util.listify(aliases)
+ self.is_list = is_list
+ self.is_onoff = is_onoff
+ self.is_bool = is_bool
def parse(self, opts, inst, support_cb=None, lookup=False):
@@ -1009,7 +1012,7 @@ class _VirtCLIArgument(object):
for cliname in self.aliases + [self.cliname]:
# We iterate over all values unconditionally, so they are
# removed from opts
- foundval = opts.get_opt_param(cliname)
+ foundval = opts.get_opt_param(cliname, is_bool=self.is_bool)
if foundval is not None:
val = foundval
if val is None:
@@ -1044,7 +1047,7 @@ class _VirtCLIArgument(object):
class VirtOptionString(object):
- def __init__(self, optstr, virtargs, remove_first=None):
+ def __init__(self, optstr, virtargs, remove_first):
"""
Helper class for parsing opt strings of the form
opt1=val1,opt2=val2,...
@@ -1066,7 +1069,9 @@ class VirtOptionString(object):
self.opts, self.orderedopts = self._parse_optstr(
virtargmap, remove_first)
- def get_opt_param(self, key):
+ def get_opt_param(self, key, is_bool=False):
+ if is_bool and key in self.opts and self.opts[key] is None:
+ self.opts[key] = True
return self.opts.pop(key, None)
def check_leftover_opts(self):
@@ -1103,6 +1108,8 @@ class VirtOptionString(object):
if opt.count("="):
cliname, val = opt.split("=", 1)
remove_first = []
+ elif cliname in virtargmap and virtargmap[cliname].is_bool:
+ remove_first = []
elif remove_first:
val = cliname
cliname = remove_first.pop(0)
@@ -1174,6 +1181,10 @@ class VirtCLIParser(object):
@support_cb: An extra support check function for further validation.
Called before the virtinst object is altered. Take arguments
(inst, attrname, cliname)
+ @clear_attr: If the user requests to clear the XML (--disk clearxml),
+ this is the property name we grab from inst to actually clear
+ (so 'security' to get guest.security). If it's True, then
+ clear inst (in the case of devices)
"""
self.cli_arg_name = cli_arg_name
# This is the name of the variable that argparse will set in
@@ -1184,12 +1195,32 @@ class VirtCLIParser(object):
self.remove_first = None
self.check_none = False
self.support_cb = None
+ self.clear_attr = None
self._params = []
self._inparse = False
+ self.__init_global_params()
self._init_params()
+
+ def __init_global_params(self):
+ def set_clearxml_cb(opts, inst, cliname, val):
+ ignore = opts = cliname
+ if not self.clear_attr and not self.devclass:
+ raise RuntimeError("Don't know how to clearxml --%s" %
+ self.cli_arg_name)
+
+ clearobj = inst
+ if self.clear_attr:
+ clearobj = getattr(inst, self.clear_attr)
+ if val is not True:
+ return
+ clearobj.clear()
+
+ self.set_param(None, "clearxml",
+ setter_cb=set_clearxml_cb, is_bool=True)
+
def check_introspection(self, option):
for optstr in util.listify(option):
if optstr == "?":
@@ -1257,8 +1288,7 @@ class VirtCLIParser(object):
ret = []
for inst in devlist:
- opts = VirtOptionString(optstr, self._params,
- remove_first=self.remove_first)
+ opts = VirtOptionString(optstr, self._params, self.remove_first)
valid = True
for param in self._params:
if param.parse(opts, inst,
@@ -1282,8 +1312,7 @@ class VirtCLIParser(object):
try:
self.guest = guest
self._inparse = True
- opts = VirtOptionString(optstr, self._params,
- remove_first=self.remove_first)
+ opts = VirtOptionString(optstr, self._params, self.remove_first)
return self._parse(opts, inst)
finally:
self.guest = None
@@ -1317,6 +1346,7 @@ class ParserMetadata(VirtCLIParser):
class ParserNumatune(VirtCLIParser):
def _init_params(self):
+ self.clear_attr = "numatune"
self.remove_first = "nodeset"
self.set_param("numatune.memory_nodeset", "nodeset", can_comma=True)
@@ -1393,6 +1423,7 @@ class ParserVCPU(VirtCLIParser):
class ParserCPU(VirtCLIParser):
def _init_params(self):
+ self.clear_attr = "cpu"
self.remove_first = "model"
def set_model_cb(opts, inst, cliname, val):
@@ -1458,6 +1489,8 @@ class ParserCPU(VirtCLIParser):
class ParserBoot(VirtCLIParser):
def _init_params(self):
+ self.clear_attr = "os"
+
self.set_param("os.useserial", "useserial", is_onoff=True)
self.set_param("os.enable_bootmenu", "menu", is_onoff=True)
self.set_param("os.kernel", "kernel")
@@ -1501,6 +1534,8 @@ class ParserBoot(VirtCLIParser):
class ParserSecurity(VirtCLIParser):
def _init_params(self):
+ self.clear_attr = "seclabel"
+
self.set_param("seclabel.type", "type")
self.set_param("seclabel.label", "label", can_comma=True)
self.set_param("seclabel.relabel", "relabel",
@@ -1513,6 +1548,8 @@ class ParserSecurity(VirtCLIParser):
class ParserFeatures(VirtCLIParser):
def _init_params(self):
+ self.clear_attr = "features"
+
self.set_param("features.acpi", "acpi", is_onoff=True)
self.set_param("features.apic", "apic", is_onoff=True)
self.set_param("features.pae", "pae", is_onoff=True)
@@ -1540,6 +1577,8 @@ class ParserFeatures(VirtCLIParser):
class ParserClock(VirtCLIParser):
def _init_params(self):
+ self.clear_attr = "clock"
+
self.set_param("clock.offset", "offset")
def set_timer(opts, inst, cliname, val):
diff --git a/virtinst/connection.py b/virtinst/connection.py
index 6f89fae4..30007901 100644
--- a/virtinst/connection.py
+++ b/virtinst/connection.py
@@ -80,7 +80,7 @@ class VirtualConnection(object):
ret = uri.split(",", 1)
self._open_uri = ret[0]
self._test_opts = VirtOptionString(
- len(ret) > 1 and ret[1] or "", []).opts
+ len(ret) > 1 and ret[1] or "", [], None).opts
self._early_virtinst_test_uri()
self._uri = self._virtinst_uri_make_fake()
else: