Skip to content

Commit

Permalink
Feature/update check (netbirdio#1232)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
pappz authored Oct 30, 2023
1 parent 82c8ac1 commit e1ce3a3
Show file tree
Hide file tree
Showing 23 changed files with 492 additions and 18 deletions.
1 change: 1 addition & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ on:
- 'release_files/**'
- '**/Dockerfile'
- '**/Dockerfile.*'
- 'client/ui/**'

env:
SIGN_PIPE_VER: "v0.0.9"
Expand Down
6 changes: 3 additions & 3 deletions .goreleaser_ui.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -91,4 +91,4 @@ uploads:
mode: archive
target: https://pkgs.wiretrustee.com/yum/{{ .Arch }}{{ if .Arm }}{{ .Arm }}{{ end }}
username: [email protected]
method: PUT
method: PUT
145 changes: 131 additions & 14 deletions client/ui/client_ui.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ import (
"runtime"
"strconv"
"strings"
"sync"
"syscall"
"time"
"unicode"

"fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
Expand Down Expand Up @@ -74,33 +76,51 @@ 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
conn proto.DaemonServiceClient

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
Expand All @@ -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
Expand All @@ -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 {
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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)
Expand All @@ -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.
Expand Down Expand Up @@ -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")
Expand Down
Binary file removed client/ui/connected.ico
Binary file not shown.
Binary file removed client/ui/connected.png
Binary file not shown.
Binary file removed client/ui/disconnected.ico
Binary file not shown.
Binary file removed client/ui/disconnected.png
Binary file not shown.
Binary file added client/ui/netbird-systemtray-connected.ico
Binary file not shown.
Binary file added client/ui/netbird-systemtray-connected.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/ui/netbird-systemtray-default.ico
Binary file not shown.
Binary file added client/ui/netbird-systemtray-default.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/ui/netbird-systemtray-update-cloud.ico
Binary file not shown.
Binary file added client/ui/netbird-systemtray-update-cloud.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/ui/netbird-systemtray-update.ico
Binary file not shown.
Binary file added client/ui/netbird-systemtray-update.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion release_files/darwin-ui-installer.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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" ]
Expand Down Expand Up @@ -41,4 +42,4 @@ netbird service install 2> /dev/null || true
netbird service start || true

# start app
open /Applications/Netbird\ UI.app
open /Applications/Netbird\ UI.app
7 changes: 7 additions & 0 deletions release_files/darwin_pkg/preinstall
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
Loading

0 comments on commit e1ce3a3

Please sign in to comment.