tstest/natlab/vmtest: add Fedora + DNS-backend coverage, harden non-KVM boot (#20409)

* tstest/natlab/vmtest: make cloud VM boot robust without KVM

Adding heavier distro images (Fedora) surfaced several ways the cloud VM
boot path breaks under TCG software emulation (no /dev/kvm), especially
with multiple concurrent VMs on few cores.

- Add a virtio-rng device to the cloud path so early boot doesn't block in
  getrandom() waiting for the CRNG to seed.
- When no hardware acceleration is available, relax the stuck-console
  watchdog (tuned for KVM's ~1-2s first output) and serialize VM boots so a
  heavy guest doesn't starve its siblings' emulation threads.
- Bound the bring-up context to the test deadline and dump each VM's console
  on failure, so a hang surfaces as a diagnosable Fatalf instead of an
  opaque `go test -timeout` panic (which skips cleanups).

Fixes tailscale/corp#44794
Updates tailscale/corp#44793

Signed-off-by: Brendan Creane <bcreane@gmail.com>

* tstest/natlab/vmtest: add Fedora and DNS-backend test coverage

Add the first RHEL-family distro and the machinery to assert and provision
distinct DNS backends, so adding a distro isn't "basically equivalent" to
the others.

- Add a Fedora 43 image (NetworkManager + systemd-resolved, SELinux
  enforcing). restorecon-relabel the curl'd binaries so they exec under
  enforcing mode.
- Add DNSBackend/AssertDNSBackend, reading the dns_manager_linux_mode_*
  clientmetric to assert which backend tailscaled selected.
- Add a WithDNSMode node option. WithDNSMode(DNSDirect) masks
  systemd-resolved and writes a plain resolv.conf pointing at natlab's fake
  DNS, forcing the direct backend -- so one image covers multiple backends.

Fixes tailscale/corp#44796
Updates tailscale/corp#44793

Signed-off-by: Brendan Creane <bcreane@gmail.com>

---------

Signed-off-by: Brendan Creane <bcreane@gmail.com>
This commit is contained in:
Brendan Creane
2026-07-20 12:41:25 -07:00
committed by GitHub
parent c130a9b520
commit a7cb5745a2
5 changed files with 243 additions and 27 deletions
+30
View File
@@ -84,6 +84,28 @@ func TestSubnetRouterFreeBSD(t *testing.T) {
testSubnetRouterForOS(t, vmtest.FreeBSD150)
}
func TestSubnetRouterFedora(t *testing.T) {
testSubnetRouterForOS(t, vmtest.Fedora43)
}
// TestFedoraDNSDirect verifies that provisioning a Fedora node with
// WithDNSMode(DNSDirect) — which masks systemd-resolved — makes tailscaled
// select the "direct" DNS backend instead of the image default
// ("systemd-resolved"). This is what lets one distro image cover multiple DNS
// backends, so adding a distro isn't "basically equivalent" to the others.
func TestFedoraDNSDirect(t *testing.T) {
env := vmtest.New(t)
net := env.AddNetwork("2.1.1.1", "192.168.1.1/24", vnet.EasyNAT)
node := env.AddNode("fedora", net,
vmtest.OS(vmtest.Fedora43),
vmtest.WithDNSMode(vmtest.DNSDirect))
env.Start()
env.AssertDNSBackend(node, "direct")
}
func testSubnetRouterForOS(t testing.TB, srOS vmtest.OSImage) {
t.Helper()
env := vmtest.New(t)
@@ -107,6 +129,14 @@ func testSubnetRouterForOS(t testing.TB, srOS vmtest.OSImage) {
env.Start()
// Log which DNS backend the (Linux) subnet router selected. This is the
// whole point of testing multiple distros: they should exercise different
// DNS managers. Once we've confirmed the expected value per distro, this
// can become an AssertDNSBackend. FreeBSD has no Linux DNS gauge, so skip.
if srOS.GOOS() == "linux" {
t.Logf("subnet-router (%s) DNS backend: %s", srOS.Name, env.DNSBackend(sr))
}
approveStep.Begin()
env.ApproveRoutes(sr, "10.0.0.0/24")
approveStep.End(nil)