From 0e21942cd6616c239e3942b051c3d0168581e0ff Mon Sep 17 00:00:00 2001 From: Harvey Tindall Date: Mon, 3 May 2021 20:08:23 +0100 Subject: [PATCH] add hard restart for updates on *nix reincarnates app.Restart() removed in bbb0568cc4ccd6db4f65618ca273cab4542518b6 as app.HardRestart(). --- api.go | 5 +++++ lang/admin/en-us.json | 1 + restart.go | 32 ++++++++++++++++++++++++++++++++ restart_windows.go | 7 +++++++ ts/modules/update.ts | 11 +++++++++-- updater.go | 11 ++++++++++- 6 files changed, 64 insertions(+), 3 deletions(-) create mode 100644 restart.go create mode 100644 restart_windows.go diff --git a/api.go b/api.go index 4656522..574dccb 100644 --- a/api.go +++ b/api.go @@ -1788,7 +1788,12 @@ func (app *appContext) ApplyUpdate(gc *gin.Context) { respondBool(500, false, gc) return } + if PLATFORM == "windows" { + respondBool(500, true, gc) + return + } respondBool(200, true, gc) + app.HardRestart() } // @Summary Logout by deleting refresh token from cookies. diff --git a/lang/admin/en-us.json b/lang/admin/en-us.json index 7856394..dcd9d6a 100644 --- a/lang/admin/en-us.json +++ b/lang/admin/en-us.json @@ -103,6 +103,7 @@ "sentAnnouncement": "Announcement sent.", "setOmbiDefaults": "Stored ombi defaults.", "updateApplied": "Update applied, please restart.", + "updateAppliedRefresh": "Update applied, please refresh.", "errorConnection": "Couldn't connect to jfa-go.", "error401Unauthorized": "Unauthorized. Try refreshing the page.", "errorSettingsAppliedNoHomescreenLayout": "Settings were applied, but applying homescreen layout may have failed.", diff --git a/restart.go b/restart.go new file mode 100644 index 0000000..1713619 --- /dev/null +++ b/restart.go @@ -0,0 +1,32 @@ +// +build !windows + +package main + +import ( + "fmt" + "os" + "os/signal" + "syscall" +) + +func (app *appContext) HardRestart() error { + defer func() { + if r := recover(); r != nil { + signal.Notify(app.quit, os.Interrupt) + <-app.quit + } + }() + args := os.Args + // After a single restart, args[0] gets messed up and isnt the real executable. + // JFA_DEEP tells the new process its a child, and JFA_EXEC is the real executable + if os.Getenv("JFA_DEEP") == "" { + os.Setenv("JFA_DEEP", "1") + os.Setenv("JFA_EXEC", args[0]) + } + env := os.Environ() + err := syscall.Exec(os.Getenv("JFA_EXEC"), []string{""}, env) + if err != nil { + return err + } + panic(fmt.Errorf("r")) +} diff --git a/restart_windows.go b/restart_windows.go new file mode 100644 index 0000000..54c05cf --- /dev/null +++ b/restart_windows.go @@ -0,0 +1,7 @@ +package main + +import "fmt" + +func (app *appContext) HardRestart() error { + return fmt.Errorf("hard restarts not available on windows") +} diff --git a/ts/modules/update.ts b/ts/modules/update.ts index bfc059c..e490e89 100644 --- a/ts/modules/update.ts +++ b/ts/modules/update.ts @@ -107,13 +107,20 @@ export class Updater implements updater { _post("/config/update", null, (req: XMLHttpRequest) => { if (req.readyState == 4) { toggleLoader(update); - if (req.status != 200) { + const success = req.response["success"] as Boolean; + if (req.status == 500 && success) { + window.notifications.customSuccess("applyUpdate", window.lang.notif("updateAppliedRefresh")); + } else if (req.status != 200) { window.notifications.customError("applyUpdateError", window.lang.notif("errorApplyUpdate")); } else { - window.notifications.customSuccess("applyUpdate", window.lang.notif("updateApplied")); + window.notifications.customSuccess("applyUpdate", window.lang.notif("updateAppliedRefresh")); } window.modals.updateInfo.close(); } + }, true, (req: XMLHttpRequest) => { + if (req.status == 0) { + window.notifications.customSuccess("applyUpdate", window.lang.notif("updateAppliedRefresh")); + } }); }; this.checkForUpdates(() => { diff --git a/updater.go b/updater.go index 9a45930..560142a 100644 --- a/updater.go +++ b/updater.go @@ -440,7 +440,16 @@ func (ud *Updater) pullInternal(url string) (applyUpdate ApplyUpdate, status int return } applyUpdate = func() error { - return os.Rename(path+"_", path) + oldName := path + "-" + version + "-" + commit + err := os.Rename(path, oldName) + if err != nil { + return err + } + err = os.Rename(path+"_", path) + if err != nil { + return err + } + return os.Remove(oldName) } return }