Working version of QEMU configuration
This commit is contained in:
parent
49cc960703
commit
78d7233ff3
3 changed files with 138 additions and 2 deletions
|
|
@ -23,7 +23,7 @@ module Downloader
|
|||
puts "File does not exist, downloading..."
|
||||
URI.open(uri) do |input|
|
||||
File.open(path, 'wb') do |output|
|
||||
IO.copy_stream(input, output)
|
||||
IO.copy_stream(input, output)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
require 'downloader'
|
||||
require 'system'
|
||||
require_relative 'data/resources/iso-images'
|
||||
require 'vm/qemu'
|
||||
|
||||
module VirtualMachine
|
||||
def self.distro(name, arch, type = :install)
|
||||
|
|
@ -27,14 +28,23 @@ module VirtualMachine
|
|||
|
||||
Downloader.get(url) do |path|
|
||||
disk_img_path = File.join(User.cache_path, "vm", distro.to_s, arch.to_s, options[:name], "root.img")
|
||||
create_disk_image(disk_img_path, 500)
|
||||
create_disk_image(disk_img_path, 5000)
|
||||
|
||||
puts path
|
||||
puts disk_img_path
|
||||
|
||||
Qemu.launch(
|
||||
arch,
|
||||
disk_img_path,
|
||||
cpus: [1, System.cpus - 2].max,
|
||||
cdrom: path,
|
||||
detach: false
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
# size in MB
|
||||
# lsof /Users/artur/.cache/dat/vm/debian/arm64/debian/root.img
|
||||
def self.create_disk_image(path, size)
|
||||
size_in_bytes = 1024 * 1024 * size
|
||||
|
||||
|
|
|
|||
126
lib/vm/qemu.rb
Normal file
126
lib/vm/qemu.rb
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
require "fileutils"
|
||||
require "ostruct"
|
||||
|
||||
module Qemu
|
||||
def self.qemu_bin_for(arch)
|
||||
{
|
||||
x86_64: "qemu-system-x86_64",
|
||||
x86_32: "qemu-system-i386",
|
||||
arm64: "qemu-system-aarch64",
|
||||
armv7: "qemu-system-arm",
|
||||
armv6: "qemu-system-arm",
|
||||
armv5: "qemu-system-arm",
|
||||
riscv64: "qemu-system-riscv64",
|
||||
ppc64le: "qemu-system-ppc64",
|
||||
ppc64: "qemu-system-ppc64",
|
||||
ppc32: "qemu-system-ppc",
|
||||
s390x: "qemu-system-s390x",
|
||||
mips64el: "qemu-system-mips64el",
|
||||
mips64: "qemu-system-mips64",
|
||||
mipsel: "qemu-system-mipsel",
|
||||
mips: "qemu-system-mips",
|
||||
loongarch64: "qemu-system-loongarch64",
|
||||
sparc64: "qemu-system-sparc64",
|
||||
alpha: "qemu-system-alpha",
|
||||
hppa: "qemu-system-hppa",
|
||||
ia64: "qemu-system-ia64",
|
||||
}.fetch(arch) { raise "Unsupported arch: #{arch.inspect}" }
|
||||
end
|
||||
|
||||
def self.accel_args
|
||||
host = RbConfig::CONFIG["host_os"]
|
||||
if host =~ /linux/i && File.exist?("/dev/kvm")
|
||||
["-accel", "kvm"]
|
||||
elsif host =~ /darwin/i
|
||||
# hvf exists on Apple Silicon + Intel macOS; QEMU falls back if not available
|
||||
["-accel", "hvf"]
|
||||
elsif host =~ /freebsd/i
|
||||
# if QEMU was built with it; otherwise it will ignore
|
||||
["-accel", "bhyve"]
|
||||
else
|
||||
["-accel", "tcg"]
|
||||
end
|
||||
end
|
||||
|
||||
def self.machine_args_for(arch)
|
||||
case arch
|
||||
when :x86_64, :x86_32
|
||||
[]
|
||||
when :arm64
|
||||
# -machine type=virt
|
||||
# -cpu cortex-a72
|
||||
["-machine", "virt", "-cpu", "max"]
|
||||
when :armv7, :armv6, :armv5
|
||||
["-machine", "virt", "-cpu", "cortex-a15"]
|
||||
when :riscv64
|
||||
["-machine", "virt"]
|
||||
when :loongarch64
|
||||
["-machine", "virt"]
|
||||
else
|
||||
[]
|
||||
end
|
||||
end
|
||||
|
||||
#def self.launch(arch, disk_path, cdrom = nil, detach = true)
|
||||
def self.launch(arch, disk_path, **options)
|
||||
defaults = {
|
||||
arch: System::ARCH,
|
||||
cdrom: nil,
|
||||
detach: true,
|
||||
ram: 2048,
|
||||
cpus: 1
|
||||
}
|
||||
opts = defaults.merge(options)
|
||||
|
||||
puts opts
|
||||
|
||||
qemu = qemu_bin_for(arch)
|
||||
args = []
|
||||
|
||||
if System::OS == :macos && arch == :arm64
|
||||
# args += ["-bios", "/opt/homebrew/share/qemu/edk2-aarch64-code.fd"]
|
||||
args += ["-drive", "if=pflash,format=raw,unit=0,readonly=on,file=/opt/homebrew/share/qemu/edk2-aarch64-code.fd"]
|
||||
|
||||
#args += ["-device", "virtio-gpu-device"]
|
||||
args += ["-display", "cocoa"]
|
||||
args += ["-device", "qemu-xhci,id=xhci"]
|
||||
args += ["-device", "usb-kbd"]
|
||||
args += ["-device", "usb-tablet"]
|
||||
|
||||
args += ["-device", "virtio-keyboard-device"]
|
||||
args += ["-device", "virtio-mouse-device"]
|
||||
args += ["-device", "virtio-gpu"]
|
||||
|
||||
|
||||
# copy to /Users/artur/.cache/dat/vm/debian/arm64/debian/vars.fd
|
||||
# /opt/homebrew/share/qemu/edk2-aarch64-vars.fd
|
||||
# args += ["-drive", "if=pflash,format=raw,unit=1,file=/Users/artur/.cache/dat/vm/debian/arm64/debian/vars.fd"]
|
||||
end
|
||||
|
||||
args += accel_args
|
||||
args += machine_args_for(arch)
|
||||
args += ["-m", opts[:ram].to_s, "-smp", opts[:cpus].to_s]
|
||||
args += ["-name", "FirstVM", "-boot", "order=d"] # boot from CD first
|
||||
args += ["-drive", "file=#{disk_path},if=virtio,cache=writeback,format=raw"]
|
||||
if opts[:cdrom] != nil
|
||||
args += ["-cdrom", opts[:cdrom]]
|
||||
end
|
||||
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"]
|
||||
|
||||
cmd = [qemu, *args]
|
||||
|
||||
puts "Launching: #{cmd.join(' ')}"
|
||||
pid = Process.spawn(*cmd, pgroup: true, out: $stdout, err: $stderr)
|
||||
|
||||
if opts[:detach]
|
||||
Process.detach(pid)
|
||||
puts "QEMU pid=#{pid}"
|
||||
else
|
||||
Process.wait(pid)
|
||||
status = $?
|
||||
puts "Exit status: #{status.exitstatus}"
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue