diff --git a/man/virt-install.rst b/man/virt-install.rst index b767afe1..6008adf7 100644 --- a/man/virt-install.rst +++ b/man/virt-install.rst @@ -258,6 +258,24 @@ The --xml option has 4 sub options: +**xpath subarguments** +`````````````````````` + +Similar to the ``--xml`` option, most top level options have ``xpath.*`` +suboptions. For example, ``--disk xpath1.set=./@foo=bar,xpath2.create=./newelement`` +would generate XML alterations like + +.. code-block:: + + + + + +This is useful for setting XML options per device, when virt-install does not +support those options yet. + + + ``--qemu-commandline`` ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/data/cli/compare/virt-install-many-devices.xml b/tests/data/cli/compare/virt-install-many-devices.xml index eefdd1ae..0c631916 100644 --- a/tests/data/cli/compare/virt-install-many-devices.xml +++ b/tests/data/cli/compare/virt-install-many-devices.xml @@ -657,6 +657,10 @@ + +
+ + diff --git a/tests/data/cli/compare/virt-xml-edit-device-xpath.xml b/tests/data/cli/compare/virt-xml-edit-device-xpath.xml new file mode 100644 index 00000000..c6f76ddf --- /dev/null +++ b/tests/data/cli/compare/virt-xml-edit-device-xpath.xml @@ -0,0 +1,15 @@ + + /usr/lib/xen/bin/qemu-dm + +- + +- ++ +
++ + + + + +Domain 'test-for-virtxml' defined successfully. +Changes will take effect after the domain is fully powered off. diff --git a/tests/test_cli.py b/tests/test_cli.py index d3629350..80982124 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -646,6 +646,7 @@ source.reservations.managed=no,source.reservations.source.type=unix,source.reser --input mouse,bus=virtio,model=virtio-non-transitional --input passthrough,source.evdev=/dev/input/event1,bus=virtio --input evdev,source.dev=/dev/input/event1234,source.repeat=on,source.grab=all,source.grabToggle=ctrl-ctrl +--input mouse,model=FOOBAR,xpath0.set=./@bus=usb,xpath2.set=./address/@type=usb,xpath6.set=./willbeoverwritten=foo,xpath6.create=./randomelement,xpath7.create=./deleteme,xpath8.delete=./deleteme,xpath9.set=./@model=,xpath10.set=./@type,xpath10.value=keyboard --serial char_type=tcp,host=:2222,mode=bind,protocol=telnet,log.file=/tmp/foo.log,log.append=yes,,target.model.name=pci-serial @@ -1360,6 +1361,7 @@ c.add_compare("--clock offset=localtime,hpet_present=yes,kvmclock_present=no,kvm c.add_compare("--pm suspend_to_mem.enabled=yes,suspend_to_disk.enabled=no", "edit-simple-pm") c.add_compare("--disk /dev/zero,perms=ro,source.startupPolicy=optional", "edit-simple-disk") c.add_compare("--disk path=", "edit-simple-disk-remove-path") +c.add_compare("--disk xpath1.delete=./source,xpath2.set=./boot/@order,xpath2.value=6,xpath3.create=./fakeelement", "edit-device-xpath") c.add_compare("--network source=br0,type=bridge,model=virtio,mac=", "edit-simple-network") c.add_compare("--graphics tlsport=5902,keymap=ja", "edit-simple-graphics") c.add_compare("--graphics listen=none", "edit-graphics-listen-none") diff --git a/virtinst/cli.py b/virtinst/cli.py index 7580234a..f42cb5d9 100644 --- a/virtinst/cli.py +++ b/virtinst/cli.py @@ -1366,6 +1366,8 @@ class VirtCLIParser(metaclass=_InitClass): prefix = "0" if virtarg.cliname.startswith("address."): prefix = "1" + if virtarg.cliname.startswith("xpath"): + prefix = "2" return prefix + virtarg.cliname print("%s options:" % cls.cli_flag_name()) @@ -1400,7 +1402,9 @@ class VirtCLIParser(metaclass=_InitClass): @staticmethod def _virtcli_class_init_common(subclass): - pass + if subclass and subclass.guest_propname: + _add_xpath_args(subclass) + def __init__(self, optstr, guest=None, editing=None): self.optstr = optstr @@ -1615,6 +1619,31 @@ def parse_xmlcli(guest, options): guest.xml_actions.append(inst) +def _add_xpath_args(cls): + """ + Add xpath.* subarguments to XML based CLI options + """ + def find_xpath_cb(self, *args, **kwargs): + cliarg = "xpath" # xpath[0-9]* + list_propname = "xml_actions" + # pylint: disable=protected-access + cb = self._make_find_inst_cb(cliarg, list_propname) + return cb(*args, **kwargs) + + def _add_arg(*args, **kwargs): + kwargs["skip_testsuite_tracking"] = True + cls.add_arg(*args, **kwargs) + + _add_arg("xpath[0-9]*.delete", "xpath_delete", + can_comma=True, lookup_cb=None, find_inst_cb=find_xpath_cb) + _add_arg("xpath[0-9]*.set", "xpath_set", + can_comma=True, lookup_cb=None, find_inst_cb=find_xpath_cb) + _add_arg("xpath[0-9]*.create", "xpath_create", + can_comma=True, lookup_cb=None, find_inst_cb=find_xpath_cb) + _add_arg("xpath[0-9]*.value", "xpath_value", + can_comma=True, lookup_cb=None, find_inst_cb=find_xpath_cb) + + ######################## # --unattended parsing # ######################## @@ -4422,6 +4451,7 @@ class _ParserChar(VirtCLIParser): VirtCLIParser._virtcli_class_init_common(cls) _add_common_device_args(cls) + _add_xpath_args(cls) cls.add_arg("type", "type")