diff --git a/backend/networking/shutdown.go b/backend/networking/shutdown.go index ba5699f9..345f0f92 100644 --- a/backend/networking/shutdown.go +++ b/backend/networking/shutdown.go @@ -31,9 +31,10 @@ func ShutdownDevice(device *models.Record) error { ctx := context.Background() ctx, cancel := context.WithCancel(ctx) + defer cancel() + cmd := exec.CommandContext(ctx, shell, shell_arg, shutdown_cmd) SetProcessAttributes(cmd) - logger.Debug.Println(cmd) var stderr bytes.Buffer cmd.Stderr = &stderr @@ -56,7 +57,6 @@ func ShutdownDevice(device *models.Record) error { if err := KillProcess(cmd.Process); err != nil { logger.Error.Println(err) } - cancel() return fmt.Errorf("%s not offline after 2 minutes", device.GetString("name")) } isOnline := PingDevice(device) @@ -64,7 +64,6 @@ func ShutdownDevice(device *models.Record) error { if err := KillProcess(cmd.Process); err != nil { logger.Error.Println(err) } - cancel() return nil } case err := <-done: @@ -72,7 +71,6 @@ func ShutdownDevice(device *models.Record) error { if err := KillProcess(cmd.Process); err != nil { logger.Error.Println(err) } - cancel() return fmt.Errorf("%s", stderr.String()) } } diff --git a/backend/networking/shutdown_linux.go b/backend/networking/shutdown_linux.go index 5487483f..c3e547da 100644 --- a/backend/networking/shutdown_linux.go +++ b/backend/networking/shutdown_linux.go @@ -4,9 +4,8 @@ import ( "os" "os/exec" - "golang.org/x/sys/unix" - "github.com/seriousm4x/upsnap/logger" + "golang.org/x/sys/unix" ) // Set platform specifiy custom process attributes @@ -16,10 +15,18 @@ func SetProcessAttributes(cmd *exec.Cmd) { // Kills child processes on Linux. Windows doesn't provide a direct way to kill child processes, so we kill just the main process. func KillProcess(process *os.Process) error { + logger.Warning.Println("Your shutdown cmd didn't finish in 2 minutes. It will be killed.") pgid, err := unix.Getpgid(process.Pid) - logger.Debug.Println(pgid) if err != nil { return err } - return unix.Kill(-pgid, unix.SIGKILL) + + err = unix.Kill(-pgid, unix.SIGTERM) + if err != nil { + return unix.Kill(-pgid, unix.SIGKILL) + } + + _, err = process.Wait() + + return err } diff --git a/backend/networking/shutdown_other.go b/backend/networking/shutdown_other.go index 99cb7d23..29870ab0 100644 --- a/backend/networking/shutdown_other.go +++ b/backend/networking/shutdown_other.go @@ -1,4 +1,5 @@ -//go:build !linux +//go:build windows +// +build windows package networking @@ -12,8 +13,5 @@ func SetProcessAttributes(cmd *exec.Cmd) {} // Kills child processes on Linux. Windows doesn't provide a direct way to kill child processes, so we kill just the main process. func KillProcess(process *os.Process) error { - if err := process.Kill(); err != nil { - return err - } - return nil + return windows.GenerateConsoleCtrlEvent(windows.CTRL_BREAK_EVENT, uint32(process.Pid)) }