cmd/tailscale/cli: fix race condition in up --force-reauth

This commit fixes a race condition where `tailscale up --force-reauth` would
exit prematurely on an already-logged in device.

Previously, the CLI would wait for IPN to report the "Running" state and then
exit. However, this could happen before the new auth URL was printed, leading
to two distinct issues:

*   **Without seamless key renewal:** The CLI could exit immediately after
    the `StartLoginInteractive` call, before IPN has time to switch into
    the "Starting" state or send a new auth URL back to the CLI.
*   **With seamless key renewal:** IPN stays in the "Running" state
    throughout the process, so the CLI exits immediately without performing
    any reauthentication.

The fix is to change the CLI's exit condition.

Instead of waiting for the "Running" state, if we're doing a `--force-reauth`
we now wait to see the node key change, which is a more reliable indicator
that a successful authentication has occurred.

Updates tailscale/corp#31476
Updates tailscale/tailscale#17108

Signed-off-by: Alex Chan <alexc@tailscale.com>
This commit is contained in:
Alex Chan
2025-09-16 11:22:47 +01:00
committed by Alex Chan
parent c011369de2
commit 41a2aaf1da
2 changed files with 43 additions and 34 deletions

View File

@@ -337,14 +337,6 @@ func TestOneNodeUpAuth(t *testing.T) {
t.Run(fmt.Sprintf("%s-seamless-%t", tt.name, useSeamlessKeyRenewal), func(t *testing.T) {
tstest.Parallel(t)
// TODO(alexc): This test is failing because of a bug in `tailscale up` where
// it waits for ipn to enter the "Running" state. If we're already logged in
// and running, this completes immediately, before we've had a chance to show
// the user the auth URL.
if tt.name == "up-with-force-reauth-after-login" {
t.Skip()
}
env := NewTestEnv(t, ConfigureControl(
func(control *testcontrol.Server) {
if tt.authKey != "" {