.github, tstest/natlab/vmtest: replace old VM runner job with natlab tests
The "vm" CI job ran a single test (TestRunUbuntu2404 from tstest/integration/vms) on a privileged self-hosted runner. Its coverage is nearly all redundant with the modern natlab vmtest suite, which boots real Ubuntu VMs and already exercises connectivity, kernel TUN, SSH, Taildrop, ACME, and OS DNS integration on GitHub-hosted runners. The two things it tested that natlab didn't are added back as natlab tests so the runner can be decommissioned: TestUbuntuSystemdUnit runs tailscaled via the stock systemd unit that Linux packages ship (cmd/tailscaled/tailscaled.service with tailscaled.defaults as its EnvironmentFile) instead of launching the binary directly, verifying the unit's directives and its Type=notify readiness handshake. TestDNSExtraRecordsSearchDomains verifies that control-plane DNS ExtraRecords and search domains are resolvable through the guest's OS resolver (libc to systemd-resolved to quad-100). Updates #13038 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com> Change-Id: I8d0dfb8b8153289e7ca78f3af03dfece9497bfe8
This commit is contained in:
committed by
Brad Fitzpatrick
parent
6bf05cb63e
commit
bef2cd8088
@@ -6,6 +6,7 @@ package vmtest
|
||||
import (
|
||||
"crypto/ed25519"
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"os"
|
||||
@@ -110,6 +111,10 @@ func (e *Env) generateLinuxUserData(n *Node) string {
|
||||
ud.WriteString(fmt.Sprintf(" ssh_authorized_keys:\n - %s\n", strings.TrimSpace(string(pubkey))))
|
||||
}
|
||||
|
||||
if n.systemdUnit {
|
||||
e.writeSystemdUnitFiles(&ud, n)
|
||||
}
|
||||
|
||||
ud.WriteString("runcmd:\n")
|
||||
|
||||
// Remove the default route from the debug NIC (enp0s4) so traffic goes through vnet.
|
||||
@@ -130,12 +135,21 @@ func (e *Env) generateLinuxUserData(n *Node) string {
|
||||
ud.WriteString(" - [\"sysctl\", \"-w\", \"net.ipv6.conf.all.forwarding=1\"]\n")
|
||||
}
|
||||
|
||||
// Start tailscaled in the background. --statedir provides a VarRoot so
|
||||
// features like Taildrop (which needs a place to stash incoming files)
|
||||
// have a directory to work with.
|
||||
ud.WriteString(" - [\"mkdir\", \"-p\", \"/var/lib/tailscale\"]\n")
|
||||
fmt.Fprintf(&ud, " - [\"/bin/sh\", \"-c\", \"%s/usr/local/bin/tailscaled --state=mem: --statedir=/var/lib/tailscale &\"]\n", tailscaledEnvPrefix(n))
|
||||
ud.WriteString(" - [\"sleep\", \"2\"]\n")
|
||||
// Start tailscaled, either via the stock systemd unit or directly in
|
||||
// the background. --statedir provides a VarRoot so features like
|
||||
// Taildrop (which needs a place to stash incoming files) have a
|
||||
// directory to work with.
|
||||
if n.systemdUnit {
|
||||
// The unit's ExecStart runs /usr/sbin/tailscaled.
|
||||
ud.WriteString(" - [\"cp\", \"/usr/local/bin/tailscaled\", \"/usr/sbin/tailscaled\"]\n")
|
||||
ud.WriteString(" - [\"systemctl\", \"daemon-reload\"]\n")
|
||||
// Type=notify makes this block until tailscaled reports readiness.
|
||||
ud.WriteString(" - [\"systemctl\", \"start\", \"tailscaled.service\"]\n")
|
||||
} else {
|
||||
ud.WriteString(" - [\"mkdir\", \"-p\", \"/var/lib/tailscale\"]\n")
|
||||
fmt.Fprintf(&ud, " - [\"/bin/sh\", \"-c\", \"%s/usr/local/bin/tailscaled --state=mem: --statedir=/var/lib/tailscale &\"]\n", tailscaledEnvPrefix(n))
|
||||
ud.WriteString(" - [\"sleep\", \"2\"]\n")
|
||||
}
|
||||
|
||||
// Start tta (Tailscale Test Agent).
|
||||
ud.WriteString(" - [\"/bin/sh\", \"-c\", \"/usr/local/bin/tta &\"]\n")
|
||||
@@ -225,6 +239,40 @@ func (e *Env) generateFreeBSDUserData(n *Node) string {
|
||||
return ud.String()
|
||||
}
|
||||
|
||||
// writeSystemdUnitFiles appends a cloud-init write_files section that
|
||||
// installs the stock tailscaled systemd unit from the source tree, along
|
||||
// with the packaging's /etc/default/tailscaled EnvironmentFile (plus any
|
||||
// per-node TailscaledEnv variables). File contents are base64-encoded to
|
||||
// sidestep YAML quoting.
|
||||
func (e *Env) writeSystemdUnitFiles(ud *strings.Builder, n *Node) {
|
||||
modRoot, err := findModRoot()
|
||||
if err != nil {
|
||||
e.t.Fatalf("finding module root for tailscaled.service: %v", err)
|
||||
}
|
||||
unit, err := os.ReadFile(filepath.Join(modRoot, "cmd/tailscaled/tailscaled.service"))
|
||||
if err != nil {
|
||||
e.t.Fatalf("reading tailscaled.service: %v", err)
|
||||
}
|
||||
defaults, err := os.ReadFile(filepath.Join(modRoot, "cmd/tailscaled/tailscaled.defaults"))
|
||||
if err != nil {
|
||||
e.t.Fatalf("reading tailscaled.defaults: %v", err)
|
||||
}
|
||||
var envFile strings.Builder
|
||||
envFile.Write(defaults)
|
||||
for _, env := range n.vnetNode.Env() {
|
||||
fmt.Fprintf(&envFile, "%s=%q\n", env.Key, env.Value)
|
||||
}
|
||||
|
||||
ud.WriteString("write_files:\n")
|
||||
writeFile := func(path string, content []byte) {
|
||||
fmt.Fprintf(ud, " - path: %s\n", path)
|
||||
fmt.Fprintf(ud, " encoding: b64\n")
|
||||
fmt.Fprintf(ud, " content: %s\n", base64.StdEncoding.EncodeToString(content))
|
||||
}
|
||||
writeFile("/etc/systemd/system/tailscaled.service", unit)
|
||||
writeFile("/etc/default/tailscaled", []byte(envFile.String()))
|
||||
}
|
||||
|
||||
func tailscaledEnvPrefix(n *Node) string {
|
||||
env := n.vnetNode.Env()
|
||||
if len(env) == 0 {
|
||||
|
||||
Reference in New Issue
Block a user