Pull request: home: fix exe path finding

Closes #4735.

Squashed commit of the following:

commit 8228e5f82c9d8056d5567a7f1b13b1365346c4d4
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Mon Jul 11 17:41:19 2022 +0300

    home: fix exe path finding
This commit is contained in:
Ainar Garipov 2022-07-11 18:18:17 +03:00
parent bf024fb985
commit 1eafb4e7cf
1 changed files with 38 additions and 29 deletions

View File

@ -117,7 +117,18 @@ func handleUpdate(w http.ResponseWriter, r *http.Request) {
return return
} }
err := Context.updater.Update() // Retain the current absolute path of the executable, since the updater is
// likely to change the position current one to the backup directory.
//
// See https://github.com/AdguardTeam/AdGuardHome/issues/4735.
execPath, err := os.Executable()
if err != nil {
aghhttp.Error(r, w, http.StatusInternalServerError, "getting path: %s", err)
return
}
err = Context.updater.Update()
if err != nil { if err != nil {
aghhttp.Error(r, w, http.StatusInternalServerError, "%s", err) aghhttp.Error(r, w, http.StatusInternalServerError, "%s", err)
@ -129,13 +140,10 @@ func handleUpdate(w http.ResponseWriter, r *http.Request) {
f.Flush() f.Flush()
} }
// The background context is used because the underlying functions wrap // The background context is used because the underlying functions wrap it
// it with timeout and shut down the server, which handles current // with timeout and shut down the server, which handles current request. It
// request. It also should be done in a separate goroutine due to the // also should be done in a separate goroutine for the same reason.
// same reason. go finishUpdate(context.Background(), execPath)
go func() {
finishUpdate(context.Background())
}()
} }
// versionResponse is the response for /control/version.json endpoint. // versionResponse is the response for /control/version.json endpoint.
@ -174,45 +182,46 @@ func tlsConfUsesPrivilegedPorts(c *tlsConfigSettings) (ok bool) {
} }
// finishUpdate completes an update procedure. // finishUpdate completes an update procedure.
func finishUpdate(ctx context.Context) { func finishUpdate(ctx context.Context, execPath string) {
log.Info("Stopping all tasks") var err error
log.Info("stopping all tasks")
cleanup(ctx) cleanup(ctx)
cleanupAlways() cleanupAlways()
curBinName, err := os.Executable()
if err != nil {
log.Fatalf("executable path request failed: %s", err)
}
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
if Context.runningAsService { if Context.runningAsService {
// Note: // NOTE: We can't restart the service via "kardianos/service"
// we can't restart the service via "kardianos/service" package - it kills the process first // package, because it kills the process first we can't start a new
// we can't start a new instance - Windows doesn't allow it // instance, because Windows doesn't allow it.
//
// TODO(a.garipov): Recheck the claim above.
cmd := exec.Command("cmd", "/c", "net stop AdGuardHome & net start AdGuardHome") cmd := exec.Command("cmd", "/c", "net stop AdGuardHome & net start AdGuardHome")
err = cmd.Start() err = cmd.Start()
if err != nil { if err != nil {
log.Fatalf("exec.Command() failed: %s", err) log.Fatalf("restarting: stopping: %s", err)
} }
os.Exit(0) os.Exit(0)
} }
cmd := exec.Command(curBinName, os.Args[1:]...) cmd := exec.Command(execPath, os.Args[1:]...)
log.Info("Restarting: %v", cmd.Args) log.Info("restarting: %q %q", execPath, os.Args[1:])
cmd.Stdin = os.Stdin cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr cmd.Stderr = os.Stderr
err = cmd.Start() err = cmd.Start()
if err != nil { if err != nil {
log.Fatalf("exec.Command() failed: %s", err) log.Fatalf("restarting:: %s", err)
} }
os.Exit(0) os.Exit(0)
} else { }
log.Info("Restarting: %v", os.Args)
err = syscall.Exec(curBinName, os.Args, os.Environ()) log.Info("restarting: %q %q", execPath, os.Args[1:])
err = syscall.Exec(execPath, os.Args, os.Environ())
if err != nil { if err != nil {
log.Fatalf("syscall.Exec() failed: %s", err) log.Fatalf("restarting: %s", err)
}
// Unreachable code
} }
} }