tstest/natlab/vmtest: don't require KVM; use TCG on macOS

startCloudQEMU hardcoded -machine q35,accel=kvm and -cpu host,
which fails on any host without KVM (notably macOS). Replace
with a qemuAccelArgs helper that probes /dev/kvm and falls back
to QEMU's TCG software emulation, matching the pattern already
used by tstest/integration/nat. Also wire the helper into
startGokrazyQEMU so gokrazy VMs pick up KVM when available.

Updates #13038

Change-Id: I7745518db823279b1880957bb14ca2ffdaab4c50
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
Brad Fitzpatrick
2026-05-11 17:53:45 -07:00
committed by Brad Fitzpatrick
parent e062b46984
commit f4c5613156
2 changed files with 22 additions and 4 deletions
+20 -2
View File
@@ -13,6 +13,7 @@ import (
"os/exec"
"path/filepath"
"regexp"
"runtime"
"strconv"
"strings"
"testing"
@@ -21,6 +22,21 @@ import (
"tailscale.com/tstest/natlab/vnet"
)
// qemuAccelArgs returns QEMU command-line flags for hardware-accelerated
// virtualisation when available, or nil to fall back to TCG (software
// emulation). On Linux, KVM is used when /dev/kvm is accessible. On other
// platforms (macOS, etc.) TCG is used, which allows the tests to run
// without a same-architecture hypervisor at the cost of speed.
func qemuAccelArgs() []string {
if runtime.GOOS == "linux" {
if f, err := os.OpenFile("/dev/kvm", os.O_RDWR, 0); err == nil {
f.Close()
return []string{"-enable-kvm", "-cpu", "host"}
}
}
return nil
}
// gokrazyPlatform boots gokrazy (Linux) VMs via QEMU.
type gokrazyPlatform struct{}
@@ -125,6 +141,7 @@ func (e *Env) startGokrazyQEMU(n *Node) error {
)
}
args = append(args, qemuAccelArgs()...)
return e.launchQEMU(n.name, logPath, args)
}
@@ -148,9 +165,8 @@ func (e *Env) startCloudQEMU(n *Node) error {
qmpSock := filepath.Join(e.tempDir, n.name+"-qmp.sock")
args := []string{
"-machine", "q35,accel=kvm",
"-machine", "q35",
"-m", fmt.Sprintf("%dM", n.os.MemoryMB),
"-cpu", "host",
"-smp", "2",
"-display", "none",
"-drive", fmt.Sprintf("file=%s,if=virtio", disk),
@@ -179,6 +195,8 @@ func (e *Env) startCloudQEMU(n *Node) error {
"-device", "virtio-net-pci,netdev=debug0,romfile=",
)
args = append(args, qemuAccelArgs()...)
if err := e.launchQEMU(n.name, logPath, args); err != nil {
return err
}