Browse Source

client/tailscale, cmd/tailscale/cli: move version mismatch check to CLI

So people can use the package for whois checks etc without version
skew errors.

The earlier change faa891c1f2ff759f4e5cbc158f310b3201d91b59 for #1905
was a bit too aggressive.

Fixes #2757

Signed-off-by: Brad Fitzpatrick <[email protected]>
Brad Fitzpatrick 4 years ago
parent
commit
3c8ca4b357
2 changed files with 19 additions and 3 deletions
  1. 11 3
      client/tailscale/tailscale.go
  2. 8 0
      cmd/tailscale/cli/cli.go

+ 11 - 3
client/tailscale/tailscale.go

@@ -17,7 +17,6 @@ import (
 	"net"
 	"net/http"
 	"net/url"
-	"os"
 	"strconv"
 	"strings"
 	"time"
@@ -86,6 +85,15 @@ func bestError(err error, body []byte) error {
 	return err
 }
 
+var onVersionMismatch func(clientVer, serverVer string)
+
+// SetVersionMismatchHandler sets f as the version mismatch handler
+// to be called when the client (the current process) has a version
+// number that doesn't match the server's declared version.
+func SetVersionMismatchHandler(f func(clientVer, serverVer string)) {
+	onVersionMismatch = f
+}
+
 func send(ctx context.Context, method, path string, wantStatus int, body io.Reader) ([]byte, error) {
 	req, err := http.NewRequestWithContext(ctx, method, "http://local-tailscaled.sock"+path, body)
 	if err != nil {
@@ -96,8 +104,8 @@ func send(ctx context.Context, method, path string, wantStatus int, body io.Read
 		return nil, err
 	}
 	defer res.Body.Close()
-	if server := res.Header.Get("Tailscale-Version"); server != version.Long {
-		fmt.Fprintf(os.Stderr, "Warning: client version %q != tailscaled server version %q\n", version.Long, server)
+	if server := res.Header.Get("Tailscale-Version"); server != "" && server != version.Long && onVersionMismatch != nil {
+		onVersionMismatch(version.Long, server)
 	}
 	slurp, err := ioutil.ReadAll(res.Body)
 	if err != nil {

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

@@ -19,6 +19,7 @@ import (
 	"runtime"
 	"strconv"
 	"strings"
+	"sync"
 	"syscall"
 	"text/tabwriter"
 
@@ -82,6 +83,13 @@ func Run(args []string) error {
 		args = []string{"version"}
 	}
 
+	var warnOnce sync.Once
+	tailscale.SetVersionMismatchHandler(func(clientVer, serverVer string) {
+		warnOnce.Do(func() {
+			fmt.Fprintf(os.Stderr, "Warning: client version %q != tailscaled server version %q\n", clientVer, serverVer)
+		})
+	})
+
 	rootfs := flag.NewFlagSet("tailscale", flag.ExitOnError)
 	rootfs.StringVar(&rootArgs.socket, "socket", paths.DefaultTailscaledSocket(), "path to tailscaled's unix socket")