mirror of https://github.com/jetkvm/kvm.git
feat(native): restart jetkvm_native automatically
This commit is contained in:
parent
ccba27cedd
commit
dd7cbd1a2f
102
native.go
102
native.go
|
@ -8,6 +8,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -41,6 +42,11 @@ var ongoingRequests = make(map[int32]chan *CtrlResponse)
|
||||||
|
|
||||||
var lock = &sync.Mutex{}
|
var lock = &sync.Mutex{}
|
||||||
|
|
||||||
|
var (
|
||||||
|
nativeCmd *exec.Cmd
|
||||||
|
nativeCmdLock = &sync.Mutex{}
|
||||||
|
)
|
||||||
|
|
||||||
func CallCtrlAction(action string, params map[string]interface{}) (*CtrlResponse, error) {
|
func CallCtrlAction(action string, params map[string]interface{}) (*CtrlResponse, error) {
|
||||||
lock.Lock()
|
lock.Lock()
|
||||||
defer lock.Unlock()
|
defer lock.Unlock()
|
||||||
|
@ -129,16 +135,26 @@ func StartNativeSocketServer(socketPath string, handleClient func(net.Conn), isC
|
||||||
scopedLogger.Info().Msg("server listening")
|
scopedLogger.Info().Msg("server listening")
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
conn, err := listener.Accept()
|
for {
|
||||||
listener.Close()
|
conn, err := listener.Accept()
|
||||||
if err != nil {
|
|
||||||
scopedLogger.Warn().Err(err).Msg("failed to accept socket")
|
if err != nil {
|
||||||
|
scopedLogger.Warn().Err(err).Msg("failed to accept socket")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if isCtrl {
|
||||||
|
// check if the channel is closed
|
||||||
|
select {
|
||||||
|
case <-ctrlClientConnected:
|
||||||
|
scopedLogger.Debug().Msg("ctrl client reconnected")
|
||||||
|
default:
|
||||||
|
close(ctrlClientConnected)
|
||||||
|
scopedLogger.Debug().Msg("first native ctrl socket client connected")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
go handleClient(conn)
|
||||||
}
|
}
|
||||||
if isCtrl {
|
|
||||||
close(ctrlClientConnected)
|
|
||||||
scopedLogger.Debug().Msg("first native ctrl socket client connected")
|
|
||||||
}
|
|
||||||
handleClient(conn)
|
|
||||||
}()
|
}()
|
||||||
|
|
||||||
return listener
|
return listener
|
||||||
|
@ -235,6 +251,55 @@ func handleVideoClient(conn net.Conn) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func startNativeBinaryWithLock(binaryPath string) (*exec.Cmd, error) {
|
||||||
|
nativeCmdLock.Lock()
|
||||||
|
defer nativeCmdLock.Unlock()
|
||||||
|
|
||||||
|
cmd, err := startNativeBinary(binaryPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
nativeCmd = cmd
|
||||||
|
return cmd, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func restartNativeBinary(binaryPath string) error {
|
||||||
|
time.Sleep(10 * time.Second)
|
||||||
|
// restart the binary
|
||||||
|
nativeLogger.Info().Msg("restarting jetkvm_native binary")
|
||||||
|
cmd, err := startNativeBinary(binaryPath)
|
||||||
|
if err != nil {
|
||||||
|
nativeLogger.Warn().Err(err).Msg("failed to restart binary")
|
||||||
|
}
|
||||||
|
nativeCmd = cmd
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func superviseNativeBinary(binaryPath string) error {
|
||||||
|
nativeCmdLock.Lock()
|
||||||
|
defer nativeCmdLock.Unlock()
|
||||||
|
|
||||||
|
if nativeCmd == nil || nativeCmd.Process == nil {
|
||||||
|
return restartNativeBinary(binaryPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
if nativeCmd.Process == nil {
|
||||||
|
return restartNativeBinary(binaryPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
err := nativeCmd.Wait()
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
nativeLogger.Info().Err(err).Msg("jetkvm_native binary exited with no error")
|
||||||
|
} else if exiterr, ok := err.(*exec.ExitError); ok {
|
||||||
|
nativeLogger.Warn().Int("exit_code", exiterr.ExitCode()).Msg("jetkvm_native binary exited with error")
|
||||||
|
} else {
|
||||||
|
nativeLogger.Warn().Err(err).Msg("jetkvm_native binary exited with unknown error")
|
||||||
|
}
|
||||||
|
|
||||||
|
return restartNativeBinary(binaryPath)
|
||||||
|
}
|
||||||
|
|
||||||
func ExtractAndRunNativeBin() error {
|
func ExtractAndRunNativeBin() error {
|
||||||
binaryPath := "/userdata/jetkvm/bin/jetkvm_native"
|
binaryPath := "/userdata/jetkvm/bin/jetkvm_native"
|
||||||
if err := ensureBinaryUpdated(binaryPath); err != nil {
|
if err := ensureBinaryUpdated(binaryPath); err != nil {
|
||||||
|
@ -246,12 +311,27 @@ func ExtractAndRunNativeBin() error {
|
||||||
return fmt.Errorf("failed to make binary executable: %w", err)
|
return fmt.Errorf("failed to make binary executable: %w", err)
|
||||||
}
|
}
|
||||||
// Run the binary in the background
|
// Run the binary in the background
|
||||||
cmd, err := startNativeBinary(binaryPath)
|
cmd, err := startNativeBinaryWithLock(binaryPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to start binary: %w", err)
|
return fmt.Errorf("failed to start binary: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: add auto restart
|
// check if the binary is still running every 10 seconds
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-appCtx.Done():
|
||||||
|
nativeLogger.Info().Msg("stopping native binary supervisor")
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
err := superviseNativeBinary(binaryPath)
|
||||||
|
if err != nil {
|
||||||
|
nativeLogger.Warn().Err(err).Msg("failed to supervise native binary")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
<-appCtx.Done()
|
<-appCtx.Done()
|
||||||
nativeLogger.Info().Int("pid", cmd.Process.Pid).Msg("killing process")
|
nativeLogger.Info().Int("pid", cmd.Process.Pid).Msg("killing process")
|
||||||
|
|
Loading…
Reference in New Issue