Add graceful service termination
This commit is contained in:
parent
a31c319627
commit
b04fd51245
@ -10,6 +10,7 @@ import (
|
||||
"path"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Build-time variables
|
||||
@ -94,6 +95,39 @@ func startServiceManager() {
|
||||
fmt.Println("Done")
|
||||
}
|
||||
|
||||
func stopServiceManager() {
|
||||
fmt.Println("Stopping service manager... ")
|
||||
|
||||
err := syscall.Kill(serviceManagerPid, syscall.SIGTERM)
|
||||
if err != nil {
|
||||
log.Println("Could not stop service manager!")
|
||||
}
|
||||
// Check if service manager has stopped gracefully, otherwise send sigkill on timeout
|
||||
ticker := time.NewTicker(500 * time.Millisecond)
|
||||
defer ticker.Stop()
|
||||
timer := time.NewTimer(5 * time.Second)
|
||||
defer timer.Stop()
|
||||
select {
|
||||
case <-timer.C:
|
||||
log.Println("Could not stop service manager!")
|
||||
err := syscall.Kill(serviceManagerPid, syscall.SIGKILL)
|
||||
if err != nil {
|
||||
log.Println("Could not stop service manager!")
|
||||
}
|
||||
case <-ticker.C:
|
||||
p, err := os.FindProcess(serviceManagerPid)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
err = p.Signal(syscall.Signal(0))
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Print("Done.")
|
||||
}
|
||||
|
||||
func waitZombieProcesses() {
|
||||
for {
|
||||
if wpid, _ := syscall.Wait4(-1, nil, syscall.WNOHANG, nil); wpid <= 0 {
|
||||
@ -141,17 +175,13 @@ func catchSignals() {
|
||||
func shutdownSystem() {
|
||||
fmt.Println("Shutting down...")
|
||||
|
||||
fmt.Println("Stopping services... ")
|
||||
err := syscall.Kill(serviceManagerPid, syscall.SIGTERM)
|
||||
if err != nil {
|
||||
log.Println("Could not stop service manager!")
|
||||
panic(err)
|
||||
}
|
||||
fmt.Print("Done.")
|
||||
stopServiceManager()
|
||||
|
||||
fmt.Println("Syncing disks...")
|
||||
syscall.Sync()
|
||||
|
||||
fmt.Println("Sending shutdown syscall...")
|
||||
syscall.Sync()
|
||||
err = syscall.Reboot(syscall.LINUX_REBOOT_CMD_POWER_OFF)
|
||||
err := syscall.Reboot(syscall.LINUX_REBOOT_CMD_POWER_OFF)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -160,17 +190,13 @@ func shutdownSystem() {
|
||||
func rebootSystem() {
|
||||
fmt.Println("Rebooting...")
|
||||
|
||||
fmt.Println("Stopping service manager... ")
|
||||
err := syscall.Kill(serviceManagerPid, syscall.SIGTERM)
|
||||
if err != nil {
|
||||
log.Println("Could not stop service manager!")
|
||||
panic(err)
|
||||
}
|
||||
fmt.Print("Done.")
|
||||
stopServiceManager()
|
||||
|
||||
fmt.Println("Syncing disks...")
|
||||
syscall.Sync()
|
||||
|
||||
fmt.Println("Sending reboot syscall...")
|
||||
syscall.Sync()
|
||||
err = syscall.Reboot(syscall.LINUX_REBOOT_CMD_RESTART)
|
||||
err := syscall.Reboot(syscall.LINUX_REBOOT_CMD_RESTART)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
type EnitServiceState uint8
|
||||
@ -229,7 +230,7 @@ func (service *EnitService) StartService() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
cmd := exec.Command("/bin/sh", "-c", service.StartCmd)
|
||||
cmd := exec.Command("/bin/sh", "-c", "exec "+service.StartCmd)
|
||||
if err := cmd.Start(); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -271,10 +272,28 @@ func (service *EnitService) StopService() error {
|
||||
return nil
|
||||
}
|
||||
go func() { service.stopChannel <- true }()
|
||||
|
||||
err := service.GetProcess().Signal(syscall.SIGTERM)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ticker := time.NewTicker(500 * time.Millisecond)
|
||||
defer ticker.Stop()
|
||||
timer := time.NewTimer(5 * time.Second)
|
||||
defer timer.Stop()
|
||||
|
||||
select {
|
||||
case <-timer.C:
|
||||
err := service.GetProcess().Kill()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case <-ticker.C:
|
||||
if service.GetProcess() == nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cmd := exec.Command("/bin/sh", "-c", service.StopCmd)
|
||||
if err := cmd.Run(); err != nil {
|
||||
@ -307,39 +326,6 @@ func (service *EnitService) RestartService() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkForServiceCommand() {
|
||||
for _, service := range Services {
|
||||
if _, err := os.Stat(path.Join(service.ServiceRunPath, "start")); err == nil {
|
||||
err := service.StartService()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = os.Remove(path.Join(service.ServiceRunPath, "start"))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
} else if _, err := os.Stat(path.Join(service.ServiceRunPath, "stop")); err == nil {
|
||||
err := service.StopService()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = os.Remove(path.Join(service.ServiceRunPath, "stop"))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
} else if _, err := os.Stat(path.Join(service.ServiceRunPath, "restart")); err == nil {
|
||||
err := service.RestartService()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = os.Remove(path.Join(service.ServiceRunPath, "restart"))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func listenToSocket() {
|
||||
conn, err := socket.Accept()
|
||||
if err != nil {
|
||||
|
Loading…
x
Reference in New Issue
Block a user