From 94f6154f682a88219a0b38ad93ced6abdddf284b Mon Sep 17 00:00:00 2001 From: Gregory Kurtzer Date: Mon, 7 Dec 2020 13:56:01 -0800 Subject: [PATCH 01/13] Minor fixup of variable nomenclature --- internal/app/wwctl/container/list/main.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/app/wwctl/container/list/main.go b/internal/app/wwctl/container/list/main.go index 132b118f..1a2f3128 100644 --- a/internal/app/wwctl/container/list/main.go +++ b/internal/app/wwctl/container/list/main.go @@ -18,8 +18,8 @@ func CobraRunE(cmd *cobra.Command, args []string) error { os.Exit(1) } - nconfig, _ := node.New() - nodes, _ := nconfig.FindAllNodes() + nodeDB, _ := node.New() + nodes, _ := nodeDB.FindAllNodes() nodemap := make(map[string]int) for _, n := range nodes { From f9ebd8cf4bfbdaee9c0e17a66f78b454b0ceacd7 Mon Sep 17 00:00:00 2001 From: Gregory Kurtzer Date: Mon, 7 Dec 2020 19:42:14 -0800 Subject: [PATCH 02/13] Added container delete command --- internal/app/wwctl/container/delete/main.go | 44 +++++++++++++++++++++ internal/app/wwctl/container/delete/root.go | 25 ++++++++++++ internal/app/wwctl/container/root.go | 3 +- 3 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 internal/app/wwctl/container/delete/main.go create mode 100644 internal/app/wwctl/container/delete/root.go diff --git a/internal/app/wwctl/container/delete/main.go b/internal/app/wwctl/container/delete/main.go new file mode 100644 index 00000000..dfd9d8b5 --- /dev/null +++ b/internal/app/wwctl/container/delete/main.go @@ -0,0 +1,44 @@ +package delete + +import ( + "fmt" + "github.com/hpcng/warewulf/internal/pkg/container" + "github.com/hpcng/warewulf/internal/pkg/node" + "github.com/hpcng/warewulf/internal/pkg/wwlog" + "github.com/spf13/cobra" + "os" +) + +func CobraRunE(cmd *cobra.Command, args []string) error { + + nodeDB, err := node.New() + if err != nil { + wwlog.Printf(wwlog.ERROR, "Could not open nodeDB: %s\n", err) + os.Exit(1) + } + + nodes, _ := nodeDB.FindAllNodes() + +ARG_LOOP: + for _, arg := range args { + for _, n := range nodes { + if n.ContainerName.Get() == arg { + wwlog.Printf(wwlog.ERROR, "Container is configured for nodes, skipping: %s\n", arg) + continue ARG_LOOP + } + } + + if container.ValidSource(arg) == false { + wwlog.Printf(wwlog.ERROR, "Container name is not a valid source: %s\n", arg) + continue + } + err := container.DeleteSource(arg) + if err != nil { + wwlog.Printf(wwlog.ERROR, "Could not remove source: %s\n", arg) + } else { + fmt.Printf("Container has been deleted: %s\n", arg) + } + } + + return nil +} diff --git a/internal/app/wwctl/container/delete/root.go b/internal/app/wwctl/container/delete/root.go new file mode 100644 index 00000000..2171df6a --- /dev/null +++ b/internal/app/wwctl/container/delete/root.go @@ -0,0 +1,25 @@ +package delete + +import "github.com/spf13/cobra" + +var ( + baseCmd = &cobra.Command{ + Use: "delete", + Short: "Delete Source OCI VNFS images", + Long: "Delete Source OCI VNFS images ", + RunE: CobraRunE, + Args: cobra.MinimumNArgs(1), + } + SetForce bool + SetUpdate bool + SetBuild bool +) + +func init() { + +} + +// GetRootCommand returns the root cobra.Command for the application. +func GetCommand() *cobra.Command { + return baseCmd +} diff --git a/internal/app/wwctl/container/root.go b/internal/app/wwctl/container/root.go index 9bda463a..00739fd7 100644 --- a/internal/app/wwctl/container/root.go +++ b/internal/app/wwctl/container/root.go @@ -2,6 +2,7 @@ package container import ( "github.com/hpcng/warewulf/internal/app/wwctl/container/build" + "github.com/hpcng/warewulf/internal/app/wwctl/container/delete" "github.com/hpcng/warewulf/internal/app/wwctl/container/exec" "github.com/hpcng/warewulf/internal/app/wwctl/container/list" "github.com/hpcng/warewulf/internal/app/wwctl/container/pull" @@ -22,7 +23,7 @@ func init() { baseCmd.AddCommand(list.GetCommand()) baseCmd.AddCommand(pull.GetCommand()) baseCmd.AddCommand(exec.GetCommand()) - + baseCmd.AddCommand(delete.GetCommand()) } // GetRootCommand returns the root cobra.Command for the application. From 28e66e8659f07bb05b5ac877e7b07513f67848a7 Mon Sep 17 00:00:00 2001 From: Gregory Kurtzer Date: Mon, 7 Dec 2020 19:43:04 -0800 Subject: [PATCH 03/13] Added some debugging output for building overlays --- internal/pkg/overlay/overlay.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/internal/pkg/overlay/overlay.go b/internal/pkg/overlay/overlay.go index d133aa14..00c87c96 100644 --- a/internal/pkg/overlay/overlay.go +++ b/internal/pkg/overlay/overlay.go @@ -118,9 +118,13 @@ func buildOverlay(nodeList []node.NodeInfo, overlayType string) error { var OverlayFile string if overlayType == "runtime" { + wwlog.Printf(wwlog.VERBOSE, "Building runtime overlay for: %s\n", n.Id.Get()) + OverlayDir = config.RuntimeOverlaySource(n.RuntimeOverlay.Get()) OverlayFile = config.RuntimeOverlayImage(n.Id.Get()) } else if overlayType == "system" { + wwlog.Printf(wwlog.VERBOSE, "Building system overlay for: %s\n", n.Id.Get()) + OverlayDir = config.SystemOverlaySource(n.RuntimeOverlay.Get()) OverlayFile = config.SystemOverlayImage(n.Id.Get()) } else { From dd1913c1debbca1361c0752e2d1a6e8e31239a90 Mon Sep 17 00:00:00 2001 From: Gregory Kurtzer Date: Mon, 7 Dec 2020 19:43:56 -0800 Subject: [PATCH 04/13] Backend for `container delete` --- internal/pkg/container/vnfs.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/internal/pkg/container/vnfs.go b/internal/pkg/container/vnfs.go index e86b8e45..f81ac344 100644 --- a/internal/pkg/container/vnfs.go +++ b/internal/pkg/container/vnfs.go @@ -77,9 +77,15 @@ func ValidSource(name string) bool { } if util.IsDir(fullPath) == false { - wwlog.Printf(wwlog.WARN, "Location is not a VNFS source directory: %s\n", name) + wwlog.Printf(wwlog.VERBOSE, "Location is not a VNFS source directory: %s\n", name) return false } return true } + +func DeleteSource(name string) error { + fullPath := RootFsDir(name) + + return os.RemoveAll(fullPath) +} From 7798b6b1e74b3b395cb4452ddb171b81ed635d59 Mon Sep 17 00:00:00 2001 From: Gregory Kurtzer Date: Mon, 7 Dec 2020 19:44:46 -0800 Subject: [PATCH 05/13] Add the ability to do node discovery for unconfigured nodes. --- etc/ipxe/unconfigured.ipxe | 12 +++ internal/app/warewulfd/response/ipxe.go | 103 ++++++++++++++++++------ internal/pkg/node/constructors.go | 31 +++++++ 3 files changed, 121 insertions(+), 25 deletions(-) create mode 100644 etc/ipxe/unconfigured.ipxe diff --git a/etc/ipxe/unconfigured.ipxe b/etc/ipxe/unconfigured.ipxe new file mode 100644 index 00000000..e12de477 --- /dev/null +++ b/etc/ipxe/unconfigured.ipxe @@ -0,0 +1,12 @@ +#!ipxe + +echo +echo ================================================================================ +echo Warewulf v4 +echo +echo MESSAGE: This node is unconfigured. Please have your system administrator add a +echo configuration for this node with HW address: {{$.Hwaddr}} +echo +echo Rebooting in 1 minute... +sleep 60 +reboot \ No newline at end of file diff --git a/internal/app/warewulfd/response/ipxe.go b/internal/app/warewulfd/response/ipxe.go index 794159b5..0b838ecd 100644 --- a/internal/app/warewulfd/response/ipxe.go +++ b/internal/app/warewulfd/response/ipxe.go @@ -3,6 +3,7 @@ package response import ( "fmt" "github.com/hpcng/warewulf/internal/pkg/node" + "github.com/hpcng/warewulf/internal/pkg/overlay" "github.com/hpcng/warewulf/internal/pkg/warewulfconf" "github.com/hpcng/warewulf/internal/pkg/wwlog" "log" @@ -13,6 +14,8 @@ import ( ) type iPxeTemplate struct { + Message string + WaitTime string Hostname string Fqdn string ContainerName string @@ -25,8 +28,9 @@ type iPxeTemplate struct { func IpxeSend(w http.ResponseWriter, req *http.Request) { url := strings.Split(req.URL.Path, "/") + var unconfiguredNode bool - nodes, err := node.New() + nodeDB, err := node.New() if err != nil { log.Printf("Could not read node configuration file: %s\n", err) w.WriteHeader(503) @@ -35,28 +39,56 @@ func IpxeSend(w http.ResponseWriter, req *http.Request) { if url[2] == "" { log.Printf("ERROR: Bad iPXE request from %s\n", req.RemoteAddr) - return - } - - hwaddr := strings.ReplaceAll(url[2], "-", ":") - node, err := nodes.FindByHwaddr(hwaddr) - if err != nil { - log.Printf("Could not find HW Addr: %s: %s\n", hwaddr, err) w.WriteHeader(404) return } - if node.Id.Defined() == true { - conf, err := warewulfconf.New() + conf, err := warewulfconf.New() + if err != nil { + wwlog.Printf(wwlog.ERROR, "%s\n", err) + w.WriteHeader(503) + return + } + + hwaddr := strings.ReplaceAll(url[2], "-", ":") + + n, err := nodeDB.FindByHwaddr(hwaddr) + if err != nil { + // If we failed to find a node, let's see if we can add one... + var netdev string + + wwlog.Printf(wwlog.INFO, "Node was not found, looking for discoverable nodes...\n") + + n, netdev, err = nodeDB.FindUnconfiguredNode() if err != nil { - wwlog.Printf(wwlog.ERROR, "%s\n", err) - return + wwlog.Printf(wwlog.WARN, "Node was not found, no nodes are discoverable...\n") + unconfiguredNode = true + + } else { + wwlog.Printf(wwlog.INFO, "Adding new configuration to discoverable node: %s\n", n.Id.Get()) + + n.NetDevs[netdev].Hwaddr.Set(hwaddr) + err := nodeDB.NodeUpdate(n) + if err != nil { + wwlog.Printf(wwlog.ERROR, "Could not add discovered configuration for node: %s\n", n.Id.Get()) + unconfiguredNode = true + } else { + err := nodeDB.Persist() + if err != nil { + wwlog.Printf(wwlog.ERROR, "Could not persist new node configuration while adding node: %s\n", n.Id.Get()) + unconfiguredNode = true + } else { + _ = overlay.BuildSystemOverlay([]node.NodeInfo{n}) + _ = overlay.BuildRuntimeOverlay([]node.NodeInfo{n}) + } + } } + } - log.Printf("IPXE: %15s: %s\n", node.Id.Get(), req.URL.Path) + if unconfiguredNode == true { + log.Printf("UNCONFIGURED NODE: %15s\n", hwaddr) - // TODO: Fix template path to use config package - ipxeTemplate := fmt.Sprintf("/etc/warewulf/ipxe/%s.ipxe", node.Ipxe.Get()) + ipxeTemplate := fmt.Sprintf("/etc/warewulf/ipxe/unconfigured.ipxe", n.Ipxe.Get()) tmpl, err := template.ParseFiles(ipxeTemplate) if err != nil { @@ -66,14 +98,7 @@ func IpxeSend(w http.ResponseWriter, req *http.Request) { var replace iPxeTemplate - replace.Fqdn = node.Id.Get() - replace.Ipaddr = conf.Ipaddr - replace.Port = strconv.Itoa(conf.Warewulf.Port) - replace.Hostname = node.Id.Get() - replace.Hwaddr = url[2] - replace.ContainerName = node.ContainerName.Get() - replace.KernelArgs = node.KernelArgs.Get() - replace.KernelVersion = node.KernelVersion.Get() + replace.Hwaddr = hwaddr err = tmpl.Execute(w, replace) if err != nil { @@ -81,10 +106,38 @@ func IpxeSend(w http.ResponseWriter, req *http.Request) { return } - log.Printf("SEND: %15s: %s\n", node.Id.Get(), ipxeTemplate) + return } else { - log.Printf("ERROR: iPXE request from unknown Node (hwaddr=%s)\n", url[2]) + log.Printf("IPXE: %15s: %s\n", n.Id.Get(), req.URL.Path) + + ipxeTemplate := fmt.Sprintf("/etc/warewulf/ipxe/%s.ipxe", n.Ipxe.Get()) + + tmpl, err := template.ParseFiles(ipxeTemplate) + if err != nil { + wwlog.Printf(wwlog.ERROR, "%s\n", err) + return + } + + var replace iPxeTemplate + + replace.Fqdn = n.Id.Get() + replace.Ipaddr = conf.Ipaddr + replace.Port = strconv.Itoa(conf.Warewulf.Port) + replace.Hostname = n.Id.Get() + replace.Hwaddr = url[2] + replace.ContainerName = n.ContainerName.Get() + replace.KernelArgs = n.KernelArgs.Get() + replace.KernelVersion = n.KernelVersion.Get() + + err = tmpl.Execute(w, replace) + if err != nil { + wwlog.Printf(wwlog.ERROR, "%s\n", err) + return + } + + log.Printf("SEND: %15s: %s\n", n.Id.Get(), ipxeTemplate) + } return } diff --git a/internal/pkg/node/constructors.go b/internal/pkg/node/constructors.go index 1211b384..35895d1b 100644 --- a/internal/pkg/node/constructors.go +++ b/internal/pkg/node/constructors.go @@ -7,6 +7,7 @@ import ( "gopkg.in/yaml.v2" "io/ioutil" "regexp" + "sort" "strings" ) @@ -174,9 +175,39 @@ func (self *nodeYaml) FindAllProfiles() ([]NodeInfo, error) { ret = append(ret, p) } + + sort.Slice(ret, func(i, j int) bool { + if ret[i].ClusterName.Get() < ret[j].ClusterName.Get() { + return true + } else if ret[i].ClusterName.Get() == ret[j].ClusterName.Get() { + if ret[i].Id.Get() < ret[j].Id.Get() { + return true + } + } + return false + }) + return ret, nil } +func (self *nodeYaml) FindUnconfiguredNode() (NodeInfo, string, error) { + var ret NodeInfo + + nodes, _ := self.FindAllNodes() + + for _, node := range nodes { + for netdev, dev := range node.NetDevs { + if dev.Hwaddr.Defined() == false && dev.Ipaddr.Defined() == true { + if dev.Type.Defined() == false || dev.Type.Get() == "ethernet" { + return node, netdev, nil + } + } + } + } + + return ret, "", errors.New("No unconfigured nodes found") +} + func (self *nodeYaml) FindByHwaddr(hwa string) (NodeInfo, error) { var ret NodeInfo From 0b0efa0637ac21989eef17c22059d893bcb260a1 Mon Sep 17 00:00:00 2001 From: Gregory Kurtzer Date: Thu, 10 Dec 2020 20:54:15 -0800 Subject: [PATCH 06/13] Fix minor bug WRT top level container directory not being removed --- internal/pkg/container/vnfs.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/pkg/container/vnfs.go b/internal/pkg/container/vnfs.go index f81ac344..436dfed7 100644 --- a/internal/pkg/container/vnfs.go +++ b/internal/pkg/container/vnfs.go @@ -85,7 +85,7 @@ func ValidSource(name string) bool { } func DeleteSource(name string) error { - fullPath := RootFsDir(name) + fullPath := SourceDir(name) return os.RemoveAll(fullPath) } From a5e79ae560542df0bc3bfe6596426785a417f5eb Mon Sep 17 00:00:00 2001 From: Gregory Kurtzer Date: Thu, 10 Dec 2020 20:57:02 -0800 Subject: [PATCH 07/13] Moved `wwctl service` to `wwctl system` --- internal/app/wwctl/root.go | 6 ++++-- internal/app/wwctl/{service => system}/dhcp/root.go | 0 internal/app/wwctl/{service => system}/root.go | 8 ++++---- internal/app/wwctl/{service => system}/tftp/root.go | 0 4 files changed, 8 insertions(+), 6 deletions(-) rename internal/app/wwctl/{service => system}/dhcp/root.go (100%) rename internal/app/wwctl/{service => system}/root.go (85%) rename internal/app/wwctl/{service => system}/tftp/root.go (100%) diff --git a/internal/app/wwctl/root.go b/internal/app/wwctl/root.go index 72119651..a8a0a2f0 100644 --- a/internal/app/wwctl/root.go +++ b/internal/app/wwctl/root.go @@ -7,7 +7,8 @@ import ( "github.com/hpcng/warewulf/internal/app/wwctl/overlay" "github.com/hpcng/warewulf/internal/app/wwctl/profile" "github.com/hpcng/warewulf/internal/app/wwctl/ready" - "github.com/hpcng/warewulf/internal/app/wwctl/service" + "github.com/hpcng/warewulf/internal/app/wwctl/server" + "github.com/hpcng/warewulf/internal/app/wwctl/system" "github.com/hpcng/warewulf/internal/pkg/wwlog" "github.com/spf13/cobra" @@ -37,8 +38,9 @@ func init() { rootCmd.AddCommand(kernel.GetCommand()) // rootCmd.AddCommand(group.GetCommand()) rootCmd.AddCommand(profile.GetCommand()) - rootCmd.AddCommand(service.GetCommand()) + rootCmd.AddCommand(system.GetCommand()) rootCmd.AddCommand(ready.GetCommand()) + rootCmd.AddCommand(server.GetCommand()) } diff --git a/internal/app/wwctl/service/dhcp/root.go b/internal/app/wwctl/system/dhcp/root.go similarity index 100% rename from internal/app/wwctl/service/dhcp/root.go rename to internal/app/wwctl/system/dhcp/root.go diff --git a/internal/app/wwctl/service/root.go b/internal/app/wwctl/system/root.go similarity index 85% rename from internal/app/wwctl/service/root.go rename to internal/app/wwctl/system/root.go index 55167a35..24dd050b 100644 --- a/internal/app/wwctl/service/root.go +++ b/internal/app/wwctl/system/root.go @@ -1,16 +1,16 @@ -package service +package system import ( "fmt" - "github.com/hpcng/warewulf/internal/app/wwctl/service/dhcp" - "github.com/hpcng/warewulf/internal/app/wwctl/service/tftp" + "github.com/hpcng/warewulf/internal/app/wwctl/system/dhcp" + "github.com/hpcng/warewulf/internal/app/wwctl/system/tftp" "github.com/spf13/cobra" "os" ) var ( baseCmd = &cobra.Command{ - Use: "service", + Use: "system", Short: "Initialize Warewulf services", Long: "Warewulf Service Initialization", RunE: CobraRunE, diff --git a/internal/app/wwctl/service/tftp/root.go b/internal/app/wwctl/system/tftp/root.go similarity index 100% rename from internal/app/wwctl/service/tftp/root.go rename to internal/app/wwctl/system/tftp/root.go From c53c97dbcfff82e72fbd98f0012d212dd037e2a4 Mon Sep 17 00:00:00 2001 From: Gregory Kurtzer Date: Thu, 10 Dec 2020 20:57:32 -0800 Subject: [PATCH 08/13] Created template for server process subcommands --- internal/app/warewulfd/root.go | 15 +++++++------- .../app/wwctl/container/exec/child/root.go | 9 +++++---- internal/app/wwctl/container/exec/root.go | 11 +++++----- internal/app/wwctl/server/root.go | 20 +++++++++++++++++++ internal/app/wwctl/server/start/main.go | 8 ++++++++ internal/app/wwctl/server/start/root.go | 20 +++++++++++++++++++ internal/app/wwctl/server/status/main.go | 8 ++++++++ internal/app/wwctl/server/status/root.go | 20 +++++++++++++++++++ internal/app/wwctl/server/stop/main.go | 8 ++++++++ internal/app/wwctl/server/stop/root.go | 20 +++++++++++++++++++ .../wwctl/{service => system}/dhcp/main.go | 0 .../wwctl/{service => system}/tftp/main.go | 0 12 files changed, 122 insertions(+), 17 deletions(-) create mode 100644 internal/app/wwctl/server/root.go create mode 100644 internal/app/wwctl/server/start/main.go create mode 100644 internal/app/wwctl/server/start/root.go create mode 100644 internal/app/wwctl/server/status/main.go create mode 100644 internal/app/wwctl/server/status/root.go create mode 100644 internal/app/wwctl/server/stop/main.go create mode 100644 internal/app/wwctl/server/stop/root.go rename internal/app/wwctl/{service => system}/dhcp/main.go (100%) rename internal/app/wwctl/{service => system}/tftp/main.go (100%) diff --git a/internal/app/warewulfd/root.go b/internal/app/warewulfd/root.go index 9809b0b5..7d0032c3 100644 --- a/internal/app/warewulfd/root.go +++ b/internal/app/warewulfd/root.go @@ -7,17 +7,16 @@ import ( var ( baseCmd = &cobra.Command{ - Use: "warewulfd", - Short: "Warewulf Daemon Service", - Long: "This is the primary Warewulf service for provisioning nodes", - RunE: CobraRunE, - PersistentPreRunE: rootPersistentPreRunE, + Use: "warewulfd", + Short: "Warewulf Daemon Service", + Long: "This is the primary Warewulf system for provisioning nodes", + RunE: CobraRunE, + PersistentPreRunE: rootPersistentPreRunE, } verboseArg bool - debugArg bool + debugArg bool ) - func init() { baseCmd.PersistentFlags().BoolVarP(&verboseArg, "verbose", "v", false, "Run with increased verbosity.") baseCmd.PersistentFlags().BoolVarP(&debugArg, "debug", "d", false, "Run with debugging messages enabled.") @@ -37,4 +36,4 @@ func rootPersistentPreRunE(cmd *cobra.Command, args []string) error { wwlog.SetLevel(wwlog.INFO) } return nil -} \ No newline at end of file +} diff --git a/internal/app/wwctl/container/exec/child/root.go b/internal/app/wwctl/container/exec/child/root.go index 6df31ff4..48aa0d8b 100644 --- a/internal/app/wwctl/container/exec/child/root.go +++ b/internal/app/wwctl/container/exec/child/root.go @@ -4,10 +4,11 @@ import "github.com/spf13/cobra" var ( baseCmd = &cobra.Command{ - Use: "__child", - Hidden: true, - RunE: CobraRunE, - Args: cobra.MinimumNArgs(1), + Use: "__child", + Hidden: true, + RunE: CobraRunE, + Args: cobra.MinimumNArgs(1), + FParseErrWhitelist: cobra.FParseErrWhitelist{UnknownFlags: true}, } ) diff --git a/internal/app/wwctl/container/exec/root.go b/internal/app/wwctl/container/exec/root.go index 049ca014..32b6c75b 100644 --- a/internal/app/wwctl/container/exec/root.go +++ b/internal/app/wwctl/container/exec/root.go @@ -7,11 +7,12 @@ import ( var ( baseCmd = &cobra.Command{ - Use: "exec", - Short: "Spawn any command inside a Warewulf container", - Long: "Run a command inside a Warewulf container ", - RunE: CobraRunE, - Args: cobra.MinimumNArgs(1), + Use: "exec", + Short: "Spawn any command inside a Warewulf container", + Long: "Run a command inside a Warewulf container ", + RunE: CobraRunE, + Args: cobra.MinimumNArgs(1), + FParseErrWhitelist: cobra.FParseErrWhitelist{UnknownFlags: true}, } ) diff --git a/internal/app/wwctl/server/root.go b/internal/app/wwctl/server/root.go new file mode 100644 index 00000000..26870499 --- /dev/null +++ b/internal/app/wwctl/server/root.go @@ -0,0 +1,20 @@ +package server + +import "github.com/spf13/cobra" + +var ( + baseCmd = &cobra.Command{ + Use: "server", + Short: "Warewulf server process commands", + Long: "Warewulf profiles...", + } + test bool +) + +func init() { +} + +// GetRootCommand returns the root cobra.Command for the application. +func GetCommand() *cobra.Command { + return baseCmd +} diff --git a/internal/app/wwctl/server/start/main.go b/internal/app/wwctl/server/start/main.go new file mode 100644 index 00000000..3f368ae7 --- /dev/null +++ b/internal/app/wwctl/server/start/main.go @@ -0,0 +1,8 @@ +package start + +import "github.com/spf13/cobra" + +func CobraRunE(cmd *cobra.Command, args []string) error { + + return nil +} diff --git a/internal/app/wwctl/server/start/root.go b/internal/app/wwctl/server/start/root.go new file mode 100644 index 00000000..357e0169 --- /dev/null +++ b/internal/app/wwctl/server/start/root.go @@ -0,0 +1,20 @@ +package start + +import "github.com/spf13/cobra" + +var ( + baseCmd = &cobra.Command{ + Use: "start", + Short: "Start Warewulf server", + Long: "Warewulf Server ", + RunE: CobraRunE, + } +) + +func init() { +} + +// GetRootCommand returns the root cobra.Command for the application. +func GetCommand() *cobra.Command { + return baseCmd +} diff --git a/internal/app/wwctl/server/status/main.go b/internal/app/wwctl/server/status/main.go new file mode 100644 index 00000000..5c1b993d --- /dev/null +++ b/internal/app/wwctl/server/status/main.go @@ -0,0 +1,8 @@ +package status + +import "github.com/spf13/cobra" + +func CobraRunE(cmd *cobra.Command, args []string) error { + + return nil +} diff --git a/internal/app/wwctl/server/status/root.go b/internal/app/wwctl/server/status/root.go new file mode 100644 index 00000000..71805969 --- /dev/null +++ b/internal/app/wwctl/server/status/root.go @@ -0,0 +1,20 @@ +package status + +import "github.com/spf13/cobra" + +var ( + baseCmd = &cobra.Command{ + Use: "status", + Short: "Warewulf server status", + Long: "Warewulf Server ", + RunE: CobraRunE, + } +) + +func init() { +} + +// GetRootCommand returns the root cobra.Command for the application. +func GetCommand() *cobra.Command { + return baseCmd +} diff --git a/internal/app/wwctl/server/stop/main.go b/internal/app/wwctl/server/stop/main.go new file mode 100644 index 00000000..daa8898b --- /dev/null +++ b/internal/app/wwctl/server/stop/main.go @@ -0,0 +1,8 @@ +package stop + +import "github.com/spf13/cobra" + +func CobraRunE(cmd *cobra.Command, args []string) error { + + return nil +} diff --git a/internal/app/wwctl/server/stop/root.go b/internal/app/wwctl/server/stop/root.go new file mode 100644 index 00000000..fd331c56 --- /dev/null +++ b/internal/app/wwctl/server/stop/root.go @@ -0,0 +1,20 @@ +package stop + +import "github.com/spf13/cobra" + +var ( + baseCmd = &cobra.Command{ + Use: "stop", + Short: "Stop Warewulf server", + Long: "Warewulf Server ", + RunE: CobraRunE, + } +) + +func init() { +} + +// GetRootCommand returns the root cobra.Command for the application. +func GetCommand() *cobra.Command { + return baseCmd +} diff --git a/internal/app/wwctl/service/dhcp/main.go b/internal/app/wwctl/system/dhcp/main.go similarity index 100% rename from internal/app/wwctl/service/dhcp/main.go rename to internal/app/wwctl/system/dhcp/main.go diff --git a/internal/app/wwctl/service/tftp/main.go b/internal/app/wwctl/system/tftp/main.go similarity index 100% rename from internal/app/wwctl/service/tftp/main.go rename to internal/app/wwctl/system/tftp/main.go From 90246f227f116196caa9dcc55e97371190e99d16 Mon Sep 17 00:00:00 2001 From: Gregory Kurtzer Date: Fri, 11 Dec 2020 23:30:29 -0800 Subject: [PATCH 09/13] Moved warewulfd commandline program into wwctl --- Makefile | 6 +-- cmd/warewulfd/main.go | 12 ------ internal/app/warewulfd/root.go | 39 ------------------- internal/app/warewulfd/warewulfd.go | 24 ------------ internal/app/wwctl/server/root.go | 11 +++++- internal/app/wwctl/server/start/main.go | 7 +++- internal/app/wwctl/server/status/main.go | 6 ++- internal/app/wwctl/server/stop/main.go | 7 +++- .../response => pkg/warewulfd}/container.go | 2 +- .../response => pkg/warewulfd}/ipxe.go | 2 +- .../response => pkg/warewulfd}/kernel.go | 2 +- .../response => pkg/warewulfd}/kmods.go | 2 +- .../response => pkg/warewulfd}/runtime.go | 2 +- .../response => pkg/warewulfd}/system.go | 2 +- .../response => pkg/warewulfd}/util.go | 2 +- internal/pkg/warewulfd/warewulfd.go | 27 +++++++++++++ 16 files changed, 60 insertions(+), 93 deletions(-) delete mode 100644 cmd/warewulfd/main.go delete mode 100644 internal/app/warewulfd/root.go delete mode 100644 internal/app/warewulfd/warewulfd.go rename internal/{app/warewulfd/response => pkg/warewulfd}/container.go (97%) rename internal/{app/warewulfd/response => pkg/warewulfd}/ipxe.go (99%) rename internal/{app/warewulfd/response => pkg/warewulfd}/kernel.go (97%) rename internal/{app/warewulfd/response => pkg/warewulfd}/kmods.go (97%) rename internal/{app/warewulfd/response => pkg/warewulfd}/runtime.go (99%) rename internal/{app/warewulfd/response => pkg/warewulfd}/system.go (97%) rename internal/{app/warewulfd/response => pkg/warewulfd}/util.go (98%) create mode 100644 internal/pkg/warewulfd/warewulfd.go diff --git a/Makefile b/Makefile index d4e74189..b71f2782 100644 --- a/Makefile +++ b/Makefile @@ -40,7 +40,7 @@ lint: @echo Running golangci-lint... @$(GOLANGCI_LINT) run --build-tags "$(WW_BUILD_GO_BUILD_TAGS)" ./... -all: vendor warewulfd wwctl wwclient +all: vendor wwctl wwclient files: all install -d -m 0755 /var/warewulf/ @@ -60,9 +60,6 @@ services: files # sudo systemctl enable tftp # sudo systemctl restart tftp -warewulfd: - cd cmd/warewulfd; go build -mod vendor -tags "$(WW_BUILD_GO_BUILD_TAGS)" -o ../../warewulfd - wwctl: cd cmd/wwctl; go build -mod vendor -tags "$(WW_BUILD_GO_BUILD_TAGS)" -o ../../wwctl @@ -70,7 +67,6 @@ wwclient: cd cmd/wwclient; CGO_ENABLED=0 GOOS=linux go build -mod vendor -a -ldflags '-extldflags -static' -o ../../wwclient clean: - rm -f warewulfd rm -f wwclient rm -f wwctl diff --git a/cmd/warewulfd/main.go b/cmd/warewulfd/main.go deleted file mode 100644 index 019de38f..00000000 --- a/cmd/warewulfd/main.go +++ /dev/null @@ -1,12 +0,0 @@ -package main - -import ( - "github.com/hpcng/warewulf/internal/app/warewulfd" -) - - -func main() { - root := warewulfd.GetRootCommand() - - root.Execute() -} \ No newline at end of file diff --git a/internal/app/warewulfd/root.go b/internal/app/warewulfd/root.go deleted file mode 100644 index 7d0032c3..00000000 --- a/internal/app/warewulfd/root.go +++ /dev/null @@ -1,39 +0,0 @@ -package warewulfd - -import ( - "github.com/hpcng/warewulf/internal/pkg/wwlog" - "github.com/spf13/cobra" -) - -var ( - baseCmd = &cobra.Command{ - Use: "warewulfd", - Short: "Warewulf Daemon Service", - Long: "This is the primary Warewulf system for provisioning nodes", - RunE: CobraRunE, - PersistentPreRunE: rootPersistentPreRunE, - } - verboseArg bool - debugArg bool -) - -func init() { - baseCmd.PersistentFlags().BoolVarP(&verboseArg, "verbose", "v", false, "Run with increased verbosity.") - baseCmd.PersistentFlags().BoolVarP(&debugArg, "debug", "d", false, "Run with debugging messages enabled.") -} - -// GetRootCommand returns the root cobra.Command for the application. -func GetRootCommand() *cobra.Command { - return baseCmd -} - -func rootPersistentPreRunE(cmd *cobra.Command, args []string) error { - if verboseArg == true { - wwlog.SetLevel(wwlog.VERBOSE) - } else if debugArg == true { - wwlog.SetLevel(wwlog.DEBUG) - } else { - wwlog.SetLevel(wwlog.INFO) - } - return nil -} diff --git a/internal/app/warewulfd/warewulfd.go b/internal/app/warewulfd/warewulfd.go deleted file mode 100644 index a6805d2a..00000000 --- a/internal/app/warewulfd/warewulfd.go +++ /dev/null @@ -1,24 +0,0 @@ -package warewulfd - -import ( - "github.com/hpcng/warewulf/internal/app/warewulfd/response" - "github.com/spf13/cobra" - "net/http" -) - -// TODO: https://github.com/danderson/netboot/blob/master/pixiecore/dhcp.go -// TODO: https://github.com/pin/tftp - -func CobraRunE(cmd *cobra.Command, args []string) error { - - http.HandleFunc("/ipxe/", response.IpxeSend) - http.HandleFunc("/kernel/", response.KernelSend) - http.HandleFunc("/kmods/", response.KmodsSend) - http.HandleFunc("/container/", response.ContainerSend) - http.HandleFunc("/overlay-system/", response.SystemOverlaySend) - http.HandleFunc("/overlay-runtime", response.RuntimeOverlaySend) - - http.ListenAndServe(":9873", nil) - - return nil -} diff --git a/internal/app/wwctl/server/root.go b/internal/app/wwctl/server/root.go index 26870499..b368ac4d 100644 --- a/internal/app/wwctl/server/root.go +++ b/internal/app/wwctl/server/root.go @@ -1,6 +1,11 @@ package server -import "github.com/spf13/cobra" +import ( + "github.com/hpcng/warewulf/internal/app/wwctl/server/start" + "github.com/hpcng/warewulf/internal/app/wwctl/server/status" + "github.com/hpcng/warewulf/internal/app/wwctl/server/stop" + "github.com/spf13/cobra" +) var ( baseCmd = &cobra.Command{ @@ -12,6 +17,10 @@ var ( ) func init() { + baseCmd.AddCommand(start.GetCommand()) + baseCmd.AddCommand(status.GetCommand()) + baseCmd.AddCommand(stop.GetCommand()) + } // GetRootCommand returns the root cobra.Command for the application. diff --git a/internal/app/wwctl/server/start/main.go b/internal/app/wwctl/server/start/main.go index 3f368ae7..82a18c20 100644 --- a/internal/app/wwctl/server/start/main.go +++ b/internal/app/wwctl/server/start/main.go @@ -1,8 +1,11 @@ package start -import "github.com/spf13/cobra" +import ( + "github.com/hpcng/warewulf/internal/pkg/warewulfd" + "github.com/spf13/cobra" +) func CobraRunE(cmd *cobra.Command, args []string) error { - return nil + return warewulfd.RunServer() } diff --git a/internal/app/wwctl/server/status/main.go b/internal/app/wwctl/server/status/main.go index 5c1b993d..6edbe268 100644 --- a/internal/app/wwctl/server/status/main.go +++ b/internal/app/wwctl/server/status/main.go @@ -1,8 +1,12 @@ package status -import "github.com/spf13/cobra" +import ( + "fmt" + "github.com/spf13/cobra" +) func CobraRunE(cmd *cobra.Command, args []string) error { + fmt.Printf("Not implemented yet\n") return nil } diff --git a/internal/app/wwctl/server/stop/main.go b/internal/app/wwctl/server/stop/main.go index daa8898b..19ca0495 100644 --- a/internal/app/wwctl/server/stop/main.go +++ b/internal/app/wwctl/server/stop/main.go @@ -1,8 +1,11 @@ package stop -import "github.com/spf13/cobra" +import ( + "fmt" + "github.com/spf13/cobra" +) func CobraRunE(cmd *cobra.Command, args []string) error { - + fmt.Printf("Not implemented yet\n") return nil } diff --git a/internal/app/warewulfd/response/container.go b/internal/pkg/warewulfd/container.go similarity index 97% rename from internal/app/warewulfd/response/container.go rename to internal/pkg/warewulfd/container.go index da58d804..1aa0b69d 100644 --- a/internal/app/warewulfd/response/container.go +++ b/internal/pkg/warewulfd/container.go @@ -1,4 +1,4 @@ -package response +package warewulfd import ( "github.com/hpcng/warewulf/internal/pkg/container" diff --git a/internal/app/warewulfd/response/ipxe.go b/internal/pkg/warewulfd/ipxe.go similarity index 99% rename from internal/app/warewulfd/response/ipxe.go rename to internal/pkg/warewulfd/ipxe.go index 0b838ecd..6022ca59 100644 --- a/internal/app/warewulfd/response/ipxe.go +++ b/internal/pkg/warewulfd/ipxe.go @@ -1,4 +1,4 @@ -package response +package warewulfd import ( "fmt" diff --git a/internal/app/warewulfd/response/kernel.go b/internal/pkg/warewulfd/kernel.go similarity index 97% rename from internal/app/warewulfd/response/kernel.go rename to internal/pkg/warewulfd/kernel.go index e530de98..4d8d7a5c 100644 --- a/internal/app/warewulfd/response/kernel.go +++ b/internal/pkg/warewulfd/kernel.go @@ -1,4 +1,4 @@ -package response +package warewulfd import ( "github.com/hpcng/warewulf/internal/pkg/kernel" diff --git a/internal/app/warewulfd/response/kmods.go b/internal/pkg/warewulfd/kmods.go similarity index 97% rename from internal/app/warewulfd/response/kmods.go rename to internal/pkg/warewulfd/kmods.go index 4622b3b2..7558de83 100644 --- a/internal/app/warewulfd/response/kmods.go +++ b/internal/pkg/warewulfd/kmods.go @@ -1,4 +1,4 @@ -package response +package warewulfd import ( "github.com/hpcng/warewulf/internal/pkg/kernel" diff --git a/internal/app/warewulfd/response/runtime.go b/internal/pkg/warewulfd/runtime.go similarity index 99% rename from internal/app/warewulfd/response/runtime.go rename to internal/pkg/warewulfd/runtime.go index ec6291b7..7f13668d 100644 --- a/internal/app/warewulfd/response/runtime.go +++ b/internal/pkg/warewulfd/runtime.go @@ -1,4 +1,4 @@ -package response +package warewulfd import ( "fmt" diff --git a/internal/app/warewulfd/response/system.go b/internal/pkg/warewulfd/system.go similarity index 97% rename from internal/app/warewulfd/response/system.go rename to internal/pkg/warewulfd/system.go index 3a3cf285..3a92a7a5 100644 --- a/internal/app/warewulfd/response/system.go +++ b/internal/pkg/warewulfd/system.go @@ -1,4 +1,4 @@ -package response +package warewulfd import ( "github.com/hpcng/warewulf/internal/pkg/config" diff --git a/internal/app/warewulfd/response/util.go b/internal/pkg/warewulfd/util.go similarity index 98% rename from internal/app/warewulfd/response/util.go rename to internal/pkg/warewulfd/util.go index 8ef67270..3e5403ab 100644 --- a/internal/app/warewulfd/response/util.go +++ b/internal/pkg/warewulfd/util.go @@ -1,4 +1,4 @@ -package response +package warewulfd import ( "fmt" diff --git a/internal/pkg/warewulfd/warewulfd.go b/internal/pkg/warewulfd/warewulfd.go new file mode 100644 index 00000000..ba90adcc --- /dev/null +++ b/internal/pkg/warewulfd/warewulfd.go @@ -0,0 +1,27 @@ +package warewulfd + +import ( + "github.com/hpcng/warewulf/internal/pkg/wwlog" + "net/http" +) + +// TODO: https://github.com/danderson/netboot/blob/master/pixiecore/dhcp.go +// TODO: https://github.com/pin/tftp + +func RunServer() error { + + wwlog.Printf(wwlog.DEBUG, "Registering handlers for the web service\n") + + http.HandleFunc("/ipxe/", IpxeSend) + http.HandleFunc("/kernel/", KernelSend) + http.HandleFunc("/kmods/", KmodsSend) + http.HandleFunc("/container/", ContainerSend) + http.HandleFunc("/overlay-system/", SystemOverlaySend) + http.HandleFunc("/overlay-runtime", RuntimeOverlaySend) + + wwlog.Printf(wwlog.VERBOSE, "Starting HTTPD REST service\n") + + http.ListenAndServe(":9873", nil) + + return nil +} From f1706a4a0e639b260d08fa5e2c35c50dd63c1d8d Mon Sep 17 00:00:00 2001 From: Gregory Kurtzer Date: Sat, 12 Dec 2020 23:50:38 -0800 Subject: [PATCH 10/13] 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 +} From 5c23ef9f946ba6149ed9750b1c19832d0b95f3cf Mon Sep 17 00:00:00 2001 From: Gregory Kurtzer Date: Sun, 13 Dec 2020 20:20:03 -0800 Subject: [PATCH 11/13] Fininshed with node discovery and service refactoring --- etc/nodes.conf | 8 -------- internal/app/wwctl/node/list/main.go | 3 +++ internal/app/wwctl/node/set/main.go | 21 +++++++++++++++++++++ internal/app/wwctl/node/set/root.go | 4 ++++ internal/pkg/node/constructors.go | 20 +++++++++++++++----- internal/pkg/node/datastructure.go | 21 +++++++++++++++++++-- internal/pkg/node/methods.go | 13 +++++++++++-- internal/pkg/node/modifiers.go | 8 ++++++++ internal/pkg/warewulfd/daemon.go | 3 ++- internal/pkg/warewulfd/ipxe.go | 3 ++- 10 files changed, 85 insertions(+), 19 deletions(-) delete mode 100644 etc/nodes.conf diff --git a/etc/nodes.conf b/etc/nodes.conf deleted file mode 100644 index 83b14876..00000000 --- a/etc/nodes.conf +++ /dev/null @@ -1,8 +0,0 @@ -nodeprofiles: - default: - comment: "This profile is automatically included for each node" - container name: "" - kernel version: "" - kernel args: crashkernel=no quiet - -nodes: {} diff --git a/internal/app/wwctl/node/list/main.go b/internal/app/wwctl/node/list/main.go index 4150db2d..3ec31da6 100644 --- a/internal/app/wwctl/node/list/main.go +++ b/internal/app/wwctl/node/list/main.go @@ -50,6 +50,9 @@ func CobraRunE(cmd *cobra.Command, args []string) error { fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "ClusterName", node.ClusterName.Source(), node.ClusterName.Print()) fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "Profiles", "--", strings.Join(node.Profiles, ",")) + fmt.Printf("%-20s %-18s %-12s %t\n", node.Id.Get(), "Disabled", node.Disabled.Source(), node.Disabled.PrintB()) + fmt.Printf("%-20s %-18s %-12s %t\n", node.Id.Get(), "Discoverable", node.Discoverable.Source(), node.Discoverable.PrintB()) + fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "ContainerName", node.ContainerName.Source(), node.ContainerName.Print()) fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "KernelVersion", node.KernelVersion.Source(), node.KernelVersion.Print()) fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "KernelArgs", node.KernelArgs.Source(), node.KernelArgs.Print()) diff --git a/internal/app/wwctl/node/set/main.go b/internal/app/wwctl/node/set/main.go index 942620d8..cf2245c6 100644 --- a/internal/app/wwctl/node/set/main.go +++ b/internal/app/wwctl/node/set/main.go @@ -185,6 +185,27 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } } + if SetDiscoverable == true { + wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting node to discoverable\n", n.Id.Get()) + + n.Discoverable.SetB(true) + err := nodeDB.NodeUpdate(n) + if err != nil { + wwlog.Printf(wwlog.ERROR, "%s\n", err) + os.Exit(1) + } + } + if SetUndiscoverable == true { + wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting node to undiscoverable\n", n.Id.Get()) + + n.Discoverable.SetB(false) + err := nodeDB.NodeUpdate(n) + if err != nil { + wwlog.Printf(wwlog.ERROR, "%s\n", err) + os.Exit(1) + } + } + if len(SetAddProfile) > 0 { for _, p := range SetAddProfile { wwlog.Printf(wwlog.VERBOSE, "Node: %s, adding profile to '%s'\n", n.Id.Get(), p) diff --git a/internal/app/wwctl/node/set/root.go b/internal/app/wwctl/node/set/root.go index c0eff8c5..72164fff 100644 --- a/internal/app/wwctl/node/set/root.go +++ b/internal/app/wwctl/node/set/root.go @@ -32,6 +32,8 @@ var ( SetDelProfile []string SetForce bool SetInit string + SetDiscoverable bool + SetUndiscoverable bool ) func init() { @@ -61,6 +63,8 @@ func init() { baseCmd.PersistentFlags().BoolVarP(&SetYes, "yes", "y", false, "Set 'yes' to all questions asked") baseCmd.PersistentFlags().BoolVarP(&SetForce, "force", "f", false, "Force configuration (even on error)") + baseCmd.PersistentFlags().BoolVar(&SetDiscoverable, "discoverable", false, "Make this node discoverable") + baseCmd.PersistentFlags().BoolVar(&SetUndiscoverable, "undiscoverable", false, "Remove the discoverable flag") } diff --git a/internal/pkg/node/constructors.go b/internal/pkg/node/constructors.go index 35895d1b..960bd029 100644 --- a/internal/pkg/node/constructors.go +++ b/internal/pkg/node/constructors.go @@ -74,6 +74,9 @@ func (self *nodeYaml) FindAllNodes() ([]NodeInfo, error) { n.SystemOverlay.Set(node.SystemOverlay) n.RuntimeOverlay.Set(node.RuntimeOverlay) + n.Discoverable.SetB(node.Discoverable) + n.Disabled.SetB(node.Disabled) + for devname, netdev := range node.NetDevs { if _, ok := n.NetDevs[devname]; !ok { var netdev NetDevEntry @@ -112,6 +115,9 @@ func (self *nodeYaml) FindAllNodes() ([]NodeInfo, error) { n.SystemOverlay.SetAlt(self.NodeProfiles[p].SystemOverlay, pstring) n.RuntimeOverlay.SetAlt(self.NodeProfiles[p].RuntimeOverlay, pstring) + n.Disabled.SetAltB(self.NodeProfiles[p].Disabled, pstring) + n.Discoverable.SetAltB(self.NodeProfiles[p].Discoverable, pstring) + for devname, netdev := range self.NodeProfiles[p].NetDevs { if _, ok := n.NetDevs[devname]; !ok { var netdev NetDevEntry @@ -155,6 +161,9 @@ func (self *nodeYaml) FindAllProfiles() ([]NodeInfo, error) { p.RuntimeOverlay.Set(profile.RuntimeOverlay) p.SystemOverlay.Set(profile.SystemOverlay) + p.Disabled.SetB(profile.Disabled) + p.Discoverable.SetB(profile.Discoverable) + for devname, netdev := range profile.NetDevs { if _, ok := p.NetDevs[devname]; !ok { var netdev NetDevEntry @@ -190,17 +199,18 @@ func (self *nodeYaml) FindAllProfiles() ([]NodeInfo, error) { return ret, nil } -func (self *nodeYaml) FindUnconfiguredNode() (NodeInfo, string, error) { +func (self *nodeYaml) FindDiscoverableNode() (NodeInfo, string, error) { var ret NodeInfo nodes, _ := self.FindAllNodes() for _, node := range nodes { + if node.Discoverable.GetB() == false { + continue + } for netdev, dev := range node.NetDevs { - if dev.Hwaddr.Defined() == false && dev.Ipaddr.Defined() == true { - if dev.Type.Defined() == false || dev.Type.Get() == "ethernet" { - return node, netdev, nil - } + if dev.Hwaddr.Defined() == false { + return node, netdev, nil } } } diff --git a/internal/pkg/node/datastructure.go b/internal/pkg/node/datastructure.go index d4e8077e..0b5bb8a3 100644 --- a/internal/pkg/node/datastructure.go +++ b/internal/pkg/node/datastructure.go @@ -1,6 +1,7 @@ package node import ( + "fmt" "github.com/hpcng/warewulf/internal/pkg/util" "github.com/hpcng/warewulf/internal/pkg/wwlog" "os" @@ -30,6 +31,7 @@ type NodeConf struct { RuntimeOverlay string `yaml:"runtime overlay files,omitempty"` SystemOverlay string `yaml:"system overlay files,omitempty"` Init string `yaml:"init,omitempty"` + Discoverable bool `yaml:"discoverable,omitempty"` Profiles []string `yaml:"profiles,omitempty"` NetDevs map[string]*NetDevs `yaml:"network devices,omitempty"` } @@ -71,6 +73,8 @@ type NodeInfo struct { IpmiPassword Entry RuntimeOverlay Entry SystemOverlay Entry + Discoverable Entry + Disabled Entry Init Entry //TODO: Finish adding this... Profiles []string GroupProfiles []string @@ -89,7 +93,20 @@ type NetDevEntry struct { func init() { //TODO: Check to make sure nodes.conf is found if util.IsFile(ConfigFile) == false { - wwlog.Printf(wwlog.ERROR, "Configuration file not found: %s\n", ConfigFile) - os.Exit(1) + c, err := os.OpenFile(ConfigFile, os.O_RDWR|os.O_CREATE, 0644) + if err != nil { + wwlog.Printf(wwlog.ERROR, "Could not create new configuration file: %s\n", err) + os.Exit(1) + } + + fmt.Fprintf(c, "nodeprofiles:\n") + fmt.Fprintf(c, " default:\n") + fmt.Fprintf(c, " comment: This profile is automatically included for each node\n") + fmt.Fprintf(c, " kernel args: crashkernel=no quiet\n") + fmt.Fprintf(c, "nodes: {}\n") + + c.Close() + + wwlog.Printf(wwlog.INFO, "Created default node configuration\n") } } diff --git a/internal/pkg/node/methods.go b/internal/pkg/node/methods.go index 9068831c..1fcbd7a7 100644 --- a/internal/pkg/node/methods.go +++ b/internal/pkg/node/methods.go @@ -41,8 +41,10 @@ func (self *Entry) SetAlt(val string, from string) { } func (self *Entry) SetAltB(val bool, from string) { - self.altbool = val - self.from = from + if val == true { + self.altbool = val + self.from = from + } return } @@ -106,6 +108,13 @@ func (self *Entry) Print() string { return "--" } +func (self *Entry) PrintB() bool { + if self.from == "" { + return self.bool + } + return self.altbool +} + func (self *Entry) Source() string { if self.value != "" && self.altvalue != "" { return "SUPERSEDED" diff --git a/internal/pkg/node/modifiers.go b/internal/pkg/node/modifiers.go index 9905f28c..8d36f68b 100644 --- a/internal/pkg/node/modifiers.go +++ b/internal/pkg/node/modifiers.go @@ -66,6 +66,10 @@ func (self *nodeYaml) NodeUpdate(node NodeInfo) error { self.Nodes[nodeID].IpmiPassword = node.IpmiPassword.GetReal() self.Nodes[nodeID].RuntimeOverlay = node.RuntimeOverlay.GetReal() self.Nodes[nodeID].SystemOverlay = node.SystemOverlay.GetReal() + + self.Nodes[nodeID].Disabled = node.Disabled.GetRealB() + self.Nodes[nodeID].Discoverable = node.Discoverable.GetRealB() + self.Nodes[nodeID].Profiles = node.Profiles self.Nodes[nodeID].NetDevs = make(map[string]*NetDevs) @@ -138,6 +142,10 @@ func (self *nodeYaml) ProfileUpdate(profile NodeInfo) error { self.NodeProfiles[profileID].IpmiPassword = profile.IpmiPassword.GetReal() self.NodeProfiles[profileID].RuntimeOverlay = profile.RuntimeOverlay.GetReal() self.NodeProfiles[profileID].SystemOverlay = profile.SystemOverlay.GetReal() + + self.NodeProfiles[profileID].Disabled = profile.Disabled.GetRealB() + self.NodeProfiles[profileID].Discoverable = profile.Discoverable.GetRealB() + self.NodeProfiles[profileID].Profiles = profile.Profiles self.NodeProfiles[profileID].NetDevs = make(map[string]*NetDevs) diff --git a/internal/pkg/warewulfd/daemon.go b/internal/pkg/warewulfd/daemon.go index 5dbf94e5..f52ffe9f 100644 --- a/internal/pkg/warewulfd/daemon.go +++ b/internal/pkg/warewulfd/daemon.go @@ -41,7 +41,8 @@ func DaemonStart() error { cmd.Start() pid := cmd.Process.Pid - p.WriteString(fmt.Sprintf("%d", pid)) + fmt.Fprintf(p, "%d", pid) + p.Close() time.Sleep(1 * time.Second) diff --git a/internal/pkg/warewulfd/ipxe.go b/internal/pkg/warewulfd/ipxe.go index 6022ca59..d50edc52 100644 --- a/internal/pkg/warewulfd/ipxe.go +++ b/internal/pkg/warewulfd/ipxe.go @@ -59,7 +59,7 @@ func IpxeSend(w http.ResponseWriter, req *http.Request) { wwlog.Printf(wwlog.INFO, "Node was not found, looking for discoverable nodes...\n") - n, netdev, err = nodeDB.FindUnconfiguredNode() + n, netdev, err = nodeDB.FindDiscoverableNode() if err != nil { wwlog.Printf(wwlog.WARN, "Node was not found, no nodes are discoverable...\n") unconfiguredNode = true @@ -68,6 +68,7 @@ func IpxeSend(w http.ResponseWriter, req *http.Request) { wwlog.Printf(wwlog.INFO, "Adding new configuration to discoverable node: %s\n", n.Id.Get()) n.NetDevs[netdev].Hwaddr.Set(hwaddr) + n.Discoverable.SetB(false) err := nodeDB.NodeUpdate(n) if err != nil { wwlog.Printf(wwlog.ERROR, "Could not add discovered configuration for node: %s\n", n.Id.Get()) From 487f45f7a9c3d9e762b8a338c0a8ce1e3d819180 Mon Sep 17 00:00:00 2001 From: Gregory Kurtzer Date: Sun, 13 Dec 2020 20:35:47 -0800 Subject: [PATCH 12/13] Optimizing pull to automatically build the VNFS and set default if requested --- internal/app/wwctl/container/pull/main.go | 27 ++++++++++++++++++++--- internal/app/wwctl/container/pull/root.go | 8 ++++--- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/internal/app/wwctl/container/pull/main.go b/internal/app/wwctl/container/pull/main.go index f9a9919d..2acd199d 100644 --- a/internal/app/wwctl/container/pull/main.go +++ b/internal/app/wwctl/container/pull/main.go @@ -3,6 +3,7 @@ package pull import ( "fmt" "github.com/hpcng/warewulf/internal/pkg/container" + "github.com/hpcng/warewulf/internal/pkg/node" "github.com/hpcng/warewulf/internal/pkg/util" "github.com/hpcng/warewulf/internal/pkg/wwlog" "github.com/spf13/cobra" @@ -50,9 +51,29 @@ func CobraRunE(cmd *cobra.Command, args []string) error { os.Exit(1) } - if SetBuild == true { - fmt.Printf("Building container: %s\n", name) - container.Build(name, false) + fmt.Printf("Building container: %s\n", name) + container.Build(name, true) + + if SetDefault == true { + nodeDB, err := node.New() + if err != nil { + wwlog.Printf(wwlog.ERROR, "Could not open node configuration: %s\n", err) + os.Exit(1) + } + + //TODO: Don't loop through profiles, instead have a nodeDB function that goes directly to the map + profiles, _ := nodeDB.FindAllProfiles() + for _, profile := range profiles { + wwlog.Printf(wwlog.DEBUG, "Looking for profile default: %s\n", profile.Id.Get()) + if profile.Id.Get() == "default" { + wwlog.Printf(wwlog.DEBUG, "Found profile default, setting container name to: %s\n", name) + profile.ContainerName.Set(name) + nodeDB.ProfileUpdate(profile) + } + } + nodeDB.Persist() + fmt.Printf("Set default profile to container: %s\n", name) + } return nil diff --git a/internal/app/wwctl/container/pull/root.go b/internal/app/wwctl/container/pull/root.go index 84ed3d04..882a18f0 100644 --- a/internal/app/wwctl/container/pull/root.go +++ b/internal/app/wwctl/container/pull/root.go @@ -10,15 +10,17 @@ var ( RunE: CobraRunE, Args: cobra.MinimumNArgs(1), } - SetForce bool - SetUpdate bool - SetBuild bool + SetForce bool + SetUpdate bool + SetBuild bool + SetDefault bool ) func init() { baseCmd.PersistentFlags().BoolVarP(&SetForce, "force", "f", false, "Force overwrite of an existing container") baseCmd.PersistentFlags().BoolVarP(&SetUpdate, "update", "u", false, "Update and overwrite an existing container") baseCmd.PersistentFlags().BoolVarP(&SetBuild, "build", "b", false, "Build container when after pulling") + baseCmd.PersistentFlags().BoolVar(&SetDefault, "setdefault", false, "Set this container for the default profile") } From 62a1abaab348d3dd35cb4ea93e4ba691ec01f8ea Mon Sep 17 00:00:00 2001 From: Gregory Kurtzer Date: Sun, 13 Dec 2020 22:45:08 -0800 Subject: [PATCH 13/13] Cleanups and minor fixups --- go.mod | 2 +- .../wwctl/{system => configure}/dhcp/main.go | 0 .../wwctl/{system => configure}/dhcp/root.go | 0 .../app/wwctl/{system => configure}/root.go | 10 ++++----- .../wwctl/{system => configure}/tftp/main.go | 0 .../wwctl/{system => configure}/tftp/root.go | 0 internal/app/wwctl/container/build/main.go | 8 ++++++- internal/app/wwctl/container/exec/main.go | 9 ++++++++ internal/app/wwctl/container/pull/main.go | 8 ++++++- internal/app/wwctl/kernel/build/main.go | 4 +++- internal/app/wwctl/node/add/main.go | 11 ++++++++++ internal/app/wwctl/node/add/root.go | 16 +++++++------- internal/app/wwctl/root.go | 4 ++-- internal/pkg/container/build.go | 21 +++++++------------ internal/pkg/kernel/kernel.go | 14 ++++++------- internal/pkg/warewulfd/ipxe.go | 10 ++++----- 16 files changed, 73 insertions(+), 44 deletions(-) rename internal/app/wwctl/{system => configure}/dhcp/main.go (100%) rename internal/app/wwctl/{system => configure}/dhcp/root.go (100%) rename internal/app/wwctl/{system => configure}/root.go (80%) rename internal/app/wwctl/{system => configure}/tftp/main.go (100%) rename internal/app/wwctl/{system => configure}/tftp/root.go (100%) diff --git a/go.mod b/go.mod index f7abe5fb..e3cc319e 100644 --- a/go.mod +++ b/go.mod @@ -42,7 +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/sevlyar/go-daemon v0.1.5 // indirect 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/internal/app/wwctl/system/dhcp/main.go b/internal/app/wwctl/configure/dhcp/main.go similarity index 100% rename from internal/app/wwctl/system/dhcp/main.go rename to internal/app/wwctl/configure/dhcp/main.go diff --git a/internal/app/wwctl/system/dhcp/root.go b/internal/app/wwctl/configure/dhcp/root.go similarity index 100% rename from internal/app/wwctl/system/dhcp/root.go rename to internal/app/wwctl/configure/dhcp/root.go diff --git a/internal/app/wwctl/system/root.go b/internal/app/wwctl/configure/root.go similarity index 80% rename from internal/app/wwctl/system/root.go rename to internal/app/wwctl/configure/root.go index 24dd050b..d94568c4 100644 --- a/internal/app/wwctl/system/root.go +++ b/internal/app/wwctl/configure/root.go @@ -1,17 +1,17 @@ -package system +package configure import ( "fmt" - "github.com/hpcng/warewulf/internal/app/wwctl/system/dhcp" - "github.com/hpcng/warewulf/internal/app/wwctl/system/tftp" + "github.com/hpcng/warewulf/internal/app/wwctl/configure/dhcp" + "github.com/hpcng/warewulf/internal/app/wwctl/configure/tftp" "github.com/spf13/cobra" "os" ) var ( baseCmd = &cobra.Command{ - Use: "system", - Short: "Initialize Warewulf services", + Use: "configure", + Short: "Configure Warewulf services", Long: "Warewulf Service Initialization", RunE: CobraRunE, } diff --git a/internal/app/wwctl/system/tftp/main.go b/internal/app/wwctl/configure/tftp/main.go similarity index 100% rename from internal/app/wwctl/system/tftp/main.go rename to internal/app/wwctl/configure/tftp/main.go diff --git a/internal/app/wwctl/system/tftp/root.go b/internal/app/wwctl/configure/tftp/root.go similarity index 100% rename from internal/app/wwctl/system/tftp/root.go rename to internal/app/wwctl/configure/tftp/root.go diff --git a/internal/app/wwctl/container/build/main.go b/internal/app/wwctl/container/build/main.go index 236bf712..fe9c9d88 100644 --- a/internal/app/wwctl/container/build/main.go +++ b/internal/app/wwctl/container/build/main.go @@ -24,7 +24,13 @@ func CobraRunE(cmd *cobra.Command, args []string) error { os.Exit(1) } - container.Build(c, BuildForce) + output, err := container.Build(c, BuildForce) + if err != nil { + wwlog.Printf(wwlog.ERROR, "Could not build container %s: %s\n", c, err) + os.Exit(1) + } else { + fmt.Printf("%-20s: %s\n", c, output) + } } if SetDefault == true { diff --git a/internal/app/wwctl/container/exec/main.go b/internal/app/wwctl/container/exec/main.go index 23db6553..765baf6d 100644 --- a/internal/app/wwctl/container/exec/main.go +++ b/internal/app/wwctl/container/exec/main.go @@ -36,5 +36,14 @@ func CobraRunE(cmd *cobra.Command, args []string) error { os.Exit(1) } + fmt.Printf("Rebuilding container...\n") + output, err := container.Build(containerName, false) + if err != nil { + wwlog.Printf(wwlog.ERROR, "Could not build container %s: %s\n", containerName, err) + os.Exit(1) + } else { + fmt.Printf("%s\n", output) + } + return nil } diff --git a/internal/app/wwctl/container/pull/main.go b/internal/app/wwctl/container/pull/main.go index 2acd199d..4a91d965 100644 --- a/internal/app/wwctl/container/pull/main.go +++ b/internal/app/wwctl/container/pull/main.go @@ -52,7 +52,13 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } fmt.Printf("Building container: %s\n", name) - container.Build(name, true) + output, err := container.Build(name, true) + if err != nil { + wwlog.Printf(wwlog.ERROR, "Could not build container %s: %s\n", name, err) + os.Exit(1) + } else { + fmt.Printf("%s: %s\n", name, output) + } if SetDefault == true { nodeDB, err := node.New() diff --git a/internal/app/wwctl/kernel/build/main.go b/internal/app/wwctl/kernel/build/main.go index 39ac088f..a605dae5 100644 --- a/internal/app/wwctl/kernel/build/main.go +++ b/internal/app/wwctl/kernel/build/main.go @@ -12,10 +12,12 @@ import ( func CobraRunE(cmd *cobra.Command, args []string) error { for _, arg := range args { - err := kernel.Build(arg) + output, err := kernel.Build(arg) if err != nil { wwlog.Printf(wwlog.ERROR, "Failed building kernel: %s\n", err) os.Exit(1) + } else { + fmt.Printf("%s: %s\n", arg, output) } } diff --git a/internal/app/wwctl/node/add/main.go b/internal/app/wwctl/node/add/main.go index 22937985..598b4974 100644 --- a/internal/app/wwctl/node/add/main.go +++ b/internal/app/wwctl/node/add/main.go @@ -102,6 +102,17 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } } + if SetDiscoverable == true { + wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting node to discoverable\n", n.Id.Get()) + + n.Discoverable.SetB(true) + err := nodeDB.NodeUpdate(n) + if err != nil { + wwlog.Printf(wwlog.ERROR, "%s\n", err) + os.Exit(1) + } + } + } nodeDB.Persist() diff --git a/internal/app/wwctl/node/add/root.go b/internal/app/wwctl/node/add/root.go index 99a4a75c..da7f8d60 100644 --- a/internal/app/wwctl/node/add/root.go +++ b/internal/app/wwctl/node/add/root.go @@ -10,13 +10,14 @@ var ( RunE: CobraRunE, Args: cobra.MinimumNArgs(1), } - SetGroup string - SetController string - SetNetDev string - SetIpaddr string - SetNetmask string - SetGateway string - SetHwaddr string + SetGroup string + SetController string + SetNetDev string + SetIpaddr string + SetNetmask string + SetGateway string + SetHwaddr string + SetDiscoverable bool ) func init() { @@ -27,6 +28,7 @@ func init() { baseCmd.PersistentFlags().StringVarP(&SetNetmask, "netmask", "M", "", "Set the node's network device netmask") baseCmd.PersistentFlags().StringVarP(&SetGateway, "gateway", "G", "", "Set the node's network device gateway") baseCmd.PersistentFlags().StringVarP(&SetHwaddr, "hwaddr", "H", "", "Set the node's network device HW address") + baseCmd.PersistentFlags().BoolVar(&SetDiscoverable, "discoverable", false, "Make this node discoverable") } diff --git a/internal/app/wwctl/root.go b/internal/app/wwctl/root.go index a8a0a2f0..e3bd91fe 100644 --- a/internal/app/wwctl/root.go +++ b/internal/app/wwctl/root.go @@ -1,6 +1,7 @@ package wwctl import ( + "github.com/hpcng/warewulf/internal/app/wwctl/configure" "github.com/hpcng/warewulf/internal/app/wwctl/container" "github.com/hpcng/warewulf/internal/app/wwctl/kernel" "github.com/hpcng/warewulf/internal/app/wwctl/node" @@ -8,7 +9,6 @@ import ( "github.com/hpcng/warewulf/internal/app/wwctl/profile" "github.com/hpcng/warewulf/internal/app/wwctl/ready" "github.com/hpcng/warewulf/internal/app/wwctl/server" - "github.com/hpcng/warewulf/internal/app/wwctl/system" "github.com/hpcng/warewulf/internal/pkg/wwlog" "github.com/spf13/cobra" @@ -38,7 +38,7 @@ func init() { rootCmd.AddCommand(kernel.GetCommand()) // rootCmd.AddCommand(group.GetCommand()) rootCmd.AddCommand(profile.GetCommand()) - rootCmd.AddCommand(system.GetCommand()) + rootCmd.AddCommand(configure.GetCommand()) rootCmd.AddCommand(ready.GetCommand()) rootCmd.AddCommand(server.GetCommand()) diff --git a/internal/pkg/container/build.go b/internal/pkg/container/build.go index 80ce972e..9e29f3ee 100644 --- a/internal/pkg/container/build.go +++ b/internal/pkg/container/build.go @@ -2,6 +2,7 @@ package container import ( "fmt" + "github.com/hpcng/warewulf/internal/pkg/errors" "github.com/hpcng/warewulf/internal/pkg/util" "github.com/hpcng/warewulf/internal/pkg/wwlog" "os" @@ -9,46 +10,40 @@ import ( "path" ) -func Build(name string, buildForce bool) { +func Build(name string, buildForce bool) (string, error) { rootfsPath := RootFsDir(name) imagePath := ImageFile(name) if ValidSource(name) == false { - wwlog.Printf(wwlog.INFO, "%-35s: Skipping (bad path)\n", name) - return + return "", errors.New("Container does not exist") } if buildForce == false { wwlog.Printf(wwlog.DEBUG, "Checking if there have been any updates to the VNFS directory\n") if util.PathIsNewer(rootfsPath, imagePath) { - wwlog.Printf(wwlog.INFO, "%-35s: Skipping, VNFS is current\n", name) - return + return "Skipping (VNFS is current)", nil } } wwlog.Printf(wwlog.DEBUG, "Making parent directory for: %s\n", name) err := os.MkdirAll(path.Dir(imagePath), 0755) if err != nil { - fmt.Printf("ERROR: %s\n", err) - return + return "Failed creating directory", err } wwlog.Printf(wwlog.DEBUG, "Making parent directory for: %s\n", rootfsPath) err = os.MkdirAll(path.Dir(rootfsPath), 0755) if err != nil { - fmt.Printf("ERROR: %s\n", err) - return + return "Failed creating directory", err } wwlog.Printf(wwlog.DEBUG, "Building VNFS image: '%s' -> '%s'\n", rootfsPath, imagePath) cmd := fmt.Sprintf("cd %s; find . | cpio --quiet -o -H newc | gzip -c > \"%s\"", rootfsPath, imagePath) err = exec.Command("/bin/sh", "-c", cmd).Run() if err != nil { - wwlog.Printf(wwlog.ERROR, "Failed building VNFS: %s\n", err) - return + return "Failed building VNFS", err } - wwlog.Printf(wwlog.INFO, "%-35s: Done\n", name) - + return "Done", nil } diff --git a/internal/pkg/kernel/kernel.go b/internal/pkg/kernel/kernel.go index e59444f7..d7df72ad 100644 --- a/internal/pkg/kernel/kernel.go +++ b/internal/pkg/kernel/kernel.go @@ -69,7 +69,7 @@ func ListKernels() ([]string, error) { return ret, nil } -func Build(kernelVersion string) error { +func Build(kernelVersion string) (string, error) { kernelImage := "/boot/vmlinuz-" + kernelVersion kernelDrivers := "/lib/modules/" + kernelVersion @@ -81,20 +81,19 @@ func Build(kernelVersion string) error { os.MkdirAll(path.Dir(driversDestination), 0755) if util.IsFile(kernelImage) == false { - return errors.New("Could not locate kernel image: " + kernelImage) + return "", errors.New("Could not locate kernel image") } if util.IsDir(kernelDrivers) == false { - return errors.New("Could not locate kernel drivers: " + kernelDrivers) + return "", errors.New("Could not locate kernel drivers") } wwlog.Printf(wwlog.VERBOSE, "Setting up Kernel\n") if _, err := os.Stat(kernelImage); err == nil { err := util.CopyFile(kernelImage, kernelDestination) if err != nil { - return err + return "", err } - wwlog.Printf(wwlog.INFO, "%-45s: Done\n", "vmlinuz-"+kernelVersion) } wwlog.Printf(wwlog.VERBOSE, "Building Kernel driver image\n") @@ -102,10 +101,9 @@ func Build(kernelVersion string) error { cmd := fmt.Sprintf("cd /; find .%s | cpio --quiet -o -H newc -F \"%s\"", kernelDrivers, driversDestination) err := exec.Command("/bin/sh", "-c", cmd).Run() if err != nil { - return err + return "", err } - wwlog.Printf(wwlog.INFO, "%-45s: Done\n", "kmods-"+kernelVersion+".img") } - return nil + return "Done", nil } diff --git a/internal/pkg/warewulfd/ipxe.go b/internal/pkg/warewulfd/ipxe.go index d50edc52..5fde3bc5 100644 --- a/internal/pkg/warewulfd/ipxe.go +++ b/internal/pkg/warewulfd/ipxe.go @@ -57,11 +57,11 @@ func IpxeSend(w http.ResponseWriter, req *http.Request) { // If we failed to find a node, let's see if we can add one... var netdev string - wwlog.Printf(wwlog.INFO, "Node was not found, looking for discoverable nodes...\n") + wwlog.Printf(wwlog.VERBOSE, "Node was not found, looking for discoverable nodes...\n") n, netdev, err = nodeDB.FindDiscoverableNode() if err != nil { - wwlog.Printf(wwlog.WARN, "Node was not found, no nodes are discoverable...\n") + wwlog.Printf(wwlog.WARN, "No nodes are set as discoverable...\n") unconfiguredNode = true } else { @@ -79,7 +79,9 @@ func IpxeSend(w http.ResponseWriter, req *http.Request) { wwlog.Printf(wwlog.ERROR, "Could not persist new node configuration while adding node: %s\n", n.Id.Get()) unconfiguredNode = true } else { + wwlog.Printf(wwlog.INFO, "Building System Overlay:\n") _ = overlay.BuildSystemOverlay([]node.NodeInfo{n}) + wwlog.Printf(wwlog.INFO, "Building Runtime Overlay:\n") _ = overlay.BuildRuntimeOverlay([]node.NodeInfo{n}) } } @@ -89,9 +91,7 @@ func IpxeSend(w http.ResponseWriter, req *http.Request) { if unconfiguredNode == true { log.Printf("UNCONFIGURED NODE: %15s\n", hwaddr) - ipxeTemplate := fmt.Sprintf("/etc/warewulf/ipxe/unconfigured.ipxe", n.Ipxe.Get()) - - tmpl, err := template.ParseFiles(ipxeTemplate) + tmpl, err := template.ParseFiles("/etc/warewulf/ipxe/unconfigured.ipxe") if err != nil { wwlog.Printf(wwlog.ERROR, "%s\n", err) return