Browse Source

feature/featuretags: make CLI connection error diagnostics modular

Updates #12614

Change-Id: I09b8944166ee00910b402bcd5725cd7969e2c82c
Signed-off-by: Brad Fitzpatrick <[email protected]>
Brad Fitzpatrick 5 months ago
parent
commit
7bcab4ab28

+ 1 - 1
cmd/derper/depaware.txt

@@ -87,7 +87,7 @@ tailscale.com/cmd/derper dependencies: (generated by github.com/tailscale/depawa
         tailscale.com/disco                                          from tailscale.com/derp/derpserver
         tailscale.com/drive                                          from tailscale.com/client/local+
         tailscale.com/envknob                                        from tailscale.com/client/local+
-        tailscale.com/feature                                        from tailscale.com/tsweb
+        tailscale.com/feature                                        from tailscale.com/tsweb+
         tailscale.com/health                                         from tailscale.com/net/tlsdial+
         tailscale.com/hostinfo                                       from tailscale.com/net/netmon+
         tailscale.com/ipn                                            from tailscale.com/client/local

+ 10 - 0
cmd/tailscale/cli/cli.go

@@ -26,6 +26,7 @@ import (
 	"tailscale.com/client/local"
 	"tailscale.com/cmd/tailscale/cli/ffcomplete"
 	"tailscale.com/envknob"
+	"tailscale.com/feature"
 	"tailscale.com/paths"
 	"tailscale.com/util/slicesx"
 	"tailscale.com/version/distro"
@@ -555,3 +556,12 @@ func lastSeenFmt(t time.Time) string {
 		return fmt.Sprintf(", last seen %dd ago", int(d.Hours()/24))
 	}
 }
+
+var hookFixTailscaledConnectError feature.Hook[func(error) error] // for cliconndiag
+
+func fixTailscaledConnectError(origErr error) error {
+	if f, ok := hookFixTailscaledConnectError.GetOk(); ok {
+		return f(origErr)
+	}
+	return origErr
+}

+ 7 - 3
cmd/tailscale/cli/diag.go

@@ -1,7 +1,7 @@
 // Copyright (c) Tailscale Inc & AUTHORS
 // SPDX-License-Identifier: BSD-3-Clause
 
-//go:build linux || windows || darwin
+//go:build (linux || windows || darwin) && !ts_omit_cliconndiag
 
 package cli
 
@@ -16,11 +16,15 @@ import (
 	"tailscale.com/version/distro"
 )
 
-// fixTailscaledConnectError is called when the local tailscaled has
+func init() {
+	hookFixTailscaledConnectError.Set(fixTailscaledConnectErrorImpl)
+}
+
+// fixTailscaledConnectErrorImpl is called when the local tailscaled has
 // been determined unreachable due to the provided origErr value. It
 // returns either the same error or a better one to help the user
 // understand why tailscaled isn't running for their platform.
-func fixTailscaledConnectError(origErr error) error {
+func fixTailscaledConnectErrorImpl(origErr error) error {
 	procs, err := ps.Processes()
 	if err != nil {
 		return fmt.Errorf("failed to connect to local Tailscaled process and failed to enumerate processes while looking for it")

+ 0 - 15
cmd/tailscale/cli/diag_other.go

@@ -1,15 +0,0 @@
-// Copyright (c) Tailscale Inc & AUTHORS
-// SPDX-License-Identifier: BSD-3-Clause
-
-//go:build !linux && !windows && !darwin
-
-package cli
-
-import "fmt"
-
-// The github.com/mitchellh/go-ps package doesn't work on all platforms,
-// so just don't diagnose connect failures.
-
-func fixTailscaledConnectError(origErr error) error {
-	return fmt.Errorf("failed to connect to local tailscaled process (is it running?); got: %w", origErr)
-}

+ 0 - 1
cmd/tailscaled/depaware-minbox.txt

@@ -35,7 +35,6 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
         github.com/mdlayher/netlink/nltest                           from github.com/google/nftables
         github.com/mdlayher/sdnotify                                 from tailscale.com/util/systemd
      💣 github.com/mdlayher/socket                                   from github.com/mdlayher/netlink+
-        github.com/mitchellh/go-ps                                   from tailscale.com/safesocket
      💣 github.com/safchain/ethtool                                  from tailscale.com/net/netkernelconf
         github.com/tailscale/hujson                                  from tailscale.com/ipn/conffile
      💣 github.com/tailscale/netlink                                 from tailscale.com/util/linuxfw+

+ 13 - 0
feature/buildfeatures/feature_cliconndiag_disabled.go

@@ -0,0 +1,13 @@
+// Copyright (c) Tailscale Inc & AUTHORS
+// SPDX-License-Identifier: BSD-3-Clause
+
+// Code generated by gen.go; DO NOT EDIT.
+
+//go:build ts_omit_cliconndiag
+
+package buildfeatures
+
+// HasCLIConnDiag is whether the binary was built with support for modular feature "CLI connection error diagnostics".
+// Specifically, it's whether the binary was NOT built with the "ts_omit_cliconndiag" build tag.
+// It's a const so it can be used for dead code elimination.
+const HasCLIConnDiag = false

+ 13 - 0
feature/buildfeatures/feature_cliconndiag_enabled.go

@@ -0,0 +1,13 @@
+// Copyright (c) Tailscale Inc & AUTHORS
+// SPDX-License-Identifier: BSD-3-Clause
+
+// Code generated by gen.go; DO NOT EDIT.
+
+//go:build !ts_omit_cliconndiag
+
+package buildfeatures
+
+// HasCLIConnDiag is whether the binary was built with support for modular feature "CLI connection error diagnostics".
+// Specifically, it's whether the binary was NOT built with the "ts_omit_cliconndiag" build tag.
+// It's a const so it can be used for dead code elimination.
+const HasCLIConnDiag = true

+ 1 - 0
feature/featuretags/featuretags.go

@@ -96,6 +96,7 @@ var Features = map[FeatureTag]FeatureMeta{
 	"captiveportal": {"CaptivePortal", "Captive portal detection", nil},
 	"capture":       {"Capture", "Packet capture", nil},
 	"cli":           {"CLI", "embed the CLI into the tailscaled binary", nil},
+	"cliconndiag":   {"CLIConnDiag", "CLI connection error diagnostics", nil},
 	"completion":    {"Completion", "CLI shell completion", nil},
 	"dbus":          {"DBus", "Linux DBus support", nil},
 	"debugeventbus": {"DebugEventBus", "eventbus debug support", nil},

+ 6 - 2
safesocket/safesocket.go

@@ -11,6 +11,8 @@ import (
 	"net"
 	"runtime"
 	"time"
+
+	"tailscale.com/feature"
 )
 
 type closeable interface {
@@ -31,7 +33,8 @@ func ConnCloseWrite(c net.Conn) error {
 }
 
 var processStartTime = time.Now()
-var tailscaledProcExists = func() bool { return false } // set by safesocket_ps.go
+
+var tailscaledProcExists feature.Hook[func() bool]
 
 // tailscaledStillStarting reports whether tailscaled is probably
 // still starting up. That is, it reports whether the caller should
@@ -50,7 +53,8 @@ func tailscaledStillStarting() bool {
 	if d > 5*time.Second {
 		return false
 	}
-	return tailscaledProcExists()
+	f, ok := tailscaledProcExists.GetOk()
+	return ok && f()
 }
 
 // ConnectContext connects to tailscaled using a unix socket or named pipe.

+ 3 - 3
safesocket/safesocket_ps.go

@@ -1,7 +1,7 @@
 // Copyright (c) Tailscale Inc & AUTHORS
 // SPDX-License-Identifier: BSD-3-Clause
 
-//go:build (linux && !android) || windows || (darwin && !ios) || freebsd
+//go:build ((linux && !android) || windows || (darwin && !ios) || freebsd) && !ts_omit_cliconndiag
 
 package safesocket
 
@@ -12,7 +12,7 @@ import (
 )
 
 func init() {
-	tailscaledProcExists = func() bool {
+	tailscaledProcExists.Set(func() bool {
 		procs, err := ps.Processes()
 		if err != nil {
 			return false
@@ -30,5 +30,5 @@ func init() {
 			}
 		}
 		return false
-	}
+	})
 }