implement daemonization

This commit is contained in:
mykola2312 2025-01-25 00:55:02 +02:00
parent 451b73b0f2
commit 2d7625101f
3 changed files with 69 additions and 10 deletions

6
go.mod
View file

@ -6,3 +6,9 @@ require (
github.com/google/uuid v1.6.0
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
)
require (
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect
github.com/sevlyar/go-daemon v0.1.6
golang.org/x/sys v0.29.0 // indirect
)

6
go.sum
View file

@ -1,6 +1,12 @@
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 h1:iQTw/8FWTuc7uiaSepXwyf3o52HaUYcV+Tu66S3F5GA=
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88=
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
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/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=

67
main.go
View file

@ -10,10 +10,12 @@ import (
"lux/rpc"
"os"
"os/signal"
"strconv"
"strings"
"syscall"
"github.com/op/go-logging"
"github.com/sevlyar/go-daemon"
)
var isNode bool
@ -117,6 +119,45 @@ func bootstrapNode() {
var log = logging.MustGetLogger("main")
func becomeDaemon() {
cwd, err := os.Getwd()
if err != nil {
log.Criticalf("Getwd failed: %v", err)
os.Exit(1)
}
ctx := &daemon.Context{
PidFileName: pidPath,
PidFilePerm: 0644,
WorkDir: cwd,
Umask: 027,
}
dmn, err := ctx.Reborn()
if err != nil {
log.Criticalf("ctx.Reborn failed: %v", err)
os.Exit(1)
}
if dmn != nil {
ctx.Release()
// parent process no longer needed
os.Exit(0)
}
defer ctx.Release()
// -- WE ARE NOW THE DAEMON --
// write pid
if pidPath != "" {
pidFile, _ := os.OpenFile(pidPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
defer pidFile.Close()
pidBytes := []byte(strconv.Itoa(os.Getpid()))
pidFile.Write(pidBytes)
}
}
func nodeMain() {
xmlBytes, err := os.ReadFile(configPath)
if err != nil {
@ -126,13 +167,19 @@ func nodeMain() {
var config NodeConfig
if err := xml.Unmarshal(xmlBytes, &config); err != nil {
log.Criticalf("failed to parse xml: %v\n", err)
log.Criticalf("failed to parse xml: %v", err)
os.Exit(1)
}
// setup logging
setupLogging(config.Log)
// only after logging setup, we may became daemon
println(pidPath)
if daemonize {
becomeDaemon()
}
// check presense of keystore and id in config
if config.KeyStore == "" {
log.Critical("no keystore path specified!")
@ -145,14 +192,14 @@ func nodeMain() {
nodeId, err := proto.ParseLuxID(config.ID)
if err != nil {
log.Criticalf("failed to parse node id: %v\n", err)
log.Criticalf("failed to parse node id: %v", err)
os.Exit(1)
}
// load keystore
ks := crypto.NewLuxKeyStore(config.KeyStore)
if err := ks.Load(); err != nil {
log.Criticalf("failed to laod keystore: %v\n", err)
log.Criticalf("failed to laod keystore: %v", err)
os.Exit(1)
}
@ -168,13 +215,13 @@ func nodeMain() {
// add interior exterior channels
for _, interior := range config.Interior {
if err := node.AddInterior(interior); err != nil {
log.Criticalf("failed to add interior %s: %v\n", interior, err)
log.Criticalf("failed to add interior %s: %v", interior, err)
os.Exit(1)
}
}
for _, exterior := range config.Exterior {
if err := node.AddExterior(exterior); err != nil {
log.Criticalf("failed to add exterior %s: %v\n", exterior, err)
log.Criticalf("failed to add exterior %s: %v", exterior, err)
os.Exit(1)
}
}
@ -183,12 +230,12 @@ func nodeMain() {
for _, neighbor := range config.Neighbors {
neighId, err := proto.ParseLuxID(neighbor.ID)
if err != nil {
log.Criticalf("failed to parse neigh id %s: %v\n", neighbor.ID, err)
log.Criticalf("failed to parse neigh id %s: %v", neighbor.ID, err)
os.Exit(1)
}
if err := node.AddNeighbor(neighId, neighbor.Address); err != nil {
log.Criticalf("failed to add neighbor %s: %v\n", neighbor.ID, err)
log.Criticalf("failed to add neighbor %s: %v", neighbor.ID, err)
os.Exit(1)
}
}
@ -203,14 +250,14 @@ func nodeMain() {
path := rpcPath[7:]
if err := sv.AddEndpoint("unix", path, rpc.LuxRpcTypeRoot); err != nil {
log.Criticalf("failed to add root rpc %s: %v\n", path, err)
log.Criticalf("failed to add root rpc %s: %v", path, err)
os.Exit(1)
}
} else if strings.HasPrefix(rpcPath, "tcp://") {
path := rpcPath[6:]
if err := sv.AddEndpoint("tcp", path, rpc.LuxRpcTypeQuery); err != nil {
log.Criticalf("failed to add query rpc %s: %v\n", path, err)
log.Criticalf("failed to add query rpc %s: %v", path, err)
os.Exit(1)
}
} else {
@ -364,7 +411,7 @@ func main() {
flag.StringVar(&configPath, "config", "", "node or host config")
flag.BoolVar(&bootstrap, "bootstrap", false, "bootstrap node keystore. config must be specified")
flag.BoolVar(&justNodeId, "just-node-id", false, "when bootstrapping only output node id to stdout")
flag.BoolVar(&daemonize, "daemonize", false, "run LUX as daemon in background")
flag.BoolVar(&daemonize, "daemon", false, "run LUX as daemon in background")
flag.StringVar(&pidPath, "pid", "", "after daemonization LUX will write its PID here")
flag.StringVar(&rpcPath, "rpc", "", "Run as RPC client, specify path to RPC UNIX socket or TCP socket, must be in unix:// or tcp:// form")