ipn/ipnlocal: run "tailscale update" via systemd-run on Linux (#10229)
When we run tailscled under systemd, restarting the unit kills all child processes, including "tailscale update". And during update, the package manager will restart the tailscaled unit. Specifically on Debian-based distros, interrupting `apt-get install` can get the system into a wedged state which requires the user to manually run `dpkg --configure` to recover. To avoid all this, use `systemd-run` where available to run the `tailscale update` process. This launches it in a separate temporary unit and doesn't kill it when parent unit is restarted. Also, detect when `apt-get install` complains about aborted update and try to restore the system by running `dpkg --configure tailscale`. This could help if the system unexpectedly shuts down during our auto-update. Fixes https://github.com/tailscale/corp/issues/15771 Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
This commit is contained in:
@ -415,17 +415,25 @@ func (up *Updater) updateDebLike() error {
|
||||
// we're not updating them:
|
||||
"-o", "APT::Get::List-Cleanup=0",
|
||||
)
|
||||
cmd.Stdout = up.Stdout
|
||||
cmd.Stderr = up.Stderr
|
||||
if err := cmd.Run(); err != nil {
|
||||
return err
|
||||
if out, err := cmd.CombinedOutput(); err != nil {
|
||||
return fmt.Errorf("apt-get update failed: %w; output:\n%s", err, out)
|
||||
}
|
||||
|
||||
cmd = exec.Command("apt-get", "install", "--yes", "--allow-downgrades", "tailscale="+ver)
|
||||
cmd.Stdout = up.Stdout
|
||||
cmd.Stderr = up.Stderr
|
||||
if err := cmd.Run(); err != nil {
|
||||
return err
|
||||
for i := 0; i < 2; i++ {
|
||||
out, err := exec.Command("apt-get", "install", "--yes", "--allow-downgrades", "tailscale="+ver).CombinedOutput()
|
||||
if err != nil {
|
||||
if !bytes.Contains(out, []byte(`dpkg was interrupted`)) {
|
||||
return fmt.Errorf("apt-get install failed: %w; output:\n%s", err, out)
|
||||
}
|
||||
up.Logf("apt-get install failed: %s; output:\n%s", err, out)
|
||||
up.Logf("running dpkg --configure tailscale")
|
||||
out, err = exec.Command("dpkg", "--force-confdef,downgrade", "--configure", "tailscale").CombinedOutput()
|
||||
if err != nil {
|
||||
return fmt.Errorf("dpkg --configure tailscale failed: %w; output:\n%s", err, out)
|
||||
}
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
return nil
|
||||
|
Reference in New Issue
Block a user