mirror of
https://github.com/tailscale/tailscale.git
synced 2025-12-02 07:52:05 +01:00
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>
91 lines
2.9 KiB
Go
91 lines
2.9 KiB
Go
// Copyright (c) Tailscale Inc & AUTHORS
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
package main // import "tailscale.com/cmd/tailscaled"
|
|
|
|
import (
|
|
"os"
|
|
"strings"
|
|
"testing"
|
|
|
|
"tailscale.com/envknob"
|
|
"tailscale.com/ipn"
|
|
"tailscale.com/net/netmon"
|
|
"tailscale.com/tsd"
|
|
"tailscale.com/tstest/deptest"
|
|
"tailscale.com/types/logid"
|
|
"tailscale.com/util/must"
|
|
)
|
|
|
|
func TestNothing(t *testing.T) {
|
|
// This test does nothing on purpose, so we can run
|
|
// GODEBUG=memprofilerate=1 go test -v -run=Nothing -memprofile=prof.mem
|
|
// without any errors about no matching tests.
|
|
}
|
|
|
|
func TestDeps(t *testing.T) {
|
|
deptest.DepChecker{
|
|
GOOS: "darwin",
|
|
GOARCH: "arm64",
|
|
BadDeps: map[string]string{
|
|
"testing": "do not use testing package in production code",
|
|
"gvisor.dev/gvisor/pkg/hostarch": "will crash on non-4K page sizes; see https://github.com/tailscale/tailscale/issues/8658",
|
|
"net/http/httptest": "do not use httptest in production code",
|
|
"net/http/internal/testcert": "do not use httptest in production code",
|
|
},
|
|
}.Check(t)
|
|
|
|
deptest.DepChecker{
|
|
GOOS: "linux",
|
|
GOARCH: "arm64",
|
|
BadDeps: map[string]string{
|
|
"testing": "do not use testing package in production code",
|
|
"gvisor.dev/gvisor/pkg/hostarch": "will crash on non-4K page sizes; see https://github.com/tailscale/tailscale/issues/8658",
|
|
"google.golang.org/protobuf/proto": "unexpected",
|
|
"github.com/prometheus/client_golang/prometheus": "use tailscale.com/metrics in tailscaled",
|
|
},
|
|
}.Check(t)
|
|
}
|
|
|
|
func TestStateStoreError(t *testing.T) {
|
|
logID, err := logid.NewPrivateID()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
// Don't upload any logs from tests.
|
|
envknob.SetNoLogsNoSupport()
|
|
|
|
args.statedir = t.TempDir()
|
|
args.tunname = "userspace-networking"
|
|
|
|
t.Run("new state", func(t *testing.T) {
|
|
sys := tsd.NewSystem()
|
|
sys.NetMon.Set(must.Get(netmon.New(sys.Bus.Get(), t.Logf)))
|
|
lb, err := getLocalBackend(t.Context(), t.Logf, logID.Public(), sys)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer lb.Shutdown()
|
|
if lb.HealthTracker().IsUnhealthy(ipn.StateStoreHealth) {
|
|
t.Errorf("StateStoreHealth is unhealthy on fresh LocalBackend:\n%s", strings.Join(lb.HealthTracker().Strings(), "\n"))
|
|
}
|
|
})
|
|
t.Run("corrupt state", func(t *testing.T) {
|
|
sys := tsd.NewSystem()
|
|
sys.NetMon.Set(must.Get(netmon.New(sys.Bus.Get(), t.Logf)))
|
|
// Populate the state file with something that will fail to parse to
|
|
// trigger an error from store.New.
|
|
if err := os.WriteFile(statePathOrDefault(), []byte("bad json"), 0644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
lb, err := getLocalBackend(t.Context(), t.Logf, logID.Public(), sys)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer lb.Shutdown()
|
|
if !lb.HealthTracker().IsUnhealthy(ipn.StateStoreHealth) {
|
|
t.Errorf("StateStoreHealth is healthy when state file is corrupt")
|
|
}
|
|
})
|
|
}
|