This commit is contained in:
Artur Gurgul 2025-08-28 17:48:34 +02:00
parent 764967c8e0
commit 93f402b012
9 changed files with 299 additions and 4 deletions

View file

@ -13,6 +13,10 @@ module DisplayMode
def self.window
2
end
def self.vnc
3
end
end
module Qemu
@ -81,9 +85,14 @@ module Qemu
arch: System::ARCH,
cdrom: nil,
detach: true,
shell: false,
ram: 2048 * 8,
cpus: 1,
display: DisplayMode::none
display: DisplayMode::none,
mount: {
wd: nil,
home: nil
}
}
# for testing only
@ -92,6 +101,7 @@ module Qemu
defaults[:display] = DisplayMode.fullscreen
defaults[:display] = DisplayMode.window
# defaults[:display] = DisplayMode.none
#defaults[:display] = DisplayMode.vnc
opts = defaults.merge(options)
@ -119,14 +129,78 @@ module Qemu
args += ["-drive", "if=pflash,format=raw,unit=0,readonly=on,file=#{opts[:code_fd]}"]
args += ["-drive", "if=pflash,format=raw,unit=1,file=#{opts[:vars_fd]}"]
ssh_port = nil
if opts[:shell]
ssh_port = rand(4000..9999)
# args += ['-netdev', "user,id=net0,hostfwd=tcp:127.0.0.1:#{ssh_port}-:22"]
# args += ['-device', 'virtio-net-device,netdev=net0']
# args += ['-netdev', "user,id=n0,hostfwd=tcp:127.0.0.1:#{ssh_port}-10.0.2.15:22"]
# args += ['-device', 'virtio-net,netdev=n0']
# args += ['-netdev', "user,id=net0,hostfwd=tcp:127.0.0.1:#{ssh_port}-10.0.2.15:22"]
# args += ['-device', 'virtio-net-device,netdev=net0"']
args += ['-nic', "user,model=virtio-net-pci,hostfwd=tcp:127.0.0.1:#{ssh_port}-:22"]
puts "ssh -p #{ssh_port} user@localhost"
# conf that works
#args += ["-device", "virtio-net,netdev=n0", "-netdev", "user,id=n0"]
end
# -virtfs local,path=.,mount_tag=hostfs,security_model=passthrough,id=hostfs
# mount -t 9p -o trans=virtio,version=9p2000.L hostfs /mnt
# hostfs /home 9p trans=virtio,version=9p2000.L,uid=1000,gid=1000,msize=262144,cache=mmap,nofail 0 0
# hostfs /share 9p trans=virtio,version=9p2000.L,uid=1000,gid=1000,msize=262144,cache=mmap,nofail 0 0
if opts[:mount][:wd]
args += ['-virtfs', 'local,path=.,mount_tag=hostfs,security_model=passthrough,id=hostfs']
end
if opts[:mount][:home]
#args += ['-homefs', "local,path=#{VMDATA},mount_tag=hostfs,security_model=passthrough,id=hostfs"]
end
if opts[:display] == DisplayMode::none
port = 2222
args += ['-nographic']
args += ['-netdev', "user,id=net0,hostfwd=tcp:127.0.0.1:#{port}-:22"]
args += ['-netdev', "user,id=net0,hostfwd=tcp:127.0.0.1:#{port}-:22,udp:127.0.0.1:6544-:6544=on"]
#args += ['-device', 'e1000,netdev=net0']
args += ['-device', 'virtio-net-pci,netdev=net0']
puts "ssh -p #{port} user@localhost"
elsif opts[:display] == DisplayMode::vnc
# Note: this outputs serial on the console
#args += ['-nographic']
args += ["-display", "none"]
args += ["-device", "virtio-gpu-pci"]
args += ["-device", "virtio-keyboard-pci"]
args += ["-device", "virtio-mouse-pci"]
args += ['-vnc', '127.0.0.1:0,password=on']
# tunnel ssh -L 5900:127.0.0.1:5900 user@your-host
# -monitor unix:/tmp/qemu-mon,server,nowait
# -vnc 127.0.0.1:0,password=on
# printf 'change vnc password\nMySecret\n' | socat - UNIX-CONNECT:/tmp/qemu-mon
# SASL auth (username + password)
# -vnc :0,sasl
# TLS (certificates, optional password)
# -object tls-creds-x509,id=tls0,...
# -vnc :0,tls-creds=tls0
# qemu-system-x86_64 \
# -object tls-creds-x509,id=tls0,dir=/etc/pki/qemu,endpoint=server \
# -vnc :0,tls-creds=tls0,sasl
else
#args += ["-device", "virtio-gpu-device"]
if opts[:display] == DisplayMode::fullscreen
@ -156,7 +230,18 @@ module Qemu
args += ["-device", "virtio-gpu"]
#args += ['-nic', 'user,model=virtio-net-pci']
args += ["-device", "virtio-net,netdev=n0", "-netdev", "user,id=n0"]
unless opts[:shell]
args += ["-device", "virtio-net,netdev=n0", "-netdev", "user,id=n0"]
end
### TODO: remove
port = 2222
args += ['-netdev', "user,id=net0,hostfwd=tcp:127.0.0.1:#{port}-:22,hostfwd=udp:127.0.0.1:6544-:6544"]
args += ['-virtfs', 'local,path=.,mount_tag=hostfs,security_model=passthrough,id=hostfs']
### TODO END
# macOS vmnet (shares Macs LAN)
# -netdev vmnet-shared,id=n1 \
# -device virtio-net-pci,netdev=n1
@ -211,6 +296,8 @@ module Qemu
# -netdev vmnet-shared,id=net0
end
args += ['-monitor', 'stdio']
# args += ["-device", "virtio-net,netdev=n0", "-netdev", "user,id=n0"] # user-mode NAT
# optional: uncomment to run headless with VNC on :5901
# args += ["-display", "none", "-vnc", "127.0.0.1:1"]
@ -224,6 +311,11 @@ module Qemu
pid = Process.spawn(*cmd, pgroup: false, out: log, err: log)
Process.detach(pid)
puts "QEMU pid=#{pid}"
if opts[:shell]
System.exec_ssh(ssh_port)
end
else
pid = Process.spawn(*cmd, pgroup: true, out: $stdout, err: $stderr)
Process.wait(pid)