diff --git a/cmd/tailscaled/tailscaled.go b/cmd/tailscaled/tailscaled.go index 0a2322070..8944d536e 100644 --- a/cmd/tailscaled/tailscaled.go +++ b/cmd/tailscaled/tailscaled.go @@ -341,7 +341,7 @@ func run() (err error) { // Install an event bus as early as possible, so that it's // available universally when setting up everything else. - sys := tsd.NewSystemWithEventBus() + sys := tsd.NewSystem() // Parse config, if specified, to fail early if it's invalid. var conf *conffile.Config diff --git a/cmd/tailscaled/tailscaled_windows.go b/cmd/tailscaled/tailscaled_windows.go index 9990388d7..0af434107 100644 --- a/cmd/tailscaled/tailscaled_windows.go +++ b/cmd/tailscaled/tailscaled_windows.go @@ -327,7 +327,7 @@ func beWindowsSubprocess() bool { log.Printf("Error pre-loading \"%s\": %v", fqWintunPath, err) } - sys := tsd.NewSystemWithEventBus() + sys := tsd.NewSystem() netMon, err := netmon.New(log.Printf) if err != nil { log.Fatalf("Could not create netMon: %v", err) diff --git a/cmd/tsconnect/wasm/wasm_js.go b/cmd/tsconnect/wasm/wasm_js.go index 3d423d308..779a87e49 100644 --- a/cmd/tsconnect/wasm/wasm_js.go +++ b/cmd/tsconnect/wasm/wasm_js.go @@ -100,7 +100,7 @@ func newIPN(jsConfig js.Value) map[string]any { logtail := logtail.NewLogger(c, log.Printf) logf := logtail.Logf - sys := tsd.NewSystemWithEventBus() + sys := tsd.NewSystem() sys.Set(store) dialer := &tsdial.Dialer{Logf: logf} eng, err := wgengine.NewUserspaceEngine(logf, wgengine.Config{ diff --git a/ipn/ipnlocal/local_test.go b/ipn/ipnlocal/local_test.go index b36cd0909..987258ce0 100644 --- a/ipn/ipnlocal/local_test.go +++ b/ipn/ipnlocal/local_test.go @@ -436,7 +436,7 @@ func (panicOnUseTransport) RoundTrip(*http.Request) (*http.Response, error) { } func newTestLocalBackend(t testing.TB) *LocalBackend { - return newTestLocalBackendWithSys(t, tsd.NewSystemWithEventBus()) + return newTestLocalBackendWithSys(t, tsd.NewSystem()) } // newTestLocalBackendWithSys creates a new LocalBackend with the given tsd.System. @@ -4402,7 +4402,7 @@ func newLocalBackendWithTestControl(t *testing.T, enableLogging bool, newControl if enableLogging { logf = tstest.WhileTestRunningLogger(t) } - sys := tsd.NewSystemWithEventBus() + sys := tsd.NewSystem() store := new(mem.Store) sys.Set(store) e, err := wgengine.NewFakeUserspaceEngine(logf, sys.Set, sys.HealthTracker(), sys.UserMetricsRegistry()) @@ -4748,7 +4748,7 @@ func TestConfigFileReload(t *testing.T) { cfg1 := `{"Hostname": "foo", "Version": "alpha0"}` f := filepath.Join(t.TempDir(), "cfg") must.Do(os.WriteFile(f, []byte(cfg1), 0600)) - sys := tsd.NewSystemWithEventBus() + sys := tsd.NewSystem() sys.InitialConfig = must.Get(conffile.Load(f)) lb := newTestLocalBackendWithSys(t, sys) must.Do(lb.Start(ipn.Options{})) diff --git a/ipn/ipnlocal/loglines_test.go b/ipn/ipnlocal/loglines_test.go index cfcd54c64..f4a77824e 100644 --- a/ipn/ipnlocal/loglines_test.go +++ b/ipn/ipnlocal/loglines_test.go @@ -47,7 +47,7 @@ func TestLocalLogLines(t *testing.T) { idA := logid(0xaa) // set up a LocalBackend, super bare bones. No functional data. - sys := tsd.NewSystemWithEventBus() + sys := tsd.NewSystem() store := new(mem.Store) sys.Set(store) e, err := wgengine.NewFakeUserspaceEngine(logf, sys.Set, sys.HealthTracker(), sys.UserMetricsRegistry()) diff --git a/ipn/ipnlocal/serve_test.go b/ipn/ipnlocal/serve_test.go index 78f1da42c..5e148a8a4 100644 --- a/ipn/ipnlocal/serve_test.go +++ b/ipn/ipnlocal/serve_test.go @@ -877,7 +877,7 @@ func newTestBackend(t *testing.T) *LocalBackend { logf = logger.WithPrefix(tstest.WhileTestRunningLogger(t), "... ") } - sys := tsd.NewSystemWithEventBus() + sys := tsd.NewSystem() e, err := wgengine.NewUserspaceEngine(logf, wgengine.Config{ SetSubsystem: sys.Set, HealthTracker: sys.HealthTracker(), diff --git a/ipn/ipnlocal/state_test.go b/ipn/ipnlocal/state_test.go index d22826340..d8eda11cb 100644 --- a/ipn/ipnlocal/state_test.go +++ b/ipn/ipnlocal/state_test.go @@ -295,7 +295,7 @@ func TestStateMachine(t *testing.T) { c := qt.New(t) logf := tstest.WhileTestRunningLogger(t) - sys := tsd.NewSystemWithEventBus() + sys := tsd.NewSystem() store := new(testStateStorage) sys.Set(store) e, err := wgengine.NewFakeUserspaceEngine(logf, sys.Set, sys.HealthTracker(), sys.UserMetricsRegistry()) @@ -930,7 +930,7 @@ func TestStateMachine(t *testing.T) { func TestEditPrefsHasNoKeys(t *testing.T) { logf := tstest.WhileTestRunningLogger(t) - sys := tsd.NewSystemWithEventBus() + sys := tsd.NewSystem() sys.Set(new(mem.Store)) e, err := wgengine.NewFakeUserspaceEngine(logf, sys.Set, sys.HealthTracker(), sys.UserMetricsRegistry()) if err != nil { @@ -1010,7 +1010,7 @@ func TestWGEngineStatusRace(t *testing.T) { t.Skip("test fails") c := qt.New(t) logf := tstest.WhileTestRunningLogger(t) - sys := tsd.NewSystemWithEventBus() + sys := tsd.NewSystem() sys.Set(new(mem.Store)) eng, err := wgengine.NewFakeUserspaceEngine(logf, sys.Set) diff --git a/ipn/ipnserver/server_test.go b/ipn/ipnserver/server_test.go index fd2e53f3e..e34172ff9 100644 --- a/ipn/ipnserver/server_test.go +++ b/ipn/ipnserver/server_test.go @@ -517,7 +517,7 @@ type newControlClientFn func(tb testing.TB, opts controlclient.Options) controlc func newLocalBackendWithTestControl(tb testing.TB, newControl newControlClientFn, enableLogging bool) *ipnlocal.LocalBackend { tb.Helper() - sys := tsd.NewSystemWithEventBus() + sys := tsd.NewSystem() store := &mem.Store{} sys.Set(store) diff --git a/ipn/localapi/localapi_test.go b/ipn/localapi/localapi_test.go index 38394739e..4f304bb1b 100644 --- a/ipn/localapi/localapi_test.go +++ b/ipn/localapi/localapi_test.go @@ -336,7 +336,7 @@ func TestServeWatchIPNBus(t *testing.T) { func newTestLocalBackend(t testing.TB) *ipnlocal.LocalBackend { var logf logger.Logf = logger.Discard - sys := tsd.NewSystemWithEventBus() + sys := tsd.NewSystem() store := new(mem.Store) sys.Set(store) eng, err := wgengine.NewFakeUserspaceEngine(logf, sys.Set, sys.HealthTracker(), sys.UserMetricsRegistry()) diff --git a/ssh/tailssh/tailssh_test.go b/ssh/tailssh/tailssh_test.go index ec442a83b..3dbd16047 100644 --- a/ssh/tailssh/tailssh_test.go +++ b/ssh/tailssh/tailssh_test.go @@ -1037,7 +1037,7 @@ func TestSSHAuthFlow(t *testing.T) { func TestSSH(t *testing.T) { var logf logger.Logf = t.Logf - sys := tsd.NewSystemWithEventBus() + sys := tsd.NewSystem() eng, err := wgengine.NewFakeUserspaceEngine(logf, sys.Set, sys.HealthTracker(), sys.UserMetricsRegistry()) if err != nil { t.Fatal(err) diff --git a/tsd/tsd.go b/tsd/tsd.go index 710d73aa2..cfb9ef565 100644 --- a/tsd/tsd.go +++ b/tsd/tsd.go @@ -42,6 +42,10 @@ import ( ) // System contains all the subsystems of a Tailscale node (tailscaled, etc.) +// +// A valid System value must always have a non-nil Bus populated. Callers must +// ensure this before using the value further. Call [NewSystem] to obtain a +// value ready to use. type System struct { Bus SubSystem[*eventbus.Bus] Dialer SubSystem[*tsdial.Dialer] @@ -76,9 +80,9 @@ type System struct { userMetricsRegistry usermetric.Registry } -// NewSystemWithEventBus constructs a new otherwise-empty system with a +// NewSystem constructs a new otherwise-empty [System] with a // freshly-constructed event bus populated. -func NewSystemWithEventBus() *System { +func NewSystem() *System { sys := new(System) sys.Set(eventbus.New()) return sys diff --git a/tsnet/tsnet.go b/tsnet/tsnet.go index f7d3f4a43..596ed1e44 100644 --- a/tsnet/tsnet.go +++ b/tsnet/tsnet.go @@ -556,7 +556,7 @@ func (s *Server) start() (reterr error) { s.Logf(format, a...) } - sys := tsd.NewSystemWithEventBus() + sys := tsd.NewSystem() s.sys = sys if err := s.startLogger(&closePool, sys.HealthTracker(), tsLogf); err != nil { return err diff --git a/wgengine/bench/wg.go b/wgengine/bench/wg.go index 2474f832e..9b195bdb7 100644 --- a/wgengine/bench/wg.go +++ b/wgengine/bench/wg.go @@ -46,7 +46,7 @@ func setupWGTest(b *testing.B, logf logger.Logf, traf *TrafficGen, a1, a2 netip. logf: logger.WithPrefix(logf, "tun1: "), traf: traf, } - s1 := tsd.NewSystemWithEventBus() + s1 := tsd.NewSystem() e1, err := wgengine.NewUserspaceEngine(l1, wgengine.Config{ Router: router.NewFake(l1), NetMon: nil, @@ -73,7 +73,7 @@ func setupWGTest(b *testing.B, logf logger.Logf, traf *TrafficGen, a1, a2 netip. logf: logger.WithPrefix(logf, "tun2: "), traf: traf, } - s2 := tsd.NewSystemWithEventBus() + s2 := tsd.NewSystem() e2, err := wgengine.NewUserspaceEngine(l2, wgengine.Config{ Router: router.NewFake(l2), NetMon: nil, diff --git a/wgengine/netstack/netstack_test.go b/wgengine/netstack/netstack_test.go index 667cf9fd9..bc33d829a 100644 --- a/wgengine/netstack/netstack_test.go +++ b/wgengine/netstack/netstack_test.go @@ -44,7 +44,7 @@ func TestInjectInboundLeak(t *testing.T) { t.Logf(format, args...) } } - sys := tsd.NewSystemWithEventBus() + sys := tsd.NewSystem() eng, err := wgengine.NewUserspaceEngine(logf, wgengine.Config{ Tun: tunDev, Dialer: dialer, @@ -100,7 +100,7 @@ func getMemStats() (ms runtime.MemStats) { func makeNetstack(tb testing.TB, config func(*Impl)) *Impl { tunDev := tstun.NewFake() - sys := tsd.NewSystemWithEventBus() + sys := tsd.NewSystem() sys.Set(new(mem.Store)) dialer := new(tsdial.Dialer) logf := tstest.WhileTestRunningLogger(tb) diff --git a/wgengine/userspace_ext_test.go b/wgengine/userspace_ext_test.go index b76a2b4b7..b0caffd1e 100644 --- a/wgengine/userspace_ext_test.go +++ b/wgengine/userspace_ext_test.go @@ -16,7 +16,7 @@ import ( ) func TestIsNetstack(t *testing.T) { - sys := tsd.NewSystemWithEventBus() + sys := tsd.NewSystem() e, err := wgengine.NewUserspaceEngine( tstest.WhileTestRunningLogger(t), wgengine.Config{ @@ -66,7 +66,7 @@ func TestIsNetstackRouter(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - sys := tsd.NewSystemWithEventBus() + sys := tsd.NewSystem() if tt.setNetstackRouter { sys.NetstackRouter.Set(true) }