mirror of
https://github.com/fosrl/newt.git
synced 2026-07-19 22:31:24 +02:00
22
main.go
22
main.go
@@ -1032,6 +1032,19 @@ persistent_keepalive_interval=5`, util.FixKey(privateKey.String()), util.FixKey(
|
||||
logger.Info("Tunnel destroyed, ready for reconnection")
|
||||
})
|
||||
|
||||
client.RegisterHandler("newt/wg/restart", func(msg websocket.WSMessage) {
|
||||
closeWgTunnel()
|
||||
closeClients()
|
||||
if healthMonitor != nil {
|
||||
healthMonitor.Stop()
|
||||
}
|
||||
client.Close()
|
||||
if err := reexec(); err != nil {
|
||||
logger.Error("Failed to restart: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
})
|
||||
|
||||
client.RegisterHandler("newt/wg/terminate", func(msg websocket.WSMessage) {
|
||||
logger.Info("Received termination message")
|
||||
if wgData.PublicKey != "" {
|
||||
@@ -1968,13 +1981,8 @@ persistent_keepalive_interval=5`, util.FixKey(privateKey.String()), util.FixKey(
|
||||
healthMonitor.Stop()
|
||||
}
|
||||
client.Close()
|
||||
exe, exeErr := os.Executable()
|
||||
if exeErr != nil {
|
||||
logger.Error("Failed to get executable path for restart: %v", exeErr)
|
||||
os.Exit(0)
|
||||
}
|
||||
if err := syscall.Exec(exe, os.Args, os.Environ()); err != nil {
|
||||
logger.Error("Failed to re-exec for restart: %v", err)
|
||||
if err := reexec(); err != nil {
|
||||
logger.Error("Failed to restart: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
21
reexec_unix.go
Normal file
21
reexec_unix.go
Normal file
@@ -0,0 +1,21 @@
|
||||
//go:build !windows
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// reexec replaces the current process image with a fresh copy of itself,
|
||||
// preserving all arguments and environment variables. On success it never
|
||||
// returns (execve replaces the process in-place). On failure it returns an
|
||||
// error describing why the exec could not be performed.
|
||||
func reexec() error {
|
||||
exe, err := os.Executable()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get executable path: %w", err)
|
||||
}
|
||||
return syscall.Exec(exe, os.Args, os.Environ())
|
||||
}
|
||||
30
reexec_windows.go
Normal file
30
reexec_windows.go
Normal file
@@ -0,0 +1,30 @@
|
||||
//go:build windows
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
// reexec spawns a new copy of the current process with the same arguments and
|
||||
// environment, then exits the current process. On Windows, execve is not
|
||||
// available, so we start a child process and exit. On success it never returns
|
||||
// (os.Exit terminates the current process). On failure it returns an error.
|
||||
func reexec() error {
|
||||
exe, err := os.Executable()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get executable path: %w", err)
|
||||
}
|
||||
cmd := exec.Command(exe, os.Args[1:]...)
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
cmd.Stdin = os.Stdin
|
||||
cmd.Env = os.Environ()
|
||||
if err := cmd.Start(); err != nil {
|
||||
return fmt.Errorf("failed to start new process: %w", err)
|
||||
}
|
||||
os.Exit(0)
|
||||
return nil // unreachable
|
||||
}
|
||||
Reference in New Issue
Block a user