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) + } } }()