mirror of
https://github.com/tailscale/tailscale.git
synced 2025-08-11 13:18:53 +00:00
ipn: apply tailnet-wide default for auto-updates (#10508)
When auto-update setting in local Prefs is unset, apply the tailnet default value from control. This only happens once, when we apply the default (or when the user manually overrides it), tailnet default no longer affects the node. Updates #16244 Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
This commit is contained in:
@@ -378,7 +378,7 @@ func (b *LocalBackend) newC2NUpdateResponse() tailcfg.C2NUpdateResponse {
|
||||
// invoke it here. For this purpose, it is ok to pass it a zero Arguments.
|
||||
prefs := b.Prefs().AutoUpdate()
|
||||
return tailcfg.C2NUpdateResponse{
|
||||
Enabled: envknob.AllowsRemoteUpdate() || prefs.Apply,
|
||||
Enabled: envknob.AllowsRemoteUpdate() || prefs.Apply.EqualBool(true),
|
||||
Supported: clientupdate.CanAutoUpdate(),
|
||||
}
|
||||
}
|
||||
|
@@ -76,6 +76,7 @@ import (
|
||||
"tailscale.com/types/logger"
|
||||
"tailscale.com/types/logid"
|
||||
"tailscale.com/types/netmap"
|
||||
"tailscale.com/types/opt"
|
||||
"tailscale.com/types/persist"
|
||||
"tailscale.com/types/preftype"
|
||||
"tailscale.com/types/ptr"
|
||||
@@ -1271,8 +1272,8 @@ var preferencePolicies = []preferencePolicyInfo{
|
||||
},
|
||||
{
|
||||
key: syspolicy.ApplyUpdates,
|
||||
get: func(p ipn.PrefsView) bool { return p.AutoUpdate().Apply },
|
||||
set: func(p *ipn.Prefs, v bool) { p.AutoUpdate.Apply = v },
|
||||
get: func(p ipn.PrefsView) bool { v, _ := p.AutoUpdate().Apply.Get(); return v },
|
||||
set: func(p *ipn.Prefs, v bool) { p.AutoUpdate.Apply.Set(v) },
|
||||
},
|
||||
{
|
||||
key: syspolicy.EnableRunExitNode,
|
||||
@@ -1767,25 +1768,26 @@ func (b *LocalBackend) Start(opts ipn.Options) error {
|
||||
// new controlclient. SetPrefs() allows you to overwrite ServerURL,
|
||||
// but it won't take effect until the next Start().
|
||||
cc, err := b.getNewControlClientFunc()(controlclient.Options{
|
||||
GetMachinePrivateKey: b.createGetMachinePrivateKeyFunc(),
|
||||
Logf: logger.WithPrefix(b.logf, "control: "),
|
||||
Persist: *persistv,
|
||||
ServerURL: serverURL,
|
||||
AuthKey: opts.AuthKey,
|
||||
Hostinfo: hostinfo,
|
||||
HTTPTestClient: httpTestClient,
|
||||
DiscoPublicKey: discoPublic,
|
||||
DebugFlags: debugFlags,
|
||||
NetMon: b.sys.NetMon.Get(),
|
||||
Pinger: b,
|
||||
PopBrowserURL: b.tellClientToBrowseToURL,
|
||||
OnClientVersion: b.onClientVersion,
|
||||
OnControlTime: b.em.onControlTime,
|
||||
Dialer: b.Dialer(),
|
||||
Observer: b,
|
||||
C2NHandler: http.HandlerFunc(b.handleC2N),
|
||||
DialPlan: &b.dialPlan, // pointer because it can't be copied
|
||||
ControlKnobs: b.sys.ControlKnobs(),
|
||||
GetMachinePrivateKey: b.createGetMachinePrivateKeyFunc(),
|
||||
Logf: logger.WithPrefix(b.logf, "control: "),
|
||||
Persist: *persistv,
|
||||
ServerURL: serverURL,
|
||||
AuthKey: opts.AuthKey,
|
||||
Hostinfo: hostinfo,
|
||||
HTTPTestClient: httpTestClient,
|
||||
DiscoPublicKey: discoPublic,
|
||||
DebugFlags: debugFlags,
|
||||
NetMon: b.sys.NetMon.Get(),
|
||||
Pinger: b,
|
||||
PopBrowserURL: b.tellClientToBrowseToURL,
|
||||
OnClientVersion: b.onClientVersion,
|
||||
OnTailnetDefaultAutoUpdate: b.onTailnetDefaultAutoUpdate,
|
||||
OnControlTime: b.em.onControlTime,
|
||||
Dialer: b.Dialer(),
|
||||
Observer: b,
|
||||
C2NHandler: http.HandlerFunc(b.handleC2N),
|
||||
DialPlan: &b.dialPlan, // pointer because it can't be copied
|
||||
ControlKnobs: b.sys.ControlKnobs(),
|
||||
|
||||
// Don't warn about broken Linux IP forwarding when
|
||||
// netstack is being used.
|
||||
@@ -2500,6 +2502,32 @@ func (b *LocalBackend) onClientVersion(v *tailcfg.ClientVersion) {
|
||||
b.send(ipn.Notify{ClientVersion: v})
|
||||
}
|
||||
|
||||
func (b *LocalBackend) onTailnetDefaultAutoUpdate(au bool) {
|
||||
prefs := b.pm.CurrentPrefs()
|
||||
if !prefs.Valid() {
|
||||
b.logf("[unexpected]: received tailnet default auto-update callback but current prefs are nil")
|
||||
return
|
||||
}
|
||||
if _, ok := prefs.AutoUpdate().Apply.Get(); ok {
|
||||
// Apply was already set from a previous default or manually by the
|
||||
// user. Tailnet default should not affect us, even if it changes.
|
||||
return
|
||||
}
|
||||
b.logf("using tailnet default auto-update setting: %v", au)
|
||||
prefsClone := prefs.AsStruct()
|
||||
prefsClone.AutoUpdate.Apply = opt.NewBool(au)
|
||||
_, err := b.EditPrefs(&ipn.MaskedPrefs{
|
||||
Prefs: *prefsClone,
|
||||
AutoUpdateSet: ipn.AutoUpdatePrefsMask{
|
||||
ApplySet: true,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
b.logf("failed to apply tailnet-wide default for auto-updates (%v): %v", au, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// For testing lazy machine key generation.
|
||||
var panicOnMachineKeyGeneration = envknob.RegisterBool("TS_DEBUG_PANIC_MACHINE_KEY")
|
||||
|
||||
@@ -4079,7 +4107,7 @@ func (b *LocalBackend) applyPrefsToHostinfoLocked(hi *tailcfg.Hostinfo, prefs ip
|
||||
hi.RoutableIPs = prefs.AdvertiseRoutes().AsSlice()
|
||||
hi.RequestTags = prefs.AdvertiseTags().AsSlice()
|
||||
hi.ShieldsUp = prefs.ShieldsUp()
|
||||
hi.AllowsUpdate = envknob.AllowsRemoteUpdate() || prefs.AutoUpdate().Apply
|
||||
hi.AllowsUpdate = envknob.AllowsRemoteUpdate() || prefs.AutoUpdate().Apply.EqualBool(true)
|
||||
|
||||
var sshHostKeys []string
|
||||
if prefs.RunSSH() && envknob.CanSSHD() {
|
||||
|
@@ -31,6 +31,7 @@ import (
|
||||
"tailscale.com/types/logger"
|
||||
"tailscale.com/types/logid"
|
||||
"tailscale.com/types/netmap"
|
||||
"tailscale.com/types/opt"
|
||||
"tailscale.com/types/ptr"
|
||||
"tailscale.com/util/dnsname"
|
||||
"tailscale.com/util/mak"
|
||||
@@ -1780,13 +1781,13 @@ func TestApplySysPolicy(t *testing.T) {
|
||||
prefs: ipn.Prefs{
|
||||
AutoUpdate: ipn.AutoUpdatePrefs{
|
||||
Check: true,
|
||||
Apply: false,
|
||||
Apply: opt.NewBool(false),
|
||||
},
|
||||
},
|
||||
wantPrefs: ipn.Prefs{
|
||||
AutoUpdate: ipn.AutoUpdatePrefs{
|
||||
Check: true,
|
||||
Apply: true,
|
||||
Apply: opt.NewBool(true),
|
||||
},
|
||||
},
|
||||
wantAnyChange: true,
|
||||
@@ -1799,13 +1800,13 @@ func TestApplySysPolicy(t *testing.T) {
|
||||
prefs: ipn.Prefs{
|
||||
AutoUpdate: ipn.AutoUpdatePrefs{
|
||||
Check: true,
|
||||
Apply: true,
|
||||
Apply: opt.NewBool(true),
|
||||
},
|
||||
},
|
||||
wantPrefs: ipn.Prefs{
|
||||
AutoUpdate: ipn.AutoUpdatePrefs{
|
||||
Check: true,
|
||||
Apply: false,
|
||||
Apply: opt.NewBool(false),
|
||||
},
|
||||
},
|
||||
wantAnyChange: true,
|
||||
@@ -1818,13 +1819,13 @@ func TestApplySysPolicy(t *testing.T) {
|
||||
prefs: ipn.Prefs{
|
||||
AutoUpdate: ipn.AutoUpdatePrefs{
|
||||
Check: false,
|
||||
Apply: true,
|
||||
Apply: opt.NewBool(true),
|
||||
},
|
||||
},
|
||||
wantPrefs: ipn.Prefs{
|
||||
AutoUpdate: ipn.AutoUpdatePrefs{
|
||||
Check: true,
|
||||
Apply: true,
|
||||
Apply: opt.NewBool(true),
|
||||
},
|
||||
},
|
||||
wantAnyChange: true,
|
||||
@@ -1837,13 +1838,13 @@ func TestApplySysPolicy(t *testing.T) {
|
||||
prefs: ipn.Prefs{
|
||||
AutoUpdate: ipn.AutoUpdatePrefs{
|
||||
Check: true,
|
||||
Apply: true,
|
||||
Apply: opt.NewBool(true),
|
||||
},
|
||||
},
|
||||
wantPrefs: ipn.Prefs{
|
||||
AutoUpdate: ipn.AutoUpdatePrefs{
|
||||
Check: false,
|
||||
Apply: true,
|
||||
Apply: opt.NewBool(true),
|
||||
},
|
||||
},
|
||||
wantAnyChange: true,
|
||||
@@ -2055,3 +2056,56 @@ func TestPreferencePolicyInfo(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestOnTailnetDefaultAutoUpdate(t *testing.T) {
|
||||
tests := []struct {
|
||||
desc string
|
||||
before, after opt.Bool
|
||||
tailnetDefault bool
|
||||
}{
|
||||
{
|
||||
before: opt.Bool(""),
|
||||
tailnetDefault: true,
|
||||
after: opt.NewBool(true),
|
||||
},
|
||||
{
|
||||
before: opt.Bool(""),
|
||||
tailnetDefault: false,
|
||||
after: opt.NewBool(false),
|
||||
},
|
||||
{
|
||||
before: opt.Bool("unset"),
|
||||
tailnetDefault: true,
|
||||
after: opt.NewBool(true),
|
||||
},
|
||||
{
|
||||
before: opt.Bool("unset"),
|
||||
tailnetDefault: false,
|
||||
after: opt.NewBool(false),
|
||||
},
|
||||
{
|
||||
before: opt.NewBool(false),
|
||||
tailnetDefault: true,
|
||||
after: opt.NewBool(false),
|
||||
},
|
||||
{
|
||||
before: opt.NewBool(true),
|
||||
tailnetDefault: false,
|
||||
after: opt.NewBool(true),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(fmt.Sprintf("before=%s after=%s", tt.before, tt.after), func(t *testing.T) {
|
||||
b := newTestBackend(t)
|
||||
p := ipn.NewPrefs()
|
||||
p.AutoUpdate.Apply = tt.before
|
||||
if err := b.pm.setPrefsLocked(p.View()); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
b.onTailnetDefaultAutoUpdate(tt.tailnetDefault)
|
||||
if want, got := tt.after, b.pm.CurrentPrefs().AutoUpdate().Apply; got != want {
|
||||
t.Errorf("got: %q, want %q", got, want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user