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>
pull/9926/head
Andrew Lytvynov 1 year ago committed by GitHub
parent 6f69fe8ad7
commit d3bc575f35
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

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

@ -9,6 +9,7 @@ import (
"flag"
"fmt"
"net/netip"
"os/exec"
"github.com/peterbourgon/ff/v3/ffcli"
"tailscale.com/clientupdate"
@ -17,6 +18,7 @@ import (
"tailscale.com/net/tsaddr"
"tailscale.com/safesocket"
"tailscale.com/types/views"
"tailscale.com/version"
)
var setCmd = &ffcli.Command{
@ -157,11 +159,24 @@ func runSet(ctx context.Context, args []string) (retErr error) {
}
}
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})
if errors.Is(err, errors.ErrUnsupported) {
return errors.New("automatic updates are not supported on this platform")
}
}
}
checkPrefs := curPrefs.Clone()
checkPrefs.ApplyEdits(maskedPrefs)
if err := localClient.CheckPrefs(ctx, checkPrefs); err != nil {

@ -59,6 +59,9 @@ func IsMacSysExt() bool {
return false
}
return isMacSysExt.Get(func() bool {
if strings.Contains(os.Getenv("HOME"), "/Containers/io.tailscale.ipn.macsys/") {
return true
}
exe, err := os.Executable()
if err != nil {
return false
@ -76,6 +79,12 @@ func IsMacAppStore() bool {
return false
}
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()
if err != nil {
return false

Loading…
Cancel
Save