ipn/ipnlocal,clientupdate: disallow auto-updates in containers (#11814)

Containers are typically immutable and should be updated as a whole (and
not individual packages within). Deny enablement of auto-updates in
containers.

Also, add the missing check in EditPrefs in LocalAPI, to catch cases
like tailnet default auto-updates getting enabled for nodes that don't
support it.

Updates #11544

Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
This commit is contained in:
Andrew Lytvynov
2024-04-19 13:37:21 -07:00
committed by GitHub
parent b3fb3bf084
commit bff527622d
3 changed files with 62 additions and 13 deletions

View File

@@ -2974,6 +2974,9 @@ func (b *LocalBackend) checkPrefsLocked(p *ipn.Prefs) error {
if err := b.checkFunnelEnabledLocked(p); err != nil {
errs = append(errs, err)
}
if err := b.checkAutoUpdatePrefsLocked(p); err != nil {
errs = append(errs, err)
}
return multierr.New(errs...)
}
@@ -3064,6 +3067,13 @@ func (b *LocalBackend) checkFunnelEnabledLocked(p *ipn.Prefs) error {
return nil
}
func (b *LocalBackend) checkAutoUpdatePrefsLocked(p *ipn.Prefs) error {
if p.AutoUpdate.Apply.EqualBool(true) && !clientupdate.CanAutoUpdate() {
return errors.New("Auto-updates are not supported on this platform.")
}
return nil
}
// SetUseExitNodeEnabled turns on or off the most recently selected exit node.
//
// On success, it returns the resulting prefs (or current prefs, in the case of no change).

View File

@@ -25,6 +25,7 @@ import (
"golang.org/x/net/dns/dnsmessage"
"tailscale.com/appc"
"tailscale.com/appc/appctest"
"tailscale.com/clientupdate"
"tailscale.com/control/controlclient"
"tailscale.com/drive"
"tailscale.com/drive/driveimpl"
@@ -3402,3 +3403,39 @@ func TestMinLatencyDERPregion(t *testing.T) {
})
}
}
func TestEnableAutoUpdates(t *testing.T) {
lb := newTestLocalBackend(t)
_, err := lb.EditPrefs(&ipn.MaskedPrefs{
AutoUpdateSet: ipn.AutoUpdatePrefsMask{
ApplySet: true,
},
Prefs: ipn.Prefs{
AutoUpdate: ipn.AutoUpdatePrefs{
Apply: opt.NewBool(true),
},
},
})
// Enabling may fail, depending on which environment we are running this
// test in.
wantErr := !clientupdate.CanAutoUpdate()
gotErr := err != nil
if gotErr != wantErr {
t.Fatalf("enabling auto-updates: got error: %v (%v); want error: %v", gotErr, err, wantErr)
}
// Disabling should always succeed.
if _, err := lb.EditPrefs(&ipn.MaskedPrefs{
AutoUpdateSet: ipn.AutoUpdatePrefsMask{
ApplySet: true,
},
Prefs: ipn.Prefs{
AutoUpdate: ipn.AutoUpdatePrefs{
Apply: opt.NewBool(false),
},
},
}); err != nil {
t.Fatalf("disabling auto-updates: got error: %v", err)
}
}