From 2048e9e13686a73d48a653d13d82089cd51d2488 Mon Sep 17 00:00:00 2001
From: Juan Font Alonso <juanfontalonso@gmail.com>
Date: Mon, 27 Sep 2021 16:26:18 +0200
Subject: [PATCH 1/3] Added version checker on startup

---
 Makefile                     |  2 +-
 cmd/headscale/cli/version.go |  9 +++++----
 cmd/headscale/headscale.go   | 15 +++++++++++++++
 go.mod                       |  5 ++++-
 go.sum                       |  7 +++++++
 5 files changed, 32 insertions(+), 6 deletions(-)

diff --git a/Makefile b/Makefile
index 482ae868..755253fc 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
 version = $(shell ./scripts/version-at-commit.sh)
 
 build:
-	go build -ldflags "-s -w -X github.com/juanfont/headscale/cmd/headscale/cli.version=$(version)" cmd/headscale/headscale.go
+	go build -ldflags "-s -w -X github.com/juanfont/headscale/cmd/headscale/cli.Version=$(version)" cmd/headscale/headscale.go
 
 dev: lint test build
 
diff --git a/cmd/headscale/cli/version.go b/cmd/headscale/cli/version.go
index 5de2c672..c018b142 100644
--- a/cmd/headscale/cli/version.go
+++ b/cmd/headscale/cli/version.go
@@ -2,11 +2,12 @@ package cli
 
 import (
 	"fmt"
-	"github.com/spf13/cobra"
 	"strings"
+
+	"github.com/spf13/cobra"
 )
 
-var version = "dev"
+var Version = "dev"
 
 func init() {
 	rootCmd.AddCommand(versionCmd)
@@ -19,9 +20,9 @@ var versionCmd = &cobra.Command{
 	Run: func(cmd *cobra.Command, args []string) {
 		o, _ := cmd.Flags().GetString("output")
 		if strings.HasPrefix(o, "json") {
-			JsonOutput(map[string]string{"version": version}, nil, o)
+			JsonOutput(map[string]string{"version": Version}, nil, o)
 			return
 		}
-		fmt.Println(version)
+		fmt.Println(Version)
 	},
 }
diff --git a/cmd/headscale/headscale.go b/cmd/headscale/headscale.go
index e4334e4f..07cfa8f4 100644
--- a/cmd/headscale/headscale.go
+++ b/cmd/headscale/headscale.go
@@ -1,6 +1,7 @@
 package main
 
 import (
+	"fmt"
 	"os"
 	"time"
 
@@ -9,6 +10,7 @@ import (
 	"github.com/rs/zerolog"
 	"github.com/rs/zerolog/log"
 	"github.com/spf13/viper"
+	"github.com/tcnksm/go-latest"
 )
 
 func main() {
@@ -38,6 +40,19 @@ func main() {
 		NoColor:    !colors,
 	})
 
+	githubTag := &latest.GithubTag{
+		Owner:      "juanfont",
+		Repository: "headscale",
+	}
+
+	if cli.Version != "dev" {
+		res, _ := latest.Check(githubTag, cli.Version)
+		if res.Outdated {
+			fmt.Printf("An updated version of Headscale has been found (%s vs. your current %s). Check it out https://github.com/juanfont/headscale/releases\n",
+				res.Current, cli.Version)
+		}
+	}
+
 	err := cli.LoadConfig("")
 	if err != nil {
 		log.Fatal().Err(err)
diff --git a/go.mod b/go.mod
index 390fac91..51acff89 100644
--- a/go.mod
+++ b/go.mod
@@ -10,8 +10,10 @@ require (
 	github.com/docker/cli v20.10.8+incompatible // indirect
 	github.com/docker/docker v20.10.8+incompatible // indirect
 	github.com/efekarakus/termcolor v1.0.1
-	github.com/gofrs/uuid v4.0.0+incompatible // indirect
 	github.com/gin-gonic/gin v1.7.4
+	github.com/gofrs/uuid v4.0.0+incompatible // indirect
+	github.com/google/go-github v17.0.0+incompatible // indirect
+	github.com/google/go-querystring v1.1.0 // indirect
 	github.com/hako/durafmt v0.0.0-20210608085754-5c1018a4e16b
 	github.com/klauspost/compress v1.13.5
 	github.com/lib/pq v1.10.3 // indirect
@@ -24,6 +26,7 @@ require (
 	github.com/spf13/viper v1.8.1
 	github.com/stretchr/testify v1.7.0
 	github.com/tailscale/hujson v0.0.0-20210818175511-7360507a6e88
+	github.com/tcnksm/go-latest v0.0.0-20170313132115-e3007ae9052e // indirect
 	github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
 	golang.org/x/crypto v0.0.0-20210817164053-32db794688a5
 	golang.org/x/net v0.0.0-20210913180222-943fd674d43e // indirect
diff --git a/go.sum b/go.sum
index ac934dbe..1d97f18f 100644
--- a/go.sum
+++ b/go.sum
@@ -338,6 +338,10 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
 github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
 github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
+github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
+github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
+github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
 github.com/google/goexpect v0.0.0-20210430020637-ab937bf7fd6f/go.mod h1:n1ej5+FqyEytMt/mugVDZLIiqTMO+vsrgY+kM6ohzN0=
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 github.com/google/goterm v0.0.0-20190703233501-fc88cf888a3f/go.mod h1:nOFQdrUlIlx6M6ODdSpBj1NVA+VgLC6kmw60mkw34H4=
@@ -405,6 +409,7 @@ github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerX
 github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
 github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
 github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
+github.com/hashicorp/go-version v1.2.0 h1:3vNe/fWF5CBgRIguda1meWhsZHy3m8gCJ5wx+dIzX/E=
 github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
 github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
 github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
@@ -871,6 +876,8 @@ github.com/tailscale/hujson v0.0.0-20200924210142-dde312d0d6a2/go.mod h1:STqf+YV
 github.com/tailscale/hujson v0.0.0-20210818175511-7360507a6e88 h1:q5Sxx79nhG4xWsYEJBlLdqo1hNhUV31/NhA4qQ1SKAY=
 github.com/tailscale/hujson v0.0.0-20210818175511-7360507a6e88/go.mod h1:iTDXJsA6A2wNNjurgic2rk+is6uzU4U2NLm4T+edr6M=
 github.com/tcnksm/go-httpstat v0.2.0/go.mod h1:s3JVJFtQxtBEBC9dwcdTTXS9xFnM3SXAZwPG41aurT8=
+github.com/tcnksm/go-latest v0.0.0-20170313132115-e3007ae9052e h1:IWllFTiDjjLIf2oeKxpIUmtiDV5sn71VgeQgg6vcE7k=
+github.com/tcnksm/go-latest v0.0.0-20170313132115-e3007ae9052e/go.mod h1:d7u6HkTYKSv5m6MCKkOQlHwaShTMl3HjqSGW3XtVhXM=
 github.com/tdakkota/asciicheck v0.0.0-20200416190851-d7f85be797a2/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM=
 github.com/tdakkota/asciicheck v0.0.0-20200416200610-e657995f937b/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM=
 github.com/tetafro/godot v1.3.0/go.mod h1:/7NLHhv08H1+8DNj0MElpAACw1ajsCuf3TKNQxA5S+0=

From 7c37086dd68c9a33df43ac681a593fb8827d2b3d Mon Sep 17 00:00:00 2001
From: Juan Font Alonso <juanfontalonso@gmail.com>
Date: Mon, 27 Sep 2021 17:12:31 +0200
Subject: [PATCH 2/3] Handle lack of internet

---
 cmd/headscale/headscale.go | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/cmd/headscale/headscale.go b/cmd/headscale/headscale.go
index 07cfa8f4..bc8f515b 100644
--- a/cmd/headscale/headscale.go
+++ b/cmd/headscale/headscale.go
@@ -46,8 +46,8 @@ func main() {
 	}
 
 	if cli.Version != "dev" {
-		res, _ := latest.Check(githubTag, cli.Version)
-		if res.Outdated {
+		res, err := latest.Check(githubTag, cli.Version)
+		if err == nil && res.Outdated {
 			fmt.Printf("An updated version of Headscale has been found (%s vs. your current %s). Check it out https://github.com/juanfont/headscale/releases\n",
 				res.Current, cli.Version)
 		}

From a6adcdafa9d0289338d5e2808a4df5160431c5fc Mon Sep 17 00:00:00 2001
From: Juan Font Alonso <juanfontalonso@gmail.com>
Date: Mon, 27 Sep 2021 17:24:34 +0200
Subject: [PATCH 3/3] Added switch to disable the update checks

---
 cmd/headscale/headscale.go | 28 +++++++++++++++-------------
 1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/cmd/headscale/headscale.go b/cmd/headscale/headscale.go
index bc8f515b..f815001e 100644
--- a/cmd/headscale/headscale.go
+++ b/cmd/headscale/headscale.go
@@ -3,6 +3,7 @@ package main
 import (
 	"fmt"
 	"os"
+	"runtime"
 	"time"
 
 	"github.com/efekarakus/termcolor"
@@ -40,19 +41,6 @@ func main() {
 		NoColor:    !colors,
 	})
 
-	githubTag := &latest.GithubTag{
-		Owner:      "juanfont",
-		Repository: "headscale",
-	}
-
-	if cli.Version != "dev" {
-		res, err := latest.Check(githubTag, cli.Version)
-		if err == nil && res.Outdated {
-			fmt.Printf("An updated version of Headscale has been found (%s vs. your current %s). Check it out https://github.com/juanfont/headscale/releases\n",
-				res.Current, cli.Version)
-		}
-	}
-
 	err := cli.LoadConfig("")
 	if err != nil {
 		log.Fatal().Err(err)
@@ -74,5 +62,19 @@ func main() {
 		zerolog.SetGlobalLevel(zerolog.DebugLevel)
 	}
 
+	if !viper.GetBool("disable_check_updates") {
+		if (runtime.GOOS == "linux" || runtime.GOOS == "darwin") && cli.Version != "dev" {
+			githubTag := &latest.GithubTag{
+				Owner:      "juanfont",
+				Repository: "headscale",
+			}
+			res, err := latest.Check(githubTag, cli.Version)
+			if err == nil && res.Outdated {
+				fmt.Printf("An updated version of Headscale has been found (%s vs. your current %s). Check it out https://github.com/juanfont/headscale/releases\n",
+					res.Current, cli.Version)
+			}
+		}
+	}
+
 	cli.Execute()
 }