diff options
author | Cole Robinson <crobinso@redhat.com> | 2014-01-25 15:44:14 -0500 |
---|---|---|
committer | Cole Robinson <crobinso@redhat.com> | 2014-01-25 17:20:30 -0500 |
commit | 26737eb7d59c5eb8da6c8532a8cde90569fe98ae (patch) | |
tree | 2388ca306316d421bee931d8381d2beaf058619d | |
parent | 9f5a842a3ab2bea5ba2ff6eb60206b30a1ad8a22 (diff) | |
download | virt-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.xml | 22 | ||||
-rw-r--r-- | tests/cli-test-xml/compare/virtxml-edit-clear-cpu.xml | 36 | ||||
-rw-r--r-- | tests/cli-test-xml/compare/virtxml-edit-clear-disk.xml | 17 | ||||
-rw-r--r-- | tests/clitest.py | 7 | ||||
-rw-r--r-- | virtinst/cli.py | 65 | ||||
-rw-r--r-- | virtinst/connection.py | 2 |
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: |