virt-manager-3.2.0-4.1.el8_10

- cli: Add basic --audio type=XXX,id=Y support (RHEL-17435)
- virtinst: unify detection of duplicate console when removing device (RHEL-17435)
- virtinst: fix compare for audio devices (RHEL-17435)
- testsuite: add test-spice vm definition (RHEL-17435)
- virtinst: remove spice devices when removing last spice graphics (RHEL-17435)
- guest: add convert_to_vnc() (RHEL-17435)
- guest: remove spiceport devices when spice is removed (RHEL-17435)
- guest: convert_to_vnc: convert video device (RHEL-17435)
- virt-xml: Add `--edit --convert-to-vnc` (RHEL-17435)

Resolves: RHEL-17435
This commit is contained in:
Pavel Hrdina 2025-01-27 12:00:57 +01:00
parent df484fcec0
commit 1f9594fe79
10 changed files with 1427 additions and 1 deletions

View File

@ -0,0 +1,203 @@
From a39c0f0ddb75bca67a150e8c914ce94c8d1c6858 Mon Sep 17 00:00:00 2001
Message-ID: <a39c0f0ddb75bca67a150e8c914ce94c8d1c6858.1737975657.git.phrdina@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Thu, 24 Feb 2022 13:47:59 -0500
Subject: [PATCH] cli: Add basic --audio type=XXX,id=Y support
From: Cole Robinson <crobinso@redhat.com>
Closes: #264
Signed-off-by: Cole Robinson <crobinso@redhat.com>
(cherry picked from commit cd5c34a3f3ab53be32319af6857efd3c2ac45385)
https://issues.redhat.com/browse/RHEL-17435
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
man/virt-install.rst | 10 ++++++++++
man/virt-xml.rst | 1 +
.../cli/compare/virt-install-many-devices.xml | 2 ++
tests/data/cli/compare/virt-xml-add-audio.xml | 10 ++++++++++
tests/test_cli.py | 6 ++++++
virtinst/cli.py | 16 ++++++++++++++++
virtinst/devices/__init__.py | 1 +
virtinst/devices/audio.py | 12 ++++++++++++
virtinst/guest.py | 3 ++-
9 files changed, 60 insertions(+), 1 deletion(-)
create mode 100644 tests/data/cli/compare/virt-xml-add-audio.xml
create mode 100644 virtinst/devices/audio.py
diff --git a/man/virt-install.rst b/man/virt-install.rst
index 963f95649..bafbf9f1f 100644
--- a/man/virt-install.rst
+++ b/man/virt-install.rst
@@ -1561,6 +1561,16 @@ Complete details at https://libvirt.org/formatdomain.html#elementsSound
+``--audio``
+^^^^^^^^^^^
+
+Configure host audio output for the guest's `--sound` hardware.
+
+Use --audio=? to see a list of all available sub options.
+Complete details at https://libvirt.org/formatdomain.html#audio-backends
+
+
+
``--watchdog``
^^^^^^^^^^^^^^
diff --git a/man/virt-xml.rst b/man/virt-xml.rst
index 7ff7ceca7..75c8be860 100644
--- a/man/virt-xml.rst
+++ b/man/virt-xml.rst
@@ -235,6 +235,7 @@ XML OPTIONS
* ``--hostdev``
* ``--filesystem``
* ``--sound``
+* ``--audio``
* ``--watchdog``
* ``--video``
* ``--smartcard``
diff --git a/tests/data/cli/compare/virt-install-many-devices.xml b/tests/data/cli/compare/virt-install-many-devices.xml
index 3bd756b34..d13ec6fb7 100644
--- a/tests/data/cli/compare/virt-install-many-devices.xml
+++ b/tests/data/cli/compare/virt-install-many-devices.xml
@@ -493,6 +493,8 @@
<codec type="duplex"/>
<codec type="output"/>
</sound>
+ <audio type="spice" id="1"/>
+ <audio type="pulseaudio" id="2"/>
<video>
<model type="cirrus"/>
</video>
diff --git a/tests/data/cli/compare/virt-xml-add-audio.xml b/tests/data/cli/compare/virt-xml-add-audio.xml
new file mode 100644
index 000000000..3e491518c
--- /dev/null
+++ b/tests/data/cli/compare/virt-xml-add-audio.xml
@@ -0,0 +1,10 @@
+ <vsock model="virtio">
+ <cid auto="no" address="5"/>
+ </vsock>
++ <audio type="none" id="1"/>
+ </devices>
+ <seclabel type="dynamic" model="selinux" relabel="yes"/>
+ <keywrap>
+
+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 75a891f08..532f456ae 100644
--- a/tests/test_cli.py
+++ b/tests/test_cli.py
@@ -694,6 +694,11 @@ source.reservations.managed=no,source.reservations.source.type=unix,source.reser
--sound ac97
--sound codec0.type=micro,codec1.type=duplex,codec2.type=output
+
+--audio id=1,type=spice
+--audio id=2,type=pulseaudio
+
+
--video cirrus
--video model=qxl,vgamem=1,ram=2,vram=3,heads=4,accel3d=yes,vram64=65
--video model=qxl,model.vgamem=1,model.ram=2,model.vram=3,model.heads=4,model.acceleration.accel3d=yes,model.vram64=65
@@ -1299,6 +1304,7 @@ c.add_invalid("--add-device --pm suspend_to_disk=yes") # --add-device without a
c.add_invalid("--remove-device --clock utc") # --remove-device without a dev
c.add_compare("--add-device --host-device usb_device_4b3_4485_noserial", "add-host-device")
c.add_compare("--add-device --sound pcspk", "add-sound")
+c.add_compare("--add-device --audio type=none,id=1", "add-audio", predefine_check="7.4.0")
c.add_compare("--add-device --disk %(EXISTIMG1)s,bus=virtio,target=vdf", "add-disk-basic")
c.add_compare("--add-device --disk %(EXISTIMG1)s", "add-disk-notarget") # filling in acceptable target
c.add_compare("--add-device --disk %(NEWIMG1)s,size=.01", "add-disk-create-storage")
diff --git a/virtinst/cli.py b/virtinst/cli.py
index dbd4a5452..390c54cd2 100644
--- a/virtinst/cli.py
+++ b/virtinst/cli.py
@@ -766,6 +766,10 @@ def add_device_options(devg, sound_back_compat=False):
devg.add_argument("--soundhw", action="append", dest="sound",
help=argparse.SUPPRESS)
+ ParserAudio.register()
+ devg.add_argument("--audio", action="append",
+ help=_("Configure host audio backend for sound devices"))
+
ParserWatchdog.register()
devg.add_argument("--watchdog", action="append",
help=_("Configure a guest watchdog device"))
@@ -4305,6 +4309,18 @@ class ParserSound(VirtCLIParser):
find_inst_cb=cls.codec_find_inst_cb)
+class ParserAudio(VirtCLIParser):
+ cli_arg_name = "audio"
+ guest_propname = "devices.audio"
+
+ @classmethod
+ def _init_class(cls, **kwargs):
+ VirtCLIParser._init_class(**kwargs)
+
+ cls.add_arg("type", "type")
+ cls.add_arg("id", "id")
+
+
#####################
# --hostdev parsing #
#####################
diff --git a/virtinst/devices/__init__.py b/virtinst/devices/__init__.py
index eae4b29bd..60081f603 100644
--- a/virtinst/devices/__init__.py
+++ b/virtinst/devices/__init__.py
@@ -4,6 +4,7 @@
# See the COPYING file in the top-level directory.
+from .audio import DeviceAudio
from .char import DeviceChannel, DeviceConsole, DeviceParallel, DeviceSerial
from .controller import DeviceController
from .device import Device
diff --git a/virtinst/devices/audio.py b/virtinst/devices/audio.py
new file mode 100644
index 000000000..e12975b16
--- /dev/null
+++ b/virtinst/devices/audio.py
@@ -0,0 +1,12 @@
+# This work is licensed under the GNU GPLv2 or later.
+# See the COPYING file in the top-level directory.
+
+from .device import Device
+from ..xmlbuilder import XMLProperty
+
+
+class DeviceAudio(Device):
+ XML_NAME = "audio"
+
+ type = XMLProperty("./@type")
+ id = XMLProperty("./@id")
diff --git a/virtinst/guest.py b/virtinst/guest.py
index 3269f72e3..c53516c6e 100644
--- a/virtinst/guest.py
+++ b/virtinst/guest.py
@@ -25,7 +25,7 @@ class _DomainDevices(XMLBuilder):
XML_NAME = "devices"
_XML_PROP_ORDER = ['disk', 'controller', 'filesystem', 'interface',
'smartcard', 'serial', 'parallel', 'console', 'channel',
- 'input', 'tpm', 'graphics', 'sound', 'video', 'hostdev',
+ 'input', 'tpm', 'graphics', 'sound', 'audio', 'video', 'hostdev',
'redirdev', 'watchdog', 'memballoon', 'rng', 'panic',
'memory', 'vsock', 'iommu']
@@ -43,6 +43,7 @@ class _DomainDevices(XMLBuilder):
tpm = XMLChildProperty(DeviceTpm)
graphics = XMLChildProperty(DeviceGraphics)
sound = XMLChildProperty(DeviceSound)
+ audio = XMLChildProperty(DeviceAudio)
video = XMLChildProperty(DeviceVideo)
hostdev = XMLChildProperty(DeviceHostdev)
redirdev = XMLChildProperty(DeviceRedirdev)
--
2.48.1

View File

@ -0,0 +1,397 @@
From a6f53b7da4ac6ff0139e7a130ba875a61a877617 Mon Sep 17 00:00:00 2001
Message-ID: <a6f53b7da4ac6ff0139e7a130ba875a61a877617.1737975657.git.phrdina@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Tue, 17 Sep 2024 10:02:59 -0400
Subject: [PATCH] guest: add convert_to_vnc()
From: Cole Robinson <crobinso@redhat.com>
This is the beginnings of support for a `virt-xml --convert-to-vnc`
option. Take an existing VM, strip out most of the previous graphics
config, and add VNC graphics.
We try to convert over some of the shared graphic bits, like listen
and port settings, if they were previously specified.
If spice GL was enabled, we convert to egl-headless config
Signed-off-by: Cole Robinson <crobinso@redhat.com>
(cherry picked from commit 229b905053f3d4bc17e7ad0f8d3fc2c3f23c47cd)
Conflicts:
tests/test_xmlparse.py
virtinst/guest.py
https://issues.redhat.com/browse/RHEL-17435
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
.../data/xmlparse/convert-to-vnc-empty-in.xml | 13 +++
.../xmlparse/convert-to-vnc-empty-out.xml | 13 +++
.../xmlparse/convert-to-vnc-has-vnc-in.xml | 31 +++++++
.../xmlparse/convert-to-vnc-has-vnc-out.xml | 22 +++++
.../convert-to-vnc-spice-devices-in.xml | 30 +++++++
.../convert-to-vnc-spice-devices-out.xml | 22 +++++
.../convert-to-vnc-spice-manyopts-in.xml | 20 +++++
.../convert-to-vnc-spice-manyopts-out.xml | 20 +++++
tests/test_xmlparse.py | 14 +++
virtinst/guest.py | 88 ++++++++++++++++++-
10 files changed, 269 insertions(+), 4 deletions(-)
create mode 100644 tests/data/xmlparse/convert-to-vnc-empty-in.xml
create mode 100644 tests/data/xmlparse/convert-to-vnc-empty-out.xml
create mode 100644 tests/data/xmlparse/convert-to-vnc-has-vnc-in.xml
create mode 100644 tests/data/xmlparse/convert-to-vnc-has-vnc-out.xml
create mode 100644 tests/data/xmlparse/convert-to-vnc-spice-devices-in.xml
create mode 100644 tests/data/xmlparse/convert-to-vnc-spice-devices-out.xml
create mode 100644 tests/data/xmlparse/convert-to-vnc-spice-manyopts-in.xml
create mode 100644 tests/data/xmlparse/convert-to-vnc-spice-manyopts-out.xml
diff --git a/tests/data/xmlparse/convert-to-vnc-empty-in.xml b/tests/data/xmlparse/convert-to-vnc-empty-in.xml
new file mode 100644
index 000000000..bc370a8a2
--- /dev/null
+++ b/tests/data/xmlparse/convert-to-vnc-empty-in.xml
@@ -0,0 +1,13 @@
+<domain type='qemu'>
+ <name>convert-me</name>
+ <memory unit='KiB'>8388608</memory>
+ <currentMemory unit='KiB'>2097152</currentMemory>
+ <vcpu placement='static'>2</vcpu>
+ <os>
+ <type arch='i686'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <devices>
+ </devices>
+</domain>
+
diff --git a/tests/data/xmlparse/convert-to-vnc-empty-out.xml b/tests/data/xmlparse/convert-to-vnc-empty-out.xml
new file mode 100644
index 000000000..8612a6567
--- /dev/null
+++ b/tests/data/xmlparse/convert-to-vnc-empty-out.xml
@@ -0,0 +1,13 @@
+<domain type="qemu">
+ <name>convert-me</name>
+ <memory unit="KiB">8388608</memory>
+ <currentMemory unit="KiB">2097152</currentMemory>
+ <vcpu placement="static">2</vcpu>
+ <os>
+ <type arch="i686">hvm</type>
+ <boot dev="hd"/>
+ </os>
+ <devices>
+ <graphics type="vnc" port="-1"/>
+ </devices>
+</domain>
diff --git a/tests/data/xmlparse/convert-to-vnc-has-vnc-in.xml b/tests/data/xmlparse/convert-to-vnc-has-vnc-in.xml
new file mode 100644
index 000000000..29ee53d4c
--- /dev/null
+++ b/tests/data/xmlparse/convert-to-vnc-has-vnc-in.xml
@@ -0,0 +1,31 @@
+<domain type="kvm">
+ <name>convert-me</name>
+ <memory>2097152</memory>
+ <currentMemory>2097152</currentMemory>
+ <vcpu>2</vcpu>
+ <os>
+ <type arch="x86_64" machine="q35">hvm</type>
+ <boot dev="network"/>
+ </os>
+ <features>
+ <acpi/>
+ <apic/>
+ <vmport state="off"/>
+ </features>
+ <devices>
+ <channel type="spicevmc">
+ <target type="virtio" name="com.redhat.spice.0"/>
+ </channel>
+ <graphics type="spice" port="-1" tlsPort="-1" autoport="yes">
+ <image compression="off"/>
+ </graphics>
+ <graphics type="vnc" port="5907"/>
+ <sound model="ich9"/>
+ <audio type='spice'/>
+ <video>
+ <model type="virtio"/>
+ </video>
+ <redirdev bus="usb" type="spicevmc"/>
+ <redirdev bus="usb" type="spicevmc"/>
+ </devices>
+</domain>
diff --git a/tests/data/xmlparse/convert-to-vnc-has-vnc-out.xml b/tests/data/xmlparse/convert-to-vnc-has-vnc-out.xml
new file mode 100644
index 000000000..113f70a1e
--- /dev/null
+++ b/tests/data/xmlparse/convert-to-vnc-has-vnc-out.xml
@@ -0,0 +1,22 @@
+<domain type="kvm">
+ <name>convert-me</name>
+ <memory>2097152</memory>
+ <currentMemory>2097152</currentMemory>
+ <vcpu>2</vcpu>
+ <os>
+ <type arch="x86_64" machine="q35">hvm</type>
+ <boot dev="network"/>
+ </os>
+ <features>
+ <acpi/>
+ <apic/>
+ <vmport state="off"/>
+ </features>
+ <devices>
+ <graphics type="vnc" port="5907"/>
+ <sound model="ich9"/>
+ <video>
+ <model type="virtio"/>
+ </video>
+ </devices>
+</domain>
diff --git a/tests/data/xmlparse/convert-to-vnc-spice-devices-in.xml b/tests/data/xmlparse/convert-to-vnc-spice-devices-in.xml
new file mode 100644
index 000000000..8c5c63bdf
--- /dev/null
+++ b/tests/data/xmlparse/convert-to-vnc-spice-devices-in.xml
@@ -0,0 +1,30 @@
+<domain type="kvm">
+ <name>convert-me</name>
+ <memory>2097152</memory>
+ <currentMemory>2097152</currentMemory>
+ <vcpu>2</vcpu>
+ <os>
+ <type arch="x86_64" machine="q35">hvm</type>
+ <boot dev="network"/>
+ </os>
+ <features>
+ <acpi/>
+ <apic/>
+ <vmport state="off"/>
+ </features>
+ <devices>
+ <channel type="spicevmc">
+ <target type="virtio" name="com.redhat.spice.0"/>
+ </channel>
+ <graphics type="spice" port="-1" tlsPort="-1" autoport="yes">
+ <image compression="off"/>
+ </graphics>
+ <sound model="ich9"/>
+ <audio type='spice'/>
+ <video>
+ <model type="virtio"/>
+ </video>
+ <redirdev bus="usb" type="spicevmc"/>
+ <redirdev bus="usb" type="spicevmc"/>
+ </devices>
+</domain>
diff --git a/tests/data/xmlparse/convert-to-vnc-spice-devices-out.xml b/tests/data/xmlparse/convert-to-vnc-spice-devices-out.xml
new file mode 100644
index 000000000..cc3fefabe
--- /dev/null
+++ b/tests/data/xmlparse/convert-to-vnc-spice-devices-out.xml
@@ -0,0 +1,22 @@
+<domain type="kvm">
+ <name>convert-me</name>
+ <memory>2097152</memory>
+ <currentMemory>2097152</currentMemory>
+ <vcpu>2</vcpu>
+ <os>
+ <type arch="x86_64" machine="q35">hvm</type>
+ <boot dev="network"/>
+ </os>
+ <features>
+ <acpi/>
+ <apic/>
+ <vmport state="off"/>
+ </features>
+ <devices>
+ <graphics type="vnc" port="-1"/>
+ <sound model="ich9"/>
+ <video>
+ <model type="virtio"/>
+ </video>
+ </devices>
+</domain>
diff --git a/tests/data/xmlparse/convert-to-vnc-spice-manyopts-in.xml b/tests/data/xmlparse/convert-to-vnc-spice-manyopts-in.xml
new file mode 100644
index 000000000..ebd20a56d
--- /dev/null
+++ b/tests/data/xmlparse/convert-to-vnc-spice-manyopts-in.xml
@@ -0,0 +1,20 @@
+<domain type='qemu'>
+ <name>convert-me</name>
+ <memory unit='KiB'>8388608</memory>
+ <currentMemory unit='KiB'>2097152</currentMemory>
+ <vcpu placement='static'>2</vcpu>
+ <os>
+ <type arch='i686'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <devices>
+ <graphics type='spice' port='5907' tlsPort='5901' autoport='no' passwd='sercet' passwdValidTo='2011-05-31T16:11:22' connected='disconnect' keymap='de' listen='127.0.0.1'>
+ <listen type='socket' socket='/tmp/spice.sock'/>
+ <listen type='address' address='127.0.0.1'/>
+ <gl enable='yes' rendernode='/dev/my/rendernode'/>
+ </graphics>
+ <graphics type='sdl'/>
+ </devices>
+</domain>
+
diff --git a/tests/data/xmlparse/convert-to-vnc-spice-manyopts-out.xml b/tests/data/xmlparse/convert-to-vnc-spice-manyopts-out.xml
new file mode 100644
index 000000000..c98c63830
--- /dev/null
+++ b/tests/data/xmlparse/convert-to-vnc-spice-manyopts-out.xml
@@ -0,0 +1,20 @@
+<domain type="qemu">
+ <name>convert-me</name>
+ <memory unit="KiB">8388608</memory>
+ <currentMemory unit="KiB">2097152</currentMemory>
+ <vcpu placement="static">2</vcpu>
+ <os>
+ <type arch="i686">hvm</type>
+ <boot dev="hd"/>
+ </os>
+ <clock offset="utc"/>
+ <devices>
+ <graphics type="vnc" port="5907" keymap="de" listen="127.0.0.1" passwd="sercet" passwdValidTo="2011-05-31T16:11:22">
+ <listen type="socket" socket="/tmp/spice.sock"/>
+ <listen type="address" address="127.0.0.1"/>
+ </graphics>
+ <graphics type="egl-headless">
+ <gl rendernode="/dev/my/rendernode"/>
+ </graphics>
+ </devices>
+</domain>
diff --git a/tests/test_xmlparse.py b/tests/test_xmlparse.py
index ac2fb38d2..e11d15d07 100644
--- a/tests/test_xmlparse.py
+++ b/tests/test_xmlparse.py
@@ -1135,3 +1135,17 @@ def testControllerAttachedDevices():
# Little test for DeviceAddress.pretty_desc
assert devs[-1].address.pretty_desc() == "0:0:0:3"
+
+
+def testConvertToVNC():
+ conn = utils.URIs.openconn(utils.URIs.kvm_x86)
+
+ def _test(filename_base):
+ guest, outfile = _get_test_content(conn, filename_base)
+ guest.convert_to_vnc()
+ _alter_compare(conn, guest.get_xml(), outfile)
+
+ _test("convert-to-vnc-empty")
+ _test("convert-to-vnc-spice-devices")
+ _test("convert-to-vnc-spice-manyopts")
+ _test("convert-to-vnc-has-vnc")
diff --git a/virtinst/guest.py b/virtinst/guest.py
index 7aa62be49..93e71a149 100644
--- a/virtinst/guest.py
+++ b/virtinst/guest.py
@@ -706,6 +706,84 @@ class Guest(XMLBuilder):
self.vcpus = self.cpu.vcpus_from_topology()
self.cpu.set_topology_defaults(self.vcpus)
+ def _convert_spice_gl_to_egl_headless(self):
+ if not self.has_spice():
+ return
+
+ spicedev = [g for g in self.devices.graphics if g.type == "spice"][0]
+ if not spicedev.gl:
+ return
+
+ dev = DeviceGraphics(self.conn)
+ dev.type = "egl-headless"
+ dev.set_defaults(self.conn)
+ if spicedev.rendernode:
+ dev.rendernode = spicedev.rendernode
+ self.add_device(dev)
+
+ def _convert_to_vnc_graphics(self):
+ """
+ If there's already VNC graphics configured, we leave it intact,
+ but rip out all evidence of other graphics devices.
+
+ If there's other non-VNC, non-egl-headless configured, we try to
+ inplace convert the first device we encounter.
+
+ If there's no graphics configured, set up a default VNC config.`
+ """
+ vnc_devs = [g for g in self.devices.graphics if g.type == "vnc"]
+ # We ignore egl-headless, it's not a true graphical frontend
+ other_devs = [g for g in self.devices.graphics if
+ g.type != "vnc" and g.type != "egl-headless"]
+
+ # Guest already had a vnc device.
+ # Remove all other devs and we are done
+ if vnc_devs:
+ for g in other_devs:
+ self.remove_device(g)
+ return
+
+ # We didn't find any non-vnc device to convert.
+ # Add a vnc device with default config
+ if not other_devs:
+ dev = DeviceGraphics(self.conn)
+ dev.type = dev.TYPE_VNC
+ dev.set_defaults(self.conn)
+ self.add_device(dev)
+ return
+
+ # Convert the pre-existing graphics device to vnc
+ # Remove the rest
+ dev = other_devs.pop(0)
+ srcdev = DeviceGraphics(self.conn, dev.get_xml())
+ for g in other_devs:
+ self.remove_device(g)
+
+ dev.clear()
+ dev.type = dev.TYPE_VNC
+ dev.keymap = srcdev.keymap
+ dev.port = srcdev.port
+ dev.autoport = srcdev.autoport
+ dev.passwd = srcdev.passwd
+ dev.passwdValidTo = srcdev.passwdValidTo
+ dev.listen = srcdev.listen
+ for listen in srcdev.listens:
+ srcdev.remove_child(listen)
+ dev.add_child(listen)
+ dev.set_defaults(self)
+
+ def convert_to_vnc(self):
+ """
+ Convert existing XML to have one VNC graphics connection.
+ """
+ self._convert_spice_gl_to_egl_headless()
+
+ # Rip out spice graphics devices unconditionally.
+ # Could be necessary if XML is in broken state.
+ self._force_remove_spice_devices()
+
+ self._convert_to_vnc_graphics()
+
def set_defaults(self, _guest):
self.set_capabilities_defaults()
@@ -1061,10 +1139,12 @@ class Guest(XMLBuilder):
if redirdev.type == "spicevmc":
self.devices.remove_child(redirdev)
- def _remove_spice_devices(self, rmdev):
- if rmdev.DEVICE_TYPE != "graphics" or self.has_spice():
- return
-
+ def _force_remove_spice_devices(self):
self._remove_spice_audio()
self._remove_spice_channels()
self._remove_spice_usbredir()
+
+ def _remove_spice_devices(self, rmdev):
+ if rmdev.DEVICE_TYPE != "graphics" or self.has_spice():
+ return
+ self._force_remove_spice_devices()
--
2.48.1

View File

@ -0,0 +1,190 @@
From 834497bf91142335b1ba97a7415fabd08ad55843 Mon Sep 17 00:00:00 2001
Message-ID: <834497bf91142335b1ba97a7415fabd08ad55843.1737975657.git.phrdina@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Wed, 18 Sep 2024 10:36:26 -0400
Subject: [PATCH] guest: convert_to_vnc: convert video device
From: Cole Robinson <crobinso@redhat.com>
This is mostly about stripping out spice references. All qxl devices
are converted to app defaults
Signed-off-by: Cole Robinson <crobinso@redhat.com>
(cherry picked from commit d58299ee6b8fe59b399fde59a4dd684c399c3bbb)
https://issues.redhat.com/browse/RHEL-17435
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
.../xmlparse/convert-to-vnc-empty-out.xml | 3 +++
.../xmlparse/convert-to-vnc-has-vnc-in.xml | 2 +-
.../xmlparse/convert-to-vnc-has-vnc-out.xml | 2 +-
.../convert-to-vnc-spice-devices-in.xml | 3 +++
.../convert-to-vnc-spice-devices-out.xml | 3 +++
.../convert-to-vnc-spice-manyopts-in.xml | 8 ++++++
.../convert-to-vnc-spice-manyopts-out.xml | 5 ++++
virtinst/devices/video.py | 1 +
virtinst/guest.py | 27 +++++++++++++++++++
9 files changed, 52 insertions(+), 2 deletions(-)
diff --git a/tests/data/xmlparse/convert-to-vnc-empty-out.xml b/tests/data/xmlparse/convert-to-vnc-empty-out.xml
index 8612a6567..54e0353aa 100644
--- a/tests/data/xmlparse/convert-to-vnc-empty-out.xml
+++ b/tests/data/xmlparse/convert-to-vnc-empty-out.xml
@@ -9,5 +9,8 @@
</os>
<devices>
<graphics type="vnc" port="-1"/>
+ <video>
+ <model type="vga"/>
+ </video>
</devices>
</domain>
diff --git a/tests/data/xmlparse/convert-to-vnc-has-vnc-in.xml b/tests/data/xmlparse/convert-to-vnc-has-vnc-in.xml
index 29ee53d4c..dd25347fb 100644
--- a/tests/data/xmlparse/convert-to-vnc-has-vnc-in.xml
+++ b/tests/data/xmlparse/convert-to-vnc-has-vnc-in.xml
@@ -23,7 +23,7 @@
<sound model="ich9"/>
<audio type='spice'/>
<video>
- <model type="virtio"/>
+ <model type="qxl" heads='4' vgamem='1'/>
</video>
<redirdev bus="usb" type="spicevmc"/>
<redirdev bus="usb" type="spicevmc"/>
diff --git a/tests/data/xmlparse/convert-to-vnc-has-vnc-out.xml b/tests/data/xmlparse/convert-to-vnc-has-vnc-out.xml
index 113f70a1e..e07163a78 100644
--- a/tests/data/xmlparse/convert-to-vnc-has-vnc-out.xml
+++ b/tests/data/xmlparse/convert-to-vnc-has-vnc-out.xml
@@ -16,7 +16,7 @@
<graphics type="vnc" port="5907"/>
<sound model="ich9"/>
<video>
- <model type="virtio"/>
+ <model type="vga"/>
</video>
</devices>
</domain>
diff --git a/tests/data/xmlparse/convert-to-vnc-spice-devices-in.xml b/tests/data/xmlparse/convert-to-vnc-spice-devices-in.xml
index f5dff5ed1..e57d6377a 100644
--- a/tests/data/xmlparse/convert-to-vnc-spice-devices-in.xml
+++ b/tests/data/xmlparse/convert-to-vnc-spice-devices-in.xml
@@ -21,6 +21,9 @@
</graphics>
<sound model="ich9"/>
<audio type='spice'/>
+ <video>
+ <model type="qxl" primary='yes'/>
+ </video>
<video>
<model type="virtio"/>
</video>
diff --git a/tests/data/xmlparse/convert-to-vnc-spice-devices-out.xml b/tests/data/xmlparse/convert-to-vnc-spice-devices-out.xml
index cc3fefabe..42aac52c2 100644
--- a/tests/data/xmlparse/convert-to-vnc-spice-devices-out.xml
+++ b/tests/data/xmlparse/convert-to-vnc-spice-devices-out.xml
@@ -15,6 +15,9 @@
<devices>
<graphics type="vnc" port="-1"/>
<sound model="ich9"/>
+ <video>
+ <model type="vga"/>
+ </video>
<video>
<model type="virtio"/>
</video>
diff --git a/tests/data/xmlparse/convert-to-vnc-spice-manyopts-in.xml b/tests/data/xmlparse/convert-to-vnc-spice-manyopts-in.xml
index ebd20a56d..7c12b6b34 100644
--- a/tests/data/xmlparse/convert-to-vnc-spice-manyopts-in.xml
+++ b/tests/data/xmlparse/convert-to-vnc-spice-manyopts-in.xml
@@ -15,6 +15,14 @@
<gl enable='yes' rendernode='/dev/my/rendernode'/>
</graphics>
<graphics type='sdl'/>
+ <video>
+ <model type='virtio'>
+ <acceleration accel3d='yes'/>
+ </model>
+ </video>
+ <video>
+ <model type='qxl'/>
+ </video>
</devices>
</domain>
diff --git a/tests/data/xmlparse/convert-to-vnc-spice-manyopts-out.xml b/tests/data/xmlparse/convert-to-vnc-spice-manyopts-out.xml
index c98c63830..35b1b771f 100644
--- a/tests/data/xmlparse/convert-to-vnc-spice-manyopts-out.xml
+++ b/tests/data/xmlparse/convert-to-vnc-spice-manyopts-out.xml
@@ -13,6 +13,11 @@
<listen type="socket" socket="/tmp/spice.sock"/>
<listen type="address" address="127.0.0.1"/>
</graphics>
+ <video>
+ <model type="virtio" primary="yes">
+ <acceleration accel3d="yes"/>
+ </model>
+ </video>
<graphics type="egl-headless">
<gl rendernode="/dev/my/rendernode"/>
</graphics>
diff --git a/virtinst/devices/video.py b/virtinst/devices/video.py
index f93831318..bd68e4738 100644
--- a/virtinst/devices/video.py
+++ b/virtinst/devices/video.py
@@ -19,6 +19,7 @@ class DeviceVideo(Device):
heads = XMLProperty("./model/@heads", is_int=True)
vgamem = XMLProperty("./model/@vgamem", is_int=True)
accel3d = XMLProperty("./model/acceleration/@accel3d", is_yesno=True)
+ primary = XMLProperty("./model/@primary", is_yesno=True)
##################
diff --git a/virtinst/guest.py b/virtinst/guest.py
index 3a80d8dad..b0ff87276 100644
--- a/virtinst/guest.py
+++ b/virtinst/guest.py
@@ -772,6 +772,32 @@ class Guest(XMLBuilder):
dev.add_child(listen)
dev.set_defaults(self)
+ def _convert_to_vnc_video(self):
+ """
+ If there's no video device, add a default one.
+ If there's any qxl device, reset its config to app defaults.
+ """
+ if not self.devices.video:
+ videodev = DeviceVideo(self.conn)
+ videodev.set_defaults(self)
+ self.add_device(videodev)
+ return
+
+ qxl_devs = [v for v in self.devices.video if v.model == "qxl"]
+ if qxl_devs and not any(dev.primary for dev in self.devices.video):
+ # Make sure `primary` flag is set, we need it up ahead
+ self.devices.video[0].primary = True
+
+ for dev in qxl_devs:
+ is_primary = dev.primary
+ dev.clear()
+ dev.set_defaults(self)
+ if not is_primary and dev.model != "virtio":
+ # Device can't be non-primary, so just remove it
+ log.debug("Can't use model=%s for non-primary video device, "
+ "removing it instead.", dev.model)
+ self.remove_device(dev)
+
def convert_to_vnc(self):
"""
Convert existing XML to have one VNC graphics connection.
@@ -783,6 +809,7 @@ class Guest(XMLBuilder):
self._force_remove_spice_devices()
self._convert_to_vnc_graphics()
+ self._convert_to_vnc_video()
def set_defaults(self, _guest):
self.set_capabilities_defaults()
--
2.48.1

View File

@ -0,0 +1,65 @@
From 066c261ffb471d0b5319adbdf890eb2b27d55aa9 Mon Sep 17 00:00:00 2001
Message-ID: <066c261ffb471d0b5319adbdf890eb2b27d55aa9.1737975657.git.phrdina@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Wed, 18 Sep 2024 09:57:48 -0400
Subject: [PATCH] guest: remove spiceport devices when spice is removed
From: Cole Robinson <crobinso@redhat.com>
serial/console type='spiceport' is another spice specific device,
so remove that too
Signed-off-by: Cole Robinson <crobinso@redhat.com>
(cherry picked from commit f0078a179d19c7060fa2dbd8868bd3c423cc0202)
https://issues.redhat.com/browse/RHEL-17435
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
.../data/xmlparse/convert-to-vnc-spice-devices-in.xml | 10 ++++++++++
virtinst/guest.py | 6 ++++++
2 files changed, 16 insertions(+)
diff --git a/tests/data/xmlparse/convert-to-vnc-spice-devices-in.xml b/tests/data/xmlparse/convert-to-vnc-spice-devices-in.xml
index 8c5c63bdf..f5dff5ed1 100644
--- a/tests/data/xmlparse/convert-to-vnc-spice-devices-in.xml
+++ b/tests/data/xmlparse/convert-to-vnc-spice-devices-in.xml
@@ -26,5 +26,15 @@
</video>
<redirdev bus="usb" type="spicevmc"/>
<redirdev bus="usb" type="spicevmc"/>
+ <serial type='spiceport'>
+ <source channel='org.qemu.console.serial.0'/>
+ <target type='isa-serial' port='0'>
+ <model name='isa-serial'/>
+ </target>
+ </serial>
+ <console type='spiceport'>
+ <source channel='org.qemu.console.serial.0'/>
+ <target type='serial' port='0'/>
+ </console>
</devices>
</domain>
diff --git a/virtinst/guest.py b/virtinst/guest.py
index 93e71a149..3a80d8dad 100644
--- a/virtinst/guest.py
+++ b/virtinst/guest.py
@@ -1139,10 +1139,16 @@ class Guest(XMLBuilder):
if redirdev.type == "spicevmc":
self.devices.remove_child(redirdev)
+ def _remove_spiceport(self):
+ for dev in self.devices.serial + self.devices.console:
+ if dev.type == dev.TYPE_SPICEPORT:
+ self.devices.remove_child(dev)
+
def _force_remove_spice_devices(self):
self._remove_spice_audio()
self._remove_spice_channels()
self._remove_spice_usbredir()
+ self._remove_spiceport()
def _remove_spice_devices(self, rmdev):
if rmdev.DEVICE_TYPE != "graphics" or self.has_spice():
--
2.48.1

View File

@ -0,0 +1,130 @@
From 55350d15d86be7ee188a47d62237434593c0da19 Mon Sep 17 00:00:00 2001
Message-ID: <55350d15d86be7ee188a47d62237434593c0da19.1737975657.git.phrdina@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Mon, 25 Mar 2024 13:25:32 +0100
Subject: [PATCH] testsuite: add test-spice vm definition
This will test spice related changes. Follow up patches will change this
behavior to remove spice related devices.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
(cherry picked from commit 7a03f3efa8d3b9d6146687bf8f3bf0d3ef39b562)
https://issues.redhat.com/browse/RHEL-17435
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
.../compare/virt-xml-change-spice-to-vnc.xml | 11 +++++
.../virt-xml-remove-spice-graphics.xml | 14 +++++++
tests/data/testdriver/testsuite.xml | 41 +++++++++++++++++++
tests/test_cli.py | 4 ++
4 files changed, 70 insertions(+)
create mode 100644 tests/data/cli/compare/virt-xml-change-spice-to-vnc.xml
create mode 100644 tests/data/cli/compare/virt-xml-remove-spice-graphics.xml
diff --git a/tests/data/cli/compare/virt-xml-change-spice-to-vnc.xml b/tests/data/cli/compare/virt-xml-change-spice-to-vnc.xml
new file mode 100644
index 000000000..edc667037
--- /dev/null
+++ b/tests/data/cli/compare/virt-xml-change-spice-to-vnc.xml
@@ -0,0 +1,11 @@
+ <channel type="spicevmc">
+ <target type="virtio" name="com.redhat.spice.0"/>
+ </channel>
+- <graphics type="spice" autoport="yes">
++ <graphics type="vnc" autoport="yes">
+ <listen type="address"/>
+ <image compression="off"/>
+ <gl enable="no"/>
+
+Domain 'test-spice' defined successfully.
+Changes will take effect after the domain is fully powered off.
diff --git a/tests/data/cli/compare/virt-xml-remove-spice-graphics.xml b/tests/data/cli/compare/virt-xml-remove-spice-graphics.xml
new file mode 100644
index 000000000..ed9f2a584
--- /dev/null
+++ b/tests/data/cli/compare/virt-xml-remove-spice-graphics.xml
@@ -0,0 +1,14 @@
+ <channel type="spicevmc">
+ <target type="virtio" name="com.redhat.spice.0"/>
+ </channel>
+- <graphics type="spice" autoport="yes">
+- <listen type="address"/>
+- <image compression="off"/>
+- <gl enable="no"/>
+- </graphics>
+ <audio id="1" type="spice"/>
+ <video>
+ <model type="qxl" ram="65536" vram="65536" vgamem="16384" heads="1" primary="yes"/>
+
+Domain 'test-spice' defined successfully.
+Changes will take effect after the domain is fully powered off.
diff --git a/tests/data/testdriver/testsuite.xml b/tests/data/testdriver/testsuite.xml
index a073cbce5..d6cace017 100644
--- a/tests/data/testdriver/testsuite.xml
+++ b/tests/data/testdriver/testsuite.xml
@@ -96,6 +96,47 @@
</domain>
+<domain type='test'>
+ <name>test-spice</name>
+ <uuid>12345678-1234-FFFF-1234-12345678ABCD</uuid>
+ <memory unit='KiB'>1048576</memory>
+ <currentMemory unit='KiB'>1048576</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='x86_64' machine='q35'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <features>
+ <acpi/>
+ <apic/>
+ <vmport state='off'/>
+ <smm state='on'/>
+ </features>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-x86_64</emulator>
+ <controller type='usb' index='0' model='qemu-xhci' ports='15'/>
+ <channel type='spicevmc'>
+ <target type='virtio' name='com.redhat.spice.0'/>
+ </channel>
+ <graphics type='spice' autoport='yes' connected='fail'>
+ <listen type='address'/>
+ <image compression='off'/>
+ <gl enable='no'/>
+ </graphics>
+ <audio id='1' type='spice'/>
+ <video>
+ <model type='qxl' ram='65536' vram='65536' vgamem='16384' heads='1' primary='yes'/>
+ </video>
+ <redirdev bus='usb' type='spicevmc'/>
+ <redirdev bus='usb' type='spicevmc'/>
+ </devices>
+</domain>
+
+
<domain type='test'>
<name>test-for-virtxml</name>
<metadata>
diff --git a/tests/test_cli.py b/tests/test_cli.py
index 532f456ae..04386f63b 100644
--- a/tests/test_cli.py
+++ b/tests/test_cli.py
@@ -1318,6 +1318,10 @@ c.add_compare("--remove-device --memballoon all", "remove-memballoon")
c.add_compare("--add-device --hostdev mdev_8e37ee90_2b51_45e3_9b25_bf8283c03110", "add-hostdev-mdev")
c.add_compare("--remove-device --hostdev mdev_b1ae8bf6_38b0_4c81_9d44_78ce3f520496", "remove-hostdev-mdev")
+c = vixml.add_category("edit/remove spice graphics", "test-spice --print-diff --define")
+c.add_compare("--edit --graphics type=vnc", "change-spice-to-vnc")
+c.add_compare("--remove-device --graphics type=spice", "remove-spice-graphics")
+
c = vixml.add_category("add/rm devices and start", "test-state-shutoff --print-diff --start")
c.add_invalid("--add-device --pm suspend_to_disk=yes") # --add-device without a device
c.add_invalid("--remove-device --clock utc") # --remove-device without a dev
--
2.48.1

View File

@ -0,0 +1,194 @@
From da2cbdd5b6ff2b3f07eaf14044a59d4aee7db2a7 Mon Sep 17 00:00:00 2001
Message-ID: <da2cbdd5b6ff2b3f07eaf14044a59d4aee7db2a7.1737975657.git.phrdina@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Wed, 18 Sep 2024 12:02:59 -0400
Subject: [PATCH] virt-xml: Add `--edit --convert-to-vnc`
From: Cole Robinson <crobinso@redhat.com>
This wires up the guest.convert_to_vnc function to command line,
and documents it.
There's one suboption `qemu-vdagent=on|off`, defaulting to `off`
Signed-off-by: Cole Robinson <crobinso@redhat.com>
(cherry picked from commit 51c3f1c68736fecd133791e5f057abf43287d447)
Conflicts:
tests/test_cli.py
virtinst/virtxml.py
https://issues.redhat.com/browse/RHEL-17435
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
man/virt-xml.rst | 22 ++++++++++++++++
.../virt-xml-convert-to-vnc-vdagent.xml | 15 +++++++++++
.../cli/compare/virt-xml-convert-to-vnc.xml | 12 +++++++++
tests/test_cli.py | 6 +++++
virtinst/cli.py | 26 +++++++++++++++++++
virtinst/virtxml.py | 7 +++++
6 files changed, 88 insertions(+)
create mode 100644 tests/data/cli/compare/virt-xml-convert-to-vnc-vdagent.xml
create mode 100644 tests/data/cli/compare/virt-xml-convert-to-vnc.xml
diff --git a/man/virt-xml.rst b/man/virt-xml.rst
index 75c8be860..298246ca5 100644
--- a/man/virt-xml.rst
+++ b/man/virt-xml.rst
@@ -197,6 +197,28 @@ GUEST OS OPTIONS
See virt-install(1) documentation for more details about ``--os-variant``
+``--convert-to-vnc``
+^^^^^^^^^^^^^^^^^^^^
+
+**Syntax:** ``--convert-to-vnc`` [OPTIONS]
+
+Convert an existing VM to exclusively use a single VNC graphics device.
+
+It will attempt to remove all references to any non-VNC graphics config, like
+Spice. For example:
+
+* ``qxl`` devices will be replaced
+* all ``spicevmc`` and ``spiceport`` devices will be removed
+* spice GL will be converted to ``egl-headless``
+
+Sub options are:
+
+``qemu-vdagent=on|off``
+ Add a ``qemu-vdagent`` device if one is not already configured.
+ This replaces some functionality of the spice vdagent.
+ This defaults to ``off`` but that could change in the future.
+
+
XML OPTIONS
===========
diff --git a/tests/data/cli/compare/virt-xml-convert-to-vnc-vdagent.xml b/tests/data/cli/compare/virt-xml-convert-to-vnc-vdagent.xml
new file mode 100644
index 000000000..45764e132
--- /dev/null
+++ b/tests/data/cli/compare/virt-xml-convert-to-vnc-vdagent.xml
@@ -0,0 +1,15 @@
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
++ <channel type="qemu-vdagent">
++ <target type="virtio" name="com.redhat.spice.0"/>
++ </channel>
++ <graphics type="vnc" port="-1"/>
++ <video>
++ <model type="vga"/>
++ </video>
+ </devices>
+ </domain>
+
+Domain 'test' defined successfully.
+Changes will take effect after the domain is fully powered off.
diff --git a/tests/data/cli/compare/virt-xml-convert-to-vnc.xml b/tests/data/cli/compare/virt-xml-convert-to-vnc.xml
new file mode 100644
index 000000000..a13ee9b51
--- /dev/null
+++ b/tests/data/cli/compare/virt-xml-convert-to-vnc.xml
@@ -0,0 +1,12 @@
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
++ <graphics type="vnc" port="-1"/>
++ <video>
++ <model type="vga"/>
++ </video>
+ </devices>
+ </domain>
+
+Domain 'test' 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 04386f63b..b7241b2a0 100644
--- a/tests/test_cli.py
+++ b/tests/test_cli.py
@@ -1222,6 +1222,12 @@ c.add_compare("--print-diff --remove-device --serial 1", "remove-console-dup", i
c.add_compare("--connect %(URI-KVM)s test-hyperv-uefi --edit --boot uefi", "hyperv-uefi-collision")
c.add_compare("--connect %(URI-KVM)s test-many-devices --edit --cpu host-copy", "edit-cpu-host-copy")
+# --convert-* tests
+c.add_compare("--connect %(URI-KVM-X86)s --print-diff --define --edit --convert-to-q35", "convert-to-q35", input_file=(_VIRTXMLDIR + "convert-to-q35-win10-in.xml"))
+c.add_compare("--connect %(URI-KVM-X86)s --print-diff --define --edit --convert-to-q35 num_pcie_root_ports=7", "convert-to-q35-numports", input_file=(_VIRTXMLDIR + "convert-to-q35-win10-in.xml"))
+c.add_compare("--connect %(URI-KVM-X86)s test --print-diff --define --edit --convert-to-vnc", "convert-to-vnc")
+c.add_compare("--connect %(URI-KVM-X86)s test --print-diff --define --edit --convert-to-vnc qemu-vdagent=on", "convert-to-vnc-vdagent")
+
c = vixml.add_category("simple edit diff", "test-for-virtxml --edit --print-diff --define")
c.add_compare("""--xml ./@foo=bar --xml xpath.delete=./currentMemory --xml ./new/element/test=1""", "edit-xpaths")
diff --git a/virtinst/cli.py b/virtinst/cli.py
index 390c54cd2..5f7bd20c6 100644
--- a/virtinst/cli.py
+++ b/virtinst/cli.py
@@ -1303,6 +1303,8 @@ class VirtCLIParser(metaclass=_InitClass):
@cli_arg_name: The command line argument this maps to, so
"hostdev" for --hostdev
"""
+ OPTSTR_EMPTY = 1
+
guest_propname = None
remove_first = None
stub_none = True
@@ -1390,6 +1392,8 @@ class VirtCLIParser(metaclass=_InitClass):
self.optstr = optstr
self.guest = guest
self.editing = editing
+ if self.optstr == self.OPTSTR_EMPTY:
+ self.optstr = ""
self.optdict = _parse_optstr_to_dict(self.optstr,
self._virtargs, xmlutil.listify(self.remove_first)[:])
@@ -1627,6 +1631,28 @@ def parse_xmlcli(guest, options):
guest.add_xml_manual_action(manualaction)
+############################
+# --convert-to-vnc parsing #
+############################
+
+class ParserConvertToVNC(VirtCLIParser):
+ cli_arg_name = "convert_to_vnc"
+ supports_clearxml = False
+
+ @classmethod
+ def _virtcli_class_init(cls):
+ VirtCLIParser._virtcli_class_init_common(cls)
+ cls.add_arg("qemu-vdagent", "qemu_vdagent")
+
+ def parse(self, inst):
+ class ConvertToVNCData:
+ qemu_vdagent = None
+
+ inst = ConvertToVNCData()
+ super().parse(inst)
+ self.guest.convert_to_vnc(**inst.__dict__)
+
+
########################
# --unattended parsing #
########################
diff --git a/virtinst/virtxml.py b/virtinst/virtxml.py
index 640f70a87..46fdf1fe0 100644
--- a/virtinst/virtxml.py
+++ b/virtinst/virtxml.py
@@ -396,6 +396,13 @@ def parse_args():
cli.add_os_variant_option(parser, virtinstall=False)
+ conv = parser.add_argument_group(_("Conversion options"))
+ cli.ParserConvertToVNC.register()
+ conv.add_argument("--convert-to-vnc", nargs="?",
+ const=cli.VirtCLIParser.OPTSTR_EMPTY,
+ help=_("Convert an existing VM to use VNC graphics. "
+ "This removes any remnants of Spice graphics."))
+
g = parser.add_argument_group(_("XML options"))
cli.add_disk_option(g, editexample=True)
cli.add_net_option(g)
--
2.48.1

View File

@ -0,0 +1,30 @@
From 4c4c84de0505ede1fb10b517fa359b8307300d43 Mon Sep 17 00:00:00 2001
Message-ID: <4c4c84de0505ede1fb10b517fa359b8307300d43.1737975657.git.phrdina@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Mon, 12 Feb 2024 10:40:19 +0100
Subject: [PATCH] virtinst: fix compare for audio devices
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
(cherry picked from commit 2a0aa2d56bfdaf3612bf5182659486fc4dffbb7b)
https://issues.redhat.com/browse/RHEL-17435
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
virtinst/devices/device.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/virtinst/devices/device.py b/virtinst/devices/device.py
index 132107efb..e46437144 100644
--- a/virtinst/devices/device.py
+++ b/virtinst/devices/device.py
@@ -131,6 +131,7 @@ class Device(XMLBuilder):
"interface": ["macaddr", "xmlindex"],
"input": ["bus", "type", "xmlindex"],
"sound": ["model", "xmlindex"],
+ "audio": ["type", "id"],
"video": ["model", "xmlindex"],
"watchdog": ["model", "xmlindex"],
"hostdev": ["type", "managed", "xmlindex",
--
2.48.1

View File

@ -0,0 +1,98 @@
From e3734f6e9120ed62238bcffb6bd0679b64b42c70 Mon Sep 17 00:00:00 2001
Message-ID: <e3734f6e9120ed62238bcffb6bd0679b64b42c70.1737975657.git.phrdina@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Mon, 25 Mar 2024 14:39:20 +0100
Subject: [PATCH] virtinst: remove spice devices when removing last spice
graphics
When Spice graphics is used QEMU creates a Spice server and communicates
with Spice client using multiple channels. These channels are used by
the spice devices as well. Without the Spice graphics defined there is
no use for the other devices. In addition libvirt will report error for
such configuration.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
(cherry picked from commit aaf85519142d672e7486020d9847358f36df4f70)
https://issues.redhat.com/browse/RHEL-17435
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
.../virt-xml-remove-spice-graphics.xml | 18 ++++++++++----
virtinst/guest.py | 24 +++++++++++++++++++
2 files changed, 38 insertions(+), 4 deletions(-)
diff --git a/tests/data/cli/compare/virt-xml-remove-spice-graphics.xml b/tests/data/cli/compare/virt-xml-remove-spice-graphics.xml
index ed9f2a584..3d27d4121 100644
--- a/tests/data/cli/compare/virt-xml-remove-spice-graphics.xml
+++ b/tests/data/cli/compare/virt-xml-remove-spice-graphics.xml
@@ -1,14 +1,24 @@
- <channel type="spicevmc">
- <target type="virtio" name="com.redhat.spice.0"/>
- </channel>
+ <emulator>/usr/bin/qemu-system-x86_64</emulator>
+ <controller type="usb" index="0" model="qemu-xhci" ports="15"/>
+ <controller type="virtio-serial" index="0"/>
+- <channel type="spicevmc">
+- <target type="virtio" name="com.redhat.spice.0"/>
+- </channel>
- <graphics type="spice" autoport="yes">
- <listen type="address"/>
- <image compression="off"/>
- <gl enable="no"/>
- </graphics>
- <audio id="1" type="spice"/>
+- <audio id="1" type="spice"/>
<video>
<model type="qxl" ram="65536" vram="65536" vgamem="16384" heads="1" primary="yes"/>
+ </video>
+- <redirdev bus="usb" type="spicevmc">
+- </redirdev>
+- <redirdev bus="usb" type="spicevmc">
+- </redirdev>
+ </devices>
+ </domain>
Domain 'test-spice' defined successfully.
Changes will take effect after the domain is fully powered off.
diff --git a/virtinst/guest.py b/virtinst/guest.py
index fc7b0080a..7aa62be49 100644
--- a/virtinst/guest.py
+++ b/virtinst/guest.py
@@ -483,6 +483,7 @@ class Guest(XMLBuilder):
def remove_device(self, dev):
self.devices.remove_child(dev)
self._remove_duplicate_console(dev)
+ self._remove_spice_devices(dev)
devices = XMLChildProperty(_DomainDevices, is_single=True)
@@ -1044,3 +1045,26 @@ class Guest(XMLBuilder):
if condup:
log.debug("Found duplicate console device:\n%s", condup.get_xml())
self.devices.remove_child(condup)
+
+ def _remove_spice_audio(self):
+ for audio in self.devices.audio:
+ if audio.type == "spice":
+ self.devices.remove_child(audio)
+
+ def _remove_spice_channels(self):
+ for channel in self.devices.channel:
+ if channel.type == DeviceChannel.TYPE_SPICEVMC:
+ self.devices.remove_child(channel)
+
+ def _remove_spice_usbredir(self):
+ for redirdev in self.devices.redirdev:
+ if redirdev.type == "spicevmc":
+ self.devices.remove_child(redirdev)
+
+ def _remove_spice_devices(self, rmdev):
+ if rmdev.DEVICE_TYPE != "graphics" or self.has_spice():
+ return
+
+ self._remove_spice_audio()
+ self._remove_spice_channels()
+ self._remove_spice_usbredir()
--
2.48.1

View File

@ -0,0 +1,99 @@
From e233ec657ddf5ffb583394b251e763a3d973c251 Mon Sep 17 00:00:00 2001
Message-ID: <e233ec657ddf5ffb583394b251e763a3d973c251.1737975657.git.phrdina@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Mon, 12 Feb 2024 09:38:02 +0100
Subject: [PATCH] virtinst: unify detection of duplicate console when removing
device
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
(cherry picked from commit ef64949e84bbb1c94f742f48711ed766d8c80a02)
https://issues.redhat.com/browse/RHEL-17435
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
virtManager/object/domain.py | 10 ----------
virtinst/guest.py | 9 +++++++++
virtinst/virtxml.py | 8 --------
3 files changed, 9 insertions(+), 18 deletions(-)
diff --git a/virtManager/object/domain.py b/virtManager/object/domain.py
index cc2f506d4..5215a97e9 100644
--- a/virtManager/object/domain.py
+++ b/virtManager/object/domain.py
@@ -583,21 +583,11 @@ class vmmDomain(vmmLibvirtObject):
"""
Remove passed device from the inactive guest XML
"""
- # If serial and duplicate console are both present, they both need
- # to be removed at the same time
- con = None
- if self.serial_is_console_dup(devobj):
- con = self.xmlobj.devices.console[0]
-
xmlobj = self._make_xmlobj_to_define()
editdev = self._lookup_device_to_define(xmlobj, devobj, False)
if not editdev:
return # pragma: no cover
- if con:
- rmcon = xmlobj.find_device(con)
- if rmcon:
- xmlobj.remove_device(rmcon)
xmlobj.remove_device(editdev)
self._redefine_xmlobj(xmlobj)
diff --git a/virtinst/guest.py b/virtinst/guest.py
index c53516c6e..fc7b0080a 100644
--- a/virtinst/guest.py
+++ b/virtinst/guest.py
@@ -479,8 +479,11 @@ class Guest(XMLBuilder):
def add_device(self, dev):
self.devices.add_child(dev)
+
def remove_device(self, dev):
self.devices.remove_child(dev)
+ self._remove_duplicate_console(dev)
+
devices = XMLChildProperty(_DomainDevices, is_single=True)
def find_device(self, origdev):
@@ -1035,3 +1038,9 @@ class Guest(XMLBuilder):
self._add_spice_channels()
self._add_spice_sound()
self._add_spice_usbredir()
+
+ def _remove_duplicate_console(self, dev):
+ condup = DeviceConsole.get_console_duplicate(self, dev)
+ if condup:
+ log.debug("Found duplicate console device:\n%s", condup.get_xml())
+ self.devices.remove_child(condup)
diff --git a/virtinst/virtxml.py b/virtinst/virtxml.py
index bd2b42823..640f70a87 100644
--- a/virtinst/virtxml.py
+++ b/virtinst/virtxml.py
@@ -11,7 +11,6 @@ import libvirt
from . import cli
from .cli import fail, fail_conflicting, print_stdout, print_stderr
-from .devices import DeviceConsole
from .guest import Guest
from .logger import log
from . import xmlutil
@@ -182,13 +181,6 @@ def action_remove_device(guest, options, parserclass):
getattr(options, parserclass.cli_arg_name)[-1], parserclass)
devs = xmlutil.listify(devs)
- # Check for console duplicate devices
- for dev in devs[:]:
- condup = DeviceConsole.get_console_duplicate(guest, dev)
- if condup:
- log.debug("Found duplicate console device:\n%s", condup.get_xml())
- devs.append(condup)
-
for dev in devs:
guest.remove_device(dev)
return devs
--
2.48.1

View File

@ -8,7 +8,7 @@
Name: virt-manager
Version: 3.2.0
Release: 4%{?dist}%{?extra_release}
Release: 4.1%{?dist}%{?extra_release}
%global verrel %{version}-%{release}
Summary: Desktop tool for managing virtual machines via libvirt
@ -28,6 +28,15 @@ Patch7: virt-manager-Handle-new-nodedev-name-for-mediated-devices.patch
Patch8: virt-manager-addstorage-Don-t-pass-None-to-widget.set_active.patch
Patch9: virt-manager-cli-add-ioapic.driver-to-features.patch
Patch10: virt-manager-console-fix-error-with-old-pygobject.patch
Patch11: virt-manager-cli-Add-basic-audio-type-XXX-id-Y-support.patch
Patch12: virt-manager-virtinst-unify-detection-of-duplicate-console-when-removing-device.patch
Patch13: virt-manager-virtinst-fix-compare-for-audio-devices.patch
Patch14: virt-manager-testsuite-add-test-spice-vm-definition.patch
Patch15: virt-manager-virtinst-remove-spice-devices-when-removing-last-spice-graphics.patch
Patch16: virt-manager-guest-add-convert_to_vnc.patch
Patch17: virt-manager-guest-remove-spiceport-devices-when-spice-is-removed.patch
Patch18: virt-manager-guest-convert_to_vnc-convert-video-device.patch
Patch19: virt-manager-virt-xml-Add-edit-convert-to-vnc.patch
Requires: virt-manager-common = %{verrel}
@ -197,6 +206,17 @@ done
%changelog
* Mon Jan 27 2025 Pavel Hrdina <phrdina@redhat.com> - 3.2.0-4.1.el8_10
- cli: Add basic --audio type=XXX,id=Y support (RHEL-17435)
- virtinst: unify detection of duplicate console when removing device (RHEL-17435)
- virtinst: fix compare for audio devices (RHEL-17435)
- testsuite: add test-spice vm definition (RHEL-17435)
- virtinst: remove spice devices when removing last spice graphics (RHEL-17435)
- guest: add convert_to_vnc() (RHEL-17435)
- guest: remove spiceport devices when spice is removed (RHEL-17435)
- guest: convert_to_vnc: convert video device (RHEL-17435)
- virt-xml: Add `--edit --convert-to-vnc` (RHEL-17435)
* Thu Mar 10 2022 Jonathon Jongsma <jjongsma@redhat.com> - 3.2.0-4
- console: fix error with old pygobject (rhbz#2026987)