Skip to content

Commit d3bc575

Browse files
authored
cmd/tailscale/cli: set Sparkle auto-update on macsys (tailscale#9952)
On `tailscale set --auto-update`, set the Sparkle plist option for it. Also make macsys report not supporting auto-updates over c2n, since they will be triggered by Sparkle locally. Updates tailscale#755 Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
1 parent 6f69fe8 commit d3bc575

File tree

3 files changed

+30
-4
lines changed

3 files changed

+30
-4
lines changed

clientupdate/clientupdate.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,9 @@ func (up *Updater) getUpdateFunction() (fn updateFunction, canAutoUpdate bool) {
202202
// support auto-updates.
203203
return up.updateMacAppStore, false
204204
case version.IsMacSysExt():
205-
return up.updateMacSys, true
205+
// Macsys update func kicks off Sparkle. Auto-updates are done by
206+
// Sparkle.
207+
return up.updateMacSys, false
206208
default:
207209
return nil, false
208210
}

cmd/tailscale/cli/set.go

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"flag"
1010
"fmt"
1111
"net/netip"
12+
"os/exec"
1213

1314
"github.com/peterbourgon/ff/v3/ffcli"
1415
"tailscale.com/clientupdate"
@@ -17,6 +18,7 @@ import (
1718
"tailscale.com/net/tsaddr"
1819
"tailscale.com/safesocket"
1920
"tailscale.com/types/views"
21+
"tailscale.com/version"
2022
)
2123

2224
var setCmd = &ffcli.Command{
@@ -157,9 +159,22 @@ func runSet(ctx context.Context, args []string) (retErr error) {
157159
}
158160
}
159161
if maskedPrefs.AutoUpdateSet {
160-
_, err := clientupdate.NewUpdater(clientupdate.Arguments{ForAutoUpdate: true})
161-
if errors.Is(err, errors.ErrUnsupported) {
162-
return errors.New("automatic updates are not supported on this platform")
162+
// On macsys, tailscaled will set the Sparkle auto-update setting. It
163+
// does not use clientupdate.
164+
if version.IsMacSysExt() {
165+
apply := "0"
166+
if maskedPrefs.AutoUpdate.Apply {
167+
apply = "1"
168+
}
169+
out, err := exec.Command("defaults", "write", "io.tailscale.ipn.macsys", "SUAutomaticallyUpdate", apply).CombinedOutput()
170+
if err != nil {
171+
return fmt.Errorf("failed to enable automatic updates: %v, %q", err, out)
172+
}
173+
} else {
174+
_, err := clientupdate.NewUpdater(clientupdate.Arguments{ForAutoUpdate: true})
175+
if errors.Is(err, errors.ErrUnsupported) {
176+
return errors.New("automatic updates are not supported on this platform")
177+
}
163178
}
164179
}
165180
checkPrefs := curPrefs.Clone()

version/prop.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ func IsMacSysExt() bool {
5959
return false
6060
}
6161
return isMacSysExt.Get(func() bool {
62+
if strings.Contains(os.Getenv("HOME"), "/Containers/io.tailscale.ipn.macsys/") {
63+
return true
64+
}
6265
exe, err := os.Executable()
6366
if err != nil {
6467
return false
@@ -76,6 +79,12 @@ func IsMacAppStore() bool {
7679
return false
7780
}
7881
return isMacAppStore.Get(func() bool {
82+
// Both macsys and app store versions can run CLI executable with
83+
// suffix /Contents/MacOS/Tailscale. Check $HOME to filter out running
84+
// as macsys.
85+
if strings.Contains(os.Getenv("HOME"), "/Containers/io.tailscale.ipn.macsys/") {
86+
return false
87+
}
7988
exe, err := os.Executable()
8089
if err != nil {
8190
return false

0 commit comments

Comments
 (0)