mirror of
https://github.com/juanfont/headscale.git
synced 2026-02-07 20:04:00 +01:00
all: fix errcheck lint issues
Add explicit handling for unchecked error returns: - Add _, _ = prefix to intentionally ignored w.Write calls in debug handlers - Add _, _ = prefix to rand.Read, fmt.Scanln, io.Copy, and WriteString calls - Add _ = prefix to AddNode calls in tests where error is not relevant - Wrap defer cleanup calls in closures to properly ignore errors Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
43349553f2
commit
92ffc364b6
@ -77,7 +77,7 @@ func (h *Headscale) debugHTTPServer() *http.Server {
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte(policy))
|
||||
_, _ = w.Write([]byte(policy))
|
||||
}))
|
||||
|
||||
// Filter rules endpoint
|
||||
@ -96,7 +96,7 @@ func (h *Headscale) debugHTTPServer() *http.Server {
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(filterJSON)
|
||||
_, _ = w.Write(filterJSON)
|
||||
}))
|
||||
|
||||
// SSH policies endpoint
|
||||
@ -111,7 +111,7 @@ func (h *Headscale) debugHTTPServer() *http.Server {
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(sshJSON)
|
||||
_, _ = w.Write(sshJSON)
|
||||
}))
|
||||
|
||||
// DERP map endpoint
|
||||
@ -131,14 +131,14 @@ func (h *Headscale) debugHTTPServer() *http.Server {
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(derpJSON)
|
||||
_, _ = w.Write(derpJSON)
|
||||
} else {
|
||||
// Default to text/plain for backward compatibility
|
||||
derpInfo := h.state.DebugDERPMap()
|
||||
|
||||
w.Header().Set("Content-Type", "text/plain")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte(derpInfo))
|
||||
_, _ = w.Write([]byte(derpInfo))
|
||||
}
|
||||
}))
|
||||
|
||||
@ -159,14 +159,14 @@ func (h *Headscale) debugHTTPServer() *http.Server {
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(nodeStoreJSON)
|
||||
_, _ = w.Write(nodeStoreJSON)
|
||||
} else {
|
||||
// Default to text/plain for backward compatibility
|
||||
nodeStoreInfo := h.state.DebugNodeStore()
|
||||
|
||||
w.Header().Set("Content-Type", "text/plain")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte(nodeStoreInfo))
|
||||
_, _ = w.Write([]byte(nodeStoreInfo))
|
||||
}
|
||||
}))
|
||||
|
||||
@ -182,7 +182,7 @@ func (h *Headscale) debugHTTPServer() *http.Server {
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(cacheJSON)
|
||||
_, _ = w.Write(cacheJSON)
|
||||
}))
|
||||
|
||||
// Routes endpoint
|
||||
@ -202,14 +202,14 @@ func (h *Headscale) debugHTTPServer() *http.Server {
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(routesJSON)
|
||||
_, _ = w.Write(routesJSON)
|
||||
} else {
|
||||
// Default to text/plain for backward compatibility
|
||||
routes := h.state.DebugRoutesString()
|
||||
|
||||
w.Header().Set("Content-Type", "text/plain")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte(routes))
|
||||
_, _ = w.Write([]byte(routes))
|
||||
}
|
||||
}))
|
||||
|
||||
@ -230,14 +230,14 @@ func (h *Headscale) debugHTTPServer() *http.Server {
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(policyManagerJSON)
|
||||
_, _ = w.Write(policyManagerJSON)
|
||||
} else {
|
||||
// Default to text/plain for backward compatibility
|
||||
policyManagerInfo := h.state.DebugPolicyManager()
|
||||
|
||||
w.Header().Set("Content-Type", "text/plain")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte(policyManagerInfo))
|
||||
_, _ = w.Write([]byte(policyManagerInfo))
|
||||
}
|
||||
}))
|
||||
|
||||
@ -250,7 +250,7 @@ func (h *Headscale) debugHTTPServer() *http.Server {
|
||||
|
||||
if res == nil {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte("HEADSCALE_DEBUG_DUMP_MAPRESPONSE_PATH not set"))
|
||||
_, _ = w.Write([]byte("HEADSCALE_DEBUG_DUMP_MAPRESPONSE_PATH not set"))
|
||||
|
||||
return
|
||||
}
|
||||
@ -263,7 +263,7 @@ func (h *Headscale) debugHTTPServer() *http.Server {
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(resJSON)
|
||||
_, _ = w.Write(resJSON)
|
||||
}))
|
||||
|
||||
// Batcher endpoint
|
||||
@ -283,14 +283,14 @@ func (h *Headscale) debugHTTPServer() *http.Server {
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(batcherJSON)
|
||||
_, _ = w.Write(batcherJSON)
|
||||
} else {
|
||||
// Default to text/plain for backward compatibility
|
||||
batcherInfo := h.debugBatcher()
|
||||
|
||||
w.Header().Set("Content-Type", "text/plain")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte(batcherInfo))
|
||||
_, _ = w.Write([]byte(batcherInfo))
|
||||
}
|
||||
}))
|
||||
|
||||
|
||||
@ -538,7 +538,7 @@ type multiChannelNodeConn struct {
|
||||
// generateConnectionID generates a unique connection identifier.
|
||||
func generateConnectionID() string {
|
||||
bytes := make([]byte, 8)
|
||||
rand.Read(bytes)
|
||||
_, _ = rand.Read(bytes)
|
||||
|
||||
return hex.EncodeToString(bytes)
|
||||
}
|
||||
|
||||
@ -549,7 +549,7 @@ func TestEnhancedTrackingWithBatcher(t *testing.T) {
|
||||
testNode.start()
|
||||
|
||||
// Connect the node to the batcher
|
||||
batcher.AddNode(testNode.n.ID, testNode.ch, tailcfg.CapabilityVersion(100))
|
||||
_ = batcher.AddNode(testNode.n.ID, testNode.ch, tailcfg.CapabilityVersion(100))
|
||||
|
||||
// Wait for connection to be established
|
||||
assert.EventuallyWithT(t, func(c *assert.CollectT) {
|
||||
@ -658,7 +658,7 @@ func TestBatcherScalabilityAllToAll(t *testing.T) {
|
||||
|
||||
for i := range allNodes {
|
||||
node := &allNodes[i]
|
||||
batcher.AddNode(node.n.ID, node.ch, tailcfg.CapabilityVersion(100))
|
||||
_ = batcher.AddNode(node.n.ID, node.ch, tailcfg.CapabilityVersion(100))
|
||||
|
||||
// Issue full update after each join to ensure connectivity
|
||||
batcher.AddWork(change.FullUpdate())
|
||||
@ -827,7 +827,7 @@ func TestBatcherBasicOperations(t *testing.T) {
|
||||
tn2 := testData.Nodes[1]
|
||||
|
||||
// Test AddNode with real node ID
|
||||
batcher.AddNode(tn.n.ID, tn.ch, 100)
|
||||
_ = batcher.AddNode(tn.n.ID, tn.ch, 100)
|
||||
|
||||
if !batcher.IsConnected(tn.n.ID) {
|
||||
t.Error("Node should be connected after AddNode")
|
||||
@ -848,7 +848,7 @@ func TestBatcherBasicOperations(t *testing.T) {
|
||||
drainChannelTimeout(tn.ch, "first node before second", 100*time.Millisecond)
|
||||
|
||||
// Add the second node and verify update message
|
||||
batcher.AddNode(tn2.n.ID, tn2.ch, 100)
|
||||
_ = batcher.AddNode(tn2.n.ID, tn2.ch, 100)
|
||||
assert.True(t, batcher.IsConnected(tn2.n.ID))
|
||||
|
||||
// First node should get an update that second node has connected.
|
||||
@ -1053,7 +1053,7 @@ func TestBatcherWorkQueueBatching(t *testing.T) {
|
||||
testNodes := testData.Nodes
|
||||
|
||||
ch := make(chan *tailcfg.MapResponse, 10)
|
||||
batcher.AddNode(testNodes[0].n.ID, ch, tailcfg.CapabilityVersion(100))
|
||||
_ = batcher.AddNode(testNodes[0].n.ID, ch, tailcfg.CapabilityVersion(100))
|
||||
|
||||
// Track update content for validation
|
||||
var receivedUpdates []*tailcfg.MapResponse
|
||||
@ -1157,7 +1157,7 @@ func XTestBatcherChannelClosingRace(t *testing.T) {
|
||||
ch1 := make(chan *tailcfg.MapResponse, 1)
|
||||
|
||||
wg.Go(func() {
|
||||
batcher.AddNode(testNode.n.ID, ch1, tailcfg.CapabilityVersion(100))
|
||||
_ = batcher.AddNode(testNode.n.ID, ch1, tailcfg.CapabilityVersion(100))
|
||||
})
|
||||
|
||||
// Add real work during connection chaos
|
||||
@ -1170,7 +1170,8 @@ func XTestBatcherChannelClosingRace(t *testing.T) {
|
||||
|
||||
wg.Go(func() {
|
||||
runtime.Gosched() // Yield to introduce timing variability
|
||||
batcher.AddNode(testNode.n.ID, ch2, tailcfg.CapabilityVersion(100))
|
||||
|
||||
_ = batcher.AddNode(testNode.n.ID, ch2, tailcfg.CapabilityVersion(100))
|
||||
})
|
||||
|
||||
// Remove second connection
|
||||
@ -1261,7 +1262,7 @@ func TestBatcherWorkerChannelSafety(t *testing.T) {
|
||||
ch := make(chan *tailcfg.MapResponse, 5)
|
||||
|
||||
// Add node and immediately queue real work
|
||||
batcher.AddNode(testNode.n.ID, ch, tailcfg.CapabilityVersion(100))
|
||||
_ = batcher.AddNode(testNode.n.ID, ch, tailcfg.CapabilityVersion(100))
|
||||
batcher.AddWork(change.DERPMap())
|
||||
|
||||
// Consumer goroutine to validate data and detect channel issues
|
||||
@ -1384,7 +1385,7 @@ func TestBatcherConcurrentClients(t *testing.T) {
|
||||
for _, node := range stableNodes {
|
||||
ch := make(chan *tailcfg.MapResponse, NORMAL_BUFFER_SIZE)
|
||||
stableChannels[node.n.ID] = ch
|
||||
batcher.AddNode(node.n.ID, ch, tailcfg.CapabilityVersion(100))
|
||||
_ = batcher.AddNode(node.n.ID, ch, tailcfg.CapabilityVersion(100))
|
||||
|
||||
// Monitor updates for each stable client
|
||||
go func(nodeID types.NodeID, channel chan *tailcfg.MapResponse) {
|
||||
@ -1458,7 +1459,7 @@ func TestBatcherConcurrentClients(t *testing.T) {
|
||||
|
||||
churningChannelsMutex.Unlock()
|
||||
|
||||
batcher.AddNode(nodeID, ch, tailcfg.CapabilityVersion(100))
|
||||
_ = batcher.AddNode(nodeID, ch, tailcfg.CapabilityVersion(100))
|
||||
|
||||
// Consume updates to prevent blocking
|
||||
go func() {
|
||||
@ -1771,7 +1772,7 @@ func XTestBatcherScalability(t *testing.T) {
|
||||
|
||||
for i := range testNodes {
|
||||
node := &testNodes[i]
|
||||
batcher.AddNode(node.n.ID, node.ch, tailcfg.CapabilityVersion(100))
|
||||
_ = batcher.AddNode(node.n.ID, node.ch, tailcfg.CapabilityVersion(100))
|
||||
connectedNodesMutex.Lock()
|
||||
|
||||
connectedNodes[node.n.ID] = true
|
||||
@ -2149,7 +2150,7 @@ func TestBatcherFullPeerUpdates(t *testing.T) {
|
||||
|
||||
// Connect nodes one at a time and wait for each to be connected
|
||||
for i, node := range allNodes {
|
||||
batcher.AddNode(node.n.ID, node.ch, tailcfg.CapabilityVersion(100))
|
||||
_ = batcher.AddNode(node.n.ID, node.ch, tailcfg.CapabilityVersion(100))
|
||||
t.Logf("Connected node %d (ID: %d)", i, node.n.ID)
|
||||
|
||||
// Wait for node to be connected
|
||||
|
||||
@ -102,7 +102,7 @@ func (h *Headscale) ApplePlatformConfig(
|
||||
writer.Header().
|
||||
Set("Content-Type", "application/x-apple-aspen-config; charset=utf-8")
|
||||
writer.WriteHeader(http.StatusOK)
|
||||
writer.Write(content.Bytes())
|
||||
_, _ = writer.Write(content.Bytes())
|
||||
}
|
||||
|
||||
type AppleMobileConfig struct {
|
||||
|
||||
@ -14,7 +14,8 @@ func YesNo(msg string) bool {
|
||||
fmt.Fprint(os.Stderr, msg+" [y/n] ")
|
||||
|
||||
var resp string
|
||||
fmt.Scanln(&resp)
|
||||
|
||||
_, _ = fmt.Scanln(&resp)
|
||||
|
||||
resp = strings.ToLower(resp)
|
||||
switch resp {
|
||||
|
||||
@ -87,7 +87,7 @@ func TestYesNo(t *testing.T) {
|
||||
go func() {
|
||||
defer w.Close()
|
||||
|
||||
w.WriteString(tt.input)
|
||||
_, _ = w.WriteString(tt.input)
|
||||
}()
|
||||
|
||||
// Call the function
|
||||
@ -106,7 +106,8 @@ func TestYesNo(t *testing.T) {
|
||||
|
||||
// Check that the prompt was written to stderr
|
||||
var stderrBuf bytes.Buffer
|
||||
io.Copy(&stderrBuf, stderrR)
|
||||
|
||||
_, _ = io.Copy(&stderrBuf, stderrR)
|
||||
stderrR.Close()
|
||||
|
||||
expectedPrompt := "Test question [y/n] "
|
||||
@ -134,7 +135,7 @@ func TestYesNoPromptMessage(t *testing.T) {
|
||||
go func() {
|
||||
defer w.Close()
|
||||
|
||||
w.WriteString("n\n")
|
||||
_, _ = w.WriteString("n\n")
|
||||
}()
|
||||
|
||||
// Call the function with a custom message
|
||||
@ -149,7 +150,8 @@ func TestYesNoPromptMessage(t *testing.T) {
|
||||
|
||||
// Check that the custom message was included in the prompt
|
||||
var stderrBuf bytes.Buffer
|
||||
io.Copy(&stderrBuf, stderrR)
|
||||
|
||||
_, _ = io.Copy(&stderrBuf, stderrR)
|
||||
stderrR.Close()
|
||||
|
||||
expectedPrompt := customMessage + " [y/n] "
|
||||
@ -193,7 +195,7 @@ func TestYesNoCaseInsensitive(t *testing.T) {
|
||||
go func() {
|
||||
defer w.Close()
|
||||
|
||||
w.WriteString(tc.input)
|
||||
_, _ = w.WriteString(tc.input)
|
||||
}()
|
||||
|
||||
// Call the function
|
||||
@ -206,7 +208,7 @@ func TestYesNoCaseInsensitive(t *testing.T) {
|
||||
stderrW.Close()
|
||||
|
||||
// Drain stderr
|
||||
io.Copy(io.Discard, stderrR)
|
||||
_, _ = io.Copy(io.Discard, stderrR)
|
||||
stderrR.Close()
|
||||
|
||||
if result != tc.expected {
|
||||
|
||||
@ -313,7 +313,7 @@ func TestAuthWebFlowLogoutAndReloginNewUser(t *testing.T) {
|
||||
|
||||
// Register all clients as user1 (this is where cross-user registration happens)
|
||||
// This simulates: headscale nodes register --user user1 --key <key>
|
||||
scenario.runHeadscaleRegister("user1", body)
|
||||
_ = scenario.runHeadscaleRegister("user1", body)
|
||||
}
|
||||
|
||||
// Wait for all clients to reach running state
|
||||
|
||||
@ -681,7 +681,7 @@ func (t *HeadscaleInContainer) Shutdown() (string, string, error) {
|
||||
|
||||
// Cleanup postgres container if enabled.
|
||||
if t.postgres {
|
||||
t.pool.Purge(t.pgContainer)
|
||||
_ = t.pool.Purge(t.pgContainer)
|
||||
}
|
||||
|
||||
return stdoutPath, stderrPath, t.pool.Purge(t.container)
|
||||
|
||||
@ -169,8 +169,8 @@ func NewScenario(spec ScenarioSpec) (*Scenario, error) {
|
||||
// Opportunity to clean up unreferenced networks.
|
||||
// This might be a no op, but it is worth a try as we sometime
|
||||
// dont clean up nicely after ourselves.
|
||||
dockertestutil.CleanUnreferencedNetworks(pool)
|
||||
dockertestutil.CleanImagesInCI(pool)
|
||||
_ = dockertestutil.CleanUnreferencedNetworks(pool)
|
||||
_ = dockertestutil.CleanImagesInCI(pool)
|
||||
|
||||
if spec.MaxWait == 0 {
|
||||
pool.MaxWait = dockertestMaxWait()
|
||||
@ -314,8 +314,8 @@ func (s *Scenario) Services(name string) ([]*dockertest.Resource, error) {
|
||||
}
|
||||
|
||||
func (s *Scenario) ShutdownAssertNoPanics(t *testing.T) {
|
||||
defer dockertestutil.CleanUnreferencedNetworks(s.pool)
|
||||
defer dockertestutil.CleanImagesInCI(s.pool)
|
||||
defer func() { _ = dockertestutil.CleanUnreferencedNetworks(s.pool) }()
|
||||
defer func() { _ = dockertestutil.CleanImagesInCI(s.pool) }()
|
||||
|
||||
s.controlServers.Range(func(_ string, control ControlServer) bool {
|
||||
stdoutPath, stderrPath, err := control.Shutdown()
|
||||
@ -936,7 +936,7 @@ func (s *Scenario) RunTailscaleUpWithURL(userStr, loginServer string) error {
|
||||
// If the URL is not a OIDC URL, then we need to
|
||||
// run the register command to fully log in the client.
|
||||
if !strings.Contains(loginURL.String(), "/oidc/") {
|
||||
s.runHeadscaleRegister(userStr, body)
|
||||
_ = s.runHeadscaleRegister(userStr, body)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
Loading…
Reference in New Issue
Block a user