mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-25 11:05:45 +00:00
ipn/ipnlocal,clientupdate: allow auto-updates in contaienrs (#12391)
We assume most containers are immutable and don't expect tailscale running in them to auto-update. But there's no reason to prohibit it outright. Ignore the tailnet-wide default auto-update setting in containers, but allow local users to turn on auto-updates via the CLI. RELNOTE=Auto-updates are allowed in containers, but ignore the tailnet-wide default. Fixes #12292 Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
This commit is contained in:
parent
b65221999c
commit
7a7e314096
@ -29,7 +29,6 @@
|
||||
|
||||
"github.com/google/uuid"
|
||||
"tailscale.com/clientupdate/distsign"
|
||||
"tailscale.com/hostinfo"
|
||||
"tailscale.com/types/logger"
|
||||
"tailscale.com/util/cmpver"
|
||||
"tailscale.com/util/winutil"
|
||||
@ -163,10 +162,9 @@ func NewUpdater(args Arguments) (*Updater, error) {
|
||||
type updateFunction func() error
|
||||
|
||||
func (up *Updater) getUpdateFunction() (fn updateFunction, canAutoUpdate bool) {
|
||||
canAutoUpdate = !hostinfo.New().Container.EqualBool(true) // EqualBool(false) would return false if the value is not set.
|
||||
switch runtime.GOOS {
|
||||
case "windows":
|
||||
return up.updateWindows, canAutoUpdate
|
||||
return up.updateWindows, true
|
||||
case "linux":
|
||||
switch distro.Get() {
|
||||
case distro.NixOS:
|
||||
@ -180,20 +178,20 @@ func (up *Updater) getUpdateFunction() (fn updateFunction, canAutoUpdate bool) {
|
||||
// auto-update mechanism.
|
||||
return up.updateSynology, false
|
||||
case distro.Debian: // includes Ubuntu
|
||||
return up.updateDebLike, canAutoUpdate
|
||||
return up.updateDebLike, true
|
||||
case distro.Arch:
|
||||
if up.archPackageInstalled() {
|
||||
// Arch update func just prints a message about how to update,
|
||||
// it doesn't support auto-updates.
|
||||
return up.updateArchLike, false
|
||||
}
|
||||
return up.updateLinuxBinary, canAutoUpdate
|
||||
return up.updateLinuxBinary, true
|
||||
case distro.Alpine:
|
||||
return up.updateAlpineLike, canAutoUpdate
|
||||
return up.updateAlpineLike, true
|
||||
case distro.Unraid:
|
||||
return up.updateUnraid, canAutoUpdate
|
||||
return up.updateUnraid, true
|
||||
case distro.QNAP:
|
||||
return up.updateQNAP, canAutoUpdate
|
||||
return up.updateQNAP, true
|
||||
}
|
||||
switch {
|
||||
case haveExecutable("pacman"):
|
||||
@ -202,21 +200,21 @@ func (up *Updater) getUpdateFunction() (fn updateFunction, canAutoUpdate bool) {
|
||||
// it doesn't support auto-updates.
|
||||
return up.updateArchLike, false
|
||||
}
|
||||
return up.updateLinuxBinary, canAutoUpdate
|
||||
return up.updateLinuxBinary, true
|
||||
case haveExecutable("apt-get"): // TODO(awly): add support for "apt"
|
||||
// The distro.Debian switch case above should catch most apt-based
|
||||
// systems, but add this fallback just in case.
|
||||
return up.updateDebLike, canAutoUpdate
|
||||
return up.updateDebLike, true
|
||||
case haveExecutable("dnf"):
|
||||
return up.updateFedoraLike("dnf"), canAutoUpdate
|
||||
return up.updateFedoraLike("dnf"), true
|
||||
case haveExecutable("yum"):
|
||||
return up.updateFedoraLike("yum"), canAutoUpdate
|
||||
return up.updateFedoraLike("yum"), true
|
||||
case haveExecutable("apk"):
|
||||
return up.updateAlpineLike, canAutoUpdate
|
||||
return up.updateAlpineLike, true
|
||||
}
|
||||
// If nothing matched, fall back to tarball updates.
|
||||
if up.Update == nil {
|
||||
return up.updateLinuxBinary, canAutoUpdate
|
||||
return up.updateLinuxBinary, true
|
||||
}
|
||||
case "darwin":
|
||||
switch {
|
||||
@ -232,7 +230,7 @@ func (up *Updater) getUpdateFunction() (fn updateFunction, canAutoUpdate bool) {
|
||||
return nil, false
|
||||
}
|
||||
case "freebsd":
|
||||
return up.updateFreeBSD, canAutoUpdate
|
||||
return up.updateFreeBSD, true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
@ -2575,6 +2575,12 @@ func (b *LocalBackend) onTailnetDefaultAutoUpdate(au bool) {
|
||||
// user. Tailnet default should not affect us, even if it changes.
|
||||
return
|
||||
}
|
||||
if au && b.hostinfo != nil && b.hostinfo.Container.EqualBool(true) {
|
||||
// This is a containerized node, which is usually meant to be
|
||||
// immutable. Do not enable auto-updates if the tailnet does. But users
|
||||
// can still manually enable auto-updates on this node.
|
||||
return
|
||||
}
|
||||
b.logf("using tailnet default auto-update setting: %v", au)
|
||||
prefsClone := prefs.AsStruct()
|
||||
prefsClone.AutoUpdate.Apply = opt.NewBool(au)
|
||||
|
@ -30,6 +30,7 @@
|
||||
"tailscale.com/drive"
|
||||
"tailscale.com/drive/driveimpl"
|
||||
"tailscale.com/health"
|
||||
"tailscale.com/hostinfo"
|
||||
"tailscale.com/ipn"
|
||||
"tailscale.com/ipn/store/mem"
|
||||
"tailscale.com/net/netcheck"
|
||||
@ -2296,6 +2297,7 @@ func TestPreferencePolicyInfo(t *testing.T) {
|
||||
func TestOnTailnetDefaultAutoUpdate(t *testing.T) {
|
||||
tests := []struct {
|
||||
before, after opt.Bool
|
||||
container opt.Bool
|
||||
tailnetDefault bool
|
||||
}{
|
||||
{
|
||||
@ -2328,10 +2330,30 @@ func TestOnTailnetDefaultAutoUpdate(t *testing.T) {
|
||||
tailnetDefault: false,
|
||||
after: opt.NewBool(true),
|
||||
},
|
||||
{
|
||||
before: opt.Bool(""),
|
||||
container: opt.NewBool(true),
|
||||
tailnetDefault: true,
|
||||
after: opt.Bool(""),
|
||||
},
|
||||
{
|
||||
before: opt.NewBool(false),
|
||||
container: opt.NewBool(true),
|
||||
tailnetDefault: true,
|
||||
after: opt.NewBool(false),
|
||||
},
|
||||
{
|
||||
before: opt.NewBool(true),
|
||||
container: 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)
|
||||
b.hostinfo = hostinfo.New()
|
||||
b.hostinfo.Container = tt.container
|
||||
p := ipn.NewPrefs()
|
||||
p.AutoUpdate.Apply = tt.before
|
||||
if err := b.pm.setPrefsLocked(p.View()); err != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user