mirror of
https://github.com/virt-manager/virt-manager.git
synced 2025-01-08 07:03:02 -06:00
guest: add convert_to_vnc()
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>
This commit is contained in:
parent
c498c519ed
commit
229b905053
13
tests/data/xmlparse/convert-to-vnc-empty-in.xml
Normal file
13
tests/data/xmlparse/convert-to-vnc-empty-in.xml
Normal file
@ -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>
|
||||
|
13
tests/data/xmlparse/convert-to-vnc-empty-out.xml
Normal file
13
tests/data/xmlparse/convert-to-vnc-empty-out.xml
Normal file
@ -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>
|
31
tests/data/xmlparse/convert-to-vnc-has-vnc-in.xml
Normal file
31
tests/data/xmlparse/convert-to-vnc-has-vnc-in.xml
Normal file
@ -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>
|
22
tests/data/xmlparse/convert-to-vnc-has-vnc-out.xml
Normal file
22
tests/data/xmlparse/convert-to-vnc-has-vnc-out.xml
Normal file
@ -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>
|
30
tests/data/xmlparse/convert-to-vnc-spice-devices-in.xml
Normal file
30
tests/data/xmlparse/convert-to-vnc-spice-devices-in.xml
Normal file
@ -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>
|
22
tests/data/xmlparse/convert-to-vnc-spice-devices-out.xml
Normal file
22
tests/data/xmlparse/convert-to-vnc-spice-devices-out.xml
Normal file
@ -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>
|
20
tests/data/xmlparse/convert-to-vnc-spice-manyopts-in.xml
Normal file
20
tests/data/xmlparse/convert-to-vnc-spice-manyopts-in.xml
Normal file
@ -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>
|
||||
|
20
tests/data/xmlparse/convert-to-vnc-spice-manyopts-out.xml
Normal file
20
tests/data/xmlparse/convert-to-vnc-spice-manyopts-out.xml
Normal file
@ -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>
|
@ -1215,3 +1215,17 @@ def testConvertToQ35():
|
||||
|
||||
_test("convert-to-q35-win10")
|
||||
_test("convert-to-q35-f39", num_pcie_root_ports=5)
|
||||
|
||||
|
||||
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")
|
||||
|
@ -828,6 +828,84 @@ class Guest(XMLBuilder):
|
||||
|
||||
self.add_q35_pcie_controllers()
|
||||
|
||||
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()
|
||||
|
||||
@ -1277,10 +1355,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()
|
||||
|
Loading…
Reference in New Issue
Block a user