Update dependencies

This commit is contained in:
bluepython508
2025-04-09 01:00:12 +01:00
parent f0641ffd6e
commit 5a9cfc022c
882 changed files with 68930 additions and 24201 deletions

View File

@@ -22,6 +22,7 @@ import (
"tailscale.com/envknob"
"tailscale.com/metrics"
"tailscale.com/tailcfg"
"tailscale.com/tstime"
"tailscale.com/types/opt"
"tailscale.com/util/cibuild"
"tailscale.com/util/mak"
@@ -73,6 +74,8 @@ type Tracker struct {
// mu should not be held during init.
initOnce sync.Once
testClock tstime.Clock // nil means use time.Now / tstime.StdClock{}
// mu guards everything that follows.
mu sync.Mutex
@@ -80,13 +83,13 @@ type Tracker struct {
warnableVal map[*Warnable]*warningState
// pendingVisibleTimers contains timers for Warnables that are unhealthy, but are
// not visible to the user yet, because they haven't been unhealthy for TimeToVisible
pendingVisibleTimers map[*Warnable]*time.Timer
pendingVisibleTimers map[*Warnable]tstime.TimerController
// sysErr maps subsystems to their current error (or nil if the subsystem is healthy)
// Deprecated: using Warnables should be preferred
sysErr map[Subsystem]error
watchers set.HandleSet[func(*Warnable, *UnhealthyState)] // opt func to run if error state changes
timer *time.Timer
timer tstime.TimerController
latestVersion *tailcfg.ClientVersion // or nil
checkForUpdates bool
@@ -115,6 +118,20 @@ type Tracker struct {
metricHealthMessage *metrics.MultiLabelMap[metricHealthMessageLabel]
}
func (t *Tracker) now() time.Time {
if t.testClock != nil {
return t.testClock.Now()
}
return time.Now()
}
func (t *Tracker) clock() tstime.Clock {
if t.testClock != nil {
return t.testClock
}
return tstime.StdClock{}
}
// Subsystem is the name of a subsystem whose health can be monitored.
//
// Deprecated: Registering a Warnable using Register() and updating its health state
@@ -128,9 +145,6 @@ const (
// SysDNS is the name of the net/dns subsystem.
SysDNS = Subsystem("dns")
// SysDNSOS is the name of the net/dns OSConfigurator subsystem.
SysDNSOS = Subsystem("dns-os")
// SysDNSManager is the name of the net/dns manager subsystem.
SysDNSManager = Subsystem("dns-manager")
@@ -141,7 +155,7 @@ const (
var subsystemsWarnables = map[Subsystem]*Warnable{}
func init() {
for _, s := range []Subsystem{SysRouter, SysDNS, SysDNSOS, SysDNSManager, SysTKA} {
for _, s := range []Subsystem{SysRouter, SysDNS, SysDNSManager, SysTKA} {
w := Register(&Warnable{
Code: WarnableCode(s),
Severity: SeverityMedium,
@@ -217,9 +231,11 @@ type Warnable struct {
// TODO(angott): turn this into a SeverityFunc, which allows the Warnable to change its severity based on
// the Args of the unhappy state, just like we do in the Text function.
Severity Severity
// DependsOn is a set of Warnables that this Warnable depends, on and need to be healthy
// before this Warnable can also be healthy again. The GUI can use this information to ignore
// DependsOn is a set of Warnables that this Warnable depends on and need to be healthy
// before this Warnable is relevant. The GUI can use this information to ignore
// this Warnable if one of its dependencies is unhealthy.
// That is, if any of these Warnables are unhealthy, then this Warnable is not relevant
// and should be considered healthy to bother the user about.
DependsOn []*Warnable
// MapDebugFlag is a MapRequest.DebugFlag that is sent to control when this Warnable is unhealthy
@@ -312,11 +328,11 @@ func (ws *warningState) Equal(other *warningState) bool {
// IsVisible returns whether the Warnable should be visible to the user, based on the TimeToVisible
// field of the Warnable and the BrokenSince time when the Warnable became unhealthy.
func (w *Warnable) IsVisible(ws *warningState) bool {
func (w *Warnable) IsVisible(ws *warningState, clockNow func() time.Time) bool {
if ws == nil || w.TimeToVisible == 0 {
return true
}
return time.Since(ws.BrokenSince) >= w.TimeToVisible
return clockNow().Sub(ws.BrokenSince) >= w.TimeToVisible
}
// SetMetricsRegistry sets up the metrics for the Tracker. It takes
@@ -334,7 +350,7 @@ func (t *Tracker) SetMetricsRegistry(reg *usermetric.Registry) {
)
t.metricHealthMessage.Set(metricHealthMessageLabel{
Type: "warning",
Type: MetricLabelWarning,
}, expvar.Func(func() any {
if t.nil() {
return 0
@@ -366,7 +382,7 @@ func (t *Tracker) setUnhealthyLocked(w *Warnable, args Args) {
// If we already have a warningState for this Warnable with an earlier BrokenSince time, keep that
// BrokenSince time.
brokenSince := time.Now()
brokenSince := t.now()
if existingWS := t.warnableVal[w]; existingWS != nil {
brokenSince = existingWS.BrokenSince
}
@@ -385,15 +401,15 @@ func (t *Tracker) setUnhealthyLocked(w *Warnable, args Args) {
// If the Warnable has been unhealthy for more than its TimeToVisible, the callback should be
// executed immediately. Otherwise, the callback should be enqueued to run once the Warnable
// becomes visible.
if w.IsVisible(ws) {
if w.IsVisible(ws, t.now) {
go cb(w, w.unhealthyState(ws))
continue
}
// The time remaining until the Warnable will be visible to the user is the TimeToVisible
// minus the time that has already passed since the Warnable became unhealthy.
visibleIn := w.TimeToVisible - time.Since(brokenSince)
mak.Set(&t.pendingVisibleTimers, w, time.AfterFunc(visibleIn, func() {
visibleIn := w.TimeToVisible - t.now().Sub(brokenSince)
var tc tstime.TimerController = t.clock().AfterFunc(visibleIn, func() {
t.mu.Lock()
defer t.mu.Unlock()
// Check if the Warnable is still unhealthy, as it could have become healthy between the time
@@ -402,7 +418,8 @@ func (t *Tracker) setUnhealthyLocked(w *Warnable, args Args) {
go cb(w, w.unhealthyState(ws))
delete(t.pendingVisibleTimers, w)
}
}))
})
mak.Set(&t.pendingVisibleTimers, w, tc)
}
}
}
@@ -477,7 +494,7 @@ func (t *Tracker) RegisterWatcher(cb func(w *Warnable, r *UnhealthyState)) (unre
}
handle := t.watchers.Add(cb)
if t.timer == nil {
t.timer = time.AfterFunc(time.Minute, t.timerSelfCheck)
t.timer = t.clock().AfterFunc(time.Minute, t.timerSelfCheck)
}
return func() {
t.mu.Lock()
@@ -510,22 +527,12 @@ func (t *Tracker) SetDNSHealth(err error) { t.setErr(SysDNS, err) }
// Deprecated: Warnables should be preferred over Subsystem errors.
func (t *Tracker) DNSHealth() error { return t.get(SysDNS) }
// SetDNSOSHealth sets the state of the net/dns.OSConfigurator
//
// Deprecated: Warnables should be preferred over Subsystem errors.
func (t *Tracker) SetDNSOSHealth(err error) { t.setErr(SysDNSOS, err) }
// SetDNSManagerHealth sets the state of the Linux net/dns manager's
// discovery of the /etc/resolv.conf situation.
//
// Deprecated: Warnables should be preferred over Subsystem errors.
func (t *Tracker) SetDNSManagerHealth(err error) { t.setErr(SysDNSManager, err) }
// DNSOSHealth returns the net/dns.OSConfigurator error state.
//
// Deprecated: Warnables should be preferred over Subsystem errors.
func (t *Tracker) DNSOSHealth() error { return t.get(SysDNSOS) }
// SetTKAHealth sets the health of the tailnet key authority.
//
// Deprecated: Warnables should be preferred over Subsystem errors.
@@ -651,10 +658,10 @@ func (t *Tracker) GotStreamedMapResponse() {
}
t.mu.Lock()
defer t.mu.Unlock()
t.lastStreamedMapResponse = time.Now()
t.lastStreamedMapResponse = t.now()
if !t.inMapPoll {
t.inMapPoll = true
t.inMapPollSince = time.Now()
t.inMapPollSince = t.now()
}
t.selfCheckLocked()
}
@@ -671,7 +678,7 @@ func (t *Tracker) SetOutOfPollNetMap() {
return
}
t.inMapPoll = false
t.lastMapPollEndedAt = time.Now()
t.lastMapPollEndedAt = t.now()
t.selfCheckLocked()
}
@@ -713,7 +720,7 @@ func (t *Tracker) NoteMapRequestHeard(mr *tailcfg.MapRequest) {
// against SetMagicSockDERPHome and
// SetDERPRegionConnectedState
t.lastMapRequestHeard = time.Now()
t.lastMapRequestHeard = t.now()
t.selfCheckLocked()
}
@@ -751,7 +758,7 @@ func (t *Tracker) NoteDERPRegionReceivedFrame(region int) {
}
t.mu.Lock()
defer t.mu.Unlock()
mak.Set(&t.derpRegionLastFrame, region, time.Now())
mak.Set(&t.derpRegionLastFrame, region, t.now())
t.selfCheckLocked()
}
@@ -810,9 +817,9 @@ func (t *Tracker) SetIPNState(state string, wantRunning bool) {
// The first time we see wantRunning=true and it used to be false, it means the user requested
// the backend to start. We store this timestamp and use it to silence some warnings that are
// expected during startup.
t.ipnWantRunningLastTrue = time.Now()
t.ipnWantRunningLastTrue = t.now()
t.setUnhealthyLocked(warmingUpWarnable, nil)
time.AfterFunc(warmingUpWarnableDuration, func() {
t.clock().AfterFunc(warmingUpWarnableDuration, func() {
t.mu.Lock()
t.updateWarmingUpWarnableLocked()
t.mu.Unlock()
@@ -949,10 +956,13 @@ func (t *Tracker) Strings() []string {
func (t *Tracker) stringsLocked() []string {
result := []string{}
for w, ws := range t.warnableVal {
if !w.IsVisible(ws) {
if !w.IsVisible(ws, t.now) {
// Do not append invisible warnings.
continue
}
if t.isEffectivelyHealthyLocked(w) {
continue
}
if ws.Args == nil {
result = append(result, w.Text(Args{}))
} else {
@@ -1018,7 +1028,7 @@ func (t *Tracker) updateBuiltinWarnablesLocked() {
t.setHealthyLocked(localLogWarnable)
}
now := time.Now()
now := t.now()
// How long we assume we'll have heard a DERP frame or a MapResponse
// KeepAlive by.
@@ -1028,8 +1038,10 @@ func (t *Tracker) updateBuiltinWarnablesLocked() {
recentlyOn := now.Sub(t.ipnWantRunningLastTrue) < 5*time.Second
homeDERP := t.derpHomeRegion
if recentlyOn {
if recentlyOn || !t.inMapPoll {
// If user just turned Tailscale on, don't warn for a bit.
// Also, if we're not in a map poll, that means we don't yet
// have a DERPMap or aren't in a state where we even want
t.setHealthyLocked(noDERPHomeWarnable)
t.setHealthyLocked(noDERPConnectionWarnable)
t.setHealthyLocked(derpTimeoutWarnable)
@@ -1051,11 +1063,15 @@ func (t *Tracker) updateBuiltinWarnablesLocked() {
ArgDuration: d.Round(time.Second).String(),
})
}
} else {
} else if homeDERP != 0 {
t.setUnhealthyLocked(noDERPConnectionWarnable, Args{
ArgDERPRegionID: fmt.Sprint(homeDERP),
ArgDERPRegionName: t.derpRegionNameLocked(homeDERP),
})
} else {
// No DERP home yet determined yet. There's probably some
// other problem or things are just starting up.
t.setHealthyLocked(noDERPConnectionWarnable)
}
if !t.ipnWantRunning {
@@ -1174,7 +1190,7 @@ func (t *Tracker) updateBuiltinWarnablesLocked() {
// updateWarmingUpWarnableLocked ensures the warmingUpWarnable is healthy if wantRunning has been set to true
// for more than warmingUpWarnableDuration.
func (t *Tracker) updateWarmingUpWarnableLocked() {
if !t.ipnWantRunningLastTrue.IsZero() && time.Now().After(t.ipnWantRunningLastTrue.Add(warmingUpWarnableDuration)) {
if !t.ipnWantRunningLastTrue.IsZero() && t.now().After(t.ipnWantRunningLastTrue.Add(warmingUpWarnableDuration)) {
t.setHealthyLocked(warmingUpWarnable)
}
}
@@ -1286,12 +1302,14 @@ func (t *Tracker) LastNoiseDialWasRecent() bool {
t.mu.Lock()
defer t.mu.Unlock()
now := time.Now()
now := t.now()
dur := now.Sub(t.lastNoiseDial)
t.lastNoiseDial = now
return dur < 2*time.Minute
}
const MetricLabelWarning = "warning"
type metricHealthMessageLabel struct {
// TODO: break down by warnable.severity as well?
Type string