From 7f4ff9861c7c0dff57e35387e7f358008bd7d8a2 Mon Sep 17 00:00:00 2001 From: Christian Goll Date: Thu, 11 Nov 2021 11:55:57 +0100 Subject: [PATCH 01/15] implemented dealing of SIGHUP for wwclient --- cmd/wwclient/wwclient.go | 86 +++++++++++++++++++++++----------------- 1 file changed, 49 insertions(+), 37 deletions(-) diff --git a/cmd/wwclient/wwclient.go b/cmd/wwclient/wwclient.go index b51c9aca..3bef5453 100644 --- a/cmd/wwclient/wwclient.go +++ b/cmd/wwclient/wwclient.go @@ -8,9 +8,12 @@ import ( "net/http" "os" "os/exec" + "os/signal" "strings" + "syscall" "time" + "github.com/google/uuid" "github.com/hpcng/warewulf/internal/pkg/warewulfconf" "github.com/hpcng/warewulf/internal/pkg/wwlog" "github.com/talos-systems/go-smbios/smbios" @@ -68,7 +71,6 @@ func main() { ExpectContinueTimeout: 1 * time.Second, }, } - smbiosDump, err := smbios.New() if err != nil { wwlog.Printf(wwlog.ERROR, "Could not get SMBIOS info: %s\n", err) @@ -93,43 +95,19 @@ func main() { wwid := strings.Split(wwid_tmp[1], " ")[0] + // listen on SIGHUP + sigs := make(chan os.Signal) + signal.Notify(sigs, syscall.SIGHUP) + + go func() { + for sig := range sigs { + log.Printf("Received SIGNAL: %s\n", sig) + updateSystem(webclient, conf.Ipaddr, conf.Warewulf.Port, wwid, tag, localUUID) + } + }() + for { - var resp *http.Response - counter := 0 - - for { - var err error - - getString := fmt.Sprintf("http://%s:%d/overlay-runtime/%s?assetkey=%s&uuid=%s", conf.Ipaddr, conf.Warewulf.Port, wwid, tag, localUUID) - resp, err = webclient.Get(getString) - if err == nil { - break - } else { - if counter > 60 { - counter = 0 - } - if counter == 0 { - log.Println(err) - } - counter++ - } - - time.Sleep(1000 * time.Millisecond) - } - - if resp.StatusCode != 200 { - log.Printf("Not updating runtime overlay, got status code: %d\n", resp.StatusCode) - time.Sleep(60000 * time.Millisecond) - continue - } - - log.Printf("Updating system\n") - command := exec.Command("/bin/sh", "-c", "gzip -dc | cpio -iu") - command.Stdin = resp.Body - err := command.Run() - if err != nil { - log.Printf("ERROR: Failed running CPIO: %s\n", err) - } + updateSystem(webclient, conf.Ipaddr, conf.Warewulf.Port, wwid, tag, localUUID) if conf.Warewulf.UpdateInterval > 0 { time.Sleep(time.Duration(conf.Warewulf.UpdateInterval*1000) * time.Millisecond) @@ -138,3 +116,37 @@ func main() { } } } + +func updateSystem(webclient *http.Client, ipaddr string, port int, wwid string, tag string, localUUID uuid.UUID) { + var resp *http.Response + counter := 0 + for { + var err error + getString := fmt.Sprintf("http://%s:%d/overlay-runtime/%s?assetkey=%s&uuid=%s", ipaddr, port, wwid, tag, localUUID) + resp, err = webclient.Get(getString) + if err == nil { + break + } else { + if counter > 60 { + counter = 0 + } + if counter == 0 { + log.Println(err) + } + counter++ + } + time.Sleep(1000 * time.Millisecond) + } + if resp.StatusCode != 200 { + log.Printf("Not updating runtime overlay, got status code: %d\n", resp.StatusCode) + time.Sleep(60000 * time.Millisecond) + return + } + log.Printf("Updating system\n") + command := exec.Command("/bin/sh", "-c", "gzip -dc | cpio -iu") + command.Stdin = resp.Body + err := command.Run() + if err != nil { + log.Printf("ERROR: Failed running CPIO: %s\n", err) + } +} From 48fefd31ae35b006695cddeada25a291abdc4cb3 Mon Sep 17 00:00:00 2001 From: Christian Goll Date: Fri, 12 Nov 2021 11:37:03 +0100 Subject: [PATCH 02/15] renanmed wwclient.go for cobra integration --- cmd/wwclient/wwclient.go => internal/app/wwclient/root.go | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename cmd/wwclient/wwclient.go => internal/app/wwclient/root.go (100%) diff --git a/cmd/wwclient/wwclient.go b/internal/app/wwclient/root.go similarity index 100% rename from cmd/wwclient/wwclient.go rename to internal/app/wwclient/root.go From 93c337a4693f11233e50e2a1877a55d1c78c3e2f Mon Sep 17 00:00:00 2001 From: Christian Goll Date: Fri, 12 Nov 2021 11:24:26 +0100 Subject: [PATCH 03/15] added pidfile option for wwclient --- cmd/wwclient/main.go | 22 +++++++++++++ go.mod | 1 + internal/app/wwclient/root.go | 60 +++++++++++++++++++++++++++++++---- 3 files changed, 77 insertions(+), 6 deletions(-) create mode 100644 cmd/wwclient/main.go diff --git a/cmd/wwclient/main.go b/cmd/wwclient/main.go new file mode 100644 index 00000000..335a6b1c --- /dev/null +++ b/cmd/wwclient/main.go @@ -0,0 +1,22 @@ +package main + +import ( + "fmt" + "os" + + "github.com/hpcng/warewulf/internal/app/wwclient" +) + +func main() { + + root := wwclient.GetRootCommand() + + err := root.Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "ERROR: %s\n", err) + if wwclient.DebugFlag { + fmt.Printf("\nSTACK TRACE: %+v\n", err) + } + os.Exit(255) + } +} diff --git a/go.mod b/go.mod index bdda8a46..a939665a 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/containers/storage v1.30.0 github.com/creasty/defaults v1.5.2 github.com/fatih/color v1.13.0 + github.com/google/uuid v1.1.2 github.com/manifoldco/promptui v0.8.0 github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6 github.com/opencontainers/umoci v0.4.6 diff --git a/internal/app/wwclient/root.go b/internal/app/wwclient/root.go index 3bef5453..f62ced4f 100644 --- a/internal/app/wwclient/root.go +++ b/internal/app/wwclient/root.go @@ -1,6 +1,7 @@ -package main +package wwclient import ( + "errors" "fmt" "io/ioutil" "log" @@ -14,12 +15,49 @@ import ( "time" "github.com/google/uuid" + "github.com/talos-systems/go-smbios/smbios" + "github.com/hpcng/warewulf/internal/pkg/util" "github.com/hpcng/warewulf/internal/pkg/warewulfconf" "github.com/hpcng/warewulf/internal/pkg/wwlog" - "github.com/talos-systems/go-smbios/smbios" + "github.com/spf13/cobra" ) -func main() { +var ( + rootCmd = &cobra.Command{ + Use: "wwclient", + Short: "wwclient", + Long: "wwclient fetches the runtime overlay and puts it on the disk", + RunE: CobraRunE, + SilenceUsage: true, + } + DebugFlag bool + PIDFile string +) + +func init() { + rootCmd.PersistentFlags().BoolVarP(&DebugFlag, "debug", "d", false, "Run with debugging messages enabled.") + rootCmd.PersistentFlags().StringVarP(&PIDFile, "pidfile", "p", "/var/run/wwclient.pid", "PIDFile to use") + +} + +// GetRootCommand returns the root cobra.Command for the application. +func GetRootCommand() *cobra.Command { + // Run cobra + return rootCmd +} + +func CobraRunE(cmd *cobra.Command, args []string) error { + if util.IsFile(PIDFile) { + return errors.New("wwclient is already running") + } + p, err := os.OpenFile(PIDFile, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) + if err != nil { + return err + } + defer p.Close() + + fmt.Fprintf(p, "%d", os.Getpid()) + if os.Args[0] == "/warewulf/bin/wwclient" { err := os.Chdir("/") if err != nil { @@ -97,12 +135,22 @@ func main() { // listen on SIGHUP sigs := make(chan os.Signal) - signal.Notify(sigs, syscall.SIGHUP) + + signal.Notify(sigs, syscall.SIGHUP, syscall.SIGTERM) go func() { for sig := range sigs { - log.Printf("Received SIGNAL: %s\n", sig) - updateSystem(webclient, conf.Ipaddr, conf.Warewulf.Port, wwid, tag, localUUID) + switch sig { + case syscall.SIGHUP: + log.Printf("Received SIGNAL: %s\n", sig) + updateSystem(webclient, conf.Ipaddr, conf.Warewulf.Port, wwid, tag, localUUID) + case syscall.SIGTERM: + err = os.Remove(PIDFile) + if err != nil { + errors.New("could not remove pidfile") + } + os.Exit(0) + } } }() From 6a5809e7c43d0eba5c5d4450cfa5b9a8b5d3a0e1 Mon Sep 17 00:00:00 2001 From: Christian Goll Date: Fri, 12 Nov 2021 11:54:50 +0100 Subject: [PATCH 04/15] slightly improved error handling for wwclient --- internal/app/wwclient/root.go | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/internal/app/wwclient/root.go b/internal/app/wwclient/root.go index f62ced4f..3efbae5d 100644 --- a/internal/app/wwclient/root.go +++ b/internal/app/wwclient/root.go @@ -47,6 +47,11 @@ func GetRootCommand() *cobra.Command { } func CobraRunE(cmd *cobra.Command, args []string) error { + conf, err := warewulfconf.New() + if err != nil { + return err + } + if util.IsFile(PIDFile) { return errors.New("wwclient is already running") } @@ -72,22 +77,18 @@ func CobraRunE(cmd *cobra.Command, args []string) error { err := os.MkdirAll("/warewulf/wwclient-test", 0755) if err != nil { wwlog.Printf(wwlog.ERROR, "failed to create dir: %s", err) + _ = os.Remove(PIDFile) os.Exit(1) } err = os.Chdir("/warewulf/wwclient-test") if err != nil { wwlog.Printf(wwlog.ERROR, "failed to change dir: %s", err) + _ = os.Remove(PIDFile) os.Exit(1) } } - conf, err := warewulfconf.New() - if err != nil { - wwlog.Printf(wwlog.ERROR, "Could not get Warewulf configuration: %s\n", err) - os.Exit(1) - } - localTCPAddr := net.TCPAddr{} if conf.Warewulf.Secure { // Setup local port to something privileged (<1024) From d4f180f4b45b415693d604e6e3bd98adb6240dc8 Mon Sep 17 00:00:00 2001 From: Christian Goll Date: Fri, 12 Nov 2021 14:20:22 +0100 Subject: [PATCH 05/15] wwclient cleanup --- internal/app/wwclient/root.go | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/internal/app/wwclient/root.go b/internal/app/wwclient/root.go index 3efbae5d..fce1265c 100644 --- a/internal/app/wwclient/root.go +++ b/internal/app/wwclient/root.go @@ -32,6 +32,7 @@ var ( } DebugFlag bool PIDFile string + Webclient *http.Client ) func init() { @@ -53,7 +54,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } if util.IsFile(PIDFile) { - return errors.New("wwclient is already running") + return errors.New("found pidfile " + PIDFile + " not starting") } p, err := os.OpenFile(PIDFile, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) if err != nil { @@ -67,6 +68,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error { err := os.Chdir("/") if err != nil { wwlog.Printf(wwlog.ERROR, "failed to change dir: %s", err) + _ = os.Remove(PIDFile) os.Exit(1) } log.Printf("Updating live file system LIVE, cancel now if this is in error") @@ -96,7 +98,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error { wwlog.Printf(wwlog.INFO, "Running from trusted port\n") } - webclient := &http.Client{ + Webclient = &http.Client{ Transport: &http.Transport{ Proxy: http.ProxyFromEnvironment, DialContext: (&net.Dialer{ @@ -137,26 +139,23 @@ func CobraRunE(cmd *cobra.Command, args []string) error { // listen on SIGHUP sigs := make(chan os.Signal) - signal.Notify(sigs, syscall.SIGHUP, syscall.SIGTERM) + signal.Notify(sigs, syscall.SIGHUP, syscall.SIGTERM, syscall.SIGINT) go func() { for sig := range sigs { switch sig { case syscall.SIGHUP: log.Printf("Received SIGNAL: %s\n", sig) - updateSystem(webclient, conf.Ipaddr, conf.Warewulf.Port, wwid, tag, localUUID) - case syscall.SIGTERM: - err = os.Remove(PIDFile) - if err != nil { - errors.New("could not remove pidfile") - } + updateSystem(conf.Ipaddr, conf.Warewulf.Port, wwid, tag, localUUID) + case syscall.SIGTERM, syscall.SIGINT: + cleanUp() os.Exit(0) } } }() for { - updateSystem(webclient, conf.Ipaddr, conf.Warewulf.Port, wwid, tag, localUUID) + updateSystem(conf.Ipaddr, conf.Warewulf.Port, wwid, tag, localUUID) if conf.Warewulf.UpdateInterval > 0 { time.Sleep(time.Duration(conf.Warewulf.UpdateInterval*1000) * time.Millisecond) @@ -166,13 +165,13 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } } -func updateSystem(webclient *http.Client, ipaddr string, port int, wwid string, tag string, localUUID uuid.UUID) { +func updateSystem(ipaddr string, port int, wwid string, tag string, localUUID uuid.UUID) { var resp *http.Response counter := 0 for { var err error getString := fmt.Sprintf("http://%s:%d/overlay-runtime/%s?assetkey=%s&uuid=%s", ipaddr, port, wwid, tag, localUUID) - resp, err = webclient.Get(getString) + resp, err = Webclient.Get(getString) if err == nil { break } else { @@ -199,3 +198,12 @@ func updateSystem(webclient *http.Client, ipaddr string, port int, wwid string, log.Printf("ERROR: Failed running CPIO: %s\n", err) } } + +func cleanUp() { + err := os.Remove(PIDFile) + if err != nil { + errors.New("could not remove pidfile") + } + + Webclient.CloseIdleConnections() +} From d4eab02b710ba2ff4ef441c072438e065f3b298f Mon Sep 17 00:00:00 2001 From: Christian Goll Date: Fri, 12 Nov 2021 15:17:07 +0100 Subject: [PATCH 06/15] added wwclient.service to system overlay --- .../wwinit/etc/systemd/system/wwclient.service | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 overlays/wwinit/etc/systemd/system/wwclient.service diff --git a/overlays/wwinit/etc/systemd/system/wwclient.service b/overlays/wwinit/etc/systemd/system/wwclient.service new file mode 100644 index 00000000..af958807 --- /dev/null +++ b/overlays/wwinit/etc/systemd/system/wwclient.service @@ -0,0 +1,14 @@ +[Unit] +Description=Warewulf node runtime overlay update +After=network.target +After=local-fs.target + +[Service] +Type=simple +ExecStart=/warewulf/bin/wwclient +ExecReload=/bin/kill -s SIGHUP "$MAINPID" +PIDFile=/var/run/wwclient.pid +TimeoutSec=5 + +[Install] +WantedBy=multi-user.target \ No newline at end of file From e0ab4e47f4f3a7c3ab3d09ddf6f0e1033307f4ed Mon Sep 17 00:00:00 2001 From: mslacken Date: Fri, 14 Jan 2022 16:56:18 +0100 Subject: [PATCH 07/15] Added handling of symbolic links in overlays --- internal/pkg/overlay/overlay.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/internal/pkg/overlay/overlay.go b/internal/pkg/overlay/overlay.go index 06104b40..49342927 100644 --- a/internal/pkg/overlay/overlay.go +++ b/internal/pkg/overlay/overlay.go @@ -262,6 +262,16 @@ func BuildOverlay(nodeInfo node.NodeInfo, overlayName string) error { // } else if b, _ := regexp.MatchString(`\.ww[a-zA-Z0-9\-\._]*$`, location); b { // wwlog.Printf(wwlog.DEBUG, "Ignoring WW template file: %s\n", location) + } else if info.Mode()&os.ModeSymlink == os.ModeSymlink { + wwlog.Printf(wwlog.DEBUG, "Found symlink %s\n", location) + destination, err := os.Readlink(location) + if err != nil { + wwlog.Printf(wwlog.ERROR, "%s\n", err) + } + err = os.Symlink(destination, path.Join(tmpDir, location)) + if err != nil { + wwlog.Printf(wwlog.ERROR, "%s\n", err) + } } else { err := util.CopyFile(location, path.Join(tmpDir, location)) From 05f9c4d3af5eee9ab7ddfee00f938df8eb9e735b Mon Sep 17 00:00:00 2001 From: Christian Goll Date: Mon, 15 Nov 2021 14:11:44 +0100 Subject: [PATCH 08/15] fix linter warning --- internal/app/wwclient/root.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/internal/app/wwclient/root.go b/internal/app/wwclient/root.go index fce1265c..9d9c8c21 100644 --- a/internal/app/wwclient/root.go +++ b/internal/app/wwclient/root.go @@ -202,8 +202,7 @@ func updateSystem(ipaddr string, port int, wwid string, tag string, localUUID uu func cleanUp() { err := os.Remove(PIDFile) if err != nil { - errors.New("could not remove pidfile") + log.Printf("could not remove pidfile: %s\n", err) } - Webclient.CloseIdleConnections() } From 5abb1fc4c7befd37dcc934954e3e0ee5ff4fe51f Mon Sep 17 00:00:00 2001 From: Niko Kivel Date: Wed, 17 Nov 2021 23:46:21 +0100 Subject: [PATCH 09/15] stale pidfile handling --- internal/app/wwclient/root.go | 39 +++++++-------- internal/pkg/pidfile/pidfile.go | 84 +++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 22 deletions(-) create mode 100644 internal/pkg/pidfile/pidfile.go diff --git a/internal/app/wwclient/root.go b/internal/app/wwclient/root.go index 9d9c8c21..7d911c8a 100644 --- a/internal/app/wwclient/root.go +++ b/internal/app/wwclient/root.go @@ -16,7 +16,7 @@ import ( "github.com/google/uuid" "github.com/talos-systems/go-smbios/smbios" - "github.com/hpcng/warewulf/internal/pkg/util" + "github.com/hpcng/warewulf/internal/pkg/pidfile" "github.com/hpcng/warewulf/internal/pkg/warewulfconf" "github.com/hpcng/warewulf/internal/pkg/wwlog" "github.com/spf13/cobra" @@ -53,16 +53,12 @@ func CobraRunE(cmd *cobra.Command, args []string) error { return err } - if util.IsFile(PIDFile) { + pid, err := pidfile.Write(PIDFile) + if err != nil && pid == -1 { + wwlog.Printf(wwlog.WARN, "%v. starting new wwclient", err) + } else if err != nil && pid > 0 { return errors.New("found pidfile " + PIDFile + " not starting") } - p, err := os.OpenFile(PIDFile, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) - if err != nil { - return err - } - defer p.Close() - - fmt.Fprintf(p, "%d", os.Getpid()) if os.Args[0] == "/warewulf/bin/wwclient" { err := os.Chdir("/") @@ -137,20 +133,20 @@ func CobraRunE(cmd *cobra.Command, args []string) error { wwid := strings.Split(wwid_tmp[1], " ")[0] // listen on SIGHUP - sigs := make(chan os.Signal) + sigs := make(chan os.Signal, 1) signal.Notify(sigs, syscall.SIGHUP, syscall.SIGTERM, syscall.SIGINT) go func() { - for sig := range sigs { - switch sig { - case syscall.SIGHUP: - log.Printf("Received SIGNAL: %s\n", sig) - updateSystem(conf.Ipaddr, conf.Warewulf.Port, wwid, tag, localUUID) - case syscall.SIGTERM, syscall.SIGINT: - cleanUp() - os.Exit(0) - } + sig := <-sigs + switch sig { + case syscall.SIGHUP: + log.Printf("Received SIGNAL: %s\n", sig) + updateSystem(conf.Ipaddr, conf.Warewulf.Port, wwid, tag, localUUID) + case syscall.SIGTERM, syscall.SIGINT: + wwlog.Printf(wwlog.INFO, "termination wwclient!, %v", sig) + cleanUp() + os.Exit(0) } }() @@ -200,9 +196,8 @@ func updateSystem(ipaddr string, port int, wwid string, tag string, localUUID uu } func cleanUp() { - err := os.Remove(PIDFile) + err := pidfile.Remove(PIDFile) if err != nil { - log.Printf("could not remove pidfile: %s\n", err) + wwlog.Printf(wwlog.ERROR, "could not remove pidfile: %s\n", err) } - } diff --git a/internal/pkg/pidfile/pidfile.go b/internal/pkg/pidfile/pidfile.go new file mode 100644 index 00000000..9541ea99 --- /dev/null +++ b/internal/pkg/pidfile/pidfile.go @@ -0,0 +1,84 @@ +package pidfile + +// based on original work found here, github.com/soellman/pidfile + +import ( + "errors" + "fmt" + "io/ioutil" + "os" + "strconv" + "strings" + "syscall" +) + +var ( + ErrProcessRunning = errors.New("process is running") + ErrFileStale = errors.New("pidfile exists but process is not running") + ErrFileInvalid = errors.New("pidfile has invalid contents") +) + +// Remove a pidfile +func Remove(filename string) error { + return os.RemoveAll(filename) +} + +// Write writes a pidfile, returning an error +// if the process is already running or pidfile is orphaned +func Write(filename string) (int, error) { + return WriteControl(filename, os.Getpid(), false) +} + +func WriteControl(filename string, pid int, overwrite bool) (int, error) { + // Check for existing pid + oldpid, err := pidfileContents(filename) + if err != nil && !os.IsNotExist(err) { + return oldpid, err + } + + // We have a pid + if err == nil { + if pidIsRunning(oldpid) { + return oldpid, ErrProcessRunning + } + if !overwrite { + return -1, ErrFileStale + } + } + + // We're clear to (over)write the file + return pid, ioutil.WriteFile(filename, []byte(fmt.Sprintf("%d\n", pid)), 0644) +} + +func pidfileContents(filename string) (int, error) { + contents, err := ioutil.ReadFile(filename) + if err != nil { + return 0, err + } + + pid, err := strconv.Atoi(strings.TrimSpace(string(contents))) + if err != nil { + return 0, ErrFileInvalid + } + + return pid, nil +} + +func pidIsRunning(pid int) bool { + process, err := os.FindProcess(pid) + if err != nil { + return false + } + + err = process.Signal(syscall.Signal(0)) + + if err != nil && err.Error() == "no such process" { + return false + } + + if err != nil && err.Error() == "os: process already finished" { + return false + } + + return true +} From 2207ef84d9a44dc4d71daaa0e733d78603d7253e Mon Sep 17 00:00:00 2001 From: Christian Goll Date: Mon, 15 Nov 2021 11:24:20 +0100 Subject: [PATCH 10/15] removed legacy start of wwclient, added to systemd --- .../systemd/system/multi-user.target.wants/wwclient.service | 1 + overlays/wwinit/warewulf/init.d/80-wwclient | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 120000 overlays/wwinit/etc/systemd/system/multi-user.target.wants/wwclient.service diff --git a/overlays/wwinit/etc/systemd/system/multi-user.target.wants/wwclient.service b/overlays/wwinit/etc/systemd/system/multi-user.target.wants/wwclient.service new file mode 120000 index 00000000..84f22df4 --- /dev/null +++ b/overlays/wwinit/etc/systemd/system/multi-user.target.wants/wwclient.service @@ -0,0 +1 @@ +/etc/systemd/system/wwclient.service \ No newline at end of file diff --git a/overlays/wwinit/warewulf/init.d/80-wwclient b/overlays/wwinit/warewulf/init.d/80-wwclient index 184dac4e..d0945766 100644 --- a/overlays/wwinit/warewulf/init.d/80-wwclient +++ b/overlays/wwinit/warewulf/init.d/80-wwclient @@ -1,6 +1,7 @@ #!/bin/sh . /warewulf/config - +# Only start if the systemd is no available +test -e /usr/lib/systemd/systemd && exit 0 echo "Starting wwclient" nohup /warewulf/bin/wwclient >/var/log/wwclient.log 2>&1 Date: Mon, 6 Dec 2021 11:03:45 +0100 Subject: [PATCH 11/15] Add sd_notify to systemd after first sync --- go.mod | 1 + include/systemd/warewulfd.service.in | 2 +- internal/app/wwclient/root.go | 8 +++++++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index a939665a..08cc3e1c 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/brotherpowers/ipsubnet v0.0.0-20170914094241-30bc98f0a5b1 github.com/containers/image/v5 v5.7.0 github.com/containers/storage v1.30.0 + github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e github.com/creasty/defaults v1.5.2 github.com/fatih/color v1.13.0 github.com/google/uuid v1.1.2 diff --git a/include/systemd/warewulfd.service.in b/include/systemd/warewulfd.service.in index 20bd6367..65981fcb 100644 --- a/include/systemd/warewulfd.service.in +++ b/include/systemd/warewulfd.service.in @@ -5,7 +5,7 @@ After=network-online.target AssertFileIsExecutable=@BINDIR@/wwctl [Service] -Type=forking +Type=notify User=root Group=root diff --git a/internal/app/wwclient/root.go b/internal/app/wwclient/root.go index 7d911c8a..6470f112 100644 --- a/internal/app/wwclient/root.go +++ b/internal/app/wwclient/root.go @@ -16,6 +16,7 @@ import ( "github.com/google/uuid" "github.com/talos-systems/go-smbios/smbios" + "github.com/coreos/go-systemd/daemon" "github.com/hpcng/warewulf/internal/pkg/pidfile" "github.com/hpcng/warewulf/internal/pkg/warewulfconf" "github.com/hpcng/warewulf/internal/pkg/wwlog" @@ -149,9 +150,14 @@ func CobraRunE(cmd *cobra.Command, args []string) error { os.Exit(0) } }() - + var finishedInitialSync bool = false for { updateSystem(conf.Ipaddr, conf.Warewulf.Port, wwid, tag, localUUID) + if !finishedInitialSync { + // ignore error and status here, as this wouldn't change anything + _, _ = daemon.SdNotify(false, daemon.SdNotifyReady) + finishedInitialSync = true + } if conf.Warewulf.UpdateInterval > 0 { time.Sleep(time.Duration(conf.Warewulf.UpdateInterval*1000) * time.Millisecond) From e1c11a39446f4928400439d2c8a6d3ca8fea6f95 Mon Sep 17 00:00:00 2001 From: Christian Goll Date: Mon, 6 Dec 2021 16:59:41 +0100 Subject: [PATCH 12/15] Previous commits set the wrong service Type --- include/systemd/warewulfd.service.in | 2 +- overlays/wwinit/etc/systemd/system/wwclient.service | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/systemd/warewulfd.service.in b/include/systemd/warewulfd.service.in index 65981fcb..a343a0df 100644 --- a/include/systemd/warewulfd.service.in +++ b/include/systemd/warewulfd.service.in @@ -5,7 +5,7 @@ After=network-online.target AssertFileIsExecutable=@BINDIR@/wwctl [Service] -Type=notify +Type=simple User=root Group=root diff --git a/overlays/wwinit/etc/systemd/system/wwclient.service b/overlays/wwinit/etc/systemd/system/wwclient.service index af958807..4cc81927 100644 --- a/overlays/wwinit/etc/systemd/system/wwclient.service +++ b/overlays/wwinit/etc/systemd/system/wwclient.service @@ -4,11 +4,11 @@ After=network.target After=local-fs.target [Service] -Type=simple +Type=notify ExecStart=/warewulf/bin/wwclient ExecReload=/bin/kill -s SIGHUP "$MAINPID" PIDFile=/var/run/wwclient.pid -TimeoutSec=5 +TimeoutSec=60 [Install] -WantedBy=multi-user.target \ No newline at end of file +WantedBy=multi-user.target From 83d0ce88f59309156c114f5bc249219dff69efd5 Mon Sep 17 00:00:00 2001 From: Christian Goll Date: Thu, 9 Dec 2021 16:39:10 +0100 Subject: [PATCH 13/15] added go-systemd to go.sum --- go.sum | 1 + 1 file changed, 1 insertion(+) diff --git a/go.sum b/go.sum index 36920bdd..7d0741a2 100644 --- a/go.sum +++ b/go.sum @@ -202,6 +202,7 @@ github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20161114122254-48702e0da86b/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= From 6d1b3c66c5213559784b08def9e1e9bc6b9dbfc3 Mon Sep 17 00:00:00 2001 From: Christian Goll Date: Wed, 22 Dec 2021 15:47:20 +0100 Subject: [PATCH 14/15] listen mutliple times on SIGHUP --- internal/app/wwclient/root.go | 36 +++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/internal/app/wwclient/root.go b/internal/app/wwclient/root.go index 6470f112..fdca4cef 100644 --- a/internal/app/wwclient/root.go +++ b/internal/app/wwclient/root.go @@ -133,21 +133,28 @@ func CobraRunE(cmd *cobra.Command, args []string) error { wwid := strings.Split(wwid_tmp[1], " ")[0] + + duration := 300 + if conf.Warewulf.UpdateInterval > 0 { + duration = conf.Warewulf.UpdateInterval + } + stopTimer := time.NewTimer(time.Duration(duration) * time.Second) // listen on SIGHUP sigs := make(chan os.Signal, 1) - signal.Notify(sigs, syscall.SIGHUP, syscall.SIGTERM, syscall.SIGINT) - go func() { - sig := <-sigs - switch sig { - case syscall.SIGHUP: - log.Printf("Received SIGNAL: %s\n", sig) - updateSystem(conf.Ipaddr, conf.Warewulf.Port, wwid, tag, localUUID) - case syscall.SIGTERM, syscall.SIGINT: - wwlog.Printf(wwlog.INFO, "termination wwclient!, %v", sig) - cleanUp() - os.Exit(0) + for { + sig := <-sigs + switch sig { + case syscall.SIGHUP: + log.Printf("Received SIGNAL: %s\n", sig) + stopTimer.Stop() + stopTimer.Reset(0) + case syscall.SIGTERM, syscall.SIGINT: + wwlog.Printf(wwlog.INFO, "termination wwclient!, %v", sig) + cleanUp() + os.Exit(0) + } } }() var finishedInitialSync bool = false @@ -159,11 +166,8 @@ func CobraRunE(cmd *cobra.Command, args []string) error { finishedInitialSync = true } - if conf.Warewulf.UpdateInterval > 0 { - time.Sleep(time.Duration(conf.Warewulf.UpdateInterval*1000) * time.Millisecond) - } else { - time.Sleep(30000 * time.Millisecond * 1000) - } + <-stopTimer.C + stopTimer.Reset(time.Duration(duration) * time.Second) } } From 56fe1355cebbab5cc1b79798744ecc954d8eae20 Mon Sep 17 00:00:00 2001 From: Christian Goll Date: Wed, 26 Jan 2022 17:28:08 +0100 Subject: [PATCH 15/15] runtme overlay can only be downloaded by wwclien --- etc/ipxe/default.ipxe | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/etc/ipxe/default.ipxe b/etc/ipxe/default.ipxe index 32868718..a23fcd4b 100644 --- a/etc/ipxe/default.ipxe +++ b/etc/ipxe/default.ipxe @@ -15,9 +15,8 @@ kernel --name kernel ${base}/kernel/{{.Hwaddr}}?assetkey=${asset}&uuid=${uuid} initrd --name container ${base}/container/{{.Hwaddr}}?assetkey=${asset}&uuid=${uuid} || goto reboot initrd --name kmods ${base}/kmods/{{.Hwaddr}}?assetkey=${asset}&uuid=${uuid} || goto reboot initrd --name system ${base}/overlay-system/{{.Hwaddr}}?assetkey=${asset}&uuid=${uuid} || goto reboot -initrd --name runtime ${base}/overlay-runtime/{{.Hwaddr}}?assetkey=${asset}&uuid=${uuid} || goto reboot -boot kernel initrd=container initrd=kmods initrd=system initrd=runtime wwid={{.Hwaddr}} {{.KernelArgs}} || goto reboot +boot kernel initrd=container initrd=kmods initrd=system wwid={{.Hwaddr}} {{.KernelArgs}} || goto reboot :reboot echo