From 1d1a02b305ff7dbcbb0b351d066fd5baae70e919 Mon Sep 17 00:00:00 2001 From: Gregory Kurtzer Date: Sat, 21 Nov 2020 01:48:38 -0800 Subject: [PATCH] Building set commands for nodes and groups and templating out CLI further --- internal/app/wwctl/group/add/main.go | 22 +++++ internal/app/wwctl/group/add/root.go | 25 ++++++ internal/app/wwctl/group/list/main.go | 8 ++ internal/app/wwctl/group/list/root.go | 20 +++++ internal/app/wwctl/group/root.go | 27 ++++++ internal/app/wwctl/group/set/main.go | 8 ++ internal/app/wwctl/group/set/root.go | 25 ++++++ internal/app/wwctl/node/add/main.go | 22 +++++ internal/app/wwctl/node/add/root.go | 20 +++++ internal/app/wwctl/node/root.go | 2 + internal/app/wwctl/node/set/main.go | 38 +++++--- internal/app/wwctl/node/set/root.go | 4 +- internal/app/wwctl/root.go | 2 + internal/pkg/node/node.go | 121 ++++++++++++++++++++------ 14 files changed, 305 insertions(+), 39 deletions(-) create mode 100644 internal/app/wwctl/group/add/main.go create mode 100644 internal/app/wwctl/group/add/root.go create mode 100644 internal/app/wwctl/group/list/main.go create mode 100644 internal/app/wwctl/group/list/root.go create mode 100644 internal/app/wwctl/group/root.go create mode 100644 internal/app/wwctl/group/set/main.go create mode 100644 internal/app/wwctl/group/set/root.go create mode 100644 internal/app/wwctl/node/add/main.go create mode 100644 internal/app/wwctl/node/add/root.go diff --git a/internal/app/wwctl/group/add/main.go b/internal/app/wwctl/group/add/main.go new file mode 100644 index 00000000..74dee1e9 --- /dev/null +++ b/internal/app/wwctl/group/add/main.go @@ -0,0 +1,22 @@ +package add + +import ( + "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, "Failed opening node database: %s\n", err) + os.Exit(1) + } + + nodeDB.AddGroup(args[0]) + nodeDB.Persist() + + return nil +} + diff --git a/internal/app/wwctl/group/add/root.go b/internal/app/wwctl/group/add/root.go new file mode 100644 index 00000000..114c5ba5 --- /dev/null +++ b/internal/app/wwctl/group/add/root.go @@ -0,0 +1,25 @@ +package add + +import "github.com/spf13/cobra" + +var ( + baseCmd = &cobra.Command{ + Use: "add", + Short: "Add a new node group", + Long: "Add a new node group ", + RunE: CobraRunE, + } + SetVnfs string + SetKernel string + // SetGroupLevel bool +) + +func init() { + baseCmd.PersistentFlags().StringVarP(&SetVnfs, "vnfs", "V", "", "Set node Virtual Node File System (VNFS)") + baseCmd.PersistentFlags().StringVarP(&SetKernel, "kernel", "K", "", "Set Kernel version for nodes") +} + +// GetRootCommand returns the root cobra.Command for the application. +func GetCommand() *cobra.Command { + return baseCmd +} diff --git a/internal/app/wwctl/group/list/main.go b/internal/app/wwctl/group/list/main.go new file mode 100644 index 00000000..a81fcb65 --- /dev/null +++ b/internal/app/wwctl/group/list/main.go @@ -0,0 +1,8 @@ +package list + +import "github.com/spf13/cobra" + +func CobraRunE(cmd *cobra.Command, args []string) error { + + return nil +} diff --git a/internal/app/wwctl/group/list/root.go b/internal/app/wwctl/group/list/root.go new file mode 100644 index 00000000..87d56d7b --- /dev/null +++ b/internal/app/wwctl/group/list/root.go @@ -0,0 +1,20 @@ +package list + +import "github.com/spf13/cobra" + +var ( + baseCmd = &cobra.Command{ + Use: "list", + Short: "List group configurations", + Long: "List group configurations ", + 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/group/root.go b/internal/app/wwctl/group/root.go new file mode 100644 index 00000000..85fad06d --- /dev/null +++ b/internal/app/wwctl/group/root.go @@ -0,0 +1,27 @@ +package group + +import ( + "github.com/hpcng/warewulf/internal/app/wwctl/group/add" + "github.com/hpcng/warewulf/internal/app/wwctl/group/list" + "github.com/hpcng/warewulf/internal/app/wwctl/group/set" + "github.com/spf13/cobra" +) + +var ( + baseCmd = &cobra.Command{ + Use: "group", + Short: "Group management", + Long: "Management of group settings and power management", + } +) + +func init() { + baseCmd.AddCommand(list.GetCommand()) + baseCmd.AddCommand(set.GetCommand()) + baseCmd.AddCommand(add.GetCommand()) +} + +// GetRootCommand returns the root cobra.Command for the application. +func GetCommand() *cobra.Command { + return baseCmd +} diff --git a/internal/app/wwctl/group/set/main.go b/internal/app/wwctl/group/set/main.go new file mode 100644 index 00000000..7e60806c --- /dev/null +++ b/internal/app/wwctl/group/set/main.go @@ -0,0 +1,8 @@ +package set + +import "github.com/spf13/cobra" + +func CobraRunE(cmd *cobra.Command, args []string) error { + + return nil +} diff --git a/internal/app/wwctl/group/set/root.go b/internal/app/wwctl/group/set/root.go new file mode 100644 index 00000000..47d33f64 --- /dev/null +++ b/internal/app/wwctl/group/set/root.go @@ -0,0 +1,25 @@ +package set + +import "github.com/spf13/cobra" + +var ( + baseCmd = &cobra.Command{ + Use: "set", + Short: "Set group configurations", + Long: "Set group configurations ", + RunE: CobraRunE, + } + SetVnfs string + SetKernel string + // SetGroupLevel bool +) + +func init() { + baseCmd.PersistentFlags().StringVarP(&SetVnfs, "vnfs", "V", "", "Set node Virtual Node File System (VNFS)") + baseCmd.PersistentFlags().StringVarP(&SetKernel, "kernel", "K", "", "Set Kernel version for nodes") +} + +// GetRootCommand returns the root cobra.Command for the application. +func GetCommand() *cobra.Command { + return baseCmd +} diff --git a/internal/app/wwctl/node/add/main.go b/internal/app/wwctl/node/add/main.go new file mode 100644 index 00000000..53ee5b29 --- /dev/null +++ b/internal/app/wwctl/node/add/main.go @@ -0,0 +1,22 @@ +package add + +import ( + "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, "Failed to open node database: %s\n", err) + os.Exit(1) + } + + nodeDB.AddNode(args[0], args[1]) + + nodeDB.Persist() + + return nil +} \ No newline at end of file diff --git a/internal/app/wwctl/node/add/root.go b/internal/app/wwctl/node/add/root.go new file mode 100644 index 00000000..176c8175 --- /dev/null +++ b/internal/app/wwctl/node/add/root.go @@ -0,0 +1,20 @@ +package add + +import "github.com/spf13/cobra" + +var ( + baseCmd = &cobra.Command{ + Use: "add", + Short: "Add new node", + Long: "Add new node ", + 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/node/root.go b/internal/app/wwctl/node/root.go index 71aea43b..e4e29eba 100644 --- a/internal/app/wwctl/node/root.go +++ b/internal/app/wwctl/node/root.go @@ -1,6 +1,7 @@ package node import ( + "github.com/hpcng/warewulf/internal/app/wwctl/node/add" "github.com/hpcng/warewulf/internal/app/wwctl/node/list" "github.com/hpcng/warewulf/internal/app/wwctl/node/poweron" "github.com/hpcng/warewulf/internal/app/wwctl/node/poweroff" @@ -23,6 +24,7 @@ func init() { baseCmd.AddCommand(powerstatus.GetCommand()) baseCmd.AddCommand(list.GetCommand()) baseCmd.AddCommand(set.GetCommand()) + baseCmd.AddCommand(add.GetCommand()) } diff --git a/internal/app/wwctl/node/set/main.go b/internal/app/wwctl/node/set/main.go index 4b55199a..53cd2524 100644 --- a/internal/app/wwctl/node/set/main.go +++ b/internal/app/wwctl/node/set/main.go @@ -10,9 +10,10 @@ import ( func CobraRunE(cmd *cobra.Command, args []string) error { var err error - var c int + var count int + var nodes []node.NodeInfo - n, err := node.New() + nodeDB, err := node.New() if err != nil { wwlog.Printf(wwlog.ERROR, "Could not open node configuration: %s\n", err) os.Exit(1) @@ -23,18 +24,35 @@ func CobraRunE(cmd *cobra.Command, args []string) error { os.Exit(1) } - if SetVnfs != "" { - fmt.Printf("Setting vnfs to: %s\n", SetVnfs) - c, err = n.SetNodeVal("n0000", "vnfs", SetVnfs) + if len(args) > 0 { + nodes, err = nodeDB.SearchByNameList(args) + } else { + cmd.Usage() + os.Exit(1) + } + if err != nil { + wwlog.Printf(wwlog.ERROR, "Cloud not get nodeList: %s\n", err) + os.Exit(1) + } + for _, n := range nodes { + if SetVnfs != "" { + fmt.Printf("Setting vnfs to: %s\n", SetVnfs) + c, _ := nodeDB.SetNodeVal(n.Id, "vnfs", SetVnfs) + count += c + } + if SetKernel != "" { + fmt.Printf("Setting kernel to: %s\n", SetVnfs) + c, _ := nodeDB.SetNodeVal(n.Id, "kernel", SetKernel) + count += c + } } - fmt.Printf("set count: %d\n", c) + fmt.Printf("set count: %d\n", count) - a, err := n.FindByHwaddr("00:0c:29:23:8b:48") +// nodeDB.AddGroup("moo") + nodeDB.AddNode("moo", "node01") - fmt.Printf("VNFS: %s\n", a.Vnfs) - - //n.Persist() + nodeDB.Persist() return nil } \ No newline at end of file diff --git a/internal/app/wwctl/node/set/root.go b/internal/app/wwctl/node/set/root.go index 78bbdad8..d2ab3d3d 100644 --- a/internal/app/wwctl/node/set/root.go +++ b/internal/app/wwctl/node/set/root.go @@ -10,11 +10,13 @@ var ( RunE: CobraRunE, } SetVnfs string + SetKernel string +// SetGroupLevel bool ) func init() { baseCmd.PersistentFlags().StringVarP(&SetVnfs, "vnfs", "V", "", "Set node Virtual Node File System (VNFS)") - + baseCmd.PersistentFlags().StringVarP(&SetKernel, "kernel", "K", "", "Set Kernel version for nodes") } // GetRootCommand returns the root cobra.Command for the application. diff --git a/internal/app/wwctl/root.go b/internal/app/wwctl/root.go index f7c94c66..cd1b64c3 100644 --- a/internal/app/wwctl/root.go +++ b/internal/app/wwctl/root.go @@ -2,6 +2,7 @@ package wwctl import ( "github.com/hpcng/warewulf/internal/app/wwctl/build" + "github.com/hpcng/warewulf/internal/app/wwctl/group" "github.com/hpcng/warewulf/internal/app/wwctl/kernel" "github.com/hpcng/warewulf/internal/app/wwctl/node" "github.com/hpcng/warewulf/internal/app/wwctl/overlay" @@ -30,6 +31,7 @@ func init() { rootCmd.AddCommand(vnfs.GetCommand()) rootCmd.AddCommand(node.GetCommand()) rootCmd.AddCommand(kernel.GetCommand()) + rootCmd.AddCommand(group.GetCommand()) } diff --git a/internal/pkg/node/node.go b/internal/pkg/node/node.go index c8bc9057..4904b4b3 100644 --- a/internal/pkg/node/node.go +++ b/internal/pkg/node/node.go @@ -2,10 +2,8 @@ package node import ( "fmt" - "github.com/hpcng/warewulf/internal/pkg/config" "github.com/hpcng/warewulf/internal/pkg/errors" "github.com/hpcng/warewulf/internal/pkg/util" - "github.com/hpcng/warewulf/internal/pkg/vnfs" "github.com/hpcng/warewulf/internal/pkg/wwlog" "gopkg.in/yaml.v2" "io/ioutil" @@ -21,7 +19,7 @@ func init() { } type nodeYaml struct { - NodeGroups map[string]nodeGroup //`yaml:"nodegroups"` + NodeGroups map[string]*nodeGroup //`yaml:"nodegroups"` } type nodeGroup struct { @@ -33,7 +31,7 @@ type nodeGroup struct { DomainSuffix string `yaml:"domain suffix"` KernelVersion string `yaml:"kernel version"` KernelArgs string `yaml:"kernel args"` - Nodes map[string]nodeEntry + Nodes map[string]*nodeEntry } type nodeEntry struct { @@ -60,6 +58,7 @@ type netDevs struct { } type NodeInfo struct { + Id string GroupName string HostName string DomainName string @@ -77,8 +76,6 @@ type NodeInfo struct { NetDevs map[string]netDevs } - - func New() (nodeYaml, error) { var ret nodeYaml @@ -97,16 +94,90 @@ func New() (nodeYaml, error) { return ret, nil } -func (self nodeYaml) SetNodeVal(nodename string, entry string, value string) (int, error) { +func (self *nodeYaml) AddGroup(groupname string) error { + var group nodeGroup + + self.NodeGroups[groupname] = &group + self.NodeGroups[groupname].DomainSuffix = groupname + return nil +} + +func (self *nodeYaml) AddNode(groupname string, nodename string) error { + var node nodeEntry + + self.NodeGroups[groupname].Nodes[nodename] = &node + self.NodeGroups[groupname].Nodes[nodename].Hostname = nodename + + return nil +} + +func (self *nodeYaml) SetGroupVal(groupID string, entry string, value string) (int, error) { var count int - for gname, group := range self.NodeGroups { - for nname, _ := range group.Nodes { - if nodename == nname { + for gid, group := range self.NodeGroups { + for nid := range group.Nodes { + if groupID == gid { if entry == "vnfs" { - var foo = self.NodeGroups[gname].Nodes[nname] - foo.Vnfs = value -// node.Vnfs = value + self.NodeGroups[gid].Vnfs = value + self.NodeGroups[gid].Nodes[nid].Vnfs = "" + count++ + } else if entry == "kernel" { + self.NodeGroups[gid].KernelVersion = value + self.NodeGroups[gid].Nodes[nid].KernelVersion = "" + count++ + } else if entry == "domainsuffix" { + self.NodeGroups[gid].DomainSuffix = value + self.NodeGroups[gid].Nodes[nid].DomainSuffix = "" + count++ + } else if entry == "ipxe" { + self.NodeGroups[gid].Ipxe = value + self.NodeGroups[gid].Nodes[nid].Ipxe = "" + count++ + } else if entry == "systemoverlay" { + self.NodeGroups[gid].SystemOverlay = value + self.NodeGroups[gid].Nodes[nid].SystemOverlay = "" + count++ + } else if entry == "runtimeoverlay" { + self.NodeGroups[gid].RuntimeOverlay = value + self.NodeGroups[gid].Nodes[nid].RuntimeOverlay = "" + count++ + } else if entry == "hostname" { + self.NodeGroups[gid].Nodes[nid].Hostname = value + count++ + } + } + } + } + + return count, nil +} + +func (self *nodeYaml) SetNodeVal(nodeID string, entry string, value string) (int, error) { + var count int + + for gid, group := range self.NodeGroups { + for nid := range group.Nodes { + if nodeID == gid+":"+nid { + if entry == "vnfs" { + self.NodeGroups[gid].Nodes[nid].Vnfs = value + count++ + } else if entry == "kernel" { + self.NodeGroups[gid].Nodes[nid].KernelVersion = value + count++ + } else if entry == "domainsuffix" { + self.NodeGroups[gid].Nodes[nid].DomainSuffix = value + count++ + } else if entry == "ipxe" { + self.NodeGroups[gid].Nodes[nid].Ipxe = value + count++ + } else if entry == "systemoverlay" { + self.NodeGroups[gid].Nodes[nid].SystemOverlay = value + count++ + } else if entry == "runtimeoverlay" { + self.NodeGroups[gid].Nodes[nid].RuntimeOverlay = value + count++ + } else if entry == "hostname" { + self.NodeGroups[gid].Nodes[nid].Hostname = value count++ } } @@ -128,16 +199,14 @@ func (self *nodeYaml) Persist() error { return nil } - func (self *nodeYaml) FindAllNodes() ([]NodeInfo, error) { var ret []NodeInfo - config := config.New() - for groupname, group := range self.NodeGroups { - for _, node := range group.Nodes { + for nodename, node := range group.Nodes { var n NodeInfo + n.Id = groupname + ":" + nodename n.GroupName = groupname n.HostName = node.Hostname n.IpmiIpaddr = node.IpmiIpaddr @@ -191,16 +260,13 @@ func (self *nodeYaml) FindAllNodes() ([]NodeInfo, error) { n.Fqdn = node.Hostname } - util.ValidateOrDie(n.Fqdn, "group name", n.GroupName, "^[a-zA-Z0-9-._]+$") - util.ValidateOrDie(n.Fqdn, "vnfs", n.Vnfs, "^[a-zA-Z0-9-._:/]+$") - util.ValidateOrDie(n.Fqdn, "system overlay", n.SystemOverlay, "^[a-zA-Z0-9-._]+$") - util.ValidateOrDie(n.Fqdn, "runtime overlay", n.RuntimeOverlay, "^[a-zA-Z0-9-._]+$") - util.ValidateOrDie(n.Fqdn, "domain suffix", n.DomainName, "^[a-zA-Z0-9-._]+$") - util.ValidateOrDie(n.Fqdn, "hostname", n.HostName, "^[a-zA-Z0-9-_]+$") - util.ValidateOrDie(n.Fqdn, "kernel version", n.KernelVersion, "^[a-zA-Z0-9-._]+$") - - v := vnfs.New(n.Vnfs) - n.VnfsDir = config.VnfsChroot(v.NameClean()) + util.ValidateOrDie(n.Fqdn, "group name", n.GroupName, "^[a-zA-Z0-9-._]+$") + util.ValidateOrDie(n.Fqdn, "vnfs", n.Vnfs, "^[a-zA-Z0-9-._:/]+$") + util.ValidateOrDie(n.Fqdn, "system overlay", n.SystemOverlay, "^[a-zA-Z0-9-._]+$") + util.ValidateOrDie(n.Fqdn, "runtime overlay", n.RuntimeOverlay, "^[a-zA-Z0-9-._]+$") + util.ValidateOrDie(n.Fqdn, "domain suffix", n.DomainName, "^[a-zA-Z0-9-._]+$") + util.ValidateOrDie(n.Fqdn, "hostname", n.HostName, "^[a-zA-Z0-9-_]+$") + util.ValidateOrDie(n.Fqdn, "kernel version", n.KernelVersion, "^[a-zA-Z0-9-._]+$") ret = append(ret, n) } @@ -209,7 +275,6 @@ func (self *nodeYaml) FindAllNodes() ([]NodeInfo, error) { return ret, nil } - func (nodes *nodeYaml) FindByHwaddr(hwa string) (NodeInfo, error) { var ret NodeInfo