all: apply formatter changes

This commit is contained in:
Kristoffer Dalby
2026-04-13 12:38:29 +00:00
parent 814226f327
commit 93860a5c06
16 changed files with 72 additions and 64 deletions

View File

@@ -175,8 +175,10 @@ Use --disable to disable key expiry (node will never expire).`,
now := time.Now()
expiryTime := now
if expiry != "" {
var err error
expiryTime, err = time.Parse(time.RFC3339, expiry)
if err != nil {
return fmt.Errorf("parsing expiry time: %w", err)
@@ -397,6 +399,7 @@ func nodesToPtables(
}
var ipBuilder strings.Builder
for _, addr := range node.GetIpAddresses() {
ip, err := netip.ParseAddr(addr)
if err == nil {

View File

@@ -63,6 +63,7 @@ var getPolicy = &cobra.Command{
Aliases: []string{"show", "view", "fetch"},
RunE: func(cmd *cobra.Command, args []string) error {
var policyData string
if bypass, _ := cmd.Flags().GetBool(bypassFlag); bypass {
if !confirmAction(cmd, "DO NOT run this command if an instance of headscale is running, are you sure headscale is not running?") {
return errAborted

View File

@@ -379,7 +379,7 @@ func TestEphemeralGarbageCollectorConcurrentScheduleAndClose(t *testing.T) {
stopScheduling := make(chan struct{})
// Track how many nodes have been scheduled
var scheduledCount int64
var scheduledCount atomic.Int64
// Launch goroutines that continuously schedule nodes
for schedulerIndex := range numSchedulers {
@@ -396,7 +396,7 @@ func TestEphemeralGarbageCollectorConcurrentScheduleAndClose(t *testing.T) {
default:
nodeID := types.NodeID(baseNodeID + j + 1) //nolint:gosec // safe conversion in test
gc.Schedule(nodeID, 1*time.Hour) // Long expiry to ensure it doesn't trigger during test
atomic.AddInt64(&scheduledCount, 1)
scheduledCount.Add(1)
// Yield to other goroutines to introduce variability
runtime.Gosched()
@@ -410,7 +410,7 @@ func TestEphemeralGarbageCollectorConcurrentScheduleAndClose(t *testing.T) {
defer wg.Done()
// Wait until enough nodes have been scheduled
for atomic.LoadInt64(&scheduledCount) < int64(numSchedulers*closeAfterNodes) {
for scheduledCount.Load() < int64(numSchedulers*closeAfterNodes) {
runtime.Gosched()
}

View File

@@ -633,7 +633,7 @@ func TestEphemeralGarbageCollectorLoads(t *testing.T) {
want := 1000
var deletedCount int64
var deletedCount atomic.Int64
e := NewEphemeralGarbageCollector(func(ni types.NodeID) {
mu.Lock()
@@ -644,7 +644,7 @@ func TestEphemeralGarbageCollectorLoads(t *testing.T) {
got = append(got, ni)
atomic.AddInt64(&deletedCount, 1)
deletedCount.Add(1)
})
go e.Start()
@@ -655,7 +655,7 @@ func TestEphemeralGarbageCollectorLoads(t *testing.T) {
// Wait for all deletions to complete
assert.EventuallyWithT(t, func(c *assert.CollectT) {
count := atomic.LoadInt64(&deletedCount)
count := deletedCount.Load()
assert.Equal(c, int64(want), count, "all nodes should be deleted")
}, 10*time.Second, 50*time.Millisecond, "waiting for all deletions")

View File

@@ -395,13 +395,13 @@ func (h *Headscale) debugBatcher() string {
}
if node.activeConnections > 0 {
sb.WriteString(fmt.Sprintf("Node %d:\t%s (%d connections)\n", node.id, status, node.activeConnections))
fmt.Fprintf(&sb, "Node %d:\t%s (%d connections)\n", node.id, status, node.activeConnections)
} else {
sb.WriteString(fmt.Sprintf("Node %d:\t%s\n", node.id, status))
fmt.Fprintf(&sb, "Node %d:\t%s\n", node.id, status)
}
}
sb.WriteString(fmt.Sprintf("\nSummary: %d connected, %d total\n", connectedCount, totalNodes))
fmt.Fprintf(&sb, "\nSummary: %d connected, %d total\n", connectedCount, totalNodes)
return sb.String()
}

View File

@@ -786,6 +786,7 @@ func TestBug3_CleanupOfflineNodes_TOCTOU(t *testing.T) {
entry.lastUsed.Store(time.Now().Unix())
mc.addConnection(entry)
mc.markConnected()
lb.channels[targetNode] = newCh
// Now run cleanup. Node 3 is in the candidates list (old disconnect

View File

@@ -141,9 +141,9 @@ type node struct {
ch chan *tailcfg.MapResponse
// Update tracking (all accessed atomically for thread safety)
updateCount int64
patchCount int64
fullCount int64
updateCount atomic.Int64
patchCount atomic.Int64
fullCount atomic.Int64
maxPeersCount atomic.Int64
lastPeerCount atomic.Int64
stop chan struct{}
@@ -404,14 +404,14 @@ func (n *node) start() {
for {
select {
case data := <-n.ch:
atomic.AddInt64(&n.updateCount, 1)
n.updateCount.Add(1)
// Parse update and track detailed stats
info := parseUpdateAndAnalyze(data)
{
// Track update types
if info.IsFull {
atomic.AddInt64(&n.fullCount, 1)
n.fullCount.Add(1)
n.lastPeerCount.Store(int64(info.PeerCount))
// Update max peers seen using compare-and-swap for thread safety
for {
@@ -427,7 +427,7 @@ func (n *node) start() {
}
if info.IsPatch {
atomic.AddInt64(&n.patchCount, 1)
n.patchCount.Add(1)
// For patches, we track how many patch items using compare-and-swap
for {
current := n.maxPeersCount.Load()
@@ -466,9 +466,9 @@ func (n *node) cleanup() NodeStats {
}
return NodeStats{
TotalUpdates: atomic.LoadInt64(&n.updateCount),
PatchUpdates: atomic.LoadInt64(&n.patchCount),
FullUpdates: atomic.LoadInt64(&n.fullCount),
TotalUpdates: n.updateCount.Load(),
PatchUpdates: n.patchCount.Load(),
FullUpdates: n.fullCount.Load(),
MaxPeersSeen: int(n.maxPeersCount.Load()),
LastPeerCount: int(n.lastPeerCount.Load()),
}
@@ -509,7 +509,7 @@ func TestEnhancedNodeTracking(t *testing.T) {
// Wait for tracking goroutine to process the update
assert.EventuallyWithT(t, func(c *assert.CollectT) {
assert.GreaterOrEqual(c, atomic.LoadInt64(&testNode.updateCount), int64(1), "should have processed the update")
assert.GreaterOrEqual(c, testNode.updateCount.Load(), int64(1), "should have processed the update")
}, time.Second, 10*time.Millisecond, "waiting for update to be processed")
// Check stats
@@ -553,7 +553,7 @@ func TestEnhancedTrackingWithBatcher(t *testing.T) {
// Wait for updates to be processed (at least 1 update received)
assert.EventuallyWithT(t, func(c *assert.CollectT) {
assert.GreaterOrEqual(c, atomic.LoadInt64(&testNode.updateCount), int64(1), "should have received updates")
assert.GreaterOrEqual(c, testNode.updateCount.Load(), int64(1), "should have received updates")
}, time.Second, 10*time.Millisecond, "waiting for updates to be processed")
// Check stats
@@ -2141,8 +2141,8 @@ func TestNodeDeletedWhileChangesPending(t *testing.T) {
assert.EventuallyWithT(t, func(c *assert.CollectT) {
// Node 1 and 2 should receive updates
stats1 := NodeStats{TotalUpdates: atomic.LoadInt64(&node1.updateCount)}
stats2 := NodeStats{TotalUpdates: atomic.LoadInt64(&node2.updateCount)}
stats1 := NodeStats{TotalUpdates: node1.updateCount.Load()}
stats2 := NodeStats{TotalUpdates: node2.updateCount.Load()}
assert.Positive(c, stats1.TotalUpdates, "node1 should have received updates")
assert.Positive(c, stats2.TotalUpdates, "node2 should have received updates")
}, 5*time.Second, 100*time.Millisecond, "waiting for remaining nodes to receive updates")

View File

@@ -60,6 +60,7 @@ func ReduceFilterRules(node types.NodeView, rules []tailcfg.FilterRule) []tailcf
if tsaddr.IsExitRoute(routableIP) {
continue
}
if expanded.OverlapsPrefix(routableIP) {
dests = append(dests, dest)
continue DEST_LOOP

View File

@@ -69,7 +69,7 @@ func (s *State) DebugOverview() string {
sb.WriteString("=== Headscale State Overview ===\n\n")
// Node statistics
sb.WriteString(fmt.Sprintf("Nodes: %d total\n", allNodes.Len()))
fmt.Fprintf(&sb, "Nodes: %d total\n", allNodes.Len())
userNodeCounts := make(map[string]int)
onlineCount := 0
@@ -97,26 +97,26 @@ func (s *State) DebugOverview() string {
}
}
sb.WriteString(fmt.Sprintf(" - Online: %d\n", onlineCount))
sb.WriteString(fmt.Sprintf(" - Expired: %d\n", expiredCount))
sb.WriteString(fmt.Sprintf(" - Ephemeral: %d\n", ephemeralCount))
fmt.Fprintf(&sb, " - Online: %d\n", onlineCount)
fmt.Fprintf(&sb, " - Expired: %d\n", expiredCount)
fmt.Fprintf(&sb, " - Ephemeral: %d\n", ephemeralCount)
sb.WriteString("\n")
// User statistics
sb.WriteString(fmt.Sprintf("Users: %d total\n", len(users)))
fmt.Fprintf(&sb, "Users: %d total\n", len(users))
for userName, nodeCount := range userNodeCounts {
sb.WriteString(fmt.Sprintf(" - %s: %d nodes\n", userName, nodeCount))
fmt.Fprintf(&sb, " - %s: %d nodes\n", userName, nodeCount)
}
sb.WriteString("\n")
// Policy information
sb.WriteString("Policy:\n")
sb.WriteString(fmt.Sprintf(" - Mode: %s\n", s.cfg.Policy.Mode))
fmt.Fprintf(&sb, " - Mode: %s\n", s.cfg.Policy.Mode)
if s.cfg.Policy.Mode == types.PolicyModeFile {
sb.WriteString(fmt.Sprintf(" - Path: %s\n", s.cfg.Policy.Path))
fmt.Fprintf(&sb, " - Path: %s\n", s.cfg.Policy.Path)
}
sb.WriteString("\n")
@@ -124,7 +124,7 @@ func (s *State) DebugOverview() string {
// DERP information
derpMap := s.derpMap.Load()
if derpMap != nil {
sb.WriteString(fmt.Sprintf("DERP: %d regions configured\n", len(derpMap.Regions)))
fmt.Fprintf(&sb, "DERP: %d regions configured\n", len(derpMap.Regions))
} else {
sb.WriteString("DERP: not configured\n")
}
@@ -137,7 +137,7 @@ func (s *State) DebugOverview() string {
routeCount = 0
}
sb.WriteString(fmt.Sprintf("Primary Routes: %d active\n", routeCount))
fmt.Fprintf(&sb, "Primary Routes: %d active\n", routeCount)
sb.WriteString("\n")
// Registration cache
@@ -163,18 +163,18 @@ func (s *State) DebugDERPMap() string {
sb.WriteString("=== DERP Map Configuration ===\n\n")
sb.WriteString(fmt.Sprintf("Total Regions: %d\n\n", len(derpMap.Regions)))
fmt.Fprintf(&sb, "Total Regions: %d\n\n", len(derpMap.Regions))
for regionID, region := range derpMap.Regions {
sb.WriteString(fmt.Sprintf("Region %d: %s\n", regionID, region.RegionName))
sb.WriteString(fmt.Sprintf(" - Nodes: %d\n", len(region.Nodes)))
fmt.Fprintf(&sb, "Region %d: %s\n", regionID, region.RegionName)
fmt.Fprintf(&sb, " - Nodes: %d\n", len(region.Nodes))
for _, node := range region.Nodes {
sb.WriteString(fmt.Sprintf(" - %s (%s:%d)\n",
node.Name, node.HostName, node.DERPPort))
fmt.Fprintf(&sb, " - %s (%s:%d)\n",
node.Name, node.HostName, node.DERPPort)
if node.STUNPort != 0 {
sb.WriteString(fmt.Sprintf(" STUN: %d\n", node.STUNPort))
fmt.Fprintf(&sb, " STUN: %d\n", node.STUNPort)
}
}

View File

@@ -526,8 +526,8 @@ func (s *NodeStore) DebugString() string {
sb.WriteString("=== NodeStore Debug Information ===\n\n")
// Basic counts
sb.WriteString(fmt.Sprintf("Total Nodes: %d\n", len(snapshot.nodesByID)))
sb.WriteString(fmt.Sprintf("Users with Nodes: %d\n", len(snapshot.nodesByUser)))
fmt.Fprintf(&sb, "Total Nodes: %d\n", len(snapshot.nodesByID))
fmt.Fprintf(&sb, "Users with Nodes: %d\n", len(snapshot.nodesByUser))
sb.WriteString("\n")
// User distribution (shows internal UserID tracking, not display owner)
@@ -541,7 +541,7 @@ func (s *NodeStore) DebugString() string {
userName = nodes[0].User().Name()
}
sb.WriteString(fmt.Sprintf(" - User %d (%s): %d nodes\n", userID, userName, len(nodes)))
fmt.Fprintf(&sb, " - User %d (%s): %d nodes\n", userID, userName, len(nodes))
}
}
@@ -557,20 +557,20 @@ func (s *NodeStore) DebugString() string {
totalPeers += peerCount
if node, exists := snapshot.nodesByID[nodeID]; exists {
sb.WriteString(fmt.Sprintf(" - Node %d (%s): %d peers\n",
nodeID, node.Hostname, peerCount))
fmt.Fprintf(&sb, " - Node %d (%s): %d peers\n",
nodeID, node.Hostname, peerCount)
}
}
if len(snapshot.peersByNode) > 0 {
avgPeers := float64(totalPeers) / float64(len(snapshot.peersByNode))
sb.WriteString(fmt.Sprintf(" - Average peers per node: %.1f\n", avgPeers))
fmt.Fprintf(&sb, " - Average peers per node: %.1f\n", avgPeers)
}
sb.WriteString("\n")
// Node key index
sb.WriteString(fmt.Sprintf("NodeKey Index: %d entries\n", len(snapshot.nodesByNodeKey)))
fmt.Fprintf(&sb, "NodeKey Index: %d entries\n", len(snapshot.nodesByNodeKey))
sb.WriteString("\n")
return sb.String()

View File

@@ -1790,10 +1790,12 @@ func (s *State) HandleNodeFromAuthPath(
// the initial Hostinfo from the cached client-supplied Hostinfo (or
// an empty stub if the client did not send one).
hostname := regData.Hostname
hostinfo := &tailcfg.Hostinfo{}
if regData.Hostinfo != nil {
hostinfo = regData.Hostinfo.Clone()
}
hostinfo.Hostname = hostname
// Lookup existing nodes

View File

@@ -933,7 +933,7 @@ func warnBanner(lines []string) {
b.WriteString("### ###\n")
for _, line := range lines {
b.WriteString(fmt.Sprintf("### %-54s ###\n", line))
fmt.Fprintf(&b, "### %-54s ###\n", line)
}
b.WriteString("### ###\n")

View File

@@ -30,10 +30,10 @@ func (v *VersionInfo) String() string {
version += "-dirty"
}
sb.WriteString(fmt.Sprintf("headscale version %s\n", version))
sb.WriteString(fmt.Sprintf("commit: %s\n", v.Commit))
sb.WriteString(fmt.Sprintf("build time: %s\n", v.BuildTime))
sb.WriteString(fmt.Sprintf("built with: %s %s/%s\n", v.Go.Version, v.Go.OS, v.Go.Arch))
fmt.Fprintf(&sb, "headscale version %s\n", version)
fmt.Fprintf(&sb, "commit: %s\n", v.Commit)
fmt.Fprintf(&sb, "build time: %s\n", v.BuildTime)
fmt.Fprintf(&sb, "built with: %s %s/%s\n", v.Go.Version, v.Go.OS, v.Go.Arch)
return sb.String()
}

View File

@@ -98,12 +98,12 @@ func TailcfgFilterRulesToString(rules []tailcfg.FilterRule) string {
var sb strings.Builder
for index, rule := range rules {
sb.WriteString(fmt.Sprintf(`
fmt.Fprintf(&sb, `
{
SrcIPs: %v
DstIPs: %v
}
`, rule.SrcIPs, rule.DstPorts))
`, rule.SrcIPs, rule.DstPorts)
if index < len(rules)-1 {
sb.WriteString(", ")

View File

@@ -341,11 +341,11 @@ func requireAllClientsOnlineWithSingleTimeout(t *testing.T, headscale ControlSer
stateStr = stateOnline
}
failureReport.WriteString(fmt.Sprintf("node:%d is not fully %s (timestamp: %s):\n", nodeID, stateStr, time.Now().Format(TimestampFormat)))
failureReport.WriteString(fmt.Sprintf(" - batcher: %t (expected: %t)\n", status.Batcher, expectedOnline))
failureReport.WriteString(fmt.Sprintf(" - conn count: %d\n", status.BatcherConnCount))
failureReport.WriteString(fmt.Sprintf(" - mapresponses: %t (expected: %t, down with at least one peer)\n", status.MapResponses, expectedOnline))
failureReport.WriteString(fmt.Sprintf(" - nodestore: %t (expected: %t)\n", status.NodeStore, expectedOnline))
fmt.Fprintf(&failureReport, "node:%d is not fully %s (timestamp: %s):\n", nodeID, stateStr, time.Now().Format(TimestampFormat))
fmt.Fprintf(&failureReport, " - batcher: %t (expected: %t)\n", status.Batcher, expectedOnline)
fmt.Fprintf(&failureReport, " - conn count: %d\n", status.BatcherConnCount)
fmt.Fprintf(&failureReport, " - mapresponses: %t (expected: %t, down with at least one peer)\n", status.MapResponses, expectedOnline)
fmt.Fprintf(&failureReport, " - nodestore: %t (expected: %t)\n", status.NodeStore, expectedOnline)
}
}
@@ -359,7 +359,7 @@ func requireAllClientsOnlineWithSingleTimeout(t *testing.T, headscale ControlSer
prevReport = failureReport.String()
}
failureReport.WriteString(fmt.Sprintf("validation_timestamp: %s\n", time.Now().Format(TimestampFormat)))
fmt.Fprintf(&failureReport, "validation_timestamp: %s\n", time.Now().Format(TimestampFormat))
// Note: timeout_remaining not available in this context
assert.Fail(c, failureReport.String())

View File

@@ -359,7 +359,7 @@ func writeTestDataFile(versions map[string]tailcfg.CapabilityVersion, minSupport
content.WriteString("\t{3, false, []string{")
for i, version := range latest3 {
content.WriteString(fmt.Sprintf("\"%s\"", version))
fmt.Fprintf(&content, "\"%s\"", version)
if i < len(latest3)-1 {
content.WriteString(", ")
@@ -374,7 +374,7 @@ func writeTestDataFile(versions map[string]tailcfg.CapabilityVersion, minSupport
for i, version := range latest2 {
// Strip v prefix for this test case
verNoV := strings.TrimPrefix(version, "v")
content.WriteString(fmt.Sprintf("\"%s\"", verNoV))
fmt.Fprintf(&content, "\"%s\"", verNoV)
if i < len(latest2)-1 {
content.WriteString(", ")
@@ -384,11 +384,11 @@ func writeTestDataFile(versions map[string]tailcfg.CapabilityVersion, minSupport
content.WriteString("}},\n")
// Latest N without v prefix (all supported)
content.WriteString(fmt.Sprintf("\t{%d, true, []string{\n", supportedMajorMinorVersions))
fmt.Fprintf(&content, "\t{%d, true, []string{\n", supportedMajorMinorVersions)
for _, version := range latest10 {
verNoV := strings.TrimPrefix(version, "v")
content.WriteString(fmt.Sprintf("\t\t\"%s\",\n", verNoV))
fmt.Fprintf(&content, "\t\t\"%s\",\n", verNoV)
}
content.WriteString("\t}},\n")
@@ -417,7 +417,7 @@ func writeTestDataFile(versions map[string]tailcfg.CapabilityVersion, minSupport
// Add minimum supported version
minVersionString := capVerToTailscaleVer[minSupportedCapVer]
content.WriteString(fmt.Sprintf("\t{%d, \"%s\"},\n", minSupportedCapVer, minVersionString))
fmt.Fprintf(&content, "\t{%d, \"%s\"},\n", minSupportedCapVer, minVersionString)
// Add a few more test cases
capsSorted := xmaps.Keys(capVerToTailscaleVer)
@@ -431,7 +431,7 @@ func writeTestDataFile(versions map[string]tailcfg.CapabilityVersion, minSupport
if capVer != minSupportedCapVer { // Don't duplicate the min version test
version := capVerToTailscaleVer[capVer]
content.WriteString(fmt.Sprintf("\t{%d, \"%s\"},\n", capVer, version))
fmt.Fprintf(&content, "\t{%d, \"%s\"},\n", capVer, version)
testCount++
}