diff --git a/cmd/tta/tta.go b/cmd/tta/tta.go index ed5892e76..c11807992 100644 --- a/cmd/tta/tta.go +++ b/cmd/tta/tta.go @@ -12,7 +12,6 @@ package main import ( "bufio" - "bytes" "errors" "flag" "fmt" @@ -29,8 +28,8 @@ import ( "sync" "time" - "github.com/mitchellh/go-ps" "tailscale.com/client/tailscale" + "tailscale.com/hostinfo" "tailscale.com/util/must" "tailscale.com/util/set" "tailscale.com/version/distro" @@ -71,8 +70,7 @@ func (rt localClientRoundTripper) RoundTrip(req *http.Request) (*http.Response, func main() { if distro.Get() == distro.Gokrazy { - cmdLine, _ := os.ReadFile("/proc/cmdline") - if !bytes.Contains(cmdLine, []byte("tailscale-tta=1")) { + if !hostinfo.IsNATLabGuestVM() { // "Exiting immediately with status code 0 when the // GOKRAZY_FIRST_START=1 environment variable is set means “don’t // start the program on boot”" @@ -98,34 +96,6 @@ func main() { log.Printf("Tailscale Test Agent running.") - if distro.Get() == distro.Gokrazy { - procs, err := ps.Processes() - if err != nil { - log.Fatalf("ps.Processes: %v", err) - } - killed := false - for _, p := range procs { - if p.Executable() == "tailscaled" { - if op, err := os.FindProcess(p.Pid()); err == nil { - op.Signal(os.Interrupt) - killed = true - } - } - } - log.Printf("killed = %v", killed) - if killed { - for { - _, err := exec.Command(absify("tailscale"), "status", "--json").CombinedOutput() - if err == nil { - log.Printf("tailscaled back up") - break - } - log.Printf("tailscale status error; sleeping before trying again...") - time.Sleep(50 * time.Millisecond) - } - } - } - var mux http.ServeMux var hs http.Server hs.Handler = &mux diff --git a/hostinfo/hostinfo.go b/hostinfo/hostinfo.go index 4ba7b4d61..330669aea 100644 --- a/hostinfo/hostinfo.go +++ b/hostinfo/hostinfo.go @@ -27,6 +27,7 @@ import ( "tailscale.com/util/dnsname" "tailscale.com/util/lineread" "tailscale.com/version" + "tailscale.com/version/distro" ) var started = time.Now() @@ -462,3 +463,15 @@ func IsSELinuxEnforcing() bool { out, _ := exec.Command("getenforce").Output() return string(bytes.TrimSpace(out)) == "Enforcing" } + +// IsNATLabGuestVM reports whether the current host is a NAT Lab guest VM. +func IsNATLabGuestVM() bool { + if runtime.GOOS == "linux" && distro.Get() == distro.Gokrazy { + cmdLine, _ := os.ReadFile("/proc/cmdline") + return bytes.Contains(cmdLine, []byte("tailscale-tta=1")) + } + return false +} + +// NAT Lab VMs have a unique MAC address prefix. +// See diff --git a/logpolicy/logpolicy.go b/logpolicy/logpolicy.go index 71093dd3c..74c480e11 100644 --- a/logpolicy/logpolicy.go +++ b/logpolicy/logpolicy.go @@ -31,6 +31,7 @@ import ( "tailscale.com/atomicfile" "tailscale.com/envknob" "tailscale.com/health" + "tailscale.com/hostinfo" "tailscale.com/log/filelogger" "tailscale.com/logtail" "tailscale.com/logtail/filch" @@ -566,7 +567,7 @@ func NewWithConfigPath(collection, dir, cmdName string, netMon *netmon.Monitor, conf.IncludeProcSequence = true } - if envknob.NoLogsNoSupport() || testenv.InTest() { + if envknob.NoLogsNoSupport() || testenv.InTest() || hostinfo.IsNATLabGuestVM() { logf("You have disabled logging. Tailscale will not be able to provide support.") conf.HTTPC = &http.Client{Transport: noopPretendSuccessTransport{}} } else if val := getLogTarget(); val != "" { diff --git a/tstest/natlab/vnet/vnet.go b/tstest/natlab/vnet/vnet.go index e3332ae3f..b02a9a945 100644 --- a/tstest/natlab/vnet/vnet.go +++ b/tstest/natlab/vnet/vnet.go @@ -356,6 +356,7 @@ var ( fakeControlIP = netip.AddrFrom4([4]byte{52, 52, 0, 3}) // 3=C for "Control" fakeDERP1IP = netip.AddrFrom4([4]byte{33, 4, 0, 1}) // 3340=DERP; 1=derp 1 fakeDERP2IP = netip.AddrFrom4([4]byte{33, 4, 0, 2}) // 3340=DERP; 1=derp 1 + fakeLogCatcherIP = netip.AddrFrom4([4]byte{52, 52, 0, 4}) ) type EthernetPacket struct { @@ -564,6 +565,8 @@ func (s *Server) IPv4ForDNS(qname string) (netip.Addr, bool) { switch qname { case "dns": return fakeDNSIP, true + case "log.tailscale.io": + return fakeLogCatcherIP, true case "test-driver.tailscale": return fakeTestAgentIP, true case "controlplane.tailscale.com":