finally a complete working go daemon
This commit is contained in:
parent
013d59c31e
commit
b702ab707a
7 changed files with 84 additions and 75 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -80,3 +80,4 @@ dkms.conf
|
|||
c-daemon/bin/
|
||||
go-daemon/bin/
|
||||
go-daemon/local-ref.sh
|
||||
tmp.go
|
|
@ -6,5 +6,6 @@ require github.com/sevlyar/go-daemon v0.1.6
|
|||
|
||||
require (
|
||||
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect
|
||||
golang.org/x/exp v0.0.0-20230801115018-d63ba01acd4b // indirect
|
||||
golang.org/x/sys v0.10.0 // indirect
|
||||
)
|
||||
|
|
|
@ -2,5 +2,7 @@ github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 h1:iQTw/8FWTuc7uia
|
|||
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
|
||||
github.com/sevlyar/go-daemon v0.1.6 h1:EUh1MDjEM4BI109Jign0EaknA2izkOyi0LV3ro3QQGs=
|
||||
github.com/sevlyar/go-daemon v0.1.6/go.mod h1:6dJpPatBT9eUwM5VCw9Bt6CdX9Tk6UWvhW3MebLDRKE=
|
||||
golang.org/x/exp v0.0.0-20230801115018-d63ba01acd4b h1:r+vk0EmXNmekl0S0BascoeeoHk/L7wmaW2QF90K+kYI=
|
||||
golang.org/x/exp v0.0.0-20230801115018-d63ba01acd4b/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
|
||||
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
|
||||
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
|
|
|
@ -1,51 +1,95 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"godaemon1/service"
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"os/exec"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/sevlyar/go-daemon"
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
const pidFile = "/etc/godaemon1/godaemon1.pid"
|
||||
const ExecutablePath = "/usr/bin/godaemon1"
|
||||
|
||||
func main() {
|
||||
if len(os.Args) == 2 && slices.Contains([]string{"start", "stop", "restart"}, os.Args[1]) {
|
||||
switch os.Args[1] {
|
||||
case "start":
|
||||
cntxt := &daemon.Context{
|
||||
PidFileName: "/etc/godaemon1/godaemon1.pid",
|
||||
PidFileName: pidFile,
|
||||
PidFilePerm: 0644,
|
||||
LogFileName: "/etc/godaemon1/godaemon1.log",
|
||||
LogFilePerm: 0640,
|
||||
WorkDir: "./",
|
||||
Umask: 027,
|
||||
Args: []string{ExecutablePath, "start"},
|
||||
}
|
||||
|
||||
d, err := cntxt.Reborn()
|
||||
if err != nil {
|
||||
log.Fatal("Unable to run: ", err)
|
||||
log.Fatal("Daemon ERROR:", err)
|
||||
}
|
||||
if d != nil {
|
||||
log.Println("Daemon call stack: ", d)
|
||||
return
|
||||
}
|
||||
defer cntxt.Release()
|
||||
|
||||
// TODO make both in external package service these lines but also async
|
||||
sigChannel := make(chan os.Signal, 1)
|
||||
signal.Notify(sigChannel)
|
||||
|
||||
go func() {
|
||||
for {
|
||||
s := <-sigChannel
|
||||
service.SigHandler(s)
|
||||
}
|
||||
}()
|
||||
|
||||
log.Print("- - - - - - - - - - - - - - -")
|
||||
log.Print("daemon started")
|
||||
case "stop":
|
||||
i, _ := daemon.ReadPidFile(pidFile)
|
||||
Stop(i, 15)
|
||||
os.Exit(0)
|
||||
case "restart":
|
||||
i, _ := daemon.ReadPidFile(pidFile)
|
||||
Restart(i, 15)
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
|
||||
for {
|
||||
Info()
|
||||
time.Sleep(10 * time.Second)
|
||||
time.Sleep(2 * time.Second)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func Start(executable string) {
|
||||
if executable == "" {
|
||||
executable = ExecutablePath
|
||||
}
|
||||
cmd := exec.Command(ExecutablePath, "start")
|
||||
if err := cmd.Run(); err != nil {
|
||||
log.Println("Error: ", err)
|
||||
}
|
||||
}
|
||||
|
||||
func Restart(pid, signal int) {
|
||||
log.Println("Restart Signal Caught")
|
||||
|
||||
// FILLME what you want to do before restarting daemon?
|
||||
|
||||
Stop(pid, signal)
|
||||
|
||||
// FILLME what you want to do after stopping daemon and before starting it again?
|
||||
|
||||
Start("")
|
||||
|
||||
// FILLME what you want to do after starting a new daemon
|
||||
}
|
||||
|
||||
// Stop Ahenkd Daemon with a specific PID
|
||||
// do not forget to use also os.Exit() when using in ExecStop
|
||||
func Stop(pid, signal int) {
|
||||
log.Println("Stop Signal Caught")
|
||||
|
||||
// FILLME what you want to do before stopping daemon?
|
||||
|
||||
if err := syscall.Kill(pid, syscall.Signal(signal)); err == nil {
|
||||
log.Printf("Ahenk Daemon with pid number %v Successfully stopped", pid)
|
||||
} else {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,8 @@ After=multi-user.target
|
|||
Type=forking
|
||||
User=root
|
||||
Group=root
|
||||
ExecStart=/usr/bin/godaemon1
|
||||
ExecStart=/usr/bin/godaemon1 start
|
||||
ExecStop=/usr/bin/godaemon1 stop
|
||||
PIDFile=/etc/godaemon1/godaemon1.pid
|
||||
|
||||
PrivateTmp=false
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func Restart() error {
|
||||
log.Println("Restart Signal Caught")
|
||||
|
||||
// TODO what you want to do before restarting daemon?
|
||||
|
||||
self, err := os.Executable()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
args := os.Args
|
||||
env := os.Environ()
|
||||
return syscall.Exec(self, args, env)
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func SigHandler(signal os.Signal) {
|
||||
if signal == syscall.SIGTERM {
|
||||
log.Println("Got signal: SIGTERM")
|
||||
} else if signal == syscall.SIGINT {
|
||||
log.Println("Got signal: SIGINT")
|
||||
} else if signal == syscall.SIGKILL {
|
||||
log.Println("Got signal: SIGINT")
|
||||
} else {
|
||||
log.Printf("Got another signal: %v\n", signal)
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue