cmd/tailscale/cli: add a debug command to print the statedir

Example:

```console
$ tailscale debug statedir
/tmp/ts/node1
```

Updates #18019

Change-Id: I7c93c94179bd7b56d0fa8fe57a9129df05c2c1df
Signed-off-by: Alex Chan <alexc@tailscale.com>
This commit is contained in:
Alex Chan
2026-03-23 11:59:12 +00:00
committed by Alex Chan
parent 1403920367
commit 302e49dc4e
2 changed files with 32 additions and 0 deletions

View File

@@ -387,6 +387,12 @@ func debugCmd() *ffcli.Command {
return fs
})(),
},
{
Name: "statedir",
ShortUsage: "tailscale debug statedir",
ShortHelp: "Print the location of the state directory (if any)",
Exec: runPrintStateDir,
},
ccall(debugPeerRelayCmd),
}...),
}
@@ -1407,3 +1413,22 @@ func runTestRisk(ctx context.Context, args []string) error {
fmt.Println("did-test-risky-action")
return nil
}
func runPrintStateDir(ctx context.Context, args []string) error {
if len(args) > 0 {
return errors.New("unexpected arguments")
}
v, err := localClient.DebugResultJSON(ctx, "statedir")
if err != nil {
return err
}
statedir, ok := v.(string)
if ok && statedir != "" {
fmt.Println(statedir)
return nil
} else if ok && statedir == "" {
return errors.New("no statedir is set")
} else {
return fmt.Errorf("got unexpected response from debug API: %v", v)
}
}

View File

@@ -234,6 +234,13 @@ func (h *Handler) serveDebug(w http.ResponseWriter, r *http.Request) {
}
case "rotate-disco-key":
err = h.b.DebugRotateDiscoKey()
case "statedir":
root := h.b.TailscaleVarRoot()
w.Header().Set("Content-Type", "application/json")
err = json.NewEncoder(w).Encode(root)
if err == nil {
return
}
case "":
err = fmt.Errorf("missing parameter 'action'")
default: