diff --git a/cmd/tta/tta.go b/cmd/tta/tta.go index 99205d1f5..5ed184c09 100644 --- a/cmd/tta/tta.go +++ b/cmd/tta/tta.go @@ -11,10 +11,8 @@ package main import ( - "bufio" "errors" "flag" - "fmt" "io" "log" "net" @@ -134,38 +132,8 @@ func main() { return }) mux.HandleFunc("/up", func(w http.ResponseWriter, r *http.Request) { - cmd := exec.Command(absify("tailscale"), "debug", "daemon-logs") - out, err := cmd.StdoutPipe() - if err != nil { - http.Error(w, err.Error(), 500) - return - } - defer out.Close() - cmd.Start() - defer cmd.Process.Kill() - go func() { - bs := bufio.NewScanner(out) - for bs.Scan() { - log.Printf("Daemon: %s", bs.Text()) - } - }() - serveCmd(w, "tailscale", "up", "--login-server=http://control.tailscale") }) - mux.HandleFunc("/status", func(w http.ResponseWriter, r *http.Request) { - serveCmd(w, "tailscale", "status", "--json") - }) - mux.HandleFunc("/ping", func(w http.ResponseWriter, r *http.Request) { - target := r.FormValue("target") - cmd := exec.Command(absify("tailscale"), "ping", target) - w.Header().Set("Content-Type", "text/plain; charset=utf-8") - w.(http.Flusher).Flush() - cmd.Stdout = w - cmd.Stderr = w - if err := cmd.Run(); err != nil { - fmt.Fprintf(w, "error: %v\n", err) - } - }) go hs.Serve(chanListener(conns)) var lastErr string diff --git a/tstest/integration/nat/nat_test.go b/tstest/integration/nat/nat_test.go index 7e99bf216..1cc0faa07 100644 --- a/tstest/integration/nat/nat_test.go +++ b/tstest/integration/nat/nat_test.go @@ -2,9 +2,11 @@ import ( "context" + "encoding/json" "errors" "fmt" "io" + "log" "net" "net/http" "net/netip" @@ -193,6 +195,11 @@ func (nt *natTest) runTest(node1, node2 addNodeFunc) { for i, c := range clients { i, c := i, c eg.Go(func() error { + wg.Add(1) + go func() { + defer wg.Done() + streamDaemonLogs(ctx, t, c, fmt.Sprintf("node%d:", i)) + }() st, err := c.Status(ctx) if err != nil { return fmt.Errorf("node%d status: %w", i, err) @@ -223,6 +230,35 @@ func (nt *natTest) runTest(node1, node2 addNodeFunc) { t.Logf("ping route: %v, %v", logger.AsJSON(route), err) } +func streamDaemonLogs(ctx context.Context, t testing.TB, c *vnet.NodeAgentClient, nodeID string) { + ctx, cancel := context.WithCancel(ctx) + defer cancel() + r, err := c.TailDaemonLogs(ctx) + if err != nil { + t.Errorf("tailDaemonLogs: %v", err) + return + } + logger := log.New(os.Stderr, nodeID+" ", log.Lmsgprefix) + dec := json.NewDecoder(r) + for { + // /{"logtail":{"client_time":"2024-08-08T17:42:31.95095956Z","proc_id":2024742977,"proc_seq":232},"text":"magicsock: derp-1 connected; connGen=1\n"} + var logEntry struct { + LogTail struct { + ClientTime time.Time `json:"client_time"` + } + Text string `json:"text"` + } + if err := dec.Decode(&logEntry); err != nil { + if err == io.EOF { + return + } + t.Errorf("log entry: %v", err) + return + } + logger.Printf("%s %s", logEntry.LogTail.ClientTime.Format("2006/01/02 15:04:05"), logEntry.Text) + } +} + func ping(ctx context.Context, c *vnet.NodeAgentClient, target netip.Addr) (*ipnstate.PingResult, error) { n := 0 var res *ipnstate.PingResult @@ -242,11 +278,11 @@ func ping(ctx context.Context, c *vnet.NodeAgentClient, target netip.Addr) (*ipn if pr.DERPRegionID == 0 { return pr, nil } + res = pr select { case <-ctx.Done(): case <-time.After(time.Second): } - res = pr } if res == nil { return nil, errors.New("no ping response")