cmd/tailscale/cli: set Sparkle auto-update on macsys (#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 #755

Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
This commit is contained in:
Andrew Lytvynov 2023-10-24 12:17:55 -06:00 committed by GitHub
parent 6f69fe8ad7
commit d3bc575f35
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 30 additions and 4 deletions

View File

@ -202,7 +202,9 @@ func (up *Updater) getUpdateFunction() (fn updateFunction, canAutoUpdate bool) {
// support auto-updates. // support auto-updates.
return up.updateMacAppStore, false return up.updateMacAppStore, false
case version.IsMacSysExt(): case version.IsMacSysExt():
return up.updateMacSys, true // Macsys update func kicks off Sparkle. Auto-updates are done by
// Sparkle.
return up.updateMacSys, false
default: default:
return nil, false return nil, false
} }

View File

@ -9,6 +9,7 @@
"flag" "flag"
"fmt" "fmt"
"net/netip" "net/netip"
"os/exec"
"github.com/peterbourgon/ff/v3/ffcli" "github.com/peterbourgon/ff/v3/ffcli"
"tailscale.com/clientupdate" "tailscale.com/clientupdate"
@ -17,6 +18,7 @@
"tailscale.com/net/tsaddr" "tailscale.com/net/tsaddr"
"tailscale.com/safesocket" "tailscale.com/safesocket"
"tailscale.com/types/views" "tailscale.com/types/views"
"tailscale.com/version"
) )
var setCmd = &ffcli.Command{ var setCmd = &ffcli.Command{
@ -157,11 +159,24 @@ func runSet(ctx context.Context, args []string) (retErr error) {
} }
} }
if maskedPrefs.AutoUpdateSet { if maskedPrefs.AutoUpdateSet {
// On macsys, tailscaled will set the Sparkle auto-update setting. It
// does not use clientupdate.
if version.IsMacSysExt() {
apply := "0"
if maskedPrefs.AutoUpdate.Apply {
apply = "1"
}
out, err := exec.Command("defaults", "write", "io.tailscale.ipn.macsys", "SUAutomaticallyUpdate", apply).CombinedOutput()
if err != nil {
return fmt.Errorf("failed to enable automatic updates: %v, %q", err, out)
}
} else {
_, err := clientupdate.NewUpdater(clientupdate.Arguments{ForAutoUpdate: true}) _, err := clientupdate.NewUpdater(clientupdate.Arguments{ForAutoUpdate: true})
if errors.Is(err, errors.ErrUnsupported) { if errors.Is(err, errors.ErrUnsupported) {
return errors.New("automatic updates are not supported on this platform") return errors.New("automatic updates are not supported on this platform")
} }
} }
}
checkPrefs := curPrefs.Clone() checkPrefs := curPrefs.Clone()
checkPrefs.ApplyEdits(maskedPrefs) checkPrefs.ApplyEdits(maskedPrefs)
if err := localClient.CheckPrefs(ctx, checkPrefs); err != nil { if err := localClient.CheckPrefs(ctx, checkPrefs); err != nil {

View File

@ -59,6 +59,9 @@ func IsMacSysExt() bool {
return false return false
} }
return isMacSysExt.Get(func() bool { return isMacSysExt.Get(func() bool {
if strings.Contains(os.Getenv("HOME"), "/Containers/io.tailscale.ipn.macsys/") {
return true
}
exe, err := os.Executable() exe, err := os.Executable()
if err != nil { if err != nil {
return false return false
@ -76,6 +79,12 @@ func IsMacAppStore() bool {
return false return false
} }
return isMacAppStore.Get(func() bool { return isMacAppStore.Get(func() bool {
// Both macsys and app store versions can run CLI executable with
// suffix /Contents/MacOS/Tailscale. Check $HOME to filter out running
// as macsys.
if strings.Contains(os.Getenv("HOME"), "/Containers/io.tailscale.ipn.macsys/") {
return false
}
exe, err := os.Executable() exe, err := os.Executable()
if err != nil { if err != nil {
return false return false