mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-25 11:05:45 +00:00
all: update to Go 1.20, use strings.CutPrefix/Suffix instead of our fork
Updates #7123 Updates #5309 Change-Id: I90bcd87a2fb85a91834a0dd4be6e03db08438672 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
623176ebc9
commit
b1248442c3
16
.github/workflows/static-analysis.yml
vendored
16
.github/workflows/static-analysis.yml
vendored
@ -45,14 +45,17 @@ jobs:
|
||||
vet:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.19
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v3
|
||||
go-version-file: go.mod
|
||||
|
||||
- name: Run go vet
|
||||
run: go vet ./...
|
||||
|
||||
- uses: k0kubun/action-slack@v2.0.0
|
||||
with:
|
||||
payload: |
|
||||
@ -79,13 +82,14 @@ jobs:
|
||||
goarch: 386
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.19
|
||||
go-version-file: go.mod
|
||||
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install staticcheck
|
||||
run: "GOBIN=~/.local/bin go install honnef.co/go/tools/cmd/staticcheck"
|
||||
|
@ -31,7 +31,7 @@
|
||||
# $ docker exec tailscaled tailscale status
|
||||
|
||||
|
||||
FROM golang:1.19-alpine AS build-env
|
||||
FROM golang:1.20-alpine AS build-env
|
||||
|
||||
WORKDIR /go/src/tailscale
|
||||
|
||||
|
8
Makefile
8
Makefile
@ -12,13 +12,17 @@ tidy:
|
||||
./tool/go mod tidy
|
||||
|
||||
updatedeps:
|
||||
./tool/go run github.com/tailscale/depaware --update \
|
||||
# depaware (via x/tools/go/packages) shells back to "go", so make sure the "go"
|
||||
# it finds in its $$PATH is the right one.
|
||||
PATH="$$(./tool/go env GOROOT)/bin:$$PATH" ./tool/go run github.com/tailscale/depaware --update \
|
||||
tailscale.com/cmd/tailscaled \
|
||||
tailscale.com/cmd/tailscale \
|
||||
tailscale.com/cmd/derper
|
||||
|
||||
depaware:
|
||||
./tool/go run github.com/tailscale/depaware --check \
|
||||
# depaware (via x/tools/go/packages) shells back to "go", so make sure the "go"
|
||||
# it finds in its $$PATH is the right one.
|
||||
PATH="$$(./tool/go env GOROOT)/bin:$$PATH" ./tool/go run github.com/tailscale/depaware --check \
|
||||
tailscale.com/cmd/tailscaled \
|
||||
tailscale.com/cmd/tailscale \
|
||||
tailscale.com/cmd/derper
|
||||
|
@ -37,7 +37,7 @@ not open source.
|
||||
|
||||
## Building
|
||||
|
||||
We always require the latest Go release, currently Go 1.19. (While we build
|
||||
We always require the latest Go release, currently Go 1.20. (While we build
|
||||
releases with our [Go fork](https://github.com/tailscale/go/), its use is not
|
||||
required.)
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
//go:build !go1.19
|
||||
//go:build !go1.20
|
||||
|
||||
package tailscale
|
||||
|
||||
func init() {
|
||||
you_need_Go_1_19_to_compile_Tailscale()
|
||||
you_need_Go_1_20_to_compile_Tailscale()
|
||||
}
|
||||
|
@ -82,7 +82,6 @@ tailscale.com/cmd/derper dependencies: (generated by github.com/tailscale/depawa
|
||||
tailscale.com/util/lineread from tailscale.com/hostinfo+
|
||||
tailscale.com/util/mak from tailscale.com/syncs
|
||||
tailscale.com/util/singleflight from tailscale.com/net/dnscache
|
||||
tailscale.com/util/strs from tailscale.com/hostinfo+
|
||||
tailscale.com/util/vizerror from tailscale.com/tsweb
|
||||
W 💣 tailscale.com/util/winutil from tailscale.com/hostinfo+
|
||||
tailscale.com/version from tailscale.com/derp+
|
||||
@ -97,7 +96,7 @@ tailscale.com/cmd/derper dependencies: (generated by github.com/tailscale/depawa
|
||||
golang.org/x/crypto/chacha20poly1305 from crypto/tls
|
||||
golang.org/x/crypto/cryptobyte from crypto/ecdsa+
|
||||
golang.org/x/crypto/cryptobyte/asn1 from crypto/ecdsa+
|
||||
golang.org/x/crypto/curve25519 from crypto/tls+
|
||||
golang.org/x/crypto/curve25519 from golang.org/x/crypto/nacl/box+
|
||||
golang.org/x/crypto/hkdf from crypto/tls
|
||||
golang.org/x/crypto/nacl/box from tailscale.com/types/key
|
||||
golang.org/x/crypto/nacl/secretbox from golang.org/x/crypto/nacl/box
|
||||
@ -135,6 +134,7 @@ tailscale.com/cmd/derper dependencies: (generated by github.com/tailscale/depawa
|
||||
crypto/cipher from crypto/aes+
|
||||
crypto/des from crypto/tls+
|
||||
crypto/dsa from crypto/x509
|
||||
crypto/ecdh from crypto/ecdsa+
|
||||
crypto/ecdsa from crypto/tls+
|
||||
crypto/ed25519 from crypto/tls+
|
||||
crypto/elliptic from crypto/ecdsa+
|
||||
|
@ -16,7 +16,6 @@
|
||||
"tailscale.com/derp/derphttp"
|
||||
"tailscale.com/types/key"
|
||||
"tailscale.com/types/logger"
|
||||
"tailscale.com/util/strs"
|
||||
)
|
||||
|
||||
func startMesh(s *derp.Server) error {
|
||||
@ -50,7 +49,7 @@ func startMeshWithHost(s *derp.Server, host string) error {
|
||||
}
|
||||
var d net.Dialer
|
||||
var r net.Resolver
|
||||
if base, ok := strs.CutSuffix(host, ".tailscale.com"); ok && port == "443" {
|
||||
if base, ok := strings.CutSuffix(host, ".tailscale.com"); ok && port == "443" {
|
||||
subCtx, cancel := context.WithTimeout(ctx, 2*time.Second)
|
||||
defer cancel()
|
||||
vpcHost := base + "-vpc.tailscale.com"
|
||||
|
@ -39,7 +39,6 @@
|
||||
"tailscale.com/types/key"
|
||||
"tailscale.com/types/logger"
|
||||
"tailscale.com/util/must"
|
||||
"tailscale.com/util/strs"
|
||||
)
|
||||
|
||||
var debugCmd = &ffcli.Command{
|
||||
@ -259,7 +258,7 @@ func runDebug(ctx context.Context, args []string) error {
|
||||
e.Encode(wfs)
|
||||
return nil
|
||||
}
|
||||
if name, ok := strs.CutPrefix(debugArgs.file, "delete:"); ok {
|
||||
if name, ok := strings.CutPrefix(debugArgs.file, "delete:"); ok {
|
||||
return localClient.DeleteWaitingFile(ctx, name)
|
||||
}
|
||||
rc, size, err := localClient.GetWaitingFile(ctx, debugArgs.file)
|
||||
|
@ -31,7 +31,6 @@
|
||||
"tailscale.com/net/tsaddr"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/util/quarantine"
|
||||
"tailscale.com/util/strs"
|
||||
"tailscale.com/version"
|
||||
)
|
||||
|
||||
@ -90,7 +89,7 @@ func runCp(ctx context.Context, args []string) error {
|
||||
return errors.New("usage: tailscale file cp <files...> <target>:")
|
||||
}
|
||||
files, target := args[:len(args)-1], args[len(args)-1]
|
||||
target, ok := strs.CutSuffix(target, ":")
|
||||
target, ok := strings.CutSuffix(target, ":")
|
||||
if !ok {
|
||||
return fmt.Errorf("final argument to 'tailscale file cp' must end in colon")
|
||||
}
|
||||
|
@ -34,7 +34,6 @@
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/logger"
|
||||
"tailscale.com/types/preftype"
|
||||
"tailscale.com/util/strs"
|
||||
"tailscale.com/version"
|
||||
"tailscale.com/version/distro"
|
||||
)
|
||||
@ -174,7 +173,7 @@ type upArgsT struct {
|
||||
|
||||
func (a upArgsT) getAuthKey() (string, error) {
|
||||
v := a.authKeyOrFile
|
||||
if file, ok := strs.CutPrefix(v, "file:"); ok {
|
||||
if file, ok := strings.CutPrefix(v, "file:"); ok {
|
||||
b, err := os.ReadFile(file)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
@ -115,7 +115,6 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep
|
||||
tailscale.com/util/must from tailscale.com/cmd/tailscale/cli
|
||||
tailscale.com/util/quarantine from tailscale.com/cmd/tailscale/cli
|
||||
tailscale.com/util/singleflight from tailscale.com/net/dnscache
|
||||
tailscale.com/util/strs from tailscale.com/hostinfo+
|
||||
💣 tailscale.com/util/winutil from tailscale.com/hostinfo+
|
||||
tailscale.com/version from tailscale.com/cmd/tailscale/cli+
|
||||
tailscale.com/version/distro from tailscale.com/cmd/tailscale/cli+
|
||||
@ -127,7 +126,7 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep
|
||||
golang.org/x/crypto/chacha20poly1305 from crypto/tls+
|
||||
golang.org/x/crypto/cryptobyte from crypto/ecdsa+
|
||||
golang.org/x/crypto/cryptobyte/asn1 from crypto/ecdsa+
|
||||
golang.org/x/crypto/curve25519 from crypto/tls+
|
||||
golang.org/x/crypto/curve25519 from golang.org/x/crypto/nacl/box+
|
||||
golang.org/x/crypto/hkdf from crypto/tls+
|
||||
golang.org/x/crypto/nacl/box from tailscale.com/types/key
|
||||
golang.org/x/crypto/nacl/secretbox from golang.org/x/crypto/nacl/box
|
||||
@ -170,6 +169,7 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep
|
||||
crypto/cipher from crypto/aes+
|
||||
crypto/des from crypto/tls+
|
||||
crypto/dsa from crypto/x509
|
||||
crypto/ecdh from crypto/ecdsa+
|
||||
crypto/ecdsa from crypto/tls+
|
||||
crypto/ed25519 from crypto/tls+
|
||||
crypto/elliptic from crypto/ecdsa+
|
||||
|
@ -302,7 +302,6 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
|
||||
tailscale.com/util/racebuild from tailscale.com/logpolicy
|
||||
tailscale.com/util/set from tailscale.com/health+
|
||||
tailscale.com/util/singleflight from tailscale.com/control/controlclient+
|
||||
tailscale.com/util/strs from tailscale.com/hostinfo+
|
||||
tailscale.com/util/systemd from tailscale.com/control/controlclient+
|
||||
tailscale.com/util/uniq from tailscale.com/wgengine/magicsock+
|
||||
tailscale.com/util/vizerror from tailscale.com/tsweb
|
||||
@ -331,7 +330,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
|
||||
golang.org/x/crypto/chacha20poly1305 from crypto/tls+
|
||||
golang.org/x/crypto/cryptobyte from crypto/ecdsa+
|
||||
golang.org/x/crypto/cryptobyte/asn1 from crypto/ecdsa+
|
||||
golang.org/x/crypto/curve25519 from crypto/tls+
|
||||
golang.org/x/crypto/curve25519 from github.com/tailscale/golang-x-crypto/ssh+
|
||||
LD golang.org/x/crypto/ed25519 from golang.org/x/crypto/ssh+
|
||||
golang.org/x/crypto/hkdf from crypto/tls+
|
||||
golang.org/x/crypto/nacl/box from tailscale.com/types/key
|
||||
@ -381,6 +380,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
|
||||
crypto/cipher from crypto/aes+
|
||||
crypto/des from crypto/tls+
|
||||
crypto/dsa from crypto/x509+
|
||||
crypto/ecdh from crypto/ecdsa+
|
||||
crypto/ecdsa from crypto/tls+
|
||||
crypto/ed25519 from crypto/tls+
|
||||
crypto/elliptic from crypto/ecdsa+
|
||||
|
@ -1,10 +1,10 @@
|
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
//go:build !go1.19
|
||||
//go:build !go1.20
|
||||
|
||||
package main
|
||||
|
||||
func init() {
|
||||
you_need_Go_1_19_to_compile_Tailscale()
|
||||
you_need_Go_1_20_to_compile_Tailscale()
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
"net/netip"
|
||||
"net/url"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@ -37,7 +38,6 @@
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/key"
|
||||
"tailscale.com/types/logger"
|
||||
"tailscale.com/util/strs"
|
||||
)
|
||||
|
||||
// Client is a DERP-over-HTTP client.
|
||||
@ -1028,7 +1028,7 @@ func (c *Client) closeForReconnect(brokenClient *derp.Client) {
|
||||
func parseMetaCert(certs []*x509.Certificate) (serverPub key.NodePublic, serverProtoVersion int) {
|
||||
for _, cert := range certs {
|
||||
// Look for derpkey prefix added by initMetacert() on the server side.
|
||||
if pubHex, ok := strs.CutPrefix(cert.Subject.CommonName, "derpkey"); ok {
|
||||
if pubHex, ok := strings.CutPrefix(cert.Subject.CommonName, "derpkey"); ok {
|
||||
var err error
|
||||
serverPub, err = key.ParseNodePublicUntyped(mem.S(pubHex))
|
||||
if err == nil && cert.SerialNumber.BitLen() <= 8 { // supports up to version 255
|
||||
|
@ -7,11 +7,11 @@
|
||||
"fmt"
|
||||
"net/netip"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"go4.org/mem"
|
||||
"tailscale.com/types/key"
|
||||
"tailscale.com/util/strs"
|
||||
)
|
||||
|
||||
func TestMarshalAndParse(t *testing.T) {
|
||||
@ -71,7 +71,7 @@ func TestMarshalAndParse(t *testing.T) {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
foo := []byte("foo")
|
||||
got := string(tt.m.AppendMarshal(foo))
|
||||
got, ok := strs.CutPrefix(got, "foo")
|
||||
got, ok := strings.CutPrefix(got, "foo")
|
||||
if !ok {
|
||||
t.Fatalf("didn't start with foo: got %q", got)
|
||||
}
|
||||
|
10
go.mod
10
go.mod
@ -1,6 +1,6 @@
|
||||
module tailscale.com
|
||||
|
||||
go 1.19
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
filippo.io/mkcert v1.4.3
|
||||
@ -77,11 +77,11 @@ require (
|
||||
golang.org/x/sys v0.4.0
|
||||
golang.org/x/term v0.4.0
|
||||
golang.org/x/time v0.0.0-20220609170525-579cf78fd858
|
||||
golang.org/x/tools v0.2.0
|
||||
golang.org/x/tools v0.4.1-0.20221208213631-3f74d914ae6d
|
||||
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2
|
||||
golang.zx2c4.com/wireguard/windows v0.5.3
|
||||
gvisor.dev/gvisor v0.0.0-20221203005347-703fd9b7fbc0
|
||||
honnef.co/go/tools v0.4.0-0.dev.0.20220517111757-f4a2f64ce238
|
||||
honnef.co/go/tools v0.4.0-0.dev.0.20230130122044-c30b15588105
|
||||
inet.af/peercred v0.0.0-20210906144145-0893ea02156a
|
||||
inet.af/wf v0.0.0-20220728202103-50d96caab2f6
|
||||
k8s.io/api v0.25.0
|
||||
@ -300,9 +300,9 @@ require (
|
||||
github.com/yeya24/promlinter v0.1.0 // indirect
|
||||
go.uber.org/atomic v1.7.0 // indirect
|
||||
go.uber.org/multierr v1.6.0 // indirect
|
||||
golang.org/x/exp/typeparams v0.0.0-20220328175248-053ad81199eb // indirect
|
||||
golang.org/x/exp/typeparams v0.0.0-20221208152030-732eee02a75a // indirect
|
||||
golang.org/x/image v0.0.0-20201208152932-35266b937fa6 // indirect
|
||||
golang.org/x/mod v0.6.0 // indirect
|
||||
golang.org/x/mod v0.7.0 // indirect
|
||||
golang.org/x/text v0.6.0 // indirect
|
||||
gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
|
16
go.sum
16
go.sum
@ -1348,8 +1348,8 @@ golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMk
|
||||
golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=
|
||||
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db h1:D/cFflL63o2KSLJIwjlcIt8PR064j/xsmdEJL/YvY/o=
|
||||
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
||||
golang.org/x/exp/typeparams v0.0.0-20220328175248-053ad81199eb h1:fP6C8Xutcp5AlakmT/SkQot0pMicROAsEX7OfNPuG10=
|
||||
golang.org/x/exp/typeparams v0.0.0-20220328175248-053ad81199eb/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
|
||||
golang.org/x/exp/typeparams v0.0.0-20221208152030-732eee02a75a h1:Jw5wfR+h9mnIYH+OtGT2im5wV1YGGDora5vTv/aa5bE=
|
||||
golang.org/x/exp/typeparams v0.0.0-20221208152030-732eee02a75a/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.0.0-20201208152932-35266b937fa6 h1:nfeHNc1nAqecKCy2FCy4HY+soOOe5sDLJ/gZLbx6GYI=
|
||||
@ -1379,8 +1379,8 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
|
||||
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
|
||||
golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I=
|
||||
golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI=
|
||||
golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA=
|
||||
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@ -1719,8 +1719,8 @@ golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.6/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
|
||||
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
|
||||
golang.org/x/tools v0.1.8-0.20211102182255-bb4add04ddef/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
|
||||
golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE=
|
||||
golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
|
||||
golang.org/x/tools v0.4.1-0.20221208213631-3f74d914ae6d h1:9ZNWAi4CYhNv60mXGgAncgq7SGc5qa7C8VZV8Tg7Ggs=
|
||||
golang.org/x/tools v0.4.1-0.20221208213631-3f74d914ae6d/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@ -1926,8 +1926,8 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.6/go.mod h1:pyyisuGw24ruLjrr1ddx39WE0y9OooInRzEYLhQB2YY=
|
||||
honnef.co/go/tools v0.2.1/go.mod h1:lPVVZ2BS5TfnjLyizF7o7hv7j9/L+8cZY2hLyjP9cGY=
|
||||
honnef.co/go/tools v0.4.0-0.dev.0.20220517111757-f4a2f64ce238 h1:8Vr1KP9OTjoKQSSeLefzibQgDV4s2ujJElKHqMi7nsA=
|
||||
honnef.co/go/tools v0.4.0-0.dev.0.20220517111757-f4a2f64ce238/go.mod h1:DCQzo6aCmhYDJH+We7BIU38vNvVkaOKa6s57pewKdvI=
|
||||
honnef.co/go/tools v0.4.0-0.dev.0.20230130122044-c30b15588105 h1:2OzOQ+1scFmv2dt7x+wNxgikA/Rn2qKrvc/CJCVuAJM=
|
||||
honnef.co/go/tools v0.4.0-0.dev.0.20230130122044-c30b15588105/go.mod h1:36ZgoUOrqOk1GxwHhyryEkq8FQWkUO2xGuSMhUCcdvA=
|
||||
howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0=
|
||||
howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM=
|
||||
howett.net/plist v1.0.0/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g=
|
||||
|
@ -13,7 +13,6 @@
|
||||
"golang.org/x/sys/unix"
|
||||
"tailscale.com/types/ptr"
|
||||
"tailscale.com/util/lineread"
|
||||
"tailscale.com/util/strs"
|
||||
"tailscale.com/version/distro"
|
||||
)
|
||||
|
||||
@ -73,7 +72,7 @@ func linuxDeviceModel() string {
|
||||
|
||||
func getQnapQtsVersion(versionInfo string) string {
|
||||
for _, field := range strings.Fields(versionInfo) {
|
||||
if suffix, ok := strs.CutPrefix(field, "QTSFW_"); ok {
|
||||
if suffix, ok := strings.CutPrefix(field, "QTSFW_"); ok {
|
||||
return suffix
|
||||
}
|
||||
}
|
||||
|
@ -48,7 +48,6 @@
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/util/clientmetric"
|
||||
"tailscale.com/util/multierr"
|
||||
"tailscale.com/util/strs"
|
||||
"tailscale.com/wgengine"
|
||||
"tailscale.com/wgengine/filter"
|
||||
)
|
||||
@ -164,7 +163,7 @@ func (s *peerAPIServer) hasFilesWaiting() bool {
|
||||
if strings.HasSuffix(name, partialSuffix) {
|
||||
continue
|
||||
}
|
||||
if name, ok := strs.CutSuffix(name, deletedSuffix); ok { // for Windows + tests
|
||||
if name, ok := strings.CutSuffix(name, deletedSuffix); ok { // for Windows + tests
|
||||
// After we're done looping over files, then try
|
||||
// to delete this file. Don't do it proactively,
|
||||
// as the OS may return "foo.jpg.deleted" before "foo.jpg"
|
||||
@ -223,7 +222,7 @@ func (s *peerAPIServer) WaitingFiles() (ret []apitype.WaitingFile, err error) {
|
||||
if strings.HasSuffix(name, partialSuffix) {
|
||||
continue
|
||||
}
|
||||
if name, ok := strs.CutSuffix(name, deletedSuffix); ok { // for Windows + tests
|
||||
if name, ok := strings.CutSuffix(name, deletedSuffix); ok { // for Windows + tests
|
||||
if deleted == nil {
|
||||
deleted = map[string]bool{}
|
||||
}
|
||||
@ -946,7 +945,7 @@ func (h *peerAPIHandler) handlePeerPut(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
rawPath := r.URL.EscapedPath()
|
||||
suffix, ok := strs.CutPrefix(rawPath, "/v0/put/")
|
||||
suffix, ok := strings.CutPrefix(rawPath, "/v0/put/")
|
||||
if !ok {
|
||||
http.Error(w, "misconfigured internals", 500)
|
||||
return
|
||||
|
@ -10,6 +10,7 @@
|
||||
"math/rand"
|
||||
"net/netip"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"golang.org/x/exp/slices"
|
||||
@ -18,7 +19,6 @@
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/logger"
|
||||
"tailscale.com/util/clientmetric"
|
||||
"tailscale.com/util/strs"
|
||||
"tailscale.com/util/winutil"
|
||||
"tailscale.com/version"
|
||||
)
|
||||
@ -520,7 +520,7 @@ func newProfileManagerWithGOOS(store ipn.StateStore, logf logger.Logf, goos stri
|
||||
}
|
||||
}
|
||||
if pm.currentProfile == nil {
|
||||
if suf, ok := strs.CutPrefix(string(stateKey), "user-"); ok {
|
||||
if suf, ok := strings.CutPrefix(string(stateKey), "user-"); ok {
|
||||
pm.currentUserID = ipn.WindowsUserID(suf)
|
||||
}
|
||||
pm.NewProfile()
|
||||
|
@ -31,7 +31,6 @@
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/logger"
|
||||
"tailscale.com/util/mak"
|
||||
"tailscale.com/util/strs"
|
||||
"tailscale.com/version"
|
||||
)
|
||||
|
||||
@ -552,7 +551,7 @@ func expandProxyArg(s string) (targetURL string, insecureSkipVerify bool) {
|
||||
if strings.HasPrefix(s, "http://") || strings.HasPrefix(s, "https://") {
|
||||
return s, false
|
||||
}
|
||||
if rest, ok := strs.CutPrefix(s, "https+insecure://"); ok {
|
||||
if rest, ok := strings.CutPrefix(s, "https+insecure://"); ok {
|
||||
return "https://" + rest, true
|
||||
}
|
||||
if allNumeric(s) {
|
||||
|
@ -8,9 +8,9 @@
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"tailscale.com/ipn/ipnlocal"
|
||||
"tailscale.com/util/strs"
|
||||
)
|
||||
|
||||
func (h *Handler) serveCert(w http.ResponseWriter, r *http.Request) {
|
||||
@ -18,7 +18,7 @@ func (h *Handler) serveCert(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, "cert access denied", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
domain, ok := strs.CutPrefix(r.URL.Path, "/localapi/v0/cert/")
|
||||
domain, ok := strings.CutPrefix(r.URL.Path, "/localapi/v0/cert/")
|
||||
if !ok {
|
||||
http.Error(w, "internal handler config wired wrong", 500)
|
||||
return
|
||||
|
@ -43,7 +43,6 @@
|
||||
"tailscale.com/util/clientmetric"
|
||||
"tailscale.com/util/httpm"
|
||||
"tailscale.com/util/mak"
|
||||
"tailscale.com/util/strs"
|
||||
"tailscale.com/version"
|
||||
)
|
||||
|
||||
@ -213,7 +212,7 @@ func handlerForPath(urlPath string) (h localAPIHandler, ok bool) {
|
||||
if urlPath == "/" {
|
||||
return (*Handler).serveLocalAPIRoot, true
|
||||
}
|
||||
suff, ok := strs.CutPrefix(urlPath, "/localapi/v0/")
|
||||
suff, ok := strings.CutPrefix(urlPath, "/localapi/v0/")
|
||||
if !ok {
|
||||
// Currently all LocalAPI methods start with "/localapi/v0/" to signal
|
||||
// to people that they're not necessarily stable APIs. In practice we'll
|
||||
@ -886,7 +885,7 @@ func (h *Handler) serveFiles(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, "file access denied", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
suffix, ok := strs.CutPrefix(r.URL.EscapedPath(), "/localapi/v0/files/")
|
||||
suffix, ok := strings.CutPrefix(r.URL.EscapedPath(), "/localapi/v0/files/")
|
||||
if !ok {
|
||||
http.Error(w, "misconfigured", http.StatusInternalServerError)
|
||||
return
|
||||
@ -1008,7 +1007,7 @@ func (h *Handler) serveFilePut(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
upath, ok := strs.CutPrefix(r.URL.EscapedPath(), "/localapi/v0/file-put/")
|
||||
upath, ok := strings.CutPrefix(r.URL.EscapedPath(), "/localapi/v0/file-put/")
|
||||
if !ok {
|
||||
http.Error(w, "misconfigured", http.StatusInternalServerError)
|
||||
return
|
||||
@ -1448,7 +1447,7 @@ func (h *Handler) serveProfiles(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, "profiles access denied", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
suffix, ok := strs.CutPrefix(r.URL.EscapedPath(), "/localapi/v0/profiles/")
|
||||
suffix, ok := strings.CutPrefix(r.URL.EscapedPath(), "/localapi/v0/profiles/")
|
||||
if !ok {
|
||||
http.Error(w, "misconfigured", http.StatusInternalServerError)
|
||||
return
|
||||
|
@ -13,8 +13,6 @@
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"tailscale.com/util/strs"
|
||||
)
|
||||
|
||||
// dohOfIP maps from public DNS IPs to their DoH base URL.
|
||||
@ -82,7 +80,7 @@ func DoHIPsOfBase(dohBase string) []netip.Addr {
|
||||
if s := dohIPsOfBase[dohBase]; len(s) > 0 {
|
||||
return s
|
||||
}
|
||||
if hexStr, ok := strs.CutPrefix(dohBase, "https://dns.nextdns.io/"); ok {
|
||||
if hexStr, ok := strings.CutPrefix(dohBase, "https://dns.nextdns.io/"); ok {
|
||||
// The path is of the form /<profile-hex>[/<hostname>/<model>/<device id>...]
|
||||
// or /<profile-hex>?<query params>
|
||||
// but only the <profile-hex> is required. Ignore the rest:
|
||||
|
@ -20,7 +20,6 @@
|
||||
"strings"
|
||||
|
||||
"tailscale.com/util/dnsname"
|
||||
"tailscale.com/util/strs"
|
||||
)
|
||||
|
||||
// Path is the canonical location of resolv.conf.
|
||||
@ -69,7 +68,7 @@ func Parse(r io.Reader) (*Config, error) {
|
||||
line, _, _ = strings.Cut(line, "#") // remove any comments
|
||||
line = strings.TrimSpace(line)
|
||||
|
||||
if s, ok := strs.CutPrefix(line, "nameserver"); ok {
|
||||
if s, ok := strings.CutPrefix(line, "nameserver"); ok {
|
||||
nameserver := strings.TrimSpace(s)
|
||||
if len(nameserver) == len(s) {
|
||||
return nil, fmt.Errorf("missing space after \"nameserver\" in %q", line)
|
||||
@ -82,7 +81,7 @@ func Parse(r io.Reader) (*Config, error) {
|
||||
continue
|
||||
}
|
||||
|
||||
if s, ok := strs.CutPrefix(line, "search"); ok {
|
||||
if s, ok := strings.CutPrefix(line, "search"); ok {
|
||||
domains := strings.TrimSpace(s)
|
||||
if len(domains) == len(s) {
|
||||
// No leading space?!
|
||||
|
@ -33,7 +33,6 @@
|
||||
"tailscale.com/util/clientmetric"
|
||||
"tailscale.com/util/cloudenv"
|
||||
"tailscale.com/util/dnsname"
|
||||
"tailscale.com/util/strs"
|
||||
"tailscale.com/wgengine/monitor"
|
||||
)
|
||||
|
||||
@ -1215,7 +1214,7 @@ func (r *Resolver) respond(query []byte) ([]byte, error) {
|
||||
// unARPA maps from "4.4.8.8.in-addr.arpa." to "8.8.4.4", etc.
|
||||
func unARPA(a string) (ipStr string, ok bool) {
|
||||
const suf4 = ".in-addr.arpa."
|
||||
if s, ok := strs.CutSuffix(a, suf4); ok {
|
||||
if s, ok := strings.CutSuffix(a, suf4); ok {
|
||||
// Parse and reverse octets.
|
||||
ip, err := netip.ParseAddr(s)
|
||||
if err != nil || !ip.Is4() {
|
||||
|
@ -22,7 +22,6 @@
|
||||
"tailscale.com/net/stun"
|
||||
"tailscale.com/net/stun/stuntest"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/util/strs"
|
||||
)
|
||||
|
||||
func TestHairpinSTUN(t *testing.T) {
|
||||
@ -621,7 +620,7 @@ func TestLogConciseReport(t *testing.T) {
|
||||
var buf bytes.Buffer
|
||||
c := &Client{Logf: func(f string, a ...any) { fmt.Fprintf(&buf, f, a...) }}
|
||||
c.logConciseReport(tt.r, dm)
|
||||
if got, ok := strs.CutPrefix(buf.String(), "[v1] report: "); !ok {
|
||||
if got, ok := strings.CutPrefix(buf.String(), "[v1] report: "); !ok {
|
||||
t.Errorf("unexpected result.\n got: %#q\nwant: %#q\n", got, tt.want)
|
||||
}
|
||||
})
|
||||
|
@ -41,7 +41,6 @@
|
||||
"tailscale.com/tempfork/gliderlabs/ssh"
|
||||
"tailscale.com/types/logger"
|
||||
"tailscale.com/util/lineread"
|
||||
"tailscale.com/util/strs"
|
||||
"tailscale.com/version/distro"
|
||||
)
|
||||
|
||||
@ -653,7 +652,7 @@ func pathFromPAMEnvLine(line []byte, u *user.User) (path string) {
|
||||
return ""
|
||||
}
|
||||
rest := strings.TrimSpace(strings.TrimPrefix(string(line), "PATH"))
|
||||
if quoted, ok := strs.CutPrefix(rest, "DEFAULT="); ok {
|
||||
if quoted, ok := strings.CutPrefix(rest, "DEFAULT="); ok {
|
||||
if path, err := strconv.Unquote(quoted); err == nil {
|
||||
return expandDefaultPathTmpl(path, u)
|
||||
}
|
||||
|
@ -42,7 +42,6 @@
|
||||
"tailscale.com/util/cibuild"
|
||||
"tailscale.com/util/lineread"
|
||||
"tailscale.com/util/must"
|
||||
"tailscale.com/util/strs"
|
||||
"tailscale.com/version/distro"
|
||||
"tailscale.com/wgengine"
|
||||
)
|
||||
@ -286,7 +285,7 @@ func (ts *localState) WhoIs(ipp netip.AddrPort) (n *tailcfg.Node, u tailcfg.User
|
||||
|
||||
func (ts *localState) DoNoiseRequest(req *http.Request) (*http.Response, error) {
|
||||
rec := httptest.NewRecorder()
|
||||
k, ok := strs.CutPrefix(req.URL.Path, "/ssh-action/")
|
||||
k, ok := strings.CutPrefix(req.URL.Path, "/ssh-action/")
|
||||
if !ok {
|
||||
rec.WriteHeader(http.StatusNotFound)
|
||||
}
|
||||
|
@ -31,7 +31,6 @@
|
||||
"tailscale.com/metrics"
|
||||
"tailscale.com/net/tsaddr"
|
||||
"tailscale.com/types/logger"
|
||||
"tailscale.com/util/strs"
|
||||
"tailscale.com/util/vizerror"
|
||||
"tailscale.com/version"
|
||||
)
|
||||
@ -753,7 +752,7 @@ func structTypeSortedFields(t reflect.Type) []sortedStructField {
|
||||
// removed.
|
||||
func removeTypePrefixes(s string) string {
|
||||
for _, prefix := range prefixesToTrim {
|
||||
if trimmed, ok := strs.CutPrefix(s, prefix); ok {
|
||||
if trimmed, ok := strings.CutPrefix(s, prefix); ok {
|
||||
return trimmed
|
||||
}
|
||||
}
|
||||
|
@ -1001,11 +1001,11 @@ func FuzzTime(f *testing.F) {
|
||||
) {
|
||||
t1 := time.Unix(s1, ns1)
|
||||
if loc1 {
|
||||
t1.In(time.FixedZone(name1, off1))
|
||||
_ = t1.In(time.FixedZone(name1, off1))
|
||||
}
|
||||
t2 := time.Unix(s2, ns2)
|
||||
if loc2 {
|
||||
t2.In(time.FixedZone(name2, off2))
|
||||
_ = t2.In(time.FixedZone(name2, off2))
|
||||
}
|
||||
got := Hash(&t1) == Hash(&t2)
|
||||
want := t1.Format(time.RFC3339Nano) == t2.Format(time.RFC3339Nano)
|
||||
|
@ -1,35 +0,0 @@
|
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
// Package strs contains string-related utility funcs.
|
||||
package strs
|
||||
|
||||
import "strings"
|
||||
|
||||
// CutPrefix returns s without the provided leading prefix string
|
||||
// and reports whether it found the prefix.
|
||||
// If s doesn't start with prefix, CutPrefix returns s, false.
|
||||
// If prefix is the empty string, CutPrefix returns s, true.
|
||||
//
|
||||
// TODO: remove this once Go 1.20 is out with it.
|
||||
// See https://github.com/tailscale/tailscale/issues/5309
|
||||
func CutPrefix(s, prefix string) (after string, found bool) {
|
||||
if !strings.HasPrefix(s, prefix) {
|
||||
return s, false
|
||||
}
|
||||
return s[len(prefix):], true
|
||||
}
|
||||
|
||||
// CutSuffix returns s without the provided ending suffix string
|
||||
// and reports whether it found the suffix.
|
||||
// If s doesn't end with suffix, CutSuffix returns s, false.
|
||||
// If suffix is the empty string, CutSuffix returns s, true.
|
||||
//
|
||||
// See https://github.com/tailscale/tailscale/issues/5309
|
||||
// TODO: remove this once Go 1.20 is out with it.
|
||||
func CutSuffix(s, suffix string) (before string, found bool) {
|
||||
if !strings.HasSuffix(s, suffix) {
|
||||
return s, false
|
||||
}
|
||||
return s[:len(s)-len(suffix)], true
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package strs
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestCut(t *testing.T) {
|
||||
tests := []struct {
|
||||
fn func(string, string) (string, bool)
|
||||
in1, in2 string
|
||||
want string
|
||||
wantOK bool
|
||||
}{
|
||||
{CutPrefix, "foo", "fo", "o", true},
|
||||
{CutPrefix, "bar", "fo", "bar", false},
|
||||
{CutSuffix, "foo", "o", "fo", true},
|
||||
{CutSuffix, "bar", "fo", "bar", false},
|
||||
}
|
||||
for i, tt := range tests {
|
||||
got, gotOK := tt.fn(tt.in1, tt.in2)
|
||||
if got != tt.want {
|
||||
t.Errorf("%d. got %q; want %q", i, got, tt.want)
|
||||
}
|
||||
if gotOK != tt.wantOK {
|
||||
t.Errorf("%d. got %v; want %v", i, gotOK, tt.wantOK)
|
||||
}
|
||||
}
|
||||
}
|
@ -14,8 +14,6 @@
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"tailscale.com/util/strs"
|
||||
)
|
||||
|
||||
// CmdName returns either the base name of the current binary
|
||||
@ -42,7 +40,7 @@ func cmdName(exe string) string {
|
||||
// v is like:
|
||||
// "path\ttailscale.com/cmd/tailscale\nmod\ttailscale.com\t(devel)\t\ndep\tgithub.com/apenwarr/fixconsole\tv0.0.0-20191012055117-5a9f6489cc29\th1:muXWUcay7DDy1/hEQWrYlBy+g0EuwT70sBHg65SeUc4=\ndep\tgithub....
|
||||
for _, line := range strings.Split(info, "\n") {
|
||||
if goPkg, ok := strs.CutPrefix(line, "path\t"); ok { // like "tailscale.com/cmd/tailscale"
|
||||
if goPkg, ok := strings.CutPrefix(line, "path\t"); ok { // like "tailscale.com/cmd/tailscale"
|
||||
ret = path.Base(goPkg) // goPkg is always forward slashes; use path, not filepath
|
||||
break
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user