tstest/natlab/vmtest: add macOS VM support using Tart base images

Add macOS VM support to the vmtest framework using Tart's pre-built
macOS images (ghcr.io/cirruslabs/macos-tahoe-base) instead of building
from IPSW. The Tart image has SIP disabled and SSH enabled.

At test time, the Tart base image's disk, NVRAM, and hardware identity
are APFS-cloned into a tailmac-compatible directory layout, and the VM
is booted headlessly via tailmac's Host.app (Virtualization.framework)
with its NIC connected to vnet's dgram socket.

New features:
- tailmac.go: ensureTartImage (auto-pull), cloneTartToTailmac (format
  conversion), startTailMacVM (launch + cleanup)
- NoAgent() node option for VMs without TTA installed
- LANPing() for ICMP reachability testing via TTA's /ping endpoint
- IsMacOS field on OSImage, with GOOS/GOARCH support
- Dgram socket listener in Start() for macOS VMs
- Fix ReadFromUnix error spam on dgram socket close in vnet

TestMacOSAndLinuxCanPing verifies a macOS Tart VM and a gokrazy Linux
VM can ping each other on the same vnet LAN.

Updates #13038

Change-Id: I5e73a27878abf009f780fdf11a346fc857711cff
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
Brad Fitzpatrick
2026-04-28 12:10:45 -07:00
committed by Brad Fitzpatrick
parent ec7b11d986
commit b2d4ba04b6
5 changed files with 408 additions and 17 deletions
+20
View File
@@ -16,6 +16,26 @@ import (
"tailscale.com/tstest/natlab/vnet"
)
func TestMacOSAndLinuxCanPing(t *testing.T) {
env := vmtest.New(t)
lan := env.AddNetwork("192.168.1.1/24")
linux := env.AddNode("linux", lan,
vmtest.OS(vmtest.Gokrazy),
vmtest.DontJoinTailnet())
macos := env.AddNode("macos", lan,
vmtest.OS(vmtest.MacOS),
vmtest.DontJoinTailnet(),
vmtest.NoAgent())
env.Start()
// Ping from Linux (which has TTA) to macOS (which just responds to ICMP).
// LANPing retries until the macOS VM has booted and acquired a DHCP lease.
env.LANPing(linux, macos.LanIP(lan))
}
func TestSubnetRouter(t *testing.T) {
testSubnetRouterForOS(t, vmtest.Ubuntu2404)
}