health,ipn/ipnlocal: introduce eventbus in heath.Tracker (#17085)

The Tracker was using direct callbacks to ipnlocal. This PR moves those
to be triggered via the eventbus.

Additionally, the eventbus is now closed on exit from tailscaled
explicitly, and health is now a SubSystem in tsd.

Updates #15160

Signed-off-by: Claus Lensbøl <claus@tailscale.com>
This commit is contained in:
Claus Lensbøl
2025-09-16 11:25:29 -04:00
committed by GitHub
parent 4cca9f7c67
commit 2015ce4081
37 changed files with 404 additions and 245 deletions

View File

@@ -53,7 +53,7 @@ func setupWGTest(b *testing.B, logf logger.Logf, traf *TrafficGen, a1, a2 netip.
ListenPort: 0,
Tun: t1,
SetSubsystem: s1.Set,
HealthTracker: s1.HealthTracker(),
HealthTracker: s1.HealthTracker.Get(),
})
if err != nil {
log.Fatalf("e1 init: %v", err)
@@ -80,7 +80,7 @@ func setupWGTest(b *testing.B, logf logger.Logf, traf *TrafficGen, a1, a2 netip.
ListenPort: 0,
Tun: t2,
SetSubsystem: s2.Set,
HealthTracker: s2.HealthTracker(),
HealthTracker: s2.HealthTracker.Get(),
})
if err != nil {
log.Fatalf("e2 init: %v", err)

View File

@@ -67,6 +67,7 @@ import (
"tailscale.com/util/cibuild"
"tailscale.com/util/clientmetric"
"tailscale.com/util/eventbus"
"tailscale.com/util/eventbus/eventbustest"
"tailscale.com/util/must"
"tailscale.com/util/racebuild"
"tailscale.com/util/set"
@@ -179,14 +180,13 @@ func newMagicStack(t testing.TB, logf logger.Logf, l nettype.PacketListener, der
func newMagicStackWithKey(t testing.TB, logf logger.Logf, l nettype.PacketListener, derpMap *tailcfg.DERPMap, privateKey key.NodePrivate) *magicStack {
t.Helper()
bus := eventbus.New()
t.Cleanup(bus.Close)
bus := eventbustest.NewBus(t)
netMon, err := netmon.New(bus, logf)
if err != nil {
t.Fatalf("netmon.New: %v", err)
}
ht := new(health.Tracker)
ht := health.NewTracker(bus)
var reg usermetric.Registry
epCh := make(chan []tailcfg.Endpoint, 100) // arbitrary
@@ -1352,8 +1352,7 @@ func newTestConn(t testing.TB) *Conn {
t.Helper()
port := pickPort(t)
bus := eventbus.New()
t.Cleanup(bus.Close)
bus := eventbustest.NewBus(t)
netMon, err := netmon.New(bus, logger.WithPrefix(t.Logf, "... netmon: "))
if err != nil {
@@ -1364,7 +1363,7 @@ func newTestConn(t testing.TB) *Conn {
conn, err := NewConn(Options{
NetMon: netMon,
EventBus: bus,
HealthTracker: new(health.Tracker),
HealthTracker: health.NewTracker(bus),
Metrics: new(usermetric.Registry),
DisablePortMapper: true,
Logf: t.Logf,
@@ -3038,7 +3037,7 @@ func TestMaybeSetNearestDERP(t *testing.T) {
}
for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
ht := new(health.Tracker)
ht := health.NewTracker(eventbustest.NewBus(t))
c := newConn(t.Logf)
c.myDerp = tt.old
c.derpMap = derpMap

View File

@@ -50,7 +50,7 @@ func TestInjectInboundLeak(t *testing.T) {
Tun: tunDev,
Dialer: dialer,
SetSubsystem: sys.Set,
HealthTracker: sys.HealthTracker(),
HealthTracker: sys.HealthTracker.Get(),
Metrics: sys.UserMetricsRegistry(),
EventBus: sys.Bus.Get(),
})
@@ -110,7 +110,7 @@ func makeNetstack(tb testing.TB, config func(*Impl)) *Impl {
Tun: tunDev,
Dialer: dialer,
SetSubsystem: sys.Set,
HealthTracker: sys.HealthTracker(),
HealthTracker: sys.HealthTracker.Get(),
Metrics: sys.UserMetricsRegistry(),
EventBus: sys.Bus.Get(),
})

View File

@@ -375,7 +375,7 @@ ip route add throw 192.168.0.0/24 table 52` + basic,
defer mon.Close()
fake := NewFakeOS(t)
ht := new(health.Tracker)
ht := health.NewTracker(bus)
router, err := newUserspaceRouterAdvanced(t.Logf, "tailscale0", mon, fake, ht, bus)
router.(*linuxRouter).nfr = fake.nfr
if err != nil {

View File

@@ -21,7 +21,7 @@ func TestIsNetstack(t *testing.T) {
tstest.WhileTestRunningLogger(t),
wgengine.Config{
SetSubsystem: sys.Set,
HealthTracker: sys.HealthTracker(),
HealthTracker: sys.HealthTracker.Get(),
Metrics: sys.UserMetricsRegistry(),
EventBus: sys.Bus.Get(),
},
@@ -73,7 +73,7 @@ func TestIsNetstackRouter(t *testing.T) {
}
conf := tt.conf
conf.SetSubsystem = sys.Set
conf.HealthTracker = sys.HealthTracker()
conf.HealthTracker = sys.HealthTracker.Get()
conf.Metrics = sys.UserMetricsRegistry()
conf.EventBus = sys.Bus.Get()
e, err := wgengine.NewUserspaceEngine(logger.Discard, conf)

View File

@@ -25,7 +25,7 @@ import (
"tailscale.com/types/key"
"tailscale.com/types/netmap"
"tailscale.com/types/opt"
"tailscale.com/util/eventbus"
"tailscale.com/util/eventbus/eventbustest"
"tailscale.com/util/usermetric"
"tailscale.com/wgengine/router"
"tailscale.com/wgengine/wgcfg"
@@ -101,10 +101,9 @@ func nodeViews(v []*tailcfg.Node) []tailcfg.NodeView {
}
func TestUserspaceEngineReconfig(t *testing.T) {
bus := eventbus.New()
defer bus.Close()
bus := eventbustest.NewBus(t)
ht := new(health.Tracker)
ht := health.NewTracker(bus)
reg := new(usermetric.Registry)
e, err := NewFakeUserspaceEngine(t.Logf, 0, ht, reg, bus)
if err != nil {
@@ -170,12 +169,11 @@ func TestUserspaceEnginePortReconfig(t *testing.T) {
var knobs controlknobs.Knobs
bus := eventbus.New()
defer bus.Close()
bus := eventbustest.NewBus(t)
// Keep making a wgengine until we find an unused port
var ue *userspaceEngine
ht := new(health.Tracker)
ht := health.NewTracker(bus)
reg := new(usermetric.Registry)
for i := range 100 {
attempt := uint16(defaultPort + i)
@@ -258,9 +256,8 @@ func TestUserspaceEnginePeerMTUReconfig(t *testing.T) {
var knobs controlknobs.Knobs
bus := eventbus.New()
defer bus.Close()
ht := new(health.Tracker)
bus := eventbustest.NewBus(t)
ht := health.NewTracker(bus)
reg := new(usermetric.Registry)
e, err := NewFakeUserspaceEngine(t.Logf, 0, &knobs, ht, reg, bus)
if err != nil {

View File

@@ -9,7 +9,7 @@ import (
"time"
"tailscale.com/health"
"tailscale.com/util/eventbus"
"tailscale.com/util/eventbus/eventbustest"
"tailscale.com/util/usermetric"
)
@@ -25,9 +25,8 @@ func TestWatchdog(t *testing.T) {
t.Run("default watchdog does not fire", func(t *testing.T) {
t.Parallel()
bus := eventbus.New()
defer bus.Close()
ht := new(health.Tracker)
bus := eventbustest.NewBus(t)
ht := health.NewTracker(bus)
reg := new(usermetric.Registry)
e, err := NewFakeUserspaceEngine(t.Logf, 0, ht, reg, bus)
if err != nil {