finally a complete working go daemon

This commit is contained in:
Aliberk Sandıkçı 2023-08-02 15:56:06 +03:00
parent 013d59c31e
commit b702ab707a
Signed by: asandikci
GPG key ID: 25C67A03B5666BC1
7 changed files with 84 additions and 75 deletions

3
.gitignore vendored
View file

@ -79,4 +79,5 @@ dkms.conf
### USER MODIFIED ###
c-daemon/bin/
go-daemon/bin/
go-daemon/local-ref.sh
go-daemon/local-ref.sh
tmp.go

View file

@ -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
)

View file

@ -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=

View file

@ -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() {
cntxt := &daemon.Context{
PidFileName: "/etc/godaemon1/godaemon1.pid",
PidFilePerm: 0644,
LogFileName: "/etc/godaemon1/godaemon1.log",
LogFilePerm: 0640,
WorkDir: "./",
Umask: 027,
}
d, err := cntxt.Reborn()
if err != nil {
log.Fatal("Unable to run: ", err)
}
if d != nil {
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)
if len(os.Args) == 2 && slices.Contains([]string{"start", "stop", "restart"}, os.Args[1]) {
switch os.Args[1] {
case "start":
cntxt := &daemon.Context{
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("Daemon ERROR:", err)
}
if d != nil {
log.Println("Daemon call stack: ", d)
return
}
defer cntxt.Release()
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)
}
}()
log.Print("- - - - - - - - - - - - - - -")
log.Print("daemon started")
}
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)
}
}

View file

@ -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

View file

@ -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)
}

View file

@ -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)
}
}