mirror of
https://github.com/tailscale/tailscale.git
synced 2025-12-24 01:26:39 +00:00
cmd/tailscaled,ipn: show a health warning when state store fails to open (#17883)
With the introduction of node sealing, store.New fails in some cases due to the TPM device being reset or unavailable. Currently it results in tailscaled crashing at startup, which is not obvious to the user until they check the logs. Instead of crashing tailscaled at startup, start with an in-memory store with a health warning about state initialization and a link to (future) docs on what to do. When this health message is set, also block any login attempts to avoid masking the problem with an ephemeral node registration. Updates #15830 Updates #17654 Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
This commit is contained in:
@@ -22,6 +22,7 @@ import (
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
@@ -36,6 +37,7 @@ import (
|
||||
"tailscale.com/cmd/testwrapper/flakytest"
|
||||
"tailscale.com/feature"
|
||||
_ "tailscale.com/feature/clientupdate"
|
||||
"tailscale.com/health"
|
||||
"tailscale.com/hostinfo"
|
||||
"tailscale.com/ipn"
|
||||
"tailscale.com/net/tsaddr"
|
||||
@@ -2246,3 +2248,38 @@ func TestNetworkLock(t *testing.T) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestNodeWithBadStateFile(t *testing.T) {
|
||||
tstest.Shard(t)
|
||||
tstest.Parallel(t)
|
||||
env := NewTestEnv(t)
|
||||
n1 := NewTestNode(t, env)
|
||||
if err := os.WriteFile(n1.stateFile, []byte("bad json"), 0644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
d1 := n1.StartDaemon()
|
||||
n1.AwaitResponding()
|
||||
|
||||
// Make sure the health message shows up in status output.
|
||||
n1.AwaitBackendState("NoState")
|
||||
st := n1.MustStatus()
|
||||
wantHealth := ipn.StateStoreHealth.Text(health.Args{health.ArgError: ""})
|
||||
if !slices.ContainsFunc(st.Health, func(m string) bool { return strings.HasPrefix(m, wantHealth) }) {
|
||||
t.Errorf("Status does not contain expected health message %q\ngot health messages: %q", wantHealth, st.Health)
|
||||
}
|
||||
|
||||
// Make sure login attempts are rejected.
|
||||
cmd := n1.Tailscale("up", "--login-server="+n1.env.ControlURL())
|
||||
t.Logf("Running %v ...", cmd)
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err == nil {
|
||||
t.Fatalf("up succeeded with output %q", out)
|
||||
}
|
||||
wantOut := "cannot start backend when state store is unhealthy"
|
||||
if !strings.Contains(string(out), wantOut) {
|
||||
t.Fatalf("got up output:\n%s\nwant:\n%s", string(out), wantOut)
|
||||
}
|
||||
|
||||
d1.MustCleanShutdown(t)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user