From e1ce3a353de7d48c4ce4d2eb8736fe742385e002 Mon Sep 17 00:00:00 2001 From: Zoltan Papp Date: Mon, 30 Oct 2023 10:32:48 +0100 Subject: [PATCH] Feature/update check (#1232) Periodically fetch the latest available version, and the UI will shows a new menu for the download link. It checks both the daemon version and the UI version. --- .github/workflows/release.yml | 1 + .goreleaser_ui.yaml | 6 +- client/ui/client_ui.go | 145 ++++++++++++-- client/ui/connected.ico | Bin 110003 -> 0 bytes client/ui/connected.png | Bin 10290 -> 0 bytes client/ui/disconnected.ico | Bin 106176 -> 0 bytes client/ui/disconnected.png | Bin 6461 -> 0 bytes client/ui/netbird-systemtray-connected.ico | Bin 0 -> 4452 bytes client/ui/netbird-systemtray-connected.png | Bin 0 -> 7251 bytes client/ui/netbird-systemtray-default.ico | Bin 0 -> 2876 bytes client/ui/netbird-systemtray-default.png | Bin 0 -> 4938 bytes client/ui/netbird-systemtray-update-cloud.ico | Bin 0 -> 3647 bytes client/ui/netbird-systemtray-update-cloud.png | Bin 0 -> 5652 bytes client/ui/netbird-systemtray-update.ico | Bin 0 -> 4726 bytes client/ui/netbird-systemtray-update.png | Bin 0 -> 7521 bytes release_files/darwin-ui-installer.sh | 3 +- release_files/darwin_pkg/preinstall | 7 + version/update.go | 184 ++++++++++++++++++ version/update_test.go | 101 ++++++++++ version/url.go | 5 + version/url_darwin.go | 33 ++++ version/url_linux.go | 6 + version/url_windows.go | 19 ++ 23 files changed, 492 insertions(+), 18 deletions(-) delete mode 100644 client/ui/connected.ico delete mode 100644 client/ui/connected.png delete mode 100644 client/ui/disconnected.ico delete mode 100644 client/ui/disconnected.png create mode 100644 client/ui/netbird-systemtray-connected.ico create mode 100644 client/ui/netbird-systemtray-connected.png create mode 100644 client/ui/netbird-systemtray-default.ico create mode 100644 client/ui/netbird-systemtray-default.png create mode 100644 client/ui/netbird-systemtray-update-cloud.ico create mode 100644 client/ui/netbird-systemtray-update-cloud.png create mode 100644 client/ui/netbird-systemtray-update.ico create mode 100644 client/ui/netbird-systemtray-update.png create mode 100644 version/update.go create mode 100644 version/update_test.go create mode 100644 version/url.go create mode 100644 version/url_darwin.go create mode 100644 version/url_linux.go create mode 100644 version/url_windows.go diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3feefdd49c2..5833638c509 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -17,6 +17,7 @@ on: - 'release_files/**' - '**/Dockerfile' - '**/Dockerfile.*' + - 'client/ui/**' env: SIGN_PIPE_VER: "v0.0.9" diff --git a/.goreleaser_ui.yaml b/.goreleaser_ui.yaml index c6f7a7c3443..66a22ee34a2 100644 --- a/.goreleaser_ui.yaml +++ b/.goreleaser_ui.yaml @@ -54,7 +54,7 @@ nfpms: contents: - src: client/ui/netbird.desktop dst: /usr/share/applications/netbird.desktop - - src: client/ui/disconnected.png + - src: client/ui/netbird-systemtray-default.png dst: /usr/share/pixmaps/netbird.png dependencies: - netbird @@ -71,7 +71,7 @@ nfpms: contents: - src: client/ui/netbird.desktop dst: /usr/share/applications/netbird.desktop - - src: client/ui/disconnected.png + - src: client/ui/netbird-systemtray-default.png dst: /usr/share/pixmaps/netbird.png dependencies: - netbird @@ -91,4 +91,4 @@ uploads: mode: archive target: https://pkgs.wiretrustee.com/yum/{{ .Arch }}{{ if .Arm }}{{ .Arm }}{{ end }} username: dev@wiretrustee.com - method: PUT \ No newline at end of file + method: PUT diff --git a/client/ui/client_ui.go b/client/ui/client_ui.go index 9c7685db03d..e66d03d951e 100644 --- a/client/ui/client_ui.go +++ b/client/ui/client_ui.go @@ -15,8 +15,10 @@ import ( "runtime" "strconv" "strings" + "sync" "syscall" "time" + "unicode" "fyne.io/fyne/v2" "fyne.io/fyne/v2/app" @@ -74,18 +76,30 @@ func main() { } } -//go:embed connected.ico +//go:embed netbird-systemtray-connected.ico var iconConnectedICO []byte -//go:embed connected.png +//go:embed netbird-systemtray-connected.png var iconConnectedPNG []byte -//go:embed disconnected.ico +//go:embed netbird-systemtray-default.ico var iconDisconnectedICO []byte -//go:embed disconnected.png +//go:embed netbird-systemtray-default.png var iconDisconnectedPNG []byte +//go:embed netbird-systemtray-update.ico +var iconUpdateICO []byte + +//go:embed netbird-systemtray-update.png +var iconUpdatePNG []byte + +//go:embed netbird-systemtray-update-cloud.ico +var iconUpdateCloudICO []byte + +//go:embed netbird-systemtray-update-cloud.png +var iconUpdateCloudPNG []byte + type serviceClient struct { ctx context.Context addr string @@ -93,14 +107,20 @@ type serviceClient struct { icConnected []byte icDisconnected []byte + icUpdate []byte + icUpdateCloud []byte // systray menu items - mStatus *systray.MenuItem - mUp *systray.MenuItem - mDown *systray.MenuItem - mAdminPanel *systray.MenuItem - mSettings *systray.MenuItem - mQuit *systray.MenuItem + mStatus *systray.MenuItem + mUp *systray.MenuItem + mDown *systray.MenuItem + mAdminPanel *systray.MenuItem + mSettings *systray.MenuItem + mAbout *systray.MenuItem + mVersionUI *systray.MenuItem + mVersionDaemon *systray.MenuItem + mUpdate *systray.MenuItem + mQuit *systray.MenuItem // application with main windows. app fyne.App @@ -118,6 +138,11 @@ type serviceClient struct { managementURL string preSharedKey string adminURL string + + update *version.Update + daemonVersion string + updateIndicationLock sync.Mutex + isUpdateIconActive bool } // newServiceClient instance constructor @@ -130,14 +155,20 @@ func newServiceClient(addr string, a fyne.App, showSettings bool) *serviceClient app: a, showSettings: showSettings, + update: version.NewUpdate(), } if runtime.GOOS == "windows" { s.icConnected = iconConnectedICO s.icDisconnected = iconDisconnectedICO + s.icUpdate = iconUpdateICO + s.icUpdateCloud = iconUpdateCloudICO + } else { s.icConnected = iconConnectedPNG s.icDisconnected = iconDisconnectedPNG + s.icUpdate = iconUpdatePNG + s.icUpdateCloud = iconUpdateCloudPNG } if showSettings { @@ -328,19 +359,53 @@ func (s *serviceClient) updateStatus() error { return err } + s.updateIndicationLock.Lock() + defer s.updateIndicationLock.Unlock() + + var systrayIconState bool if status.Status == string(internal.StatusConnected) && !s.mUp.Disabled() { - systray.SetIcon(s.icConnected) + if !s.isUpdateIconActive { + systray.SetIcon(s.icConnected) + } systray.SetTooltip("NetBird (Connected)") s.mStatus.SetTitle("Connected") s.mUp.Disable() s.mDown.Enable() + systrayIconState = true } else if status.Status != string(internal.StatusConnected) && s.mUp.Disabled() { - systray.SetIcon(s.icDisconnected) + if !s.isUpdateIconActive { + systray.SetIcon(s.icDisconnected) + } systray.SetTooltip("NetBird (Disconnected)") s.mStatus.SetTitle("Disconnected") s.mDown.Disable() s.mUp.Enable() + systrayIconState = false + } + + // the updater struct notify by the upgrades available only, but if meanwhile the daemon has successfully + // updated must reset the mUpdate visibility state + if s.daemonVersion != status.DaemonVersion { + s.mUpdate.Hide() + s.daemonVersion = status.DaemonVersion + + s.isUpdateIconActive = s.update.SetDaemonVersion(status.DaemonVersion) + if !s.isUpdateIconActive { + if systrayIconState { + systray.SetIcon(s.icConnected) + s.mAbout.SetIcon(s.icConnected) + } else { + systray.SetIcon(s.icDisconnected) + s.mAbout.SetIcon(s.icDisconnected) + } + } + + daemonVersionTitle := normalizedVersion(s.daemonVersion) + s.mVersionDaemon.SetTitle(fmt.Sprintf("Daemon: %s", daemonVersionTitle)) + s.mVersionDaemon.SetTooltip(fmt.Sprintf("Daemon version: %s", daemonVersionTitle)) + s.mVersionDaemon.Show() } + return nil }, &backoff.ExponentialBackOff{ InitialInterval: time.Second, @@ -374,11 +439,24 @@ func (s *serviceClient) onTrayReady() { systray.AddSeparator() s.mSettings = systray.AddMenuItem("Settings", "Settings of the application") systray.AddSeparator() - v := systray.AddMenuItem("v"+version.NetbirdVersion(), "Client Version: "+version.NetbirdVersion()) - v.Disable() + + s.mAbout = systray.AddMenuItem("About", "About") + s.mAbout.SetIcon(s.icDisconnected) + versionString := normalizedVersion(version.NetbirdVersion()) + s.mVersionUI = s.mAbout.AddSubMenuItem(fmt.Sprintf("GUI: %s", versionString), fmt.Sprintf("GUI Version: %s", versionString)) + s.mVersionUI.Disable() + + s.mVersionDaemon = s.mAbout.AddSubMenuItem("", "") + s.mVersionDaemon.Disable() + s.mVersionDaemon.Hide() + + s.mUpdate = s.mAbout.AddSubMenuItem("Download latest version", "Download latest version") + s.mUpdate.Hide() + systray.AddSeparator() s.mQuit = systray.AddMenuItem("Quit", "Quit the client app") + s.update.SetOnUpdateListener(s.onUpdateAvailable) go func() { s.getSrvConfig() for { @@ -436,6 +514,11 @@ func (s *serviceClient) onTrayReady() { case <-s.mQuit.ClickedCh: systray.Quit() return + case <-s.mUpdate.ClickedCh: + err := openURL(version.DownloadUrl()) + if err != nil { + log.Errorf("%s", err) + } } if err != nil { log.Errorf("process connection: %v", err) @@ -444,6 +527,14 @@ func (s *serviceClient) onTrayReady() { }() } +func normalizedVersion(version string) string { + versionString := version + if unicode.IsDigit(rune(versionString[0])) { + versionString = fmt.Sprintf("v%s", versionString) + } + return versionString +} + func (s *serviceClient) onTrayExit() {} // getSrvClient connection to the service. @@ -504,6 +595,32 @@ func (s *serviceClient) getSrvConfig() { } } +func (s *serviceClient) onUpdateAvailable() { + s.updateIndicationLock.Lock() + defer s.updateIndicationLock.Unlock() + + s.mUpdate.Show() + s.mAbout.SetIcon(s.icUpdateCloud) + + s.isUpdateIconActive = true + systray.SetIcon(s.icUpdate) +} + +func openURL(url string) error { + var err error + switch runtime.GOOS { + case "windows": + err = exec.Command("rundll32", "url.dll,FileProtocolHandler", url).Start() + case "darwin": + err = exec.Command("open", url).Start() + case "linux": + err = exec.Command("xdg-open", url).Start() + default: + err = fmt.Errorf("unsupported platform") + } + return err +} + // checkPIDFile exists and return error, or write new. func checkPIDFile() error { pidFile := path.Join(os.TempDir(), "wiretrustee-ui.pid") diff --git a/client/ui/connected.ico b/client/ui/connected.ico deleted file mode 100644 index 3dd598fa70df6209567ef4613b08d4274b0ca8c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 110003 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 b2LSaA9%w(j9p>mQ0RevaIt$-sio^X6IH3q4 diff --git a/client/ui/connected.png b/client/ui/connected.png deleted file mode 100644 index 64b25ade12e36b1b1f8ca695f4fac45c38cf162a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10290 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 QuO&71k2Z{ED`d}jv3NLULD{gJTl*vu{%wiJF- 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 G=KlcAE9s5^ diff --git a/client/ui/netbird-systemtray-connected.ico b/client/ui/netbird-systemtray-connected.ico new file mode 100644 index 0000000000000000000000000000000000000000..621afce9fb2a65c34e68df372aaa6770ee98c8d0 GIT binary patch literal 4452 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 I7T)py1qRz*Pyhe` literal 0 HcmV?d00001 diff --git a/client/ui/netbird-systemtray-connected.png b/client/ui/netbird-systemtray-connected.png new file mode 100644 index 0000000000000000000000000000000000000000..c5878d0187e9a5151814a6dfb29e311e475110b4 GIT binary patch literal 7251 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 literal 0 HcmV?d00001 diff --git a/client/ui/netbird-systemtray-default.ico b/client/ui/netbird-systemtray-default.ico new file mode 100644 index 0000000000000000000000000000000000000000..5a025267599c8bb00849160cc4da5dbdb4ea41ca GIT binary patch literal 2876 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 literal 0 HcmV?d00001 diff --git a/client/ui/netbird-systemtray-default.png b/client/ui/netbird-systemtray-default.png new file mode 100644 index 0000000000000000000000000000000000000000..12e7a2dc1008861fe1d98914b8fb44364990c7aa GIT binary patch literal 4938 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 literal 0 HcmV?d00001 diff --git a/client/ui/netbird-systemtray-update-cloud.ico b/client/ui/netbird-systemtray-update-cloud.ico new file mode 100644 index 0000000000000000000000000000000000000000..b87c6f4b55620eea0b397d6243063e22315933f4 GIT binary patch literal 3647 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 UPWN{{D&hjh2Il(Jy7=h-0rzr)wg3PC literal 0 HcmV?d00001 diff --git a/client/ui/netbird-systemtray-update.ico b/client/ui/netbird-systemtray-update.ico new file mode 100644 index 0000000000000000000000000000000000000000..1a1c4086d5ec7ed97f8c633b4ade786fe24fb522 GIT binary patch literal 4726 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 literal 0 HcmV?d00001 diff --git a/client/ui/netbird-systemtray-update.png b/client/ui/netbird-systemtray-update.png new file mode 100644 index 0000000000000000000000000000000000000000..1f4651df9db198901f4498d240c498c504731f40 GIT binary patch literal 7521 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 literal 0 HcmV?d00001 diff --git a/release_files/darwin-ui-installer.sh b/release_files/darwin-ui-installer.sh index 7e8115b64cf..5179f02d6ed 100644 --- a/release_files/darwin-ui-installer.sh +++ b/release_files/darwin-ui-installer.sh @@ -10,6 +10,7 @@ then wiretrustee service stop || true wiretrustee service uninstall || true fi + # check if netbird is installed NB_BIN=$(which netbird) if [ -z "$NB_BIN" ] @@ -41,4 +42,4 @@ netbird service install 2> /dev/null || true netbird service start || true # start app -open /Applications/Netbird\ UI.app \ No newline at end of file +open /Applications/Netbird\ UI.app diff --git a/release_files/darwin_pkg/preinstall b/release_files/darwin_pkg/preinstall index cdea1465c21..5965e82ebe4 100755 --- a/release_files/darwin_pkg/preinstall +++ b/release_files/darwin_pkg/preinstall @@ -8,6 +8,13 @@ AGENT=/usr/local/bin/netbird mkdir -p /var/log/netbird/ { + # check if it was installed with brew + brew list --formula | grep netbird + if [ $? -eq 0 ] + then + echo "NetBird has been installed with Brew. Please use Brew to update the package." + exit 1 + fi osascript -e 'quit app "Netbird"' || true $AGENT service stop || true diff --git a/version/update.go b/version/update.go new file mode 100644 index 00000000000..1de60ea9a3c --- /dev/null +++ b/version/update.go @@ -0,0 +1,184 @@ +package version + +import ( + "io" + "net/http" + "sync" + "time" + + goversion "github.com/hashicorp/go-version" + log "github.com/sirupsen/logrus" +) + +const ( + fetchPeriod = 30 * time.Minute +) + +var ( + versionURL = "https://pkgs.netbird.io/releases/latest/version" +) + +// Update fetch the version info periodically and notify the onUpdateListener in case the UI version or the +// daemon version are deprecated +type Update struct { + uiVersion *goversion.Version + daemonVersion *goversion.Version + latestAvailable *goversion.Version + versionsLock sync.Mutex + + fetchTicker *time.Ticker + fetchDone chan struct{} + + onUpdateListener func() + listenerLock sync.Mutex +} + +// NewUpdate instantiate Update and start to fetch the new version information +func NewUpdate() *Update { + currentVersion, err := goversion.NewVersion(version) + if err != nil { + currentVersion, _ = goversion.NewVersion("0.0.0") + } + + latestAvailable, _ := goversion.NewVersion("0.0.0") + + u := &Update{ + latestAvailable: latestAvailable, + uiVersion: currentVersion, + fetchTicker: time.NewTicker(fetchPeriod), + fetchDone: make(chan struct{}), + } + go u.startFetcher() + return u +} + +// StopWatch stop the version info fetch loop +func (u *Update) StopWatch() { + u.fetchTicker.Stop() + + select { + case u.fetchDone <- struct{}{}: + default: + } +} + +// SetDaemonVersion update the currently running daemon version. If new version is available it will trigger +// the onUpdateListener +func (u *Update) SetDaemonVersion(newVersion string) bool { + daemonVersion, err := goversion.NewVersion(newVersion) + if err != nil { + daemonVersion, _ = goversion.NewVersion("0.0.0") + } + + u.versionsLock.Lock() + if u.daemonVersion != nil && u.daemonVersion.Equal(daemonVersion) { + u.versionsLock.Unlock() + return false + } + + u.daemonVersion = daemonVersion + u.versionsLock.Unlock() + return u.checkUpdate() +} + +// SetOnUpdateListener set new update listener +func (u *Update) SetOnUpdateListener(updateFn func()) { + u.listenerLock.Lock() + defer u.listenerLock.Unlock() + + u.onUpdateListener = updateFn + if u.isUpdateAvailable() { + u.onUpdateListener() + } +} + +func (u *Update) startFetcher() { + changed := u.fetchVersion() + if changed { + u.checkUpdate() + } + + select { + case <-u.fetchDone: + return + case <-u.fetchTicker.C: + changed := u.fetchVersion() + if changed { + u.checkUpdate() + } + } +} + +func (u *Update) fetchVersion() bool { + resp, err := http.Get(versionURL) + if err != nil { + log.Errorf("failed to fetch version info: %s", err) + return false + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + log.Errorf("invalid status code: %d", resp.StatusCode) + return false + } + + if resp.ContentLength > 100 { + log.Errorf("too large response: %d", resp.ContentLength) + return false + } + + content, err := io.ReadAll(resp.Body) + if err != nil { + log.Errorf("failed to read content: %s", err) + return false + } + + latestAvailable, err := goversion.NewVersion(string(content)) + if err != nil { + log.Errorf("failed to parse the version string: %s", err) + return false + } + + u.versionsLock.Lock() + defer u.versionsLock.Unlock() + + if u.latestAvailable.Equal(latestAvailable) { + return false + } + u.latestAvailable = latestAvailable + + return true +} + +func (u *Update) checkUpdate() bool { + if !u.isUpdateAvailable() { + return false + } + + u.listenerLock.Lock() + defer u.listenerLock.Unlock() + if u.onUpdateListener == nil { + return true + } + + go u.onUpdateListener() + return true +} + +func (u *Update) isUpdateAvailable() bool { + u.versionsLock.Lock() + defer u.versionsLock.Unlock() + + if u.latestAvailable.GreaterThan(u.uiVersion) { + return true + } + + if u.daemonVersion == nil { + return false + } + + if u.latestAvailable.GreaterThan(u.daemonVersion) { + return true + } + return false +} diff --git a/version/update_test.go b/version/update_test.go new file mode 100644 index 00000000000..c2b47749522 --- /dev/null +++ b/version/update_test.go @@ -0,0 +1,101 @@ +package version + +import ( + "fmt" + "net/http" + "net/http/httptest" + "sync" + "testing" + "time" +) + +func TestNewUpdate(t *testing.T) { + version = "1.0.0" + svr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, "10.0.0") + })) + defer svr.Close() + versionURL = svr.URL + + wg := &sync.WaitGroup{} + wg.Add(1) + + onUpdate := false + u := NewUpdate() + defer u.StopWatch() + u.SetOnUpdateListener(func() { + onUpdate = true + wg.Done() + }) + + waitTimeout(wg) + if onUpdate != true { + t.Errorf("update not found") + } +} + +func TestDoNotUpdate(t *testing.T) { + version = "11.0.0" + svr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, "10.0.0") + })) + defer svr.Close() + versionURL = svr.URL + + wg := &sync.WaitGroup{} + wg.Add(1) + + onUpdate := false + u := NewUpdate() + defer u.StopWatch() + u.SetOnUpdateListener(func() { + onUpdate = true + wg.Done() + }) + + waitTimeout(wg) + if onUpdate == true { + t.Errorf("invalid update") + } +} + +func TestDaemonUpdate(t *testing.T) { + version = "11.0.0" + svr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, "11.0.0") + })) + defer svr.Close() + versionURL = svr.URL + + wg := &sync.WaitGroup{} + wg.Add(1) + + onUpdate := false + u := NewUpdate() + defer u.StopWatch() + u.SetOnUpdateListener(func() { + onUpdate = true + wg.Done() + }) + + u.SetDaemonVersion("10.0.0") + + waitTimeout(wg) + if onUpdate != true { + t.Errorf("invalid dameon version check") + } +} + +func waitTimeout(wg *sync.WaitGroup) { + c := make(chan struct{}) + go func() { + wg.Wait() + close(c) + }() + select { + case <-c: + return + case <-time.After(time.Second): + return + } +} diff --git a/version/url.go b/version/url.go new file mode 100644 index 00000000000..ed43ab04249 --- /dev/null +++ b/version/url.go @@ -0,0 +1,5 @@ +package version + +const ( + downloadURL = "https://app.netbird.io/install" +) diff --git a/version/url_darwin.go b/version/url_darwin.go new file mode 100644 index 00000000000..cb58612f52b --- /dev/null +++ b/version/url_darwin.go @@ -0,0 +1,33 @@ +package version + +import ( + "os/exec" + "runtime" +) + +const ( + urlMacIntel = "https://pkgs.netbird.io/macos/amd64" + urlMacM1M2 = "https://pkgs.netbird.io/macos/arm64" +) + +// DownloadUrl return with the proper download link +func DownloadUrl() string { + cmd := exec.Command("brew", "list --formula | grep -i netbird") + if err := cmd.Start(); err != nil { + goto PKGINSTALL + } + + if err := cmd.Wait(); err == nil { + return downloadURL + } + +PKGINSTALL: + switch runtime.GOARCH { + case "amd64": + return urlMacIntel + case "arm64": + return urlMacM1M2 + default: + return downloadURL + } +} diff --git a/version/url_linux.go b/version/url_linux.go new file mode 100644 index 00000000000..c8193e30c31 --- /dev/null +++ b/version/url_linux.go @@ -0,0 +1,6 @@ +package version + +// DownloadUrl return with the proper download link +func DownloadUrl() string { + return downloadURL +} diff --git a/version/url_windows.go b/version/url_windows.go new file mode 100644 index 00000000000..f2055b10915 --- /dev/null +++ b/version/url_windows.go @@ -0,0 +1,19 @@ +package version + +import "golang.org/x/sys/windows/registry" + +const ( + urlWinExe = "https://pkgs.netbird.io/windows/x64" +) + +var regKeyAppPath = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\Netbird" + +// DownloadUrl return with the proper download link +func DownloadUrl() string { + _, err := registry.OpenKey(registry.LOCAL_MACHINE, regKeyAppPath, registry.QUERY_VALUE) + if err == nil { + return urlWinExe + } else { + return downloadURL + } +}