Read port forwards from per-VM forwards.conf files

A QEMU config file section cannot hold more than one hostfwd entry, so
the forwards move out of the ini files into qemu/<vm>/forwards.conf, one
"LABEL HOST_PORT GUEST_PORT" rule per line. The new vmforwards.py parses
them, skips rules whose host port is taken and builds the -netdev
argument, which every launcher now passes instead of relying on a
netdev section in the ini or on -nic.

The ini files move to qemu/<vm>/config.ini and qemu/<vm>/<os>-<arch>.ini.
The *_SSH_PORT / *_RDP_PORT variables and --rdp-port / --ssh-port still
replace the host port of the SSH and RDP rules.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
GuofangandClaude Sonnet 5.5 committed 2026-10-29 14:55:30 +08:00
1 parent 07a2c6db3e
commit 78f6fd424b
29 files changed
+272 -131

No files matched your search

+83
View File
@@ -0,0 +1,83 @@
# QEMU configuration for the Windows 11 virtual machine. The accelerators and machine type
# are in <os>-<arch>.ini (os is linux or darwin), which QEMU reads after
# this file.
#
# run-windows11.py fills in the file path placeholders below, writes the result
# to <state dir>/qemu.ini and passes it to QEMU with -readconfig. Options that
# have no -readconfig equivalent (-cpu, -display) and the installation media
# attached by --install-from-iso are still added by the launcher.
[name]
guest = "windows11"
[memory]
size = "8G"
[smp-opts]
cpus = "8"
# UEFI firmware: read-only code and the per-VM variable store.
[drive "pflash0"]
if = "pflash"
format = "raw"
readonly = "on"
file = "${uefi_code}"
[drive "pflash1"]
if = "pflash"
format = "raw"
file = "${uefi_vars}"
# System disk image; the device that exposes it (and the NIC, which is
# attached to the user-mode network "net0" that the launcher defines with
# -netdev from qemu/windows11/forwards.conf because a config file section cannot hold
# more than one hostfwd) is in the architecture file.
[drive "system_disk"]
if = "none"
format = "qcow2"
file = "${disk_image}"
# Host/guest clipboard integration through the SPICE vdagent channel.
[device "virtio_serial"]
driver = "virtio-serial-pci"
[chardev "vdagent"]
backend = "qemu-vdagent"
name = "vdagent"
clipboard = "on"
mouse = "off"
[device "vdagent-port"]
driver = "virtserialport"
chardev = "vdagent"
name = "com.redhat.spice.0"
# Register the USB tablet after vdagent so QEMU selects it as the active pointer.
[device "usb_controller"]
driver = "qemu-xhci"
[device "tablet0"]
driver = "usb-tablet"
bus = "usb_controller.0"
# QEMU Guest Agent and the QEMU monitor, both on sockets in the state directory.
[chardev "qga"]
backend = "socket"
path = "${guest_agent_socket}"
server = "on"
wait = "off"
[device "qga-port"]
driver = "virtserialport"
chardev = "qga"
name = "org.qemu.guest_agent.0"
[chardev "monitor"]
backend = "socket"
path = "${monitor_socket}"
server = "on"
wait = "off"
[mon "monitor0"]
chardev = "monitor"
mode = "readline"
+41
View File
@@ -0,0 +1,41 @@
# macOS host, arm64 part of the Windows 11 QEMU configuration; read after config.ini.
# Accelerators are tried in order: HVF on macOS, else emulation.
[accel]
accel = "hvf"
[accel]
accel = "tcg"
# run-windows11.py adds kernel-irqchip=off unless installing with
# --install-from-img (see there).
[machine]
type = "virt"
# The "virt" machine has no IDE. NVMe and USB mass storage (used by the
# installation media of --install-from-iso) both have inbox Windows drivers.
[device "system_disk-dev"]
driver = "nvme"
drive = "system_disk"
serial = "win11disk"
bootindex = "1"
# Windows has no inbox driver for virtio-net; the guest tools installed by
# Configure-Windows.ps1 provide it.
[device "nic0"]
driver = "virtio-net-pci"
netdev = "net0"
# Unlike q35, "virt" has no default GPU or keyboard. virtio-gpu is the only
# display, driven by viogpudo (installed by Configure-Windows.ps1). ramfb is not
# added because Windows would then see a second adapter with a fixed-mode
# monitor. xres/yres set the preferred mode in the EDID (QEMU defaults to
# 1280x800); viogpudo accepted 1920x1200, 2048x1280 and 2304x1440 but not
# 2560x1440 or 2560x1600.
[device "gpu0"]
driver = "virtio-gpu-pci"
xres = "2304"
yres = "1440"
[device "kbd0"]
driver = "usb-kbd"
+5
View File
@@ -0,0 +1,5 @@
# Host ports forwarded to the guest: LABEL HOST_PORT GUEST_PORT
# --rdp-port and --ssh-port (or WIN11_VM_RDP_PORT and WIN11_VM_SSH_PORT)
# replace the host port of the RDP and SSH rules.
RDP 3389 3389
SSH 2222 22
+24
View File
@@ -0,0 +1,24 @@
# Linux host, amd64 part of the Windows 11 QEMU configuration; read after config.ini.
# Accelerators are tried in order: KVM on Linux, else emulation.
[accel]
accel = "kvm"
[accel]
accel = "tcg"
[machine]
type = "q35"
# The system disk is attached through IDE so that Windows can boot before the
# VirtIO storage driver is installed; the installation media of
# --install-from-iso use ide.1 to ide.3.
[device "system_disk-dev"]
driver = "ide-hd"
drive = "system_disk"
bus = "ide.0"
bootindex = "1"
[device "nic0"]
driver = "e1000e"
netdev = "net0"
+38
View File
@@ -0,0 +1,38 @@
# Linux host, arm64 part of the Windows 11 QEMU configuration; read after config.ini.
# Accelerators are tried in order: KVM on Linux, else emulation.
[accel]
accel = "kvm"
[accel]
accel = "tcg"
[machine]
type = "virt"
# The "virt" machine has no IDE. NVMe and USB mass storage (used by the
# installation media of --install-from-iso) both have inbox Windows drivers.
[device "system_disk-dev"]
driver = "nvme"
drive = "system_disk"
serial = "win11disk"
bootindex = "1"
# Windows has no inbox driver for virtio-net; the guest tools installed by
# Configure-Windows.ps1 provide it.
[device "nic0"]
driver = "virtio-net-pci"
netdev = "net0"
# Unlike q35, "virt" has no default GPU or keyboard. virtio-gpu is the only
# display, driven by viogpudo (installed by Configure-Windows.ps1). ramfb is not
# added because Windows would then see a second adapter with a fixed-mode
# monitor. xres/yres set the preferred mode in the EDID (QEMU defaults to
# 1280x800); viogpudo accepted 1920x1200 and 2048x1280 but not 2560x1600.
[device "gpu0"]
driver = "virtio-gpu-pci"
xres = "2048"
yres = "1280"
[device "kbd0"]
driver = "usb-kbd"