feat(watchdog): add auto boot up for watchdog progress
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -17,6 +17,7 @@
|
|||||||
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
|
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
|
||||||
#
|
#
|
||||||
# Binaries for programs and plugins
|
# Binaries for programs and plugins
|
||||||
|
.gocache/
|
||||||
*.exe
|
*.exe
|
||||||
*.exe~
|
*.exe~
|
||||||
*.dll
|
*.dll
|
||||||
|
|||||||
2
watchdog/keepalive.go
Normal file
2
watchdog/keepalive.go
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
package watchdog
|
||||||
|
|
||||||
@@ -4,7 +4,14 @@ import (
|
|||||||
"bufio"
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
"super-frpc/global"
|
||||||
|
"super-frpc/sys"
|
||||||
|
"super-frpc/utils"
|
||||||
|
"super-frpc/postLog"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@@ -19,9 +26,20 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func Init() error {
|
func Init() error {
|
||||||
|
if global.CurrentConfig.Watchdog.Enabled {
|
||||||
|
if err := ensureWatchdogProcess(); err != nil {
|
||||||
|
postLog.Error(fmt.Sprintf("Failed to boot watchdog program: %v", err))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tcpConnMutex.Lock()
|
tcpConnMutex.Lock()
|
||||||
defer tcpConnMutex.Unlock()
|
defer tcpConnMutex.Unlock()
|
||||||
|
|
||||||
|
if recvChan != nil || stopRecvChan != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
if tcpConn != nil {
|
if tcpConn != nil {
|
||||||
return fmt.Errorf("TCP client already initialized")
|
return fmt.Errorf("TCP client already initialized")
|
||||||
}
|
}
|
||||||
@@ -33,6 +51,86 @@ func Init() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ensureWatchdogProcess() error {
|
||||||
|
watchdogName, err := getWatchdogBinaryName()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if isWatchdogProcessRunning(watchdogName) {
|
||||||
|
postLog.Info(fmt.Sprintf("Watchdog process %s is already running, skipping initialize...", watchdogName))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
postLog.Info(fmt.Sprintf("Watchdog process %s is not running, starting it...", watchdogName))
|
||||||
|
|
||||||
|
watchdogPath := filepath.Join(".", "watchdog", watchdogName)
|
||||||
|
if !utils.IsFileExist(watchdogPath) {
|
||||||
|
return fmt.Errorf("watchdog binary not found: %s", watchdogPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := exec.Command(watchdogPath)
|
||||||
|
devNull, err := os.OpenFile(os.DevNull, os.O_RDWR, 0)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to open null device: %w", err)
|
||||||
|
}
|
||||||
|
defer devNull.Close()
|
||||||
|
|
||||||
|
cmd.Stdin = devNull
|
||||||
|
cmd.Stdout = devNull
|
||||||
|
cmd.Stderr = devNull
|
||||||
|
configureWatchdogCommand(cmd)
|
||||||
|
|
||||||
|
if err := cmd.Start(); err != nil {
|
||||||
|
return fmt.Errorf("failed to start watchdog process %s: %w", watchdogPath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getWatchdogBinaryName() (string, error) {
|
||||||
|
switch sys.GetInitSystem() {
|
||||||
|
case "systemd":
|
||||||
|
return "watchdog_systemd", nil
|
||||||
|
case "init.d":
|
||||||
|
return "watchdog_initd", nil
|
||||||
|
case "windows":
|
||||||
|
if utils.IsFileExist(filepath.Join(".", "watchdog", "watchdog_windows.exe")) {
|
||||||
|
return "watchdog_windows.exe", nil
|
||||||
|
}
|
||||||
|
return "watchdog_windows", nil
|
||||||
|
default:
|
||||||
|
return "", fmt.Errorf("unsupported init system: %s", sys.GetInitSystem())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func isWatchdogProcessRunning(watchdogName string) bool {
|
||||||
|
switch sys.GetInitSystem() {
|
||||||
|
case "windows":
|
||||||
|
cmd := exec.Command("tasklist", "/FI", fmt.Sprintf("IMAGENAME eq %s", watchdogName))
|
||||||
|
output, err := cmd.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
outputStr := strings.ToLower(string(output))
|
||||||
|
return strings.Contains(outputStr, strings.ToLower(watchdogName)) && !strings.Contains(outputStr, "no tasks are running")
|
||||||
|
case "systemd", "init.d":
|
||||||
|
cmd := exec.Command("ps", "-A", "-o", "comm=")
|
||||||
|
output, err := cmd.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, line := range strings.Split(string(output), "\n") {
|
||||||
|
if strings.TrimSpace(line) == watchdogName {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func tcpConnect(ipaddr string, port int) error {
|
func tcpConnect(ipaddr string, port int) error {
|
||||||
tcpConnMutex.Lock()
|
tcpConnMutex.Lock()
|
||||||
defer tcpConnMutex.Unlock()
|
defer tcpConnMutex.Unlock()
|
||||||
|
|||||||
8
watchdog/watchdog_build_linux.go
Normal file
8
watchdog/watchdog_build_linux.go
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
//go:build linux
|
||||||
|
|
||||||
|
package watchdog
|
||||||
|
|
||||||
|
import "os/exec"
|
||||||
|
|
||||||
|
func configureWatchdogCommand(cmd *exec.Cmd) {
|
||||||
|
}
|
||||||
12
watchdog/watchdog_build_windows.go
Normal file
12
watchdog/watchdog_build_windows.go
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
//go:build windows
|
||||||
|
|
||||||
|
package watchdog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os/exec"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
func configureWatchdogCommand(cmd *exec.Cmd) {
|
||||||
|
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user