ci: add more lints (#7909)

This is a follow-up to #7905 that adds two more linters and fixes the corresponding findings. As per the previous PR, this only flags things that are "obviously" wrong, and fixes the issues found.

Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I8739bdb7bc4f75666a7385a7a26d56ec13741b7c
pull/7935/head
Andrew Dunham 1 year ago committed by GitHub
parent 5acc7c4b1e
commit f85dc6f97c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -3,9 +3,11 @@ linters:
# enable in the list below. # enable in the list below.
disable-all: true disable-all: true
enable: enable:
- bidichk
- gofmt - gofmt
- goimports - goimports
- misspell - misspell
- revive
# Configuration for how we run golangci-lint # Configuration for how we run golangci-lint
run: run:
@ -23,6 +25,9 @@ issues:
# Per-linter settings are contained in this top-level key # Per-linter settings are contained in this top-level key
linters-settings: linters-settings:
# Enable all rules by default; we don't use invisible unicode runes.
bidichk:
gofmt: gofmt:
rewrite-rules: rewrite-rules:
- pattern: 'interface{}' - pattern: 'interface{}'
@ -31,3 +36,26 @@ linters-settings:
goimports: goimports:
misspell: misspell:
revive:
enable-all-rules: false
ignore-generated-header: true
rules:
- name: atomic
- name: context-keys-type
- name: defer
arguments: [[
# Calling 'recover' at the time a defer is registered (i.e. "defer recover()") has no effect.
"immediate-recover",
# Calling 'recover' outside of a deferred function has no effect
"recover",
# Returning values from a deferred function has no effect
"return",
]]
- name: duplicated-imports
- name: errorf
- name: string-of-int
- name: time-equal
- name: unconditional-recursion
- name: useless-break
- name: waitgroup-by-value

@ -14,7 +14,6 @@ import (
"go.uber.org/zap" "go.uber.org/zap"
appsv1 "k8s.io/api/apps/v1" appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
v1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors" apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
@ -670,11 +669,11 @@ func expectedSTS(stsName, secretName, hostname string) *appsv1.StatefulSet {
}, },
}, },
}, },
Containers: []v1.Container{ Containers: []corev1.Container{
{ {
Name: "tailscale", Name: "tailscale",
Image: "tailscale/tailscale", Image: "tailscale/tailscale",
Env: []v1.EnvVar{ Env: []corev1.EnvVar{
{Name: "TS_USERSPACE", Value: "false"}, {Name: "TS_USERSPACE", Value: "false"},
{Name: "TS_AUTH_ONCE", Value: "true"}, {Name: "TS_AUTH_ONCE", Value: "true"},
{Name: "TS_DEST_IP", Value: "10.20.30.40"}, {Name: "TS_DEST_IP", Value: "10.20.30.40"},

@ -97,7 +97,6 @@ func printReport(dm *tailcfg.DERPMap, report *netcheck.Report) error {
var err error var err error
switch netcheckArgs.format { switch netcheckArgs.format {
case "": case "":
break
case "json": case "json":
j, err = json.MarshalIndent(report, "", "\t") j, err = json.MarshalIndent(report, "", "\t")
case "json-line": case "json-line":

@ -405,7 +405,7 @@ func DisabledEtcAptSource() bool {
return false return false
} }
mod := fi.ModTime() mod := fi.ModTime()
if c, ok := etcAptSrcCache.Load().(etcAptSrcResult); ok && c.mod == mod { if c, ok := etcAptSrcCache.Load().(etcAptSrcResult); ok && c.mod.Equal(mod) {
return c.disabled return c.disabled
} }
f, err := os.Open(path) f, err := os.Open(path)

@ -243,7 +243,7 @@ func TestNextPeerExpiry(t *testing.T) {
em := newExpiryManager(t.Logf) em := newExpiryManager(t.Logf)
em.timeNow = func() time.Time { return now } em.timeNow = func() time.Time { return now }
got := em.nextPeerExpiry(tt.netmap, now) got := em.nextPeerExpiry(tt.netmap, now)
if got != tt.want { if !got.Equal(tt.want) {
t.Errorf("got %q, want %q", got.Format(time.RFC3339), tt.want.Format(time.RFC3339)) t.Errorf("got %q, want %q", got.Format(time.RFC3339), tt.want.Format(time.RFC3339))
} else if !got.IsZero() && got.Before(now) { } else if !got.IsZero() && got.Before(now) {
t.Errorf("unexpectedly got expiry %q before now %q", got.Format(time.RFC3339), now.Format(time.RFC3339)) t.Errorf("unexpectedly got expiry %q before now %q", got.Format(time.RFC3339), now.Format(time.RFC3339))
@ -269,7 +269,7 @@ func TestNextPeerExpiry(t *testing.T) {
} }
got := em.nextPeerExpiry(nm, now) got := em.nextPeerExpiry(nm, now)
want := now.Add(30 * time.Second) want := now.Add(30 * time.Second)
if got != want { if !got.Equal(want) {
t.Errorf("got %q, want %q", got.Format(time.RFC3339), want.Format(time.RFC3339)) t.Errorf("got %q, want %q", got.Format(time.RFC3339), want.Format(time.RFC3339))
} }
}) })

@ -438,7 +438,7 @@ func (b *LocalBackend) SetComponentDebugLogging(component string, until time.Tim
// unchanged when the timer actually fires. // unchanged when the timer actually fires.
b.mu.Lock() b.mu.Lock()
defer b.mu.Unlock() defer b.mu.Unlock()
if ls := b.componentLogUntil[component]; ls.until == until { if ls := b.componentLogUntil[component]; ls.until.Equal(until) {
setEnabled(false) setEnabled(false)
b.logf("debugging logging for component %q disabled (by timer)", component) b.logf("debugging logging for component %q disabled (by timer)", component)
} }

@ -17,7 +17,6 @@ import (
"net/url" "net/url"
"os" "os"
"path" "path"
pathpkg "path"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
@ -420,19 +419,19 @@ func (b *LocalBackend) getServeHandler(r *http.Request) (_ ipn.HTTPHandlerView,
if h, ok := wsc.Handlers().GetOk(r.URL.Path); ok { if h, ok := wsc.Handlers().GetOk(r.URL.Path); ok {
return h, r.URL.Path, true return h, r.URL.Path, true
} }
path := path.Clean(r.URL.Path) pth := path.Clean(r.URL.Path)
for { for {
withSlash := path + "/" withSlash := pth + "/"
if h, ok := wsc.Handlers().GetOk(withSlash); ok { if h, ok := wsc.Handlers().GetOk(withSlash); ok {
return h, withSlash, true return h, withSlash, true
} }
if h, ok := wsc.Handlers().GetOk(path); ok { if h, ok := wsc.Handlers().GetOk(pth); ok {
return h, path, true return h, pth, true
} }
if path == "/" { if pth == "/" {
return z, "", false return z, "", false
} }
path = pathpkg.Dir(path) pth = path.Dir(pth)
} }
} }

@ -22,7 +22,6 @@ import (
"time" "time"
miekdns "github.com/miekg/dns" miekdns "github.com/miekg/dns"
"golang.org/x/net/dns/dnsmessage"
dns "golang.org/x/net/dns/dnsmessage" dns "golang.org/x/net/dns/dnsmessage"
"tailscale.com/net/netaddr" "tailscale.com/net/netaddr"
"tailscale.com/net/tsdial" "tailscale.com/net/tsdial"
@ -1121,15 +1120,15 @@ func TestHandleExitNodeDNSQueryWithNetPkg(t *testing.T) {
t.Run("no_such_host", func(t *testing.T) { t.Run("no_such_host", func(t *testing.T) {
res, err := handleExitNodeDNSQueryWithNetPkg(context.Background(), t.Logf, backResolver, &response{ res, err := handleExitNodeDNSQueryWithNetPkg(context.Background(), t.Logf, backResolver, &response{
Header: dnsmessage.Header{ Header: dns.Header{
ID: 123, ID: 123,
Response: true, Response: true,
OpCode: 0, // query OpCode: 0, // query
}, },
Question: dnsmessage.Question{ Question: dns.Question{
Name: dnsmessage.MustNewName("nx-domain.test."), Name: dns.MustNewName("nx-domain.test."),
Type: dnsmessage.TypeA, Type: dns.TypeA,
Class: dnsmessage.ClassINET, Class: dns.ClassINET,
}, },
}) })
if err != nil { if err != nil {
@ -1156,74 +1155,74 @@ func TestHandleExitNodeDNSQueryWithNetPkg(t *testing.T) {
} }
tests := []struct { tests := []struct {
Type dnsmessage.Type Type dns.Type
Name string Name string
Check func(t testing.TB, got []byte) Check func(t testing.TB, got []byte)
}{ }{
{ {
Type: dnsmessage.TypeA, Type: dns.TypeA,
Name: "one-a.test.", Name: "one-a.test.",
Check: matchPacked("\x00{\x84\x00\x00\x01\x00\x01\x00\x00\x00\x00\x05one-a\x04test\x00\x00\x01\x00\x01\x05one-a\x04test\x00\x00\x01\x00\x01\x00\x00\x02X\x00\x04\x01\x02\x03\x04"), Check: matchPacked("\x00{\x84\x00\x00\x01\x00\x01\x00\x00\x00\x00\x05one-a\x04test\x00\x00\x01\x00\x01\x05one-a\x04test\x00\x00\x01\x00\x01\x00\x00\x02X\x00\x04\x01\x02\x03\x04"),
}, },
{ {
Type: dnsmessage.TypeA, Type: dns.TypeA,
Name: "two-a.test.", Name: "two-a.test.",
Check: matchPacked("\x00{\x84\x00\x00\x01\x00\x02\x00\x00\x00\x00\x05two-a\x04test\x00\x00\x01\x00\x01\xc0\f\x00\x01\x00\x01\x00\x00\x02X\x00\x04\x01\x02\x03\x04\xc0\f\x00\x01\x00\x01\x00\x00\x02X\x00\x04\x05\x06\a\b"), Check: matchPacked("\x00{\x84\x00\x00\x01\x00\x02\x00\x00\x00\x00\x05two-a\x04test\x00\x00\x01\x00\x01\xc0\f\x00\x01\x00\x01\x00\x00\x02X\x00\x04\x01\x02\x03\x04\xc0\f\x00\x01\x00\x01\x00\x00\x02X\x00\x04\x05\x06\a\b"),
}, },
{ {
Type: dnsmessage.TypeAAAA, Type: dns.TypeAAAA,
Name: "one-aaaa.test.", Name: "one-aaaa.test.",
Check: matchPacked("\x00{\x84\x00\x00\x01\x00\x01\x00\x00\x00\x00\bone-aaaa\x04test\x00\x00\x1c\x00\x01\bone-aaaa\x04test\x00\x00\x1c\x00\x01\x00\x00\x02X\x00\x10\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02"), Check: matchPacked("\x00{\x84\x00\x00\x01\x00\x01\x00\x00\x00\x00\bone-aaaa\x04test\x00\x00\x1c\x00\x01\bone-aaaa\x04test\x00\x00\x1c\x00\x01\x00\x00\x02X\x00\x10\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02"),
}, },
{ {
Type: dnsmessage.TypeAAAA, Type: dns.TypeAAAA,
Name: "two-aaaa.test.", Name: "two-aaaa.test.",
Check: matchPacked("\x00{\x84\x00\x00\x01\x00\x02\x00\x00\x00\x00\btwo-aaaa\x04test\x00\x00\x1c\x00\x01\xc0\f\x00\x1c\x00\x01\x00\x00\x02X\x00\x10\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\xc0\f\x00\x1c\x00\x01\x00\x00\x02X\x00\x10\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04"), Check: matchPacked("\x00{\x84\x00\x00\x01\x00\x02\x00\x00\x00\x00\btwo-aaaa\x04test\x00\x00\x1c\x00\x01\xc0\f\x00\x1c\x00\x01\x00\x00\x02X\x00\x10\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\xc0\f\x00\x1c\x00\x01\x00\x00\x02X\x00\x10\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04"),
}, },
{ {
Type: dnsmessage.TypePTR, Type: dns.TypePTR,
Name: "4.3.2.1.in-addr.arpa.", Name: "4.3.2.1.in-addr.arpa.",
Check: matchPacked("\x00{\x84\x00\x00\x01\x00\x01\x00\x00\x00\x00\x014\x013\x012\x011\ain-addr\x04arpa\x00\x00\f\x00\x01\x014\x013\x012\x011\ain-addr\x04arpa\x00\x00\f\x00\x01\x00\x00\x02X\x00\t\x03foo\x03com\x00"), Check: matchPacked("\x00{\x84\x00\x00\x01\x00\x01\x00\x00\x00\x00\x014\x013\x012\x011\ain-addr\x04arpa\x00\x00\f\x00\x01\x014\x013\x012\x011\ain-addr\x04arpa\x00\x00\f\x00\x01\x00\x00\x02X\x00\t\x03foo\x03com\x00"),
}, },
{ {
Type: dnsmessage.TypeCNAME, Type: dns.TypeCNAME,
Name: "cname.test.", Name: "cname.test.",
Check: matchPacked("\x00{\x84\x00\x00\x01\x00\x01\x00\x00\x00\x00\x05cname\x04test\x00\x00\x05\x00\x01\x05cname\x04test\x00\x00\x05\x00\x01\x00\x00\x02X\x00\x10\nthe-target\x03foo\x00"), Check: matchPacked("\x00{\x84\x00\x00\x01\x00\x01\x00\x00\x00\x00\x05cname\x04test\x00\x00\x05\x00\x01\x05cname\x04test\x00\x00\x05\x00\x01\x00\x00\x02X\x00\x10\nthe-target\x03foo\x00"),
}, },
// No records of various types // No records of various types
{ {
Type: dnsmessage.TypeA, Type: dns.TypeA,
Name: "no-records.test.", Name: "no-records.test.",
Check: matchPacked("\x00{\x84\x03\x00\x01\x00\x00\x00\x00\x00\x00\nno-records\x04test\x00\x00\x01\x00\x01"), Check: matchPacked("\x00{\x84\x03\x00\x01\x00\x00\x00\x00\x00\x00\nno-records\x04test\x00\x00\x01\x00\x01"),
}, },
{ {
Type: dnsmessage.TypeAAAA, Type: dns.TypeAAAA,
Name: "no-records.test.", Name: "no-records.test.",
Check: matchPacked("\x00{\x84\x03\x00\x01\x00\x00\x00\x00\x00\x00\nno-records\x04test\x00\x00\x1c\x00\x01"), Check: matchPacked("\x00{\x84\x03\x00\x01\x00\x00\x00\x00\x00\x00\nno-records\x04test\x00\x00\x1c\x00\x01"),
}, },
{ {
Type: dnsmessage.TypeCNAME, Type: dns.TypeCNAME,
Name: "no-records.test.", Name: "no-records.test.",
Check: matchPacked("\x00{\x84\x03\x00\x01\x00\x00\x00\x00\x00\x00\nno-records\x04test\x00\x00\x05\x00\x01"), Check: matchPacked("\x00{\x84\x03\x00\x01\x00\x00\x00\x00\x00\x00\nno-records\x04test\x00\x00\x05\x00\x01"),
}, },
{ {
Type: dnsmessage.TypeSRV, Type: dns.TypeSRV,
Name: "no-records.test.", Name: "no-records.test.",
Check: matchPacked("\x00{\x84\x03\x00\x01\x00\x00\x00\x00\x00\x00\nno-records\x04test\x00\x00!\x00\x01"), Check: matchPacked("\x00{\x84\x03\x00\x01\x00\x00\x00\x00\x00\x00\nno-records\x04test\x00\x00!\x00\x01"),
}, },
{ {
Type: dnsmessage.TypeTXT, Type: dns.TypeTXT,
Name: "txt.test.", Name: "txt.test.",
Check: matchPacked("\x00{\x84\x00\x00\x01\x00\x03\x00\x00\x00\x00\x03txt\x04test\x00\x00\x10\x00\x01\x03txt\x04test\x00\x00\x10\x00\x01\x00\x00\x02X\x00\t\btxt1=one\x03txt\x04test\x00\x00\x10\x00\x01\x00\x00\x02X\x00\t\btxt2=two\x03txt\x04test\x00\x00\x10\x00\x01\x00\x00\x02X\x00\v\ntxt3=three"), Check: matchPacked("\x00{\x84\x00\x00\x01\x00\x03\x00\x00\x00\x00\x03txt\x04test\x00\x00\x10\x00\x01\x03txt\x04test\x00\x00\x10\x00\x01\x00\x00\x02X\x00\t\btxt1=one\x03txt\x04test\x00\x00\x10\x00\x01\x00\x00\x02X\x00\t\btxt2=two\x03txt\x04test\x00\x00\x10\x00\x01\x00\x00\x02X\x00\v\ntxt3=three"),
}, },
{ {
Type: dnsmessage.TypeSRV, Type: dns.TypeSRV,
Name: "srv.test.", Name: "srv.test.",
Check: matchPacked("\x00{\x84\x00\x00\x01\x00\x02\x00\x00\x00\x00\x03srv\x04test\x00\x00!\x00\x01\x03srv\x04test\x00\x00!\x00\x01\x00\x00\x02X\x00\x0f\x00\x01\x00\x02\x00\x03\x03foo\x03com\x00\x03srv\x04test\x00\x00!\x00\x01\x00\x00\x02X\x00\x0f\x00\x04\x00\x05\x00\x06\x03bar\x03com\x00"), Check: matchPacked("\x00{\x84\x00\x00\x01\x00\x02\x00\x00\x00\x00\x03srv\x04test\x00\x00!\x00\x01\x03srv\x04test\x00\x00!\x00\x01\x00\x00\x02X\x00\x0f\x00\x01\x00\x02\x00\x03\x03foo\x03com\x00\x03srv\x04test\x00\x00!\x00\x01\x00\x00\x02X\x00\x0f\x00\x04\x00\x05\x00\x06\x03bar\x03com\x00"),
}, },
{ {
Type: dnsmessage.TypeNS, Type: dns.TypeNS,
Name: "ns.test.", Name: "ns.test.",
Check: matchPacked("\x00{\x84\x00\x00\x01\x00\x02\x00\x00\x00\x00\x02ns\x04test\x00\x00\x02\x00\x01\x02ns\x04test\x00\x00\x02\x00\x01\x00\x00\x02X\x00\t\x03ns1\x03foo\x00\x02ns\x04test\x00\x00\x02\x00\x01\x00\x00\x02X\x00\t\x03ns2\x03bar\x00"), Check: matchPacked("\x00{\x84\x00\x00\x01\x00\x02\x00\x00\x00\x00\x02ns\x04test\x00\x00\x02\x00\x01\x02ns\x04test\x00\x00\x02\x00\x01\x00\x00\x02X\x00\t\x03ns1\x03foo\x00\x02ns\x04test\x00\x00\x02\x00\x01\x00\x00\x02X\x00\t\x03ns2\x03bar\x00"),
}, },
@ -1232,15 +1231,15 @@ func TestHandleExitNodeDNSQueryWithNetPkg(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
t.Run(fmt.Sprintf("%v_%v", tt.Type, strings.Trim(tt.Name, ".")), func(t *testing.T) { t.Run(fmt.Sprintf("%v_%v", tt.Type, strings.Trim(tt.Name, ".")), func(t *testing.T) {
got, err := handleExitNodeDNSQueryWithNetPkg(context.Background(), t.Logf, backResolver, &response{ got, err := handleExitNodeDNSQueryWithNetPkg(context.Background(), t.Logf, backResolver, &response{
Header: dnsmessage.Header{ Header: dns.Header{
ID: 123, ID: 123,
Response: true, Response: true,
OpCode: 0, // query OpCode: 0, // query
}, },
Question: dnsmessage.Question{ Question: dns.Question{
Name: dnsmessage.MustNewName(tt.Name), Name: dns.MustNewName(tt.Name),
Type: tt.Type, Type: tt.Type,
Class: dnsmessage.ClassINET, Class: dns.ClassINET,
}, },
}) })
if err != nil { if err != nil {

@ -3160,7 +3160,6 @@ func (c *Conn) goroutinesRunningLocked() bool {
if c.activeDerp != nil { if c.activeDerp != nil {
select { select {
case <-c.derpStarted: case <-c.derpStarted:
break
default: default:
return true return true
} }

Loading…
Cancel
Save