diff --git a/man/virt-xml.rst b/man/virt-xml.rst index cf5db45c..ddd586bb 100644 --- a/man/virt-xml.rst +++ b/man/virt-xml.rst @@ -257,6 +257,17 @@ For any option, use --option=? to see a list of all available sub options, examp --help output also lists a few general examples. See the EXAMPLES section below for some common examples. +virt-xml specifically has some operations that don't really apply to virt-install +Examples: + +``--boot refresh-machine-type=yes`` + Refresh the XML ```` value to the latest one + that qemu provides. For example, if your VM has a machine type value + ``pc-q35-4.0``, this will reset the value to ``q35``, and works + similarly with other versioned machine types. Occasionally this is + necessary to get enable qemu bug fixes, or when qemu deprecates and + removes old machine type values. + MISCELLANEOUS OPTIONS ===================== diff --git a/tests/data/capabilities/kvm-s390x.xml b/tests/data/capabilities/kvm-s390x.xml index b79c0924..48365593 100644 --- a/tests/data/capabilities/kvm-s390x.xml +++ b/tests/data/capabilities/kvm-s390x.xml @@ -49,24 +49,36 @@ hvm - + 64 /usr/bin/qemu-system-s390x - s390 - s390-ccw - - /usr/bin/qemu-system-s390x - - - /usr/bin/qemu-system-s390x - s390 - s390-ccw - + s390-ccw-virtio-6.1 + s390-ccw-virtio + s390-ccw-virtio-4.0 + s390-ccw-virtio-5.2 + s390-ccw-virtio-3.1 + s390-ccw-virtio-2.6 + s390-ccw-virtio-2.12 + s390-ccw-virtio-2.9 + s390-ccw-virtio-6.0 + s390-ccw-virtio-5.1 + s390-ccw-virtio-3.0 + s390-ccw-virtio-4.2 + s390-ccw-virtio-2.5 + s390-ccw-virtio-2.11 + s390-ccw-virtio-2.8 + s390-ccw-virtio-5.0 + s390-ccw-virtio-4.1 + s390-ccw-virtio-2.4 + s390-ccw-virtio-2.10 + s390-ccw-virtio-2.7 + + - + diff --git a/tests/data/cli/compare/virt-xml-refresh-machine-type.xml b/tests/data/cli/compare/virt-xml-refresh-machine-type.xml new file mode 100644 index 00000000..9beb406b --- /dev/null +++ b/tests/data/cli/compare/virt-xml-refresh-machine-type.xml @@ -0,0 +1,17 @@ + + test + 6695eb01-f6a4-8304-79aa-97f2502e193f + 8388608 + 2097152 + 2 + + hvm + + + + destroy + restart + destroy + + + diff --git a/tests/data/cli/compare/virt-xml-stdin-edit.xml b/tests/data/cli/compare/virt-xml-stdin-edit.xml index 834755f1..5aa54146 100644 --- a/tests/data/cli/compare/virt-xml-stdin-edit.xml +++ b/tests/data/cli/compare/virt-xml-stdin-edit.xml @@ -1,11 +1,11 @@ - + test 6695eb01-f6a4-8304-79aa-97f2502e193f 8388608 2097152 2 - hvm + hvm diff --git a/tests/data/cli/virtxml/virtxml-stdin-edit.xml b/tests/data/cli/virtxml/virtxml-stdin-edit.xml index 4a7b3e32..55882a91 100644 --- a/tests/data/cli/virtxml/virtxml-stdin-edit.xml +++ b/tests/data/cli/virtxml/virtxml-stdin-edit.xml @@ -1,11 +1,11 @@ - + test 6695eb01-f6a4-8304-79aa-97f2502e193f 8388608 2097152 2 - hvm + hvm diff --git a/tests/test_cli.py b/tests/test_cli.py index 01ab59a8..d3629350 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -1316,8 +1316,10 @@ c.add_invalid("test-for-virtxml --edit --graphics password=foo,keymap= --update c.add_invalid("--build-xml --memory 10,maxmemory=20", grep="--build-xml not supported for --memory") c.add_invalid("test-state-shutoff --edit sparse=no --disk path=blah", grep="Don't know how to match device type 'disk' property 'sparse'") c.add_invalid("test --add-device --xml ./@foo=bar", grep="--xml can only be used with --edit") +c.add_invalid("test-for-virtxml --edit --boot refresh-machine-type=yes", grep="Don't know how to refresh") c.add_compare("test --print-xml --edit --vcpus 7", "print-xml") # test --print-xml c.add_compare("--edit --cpu host-passthrough", "stdin-edit", input_file=(_VIRTXMLDIR + "virtxml-stdin-edit.xml")) # stdin test +c.add_compare("--connect %(URI-KVM-X86)s --edit --boot refresh-machine-type=yes", "refresh-machine-type", input_file=(_VIRTXMLDIR + "virtxml-stdin-edit.xml")) # refresh-machine-type test. we need to use stdin XML since we can't get the libvirt testdriver to start with the machine XML we need c.add_compare("--build-xml --cpu pentium3,+x2apic", "build-cpu") c.add_compare("--build-xml --tpm path=/dev/tpm", "build-tpm") c.add_compare("--build-xml --blkiotune weight=100,device0.path=/dev/sdf,device.weight=200,device0.read_bytes_sec=10000,device0.write_bytes_sec=10000,device0.read_iops_sec=20000,device0.write_iops_sec=20000", "build-blkiotune") diff --git a/tests/test_xmlparse.py b/tests/test_xmlparse.py index ea02eea9..49c924c7 100644 --- a/tests/test_xmlparse.py +++ b/tests/test_xmlparse.py @@ -1137,3 +1137,20 @@ def testControllerAttachedDevices(): # Little test for DeviceAddress.pretty_desc assert devs[-1].address.pretty_desc() == "0:0:0:3" + + +def testRefreshMachineType(): + guest = virtinst.Guest(utils.URIs.openconn(utils.URIs.kvm_x86)) + guest.os.machine = "pc-i440fx-5.2" + guest.refresh_machine_type() + assert guest.os.machine == "pc" + + guest = virtinst.Guest(utils.URIs.openconn(utils.URIs.kvm_x86)) + guest.os.machine = "pc-q35-XYZ" + guest.refresh_machine_type() + assert guest.os.machine == "q35" + + guest = virtinst.Guest(utils.URIs.openconn(utils.URIs.kvm_s390x)) + guest.os.machine = "s390-ccw-virtio-12345" + guest.refresh_machine_type() + assert guest.os.machine == "s390-ccw-virtio" diff --git a/virtinst/cli.py b/virtinst/cli.py index 81dd7e3c..c99ad039 100644 --- a/virtinst/cli.py +++ b/virtinst/cli.py @@ -2738,6 +2738,10 @@ class ParserBoot(VirtCLIParser): # Option handling # ################### + def refresh_machine_type_cb(self, inst, val, virtarg): + if val is True: + self.guest.refresh_machine_type() + def set_uefi_cb(self, inst, val, virtarg): if not self.editing: # From virt-install, we just set this flag, and set_defaults() @@ -2797,6 +2801,10 @@ class ParserBoot(VirtCLIParser): cls.add_arg("fd", None, lookup_cb=None, cb=cls.noset_cb) cls.add_arg("network", None, lookup_cb=None, cb=cls.noset_cb) + cls.add_arg("refresh-machine-type", None, + cb=cls.refresh_machine_type_cb, + lookup_cb=None, is_onoff=True) + # UEFI depends on these bits, so set them first cls.add_arg("os_type", "os_type") cls.add_arg("arch", "arch") diff --git a/virtinst/guest.py b/virtinst/guest.py index 5d693e3b..8e95e61d 100644 --- a/virtinst/guest.py +++ b/virtinst/guest.py @@ -674,6 +674,43 @@ class Guest(XMLBuilder): log.warning( # pragma: no cover "KVM acceleration not available, using '%s'", self.type) + def refresh_machine_type(self): + """ + Reset the guests's machine type to the latest 'canonical' machine + name that qemu reports. So if my VM is using ancient pc-0.11, we + try to turn that into just `pc` + + The algorithm here is to fetch all machine types that are aliases + for a stable name (like pc -> pc-i440fx-6.2), and see if our current + machine type uses alias as a prefix. This is the format that qemu + uses for its stable machine type names. + """ + # We need to unset the machine type first, so we can perform + # a successful capsinfo lookup, otherwise we will error when qemu + # has deprecated and removed the old machine type + original_machine_type = self.os.machine or "" + self.os.machine = None + + capsinfo = self.lookup_capsinfo() + mobjs = (capsinfo.domain and + capsinfo.domain.machines) or capsinfo.guest.machines + canonical_names = [m.name for m in mobjs if m.canonical] + + for machine_alias in canonical_names: + if machine_alias == "pc": + prefix = "pc-i440fx-" + elif machine_alias == "q35": + prefix = "pc-q35-" + else: + # Example: pseries-X, virt-X, s390-ccw-virtio-X + prefix = machine_alias + "-" + + if original_machine_type.startswith(prefix): + self.os.machine = machine_alias + return + raise Exception("Don't know how to refresh machine type '%s'" % + original_machine_type) + def sync_vcpus_topology(self, defCPUs): """ topology count and always need to match. Handle