From f1706a4a0e639b260d08fa5e2c35c50dd63c1d8d Mon Sep 17 00:00:00 2001 From: Gregory Kurtzer Date: Sat, 12 Dec 2020 23:50:38 -0800 Subject: [PATCH] Daemon updates, backgrounding, and CLI integration --- go.mod | 1 + go.sum | 4 + internal/app/wwctl/server/start/main.go | 2 +- internal/app/wwctl/server/status/main.go | 5 +- internal/app/wwctl/server/stop/main.go | 4 +- internal/pkg/warewulfd/daemon.go | 113 +++++++++++++++++++++++ 6 files changed, 123 insertions(+), 6 deletions(-) create mode 100644 internal/pkg/warewulfd/daemon.go diff --git a/go.mod b/go.mod index a6e175c9..f7abe5fb 100644 --- a/go.mod +++ b/go.mod @@ -42,6 +42,7 @@ require ( github.com/prometheus/common v0.6.0 // indirect github.com/prometheus/procfs v0.0.3 // indirect github.com/russross/blackfriday/v2 v2.0.1 // indirect + github.com/sevlyar/go-daemon v0.1.5 github.com/sirupsen/logrus v1.7.0 // indirect github.com/spf13/cobra v1.1.1 github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31 // indirect diff --git a/go.sum b/go.sum index 4f9a7888..afc95a42 100644 --- a/go.sum +++ b/go.sum @@ -201,6 +201,8 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a h1:FaWFmfWdAUKbSCtOU2QjDaorUexogfaMgbipgYATUMU= github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a/go.mod h1:UJSiEoRfvx3hP73CvoARgeLjaIOjybY9vj8PUPPFGeU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +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/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8= github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= @@ -340,6 +342,8 @@ github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/sevlyar/go-daemon v0.1.5 h1:Zy/6jLbM8CfqJ4x4RPr7MJlSKt90f00kNM1D401C+Qk= +github.com/sevlyar/go-daemon v0.1.5/go.mod h1:6dJpPatBT9eUwM5VCw9Bt6CdX9Tk6UWvhW3MebLDRKE= github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= diff --git a/internal/app/wwctl/server/start/main.go b/internal/app/wwctl/server/start/main.go index 82a18c20..b3c2b339 100644 --- a/internal/app/wwctl/server/start/main.go +++ b/internal/app/wwctl/server/start/main.go @@ -7,5 +7,5 @@ import ( func CobraRunE(cmd *cobra.Command, args []string) error { - return warewulfd.RunServer() + return warewulfd.DaemonStart() } diff --git a/internal/app/wwctl/server/status/main.go b/internal/app/wwctl/server/status/main.go index 6edbe268..30b4041a 100644 --- a/internal/app/wwctl/server/status/main.go +++ b/internal/app/wwctl/server/status/main.go @@ -1,12 +1,11 @@ package status import ( - "fmt" + "github.com/hpcng/warewulf/internal/pkg/warewulfd" "github.com/spf13/cobra" ) func CobraRunE(cmd *cobra.Command, args []string) error { - fmt.Printf("Not implemented yet\n") - + warewulfd.DaemonStatus() return nil } diff --git a/internal/app/wwctl/server/stop/main.go b/internal/app/wwctl/server/stop/main.go index 19ca0495..b49f8641 100644 --- a/internal/app/wwctl/server/stop/main.go +++ b/internal/app/wwctl/server/stop/main.go @@ -1,11 +1,11 @@ package stop import ( - "fmt" + "github.com/hpcng/warewulf/internal/pkg/warewulfd" "github.com/spf13/cobra" ) func CobraRunE(cmd *cobra.Command, args []string) error { - fmt.Printf("Not implemented yet\n") + warewulfd.DaemonStop() return nil } diff --git a/internal/pkg/warewulfd/daemon.go b/internal/pkg/warewulfd/daemon.go new file mode 100644 index 00000000..5dbf94e5 --- /dev/null +++ b/internal/pkg/warewulfd/daemon.go @@ -0,0 +1,113 @@ +package warewulfd + +import ( + "fmt" + "github.com/hpcng/warewulf/internal/pkg/util" + "github.com/hpcng/warewulf/internal/pkg/wwlog" + "io/ioutil" + "os" + "os/exec" + "strconv" + "syscall" + "time" +) + +const ( + WAREWULFD_PIDFILE = "/tmp/warewulfd.pid" + WAREWULFD_LOGFILE = "/tmp/warewulfd.log" +) + +func DaemonStart() error { + + if os.Getenv("WAREWULFD_BACKGROUND") == "1" { + RunServer() + + } else { + os.Setenv("WAREWULFD_BACKGROUND", "1") + + f, err := os.OpenFile(WAREWULFD_LOGFILE, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644) + if err != nil { + return err + } + + p, err := os.OpenFile(WAREWULFD_PIDFILE, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) + if err != nil { + return err + } + + cmd := exec.Command(os.Args[0], "server", "start") + cmd.Stdout = f + cmd.Stderr = f + cmd.Start() + pid := cmd.Process.Pid + + p.WriteString(fmt.Sprintf("%d", pid)) + p.Close() + + time.Sleep(1 * time.Second) + + DaemonStatus() + } + + return nil +} + +func DaemonStatus() error { + + if util.IsFile(WAREWULFD_PIDFILE) == false { + wwlog.Printf(wwlog.INFO, "Warewulf daemon process not running (%s)\n", WAREWULFD_PIDFILE) + return nil + } + + dat, err := ioutil.ReadFile(WAREWULFD_PIDFILE) + if err != nil { + return err + } + + pid, _ := strconv.Atoi(string(dat)) + process, err := os.FindProcess(pid) + if err != nil { + fmt.Printf("Failed to find process: %s\n", err) + return err + } else { + err := process.Signal(syscall.Signal(0)) + if err != nil { + fmt.Printf("SIGCONT on pid %d returned: %v\n", pid, err) + return err + } else { + fmt.Printf("Warewulf daemon is running at PID: %d\n", pid) + } + } + + return nil +} + +func DaemonStop() error { + + if util.IsFile(WAREWULFD_PIDFILE) == false { + wwlog.Printf(wwlog.INFO, "Warewulf daemon process not running (%s)\n", WAREWULFD_PIDFILE) + return nil + } + + dat, err := ioutil.ReadFile(WAREWULFD_PIDFILE) + if err != nil { + return err + } + + pid, _ := strconv.Atoi(string(dat)) + process, err := os.FindProcess(pid) + if err != nil { + fmt.Printf("Failed to find process: %s\n", err) + } else { + err := process.Signal(syscall.Signal(15)) + if err != nil { + fmt.Printf("SIGCONT on pid %d returned: %v\n", pid, err) + } else { + fmt.Printf("Terminated Warewulf process at PID: %d\n", pid) + } + } + + os.Remove(WAREWULFD_PIDFILE) + + return nil +}