diff --git a/cmd/wwclient/wwclient.go b/cmd/wwclient/wwclient.go index 4b4fe666..fd79ef46 100644 --- a/cmd/wwclient/wwclient.go +++ b/cmd/wwclient/wwclient.go @@ -2,14 +2,14 @@ package main import ( "fmt" + "github.com/hpcng/warewulf/internal/pkg/warewulfconf" + "github.com/hpcng/warewulf/internal/pkg/wwlog" "log" "net" "net/http" "os" "os/exec" "time" - - "github.com/hpcng/warewulf/internal/pkg/config" ) func main() { @@ -24,10 +24,14 @@ func main() { os.Chdir("/warewulf/wwclient-test") } - config := config.New() + 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 config.InsecureRuntime == false { + if conf.Warewulf.Secure == true { // Setup local port to something privileged (<1024) localTCPAddr.Port = 987 } else { @@ -56,7 +60,7 @@ func main() { for true { var err error - getString := fmt.Sprintf("http://%s:%d/overlay-runtime", config.Ipaddr, config.Port) + getString := fmt.Sprintf("http://%s:%d/overlay-runtime", conf.Ipaddr, conf.Warewulf.Port) resp, err = webclient.Get(getString) if err == nil { break diff --git a/etc/nodes.conf b/etc/nodes.conf index 33a32a1c..d9d094cb 100644 --- a/etc/nodes.conf +++ b/etc/nodes.conf @@ -1,87 +1,36 @@ nodeprofiles: default: - comment: "" + comment: "Hello from the default profile" vnfs: "" kernel version: "" kernel args: crashkernel=no quiet -control: - headnode01: - comment: This is the first control system - ipaddr: 192.168.1.1 - services: - warewulfd: - port: 9873 - secure: true - dhcp: - enabled: true - range start: 192.168.1.100 - range end: 192.168.1.250 - assign static: false - config file: /etc/dhcp/dhcpd.conf - start command: systemctl start dhcpd - restart command: systemctl restart dhcpd - enable command: systemctl enable dhcpd - tftp: - enabled: true - tftproot: /var/lib/tftproot - start command: service tftp start - restart command: service tftp restart - enable command: chkconfig tftp on - nfs: - enabled: true - config file: /etc/exports - exports: - - /var/warewulf 192.168.1.1/255.255.255.0(ro,no_root_squash) - - /home 192.168.1.1/255.255.255.0(rw,no_root_squash) - start command: service nfs start - restart command: service nfs restart - enable command: chkconfig nfs on - nodegroups: - default: - comment: This is the default group - domain name: cluster01 - profiles: - - default - nodes: - n0000: - hostname: n0000 - netdevs: - eth0: - type: ethernet - hwaddr: 00:0c:29:23:8b:48 - ipaddr: 192.168.1.100 - netmask: 255.255.255.0 - gateway: 192.168.1.1 - ib0: - type: infiniband - hwaddr: aa:bb:cc:dd:ee:a0 - ipaddr: 192.168.10.100 - netmask: 255.255.255.0 - n0001: - hostname: n0001 - ipmi ipaddr: x.x.x.x - netdevs: - eth0: - hwaddr: aa:bb:cc:dd:ee:b0 - ipaddr: 192.168.1.101 - netmask: 255.255.255.0 - gateway: 192.168.1.1 - ib0: - hwaddr: aa:bb:cc:dd:ee:b1 - ipaddr: 192.168.10.100 - netmask: 255.255.255.0 - group_1: - comment: This is the group 1 - domain name: group1 - profiles: - - default - nodes: - n0000: - hostname: n0000 - netdevs: - eth0: - hwaddr: aa:bb:cc:dd:ee:c0 - ipaddr: 192.168.2.100 - netmask: 255.255.255.0 - gateway: 192.168.2.1 +nodes: + n0000.cluster01: + network devices: + eth0: + type: ethernet + hwaddr: 00:0c:29:23:8b:48 + ipaddr: 192.168.1.100 + netmask: 255.255.255.0 + ib0: + type: infiniband + hwaddr: aa:bb:cc:dd:ee:a0 + ipaddr: 192.168.10.100 + netmask: 255.255.255.0 + n0001.cluster01: + network devices: + eth0: + hwaddr: aa:bb:cc:dd:ee:b0 + ipaddr: 192.168.1.101 + ib0: + hwaddr: aa:bb:cc:dd:ee:b1 + ipaddr: 192.168.10.100 + netmask: 255.255.255.0 + n0000.cluster02: + network devices: + eth0: + hwaddr: aa:bb:cc:dd:ee:c0 + ipaddr: 192.168.2.100 + netmask: 255.255.255.0 + gateway: 192.168.1.1 diff --git a/etc/warewulf.conf b/etc/warewulf.conf index ae205e82..1f10ceec 100644 --- a/etc/warewulf.conf +++ b/etc/warewulf.conf @@ -1,4 +1,11 @@ -warewulfd ipaddr: 192.168.1.1 -warewulfd port: 9873 -insecure runtime: false -debug: false +ipaddr: 192.168.1.1 +netmask: 255.255.255.0 +warewulf: + port: 9873 + secure: true +dhcp: + enabled: true + range start: 192.168.1.150 + range end: 192.168.1.200 + template: default + diff --git a/go.mod b/go.mod index d443b1ce..63cf2a11 100644 --- a/go.mod +++ b/go.mod @@ -44,16 +44,17 @@ require ( github.com/russross/blackfriday/v2 v2.0.1 github.com/sirupsen/logrus v1.7.0 github.com/spf13/cobra v1.1.1 - github.com/ulikunitz/xz v0.5.8 - github.com/vbauerster/mpb/v5 v5.3.0 - go.etcd.io/bbolt v1.3.5 - golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9 - golang.org/x/net v0.0.0-20200602114024-627f9648deb9 - golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a - golang.org/x/sys v0.0.0-20200909081042-eff7692f9009 - google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 - google.golang.org/grpc v1.27.0 - google.golang.org/protobuf v1.24.0 - gopkg.in/square/go-jose.v2 v2.3.1 + github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31 + github.com/ulikunitz/xz v0.5.8 // indirect + github.com/vbauerster/mpb/v5 v5.3.0 // indirect + go.etcd.io/bbolt v1.3.5 // indirect + golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9 // indirect + golang.org/x/net v0.0.0-20200602114024-627f9648deb9 // indirect + golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a // indirect + golang.org/x/sys v0.0.0-20200909081042-eff7692f9009 // indirect + google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 // indirect + google.golang.org/grpc v1.27.0 // indirect + google.golang.org/protobuf v1.24.0 // indirect + gopkg.in/square/go-jose.v2 v2.3.1 // indirect gopkg.in/yaml.v2 v2.3.0 ) diff --git a/go.sum b/go.sum index e6347ff9..4f9a7888 100644 --- a/go.sum +++ b/go.sum @@ -384,6 +384,8 @@ github.com/tj/go-elastic v0.0.0-20171221160941-36157cbbebc2/go.mod h1:WjeM0Oo1eN github.com/tj/go-kinesis v0.0.0-20171128231115-08b17f58cb1b/go.mod h1:/yhzCV0xPfx6jb1bBgRFjl5lytqVqZXEaeqWP8lTEao= github.com/tj/go-spin v1.1.0/go.mod h1:Mg1mzmePZm4dva8Qz60H2lHwmJ2loum4VIrLgVnKwh4= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31 h1:OXcKh35JaYsGMRzpvFkLv/MEyPuL49CThT1pZ8aSml4= +github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31/go.mod h1:onvgF043R+lC5RZ8IT9rBXDaEDnpnw/Cl+HFiw+v/7Q= github.com/ulikunitz/xz v0.5.8 h1:ERv8V6GKqVi23rgu5cj9pVfVzJbOqAY2Ntl88O6c2nQ= github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= diff --git a/internal/app/warewulfd/response/ipxe.go b/internal/app/warewulfd/response/ipxe.go index 11194c6e..d4efa341 100644 --- a/internal/app/warewulfd/response/ipxe.go +++ b/internal/app/warewulfd/response/ipxe.go @@ -2,8 +2,8 @@ package response import ( "fmt" - "github.com/hpcng/warewulf/internal/pkg/config" "github.com/hpcng/warewulf/internal/pkg/node" + "github.com/hpcng/warewulf/internal/pkg/warewulfconf" "github.com/hpcng/warewulf/internal/pkg/wwlog" "log" "net/http" @@ -13,16 +13,15 @@ import ( ) type iPxeTemplate struct { - Hostname string - Fqdn string - Vnfs string - Hwaddr string - Ipaddr string - Port string - Kernelargs string + Hostname string + Fqdn string + Vnfs string + Hwaddr string + Ipaddr string + Port string + Kernelargs string } - func IpxeSend(w http.ResponseWriter, req *http.Request) { url := strings.Split(req.URL.Path, "/") @@ -47,9 +46,13 @@ func IpxeSend(w http.ResponseWriter, req *http.Request) { } if node.Id.Defined() == true { - conf := config.New() + conf, err := warewulfconf.New() + if err != nil { + wwlog.Printf(wwlog.ERROR, "%s\n", err) + return + } - log.Printf("IPXE: %15s: %s\n", node.Fqdn.Get(), req.URL.Path) + log.Printf("IPXE: %15s: %s\n", node.Id.Get(), req.URL.Path) // TODO: Fix template path to use config package ipxeTemplate := fmt.Sprintf("/etc/warewulf/ipxe/%s.ipxe", node.Ipxe.Get()) @@ -62,10 +65,10 @@ func IpxeSend(w http.ResponseWriter, req *http.Request) { var replace iPxeTemplate - replace.Fqdn = node.Fqdn.Get() + replace.Fqdn = node.Id.Get() replace.Ipaddr = conf.Ipaddr - replace.Port = strconv.Itoa(conf.Port) - replace.Hostname = node.HostName.Get() + replace.Port = strconv.Itoa(conf.Warewulf.Port) + replace.Hostname = node.Id.Get() replace.Hwaddr = url[2] replace.Vnfs = node.Vnfs.Get() replace.Kernelargs = node.KernelArgs.Get() @@ -76,7 +79,7 @@ func IpxeSend(w http.ResponseWriter, req *http.Request) { return } - log.Printf("SEND: %15s: %s\n", node.Fqdn.Get(), ipxeTemplate) + log.Printf("SEND: %15s: %s\n", node.Id.Get(), ipxeTemplate) } else { log.Printf("ERROR: iPXE request from unknown Node (hwaddr=%s)\n", url[2]) diff --git a/internal/app/warewulfd/response/kernel.go b/internal/app/warewulfd/response/kernel.go index f9fac3b9..a7683617 100644 --- a/internal/app/warewulfd/response/kernel.go +++ b/internal/app/warewulfd/response/kernel.go @@ -7,7 +7,6 @@ import ( ) func KernelSend(w http.ResponseWriter, req *http.Request) { - config := config.New() node, err := getSanity(req) if err != nil { @@ -19,16 +18,16 @@ func KernelSend(w http.ResponseWriter, req *http.Request) { if node.KernelVersion.Defined() == true { fileName := config.KernelImage(node.KernelVersion.Get()) - err := sendFile(w, fileName, node.Fqdn.Get()) + err := sendFile(w, fileName, node.Id.Get()) if err != nil { log.Printf("ERROR: %s\n", err) } else { - log.Printf("SEND: %15s: %s\n", node.Fqdn.Get(), fileName) + log.Printf("SEND: %15s: %s\n", node.Id.Get(), fileName) } } else { w.WriteHeader(503) - log.Printf("ERROR: No 'kernel version' set for node %s\n", node.Fqdn.Get()) + log.Printf("ERROR: No 'kernel version' set for node %s\n", node.Id.Get()) } return diff --git a/internal/app/warewulfd/response/kmods.go b/internal/app/warewulfd/response/kmods.go index 00db3605..c4366008 100644 --- a/internal/app/warewulfd/response/kmods.go +++ b/internal/app/warewulfd/response/kmods.go @@ -7,7 +7,6 @@ import ( ) func KmodsSend(w http.ResponseWriter, req *http.Request) { - config := config.New() node, err := getSanity(req) if err != nil { @@ -19,16 +18,16 @@ func KmodsSend(w http.ResponseWriter, req *http.Request) { if node.KernelVersion.Defined() == true { fileName := config.KmodsImage(node.KernelVersion.Get()) - err := sendFile(w, fileName, node.Fqdn.Get()) + err := sendFile(w, fileName, node.Id.Get()) if err != nil { log.Printf("ERROR: %s\n", err) } else { - log.Printf("SEND: %15s: %s\n", node.Fqdn.Get(), fileName) + log.Printf("SEND: %15s: %s\n", node.Id.Get(), fileName) } } else { w.WriteHeader(503) - log.Printf("ERROR: No 'kernel version' set for node %s\n", node.Fqdn.Get()) + log.Printf("ERROR: No 'kernel version' set for node %s\n", node.Id.Get()) } return diff --git a/internal/app/warewulfd/response/runtime.go b/internal/app/warewulfd/response/runtime.go index 7c784a85..ec6291b7 100644 --- a/internal/app/warewulfd/response/runtime.go +++ b/internal/app/warewulfd/response/runtime.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/hpcng/warewulf/internal/pkg/config" "github.com/hpcng/warewulf/internal/pkg/node" + "github.com/hpcng/warewulf/internal/pkg/warewulfconf" "log" "net/http" "strconv" @@ -11,7 +12,13 @@ import ( ) func RuntimeOverlaySend(w http.ResponseWriter, req *http.Request) { - config := config.New() + conf, err := warewulfconf.New() + if err != nil { + log.Printf("Could not read Warewulf configuration file: %s\n", err) + w.WriteHeader(503) + return + } + nodes, err := node.New() if err != nil { log.Printf("Could not read node configuration file: %s\n", err) @@ -32,7 +39,7 @@ func RuntimeOverlaySend(w http.ResponseWriter, req *http.Request) { return } - if config.InsecureRuntime == false { + if conf.Warewulf.Secure == true { if port >= 1024 { log.Panicf("DENIED: Connection coming from non-privledged port: %s\n", req.RemoteAddr) w.WriteHeader(401) @@ -52,21 +59,21 @@ func RuntimeOverlaySend(w http.ResponseWriter, req *http.Request) { w.WriteHeader(404) return } else { - log.Printf("REQ: %15s: %s\n", node.Fqdn.Get(), req.URL.Path) + log.Printf("REQ: %15s: %s\n", node.Id.Get(), req.URL.Path) } if node.RuntimeOverlay.Defined() == true { - fileName := config.RuntimeOverlayImage(node.Fqdn.Get()) + fileName := config.RuntimeOverlayImage(node.Id.Get()) - err := sendFile(w, fileName, node.Fqdn.Get()) + err := sendFile(w, fileName, node.Id.Get()) if err != nil { log.Printf("ERROR: %s\n", err) } else { - log.Printf("SEND: %15s: %s\n", node.Fqdn.Get(), fileName) + log.Printf("SEND: %15s: %s\n", node.Id.Get(), fileName) } } else { w.WriteHeader(503) - log.Printf("ERROR: No 'runtime system-overlay' set for node %s\n", node.Fqdn.Get()) + log.Printf("ERROR: No 'runtime system-overlay' set for node %s\n", node.Id.Get()) } return diff --git a/internal/app/warewulfd/response/system.go b/internal/app/warewulfd/response/system.go index 2a28cd56..3a3cf285 100644 --- a/internal/app/warewulfd/response/system.go +++ b/internal/app/warewulfd/response/system.go @@ -7,8 +7,6 @@ import ( ) func SystemOverlaySend(w http.ResponseWriter, req *http.Request) { - config := config.New() - node, err := getSanity(req) if err != nil { w.WriteHeader(404) @@ -17,17 +15,17 @@ func SystemOverlaySend(w http.ResponseWriter, req *http.Request) { } if node.SystemOverlay.Defined() == true { - fileName := config.SystemOverlayImage(node.Fqdn.Get()) + fileName := config.SystemOverlayImage(node.Id.Get()) - err := sendFile(w, fileName, node.Fqdn.Get()) + err := sendFile(w, fileName, node.Id.Get()) if err != nil { log.Printf("ERROR: %s\n", err) } else { - log.Printf("SEND: %15s: %s\n", node.Fqdn.Get(), fileName) + log.Printf("SEND: %15s: %s\n", node.Id.Get(), fileName) } } else { w.WriteHeader(503) - log.Printf("ERROR: No 'system system-overlay' set for node %s\n", node.Fqdn.Get()) + log.Printf("ERROR: No 'system system-overlay' set for node %s\n", node.Id.Get()) } return diff --git a/internal/app/warewulfd/response/util.go b/internal/app/warewulfd/response/util.go index f4ccc79a..8ef67270 100644 --- a/internal/app/warewulfd/response/util.go +++ b/internal/app/warewulfd/response/util.go @@ -27,12 +27,7 @@ func getSanity(req *http.Request) (node.NodeInfo, error) { return ret, errors.New("Could not find node by HW address") } - if ret.Fqdn.Defined() == false { - log.Printf("UNKNOWN: %15s: %s\n", hwaddr, req.URL.Path) - return ret, errors.New("Unknown node HW address: " + hwaddr) - } else { - log.Printf("REQ: %15s: %s\n", ret.Fqdn.Get(), req.URL.Path) - } + log.Printf("REQ: %15s: %s\n", ret.Id.Get(), req.URL.Path) return ret, nil } diff --git a/internal/app/warewulfd/response/vnfs.go b/internal/app/warewulfd/response/vnfs.go index e6e84a18..5ef72c0e 100644 --- a/internal/app/warewulfd/response/vnfs.go +++ b/internal/app/warewulfd/response/vnfs.go @@ -20,19 +20,19 @@ func VnfsSend(w http.ResponseWriter, req *http.Request) { v, err := vnfs.Load(node.Vnfs.Get()) if err != nil { w.WriteHeader(503) - log.Printf("ERROR: Could not load VNFS: %s\n", node.Fqdn.Get()) + log.Printf("ERROR: Could not load VNFS: %s\n", node.Id.Get()) return } - err = sendFile(w, v.Image, node.Fqdn.Get()) + err = sendFile(w, v.Image, node.Id.Get()) if err != nil { log.Printf("ERROR1: %s\n", err) } else { - log.Printf("SEND: %15s: %s\n", node.Fqdn.Get(), v.Image) + log.Printf("SEND: %15s: %s\n", node.Id.Get(), v.Image) } } else { w.WriteHeader(503) - log.Printf("ERROR: No VNFS set for node %s\n", node.Fqdn.Get()) + log.Printf("ERROR: No VNFS set for node %s\n", node.Id.Get()) } return diff --git a/internal/app/wwctl/build/main.go b/internal/app/wwctl/build/main.go index 353cd5a4..4bb827af 100644 --- a/internal/app/wwctl/build/main.go +++ b/internal/app/wwctl/build/main.go @@ -3,14 +3,12 @@ package build import ( "github.com/hpcng/warewulf/internal/pkg/kernel" "github.com/hpcng/warewulf/internal/pkg/node" - "github.com/hpcng/warewulf/internal/pkg/overlay" "github.com/hpcng/warewulf/internal/pkg/vnfs" "github.com/hpcng/warewulf/internal/pkg/wwlog" "github.com/spf13/cobra" "os" ) - func CobraRunE(cmd *cobra.Command, args []string) error { var nodes []node.NodeInfo showHelp := true @@ -46,7 +44,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error { wwlog.Printf(wwlog.INFO, "Building VNFS images...\n") for _, node := range nodes { - set[node.Vnfs.String()] ++ + set[node.Vnfs.Get()]++ } for e := range set { vnfs.Build(e, buildForce) @@ -60,7 +58,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error { wwlog.Printf(wwlog.INFO, "Building Kernel images...\n") for _, node := range nodes { - set[node.KernelVersion.String()] ++ + set[node.KernelVersion.Get()]++ } for e := range set { kernel.Build(e) @@ -71,14 +69,14 @@ func CobraRunE(cmd *cobra.Command, args []string) error { wwlog.Printf(wwlog.INFO, "Building System Overlays...\n") showHelp = false - overlay.SystemBuild(nodes, buildForce) + // overlay.SystemBuild(nodes, buildForce) } if buildRuntimeOverlay == true || buildAll == true { wwlog.Printf(wwlog.INFO, "Building Runtime Overlays...n") showHelp = false - overlay.RuntimeBuild(nodes, buildForce) + // overlay.RuntimeBuild(nodes, buildForce) } if showHelp == true { diff --git a/internal/app/wwctl/controller/list/main.go b/internal/app/wwctl/controller/list/main.go index 6d6a97a9..a32e8bbf 100644 --- a/internal/app/wwctl/controller/list/main.go +++ b/internal/app/wwctl/controller/list/main.go @@ -34,22 +34,28 @@ func CobraRunE(cmd *cobra.Command, args []string) error { fmt.Printf("%-15s %15s : %s = %s\n", c.Id, "Warewulf", "Enable CMD", c.Services.Warewulfd.EnableCmd) fmt.Printf("%-15s %15s : %s = %s\n", c.Id, "Warewulf", "Restart CMD", c.Services.Warewulfd.RestartCmd) fmt.Printf("%-15s %15s : %s = %t\n", c.Id, "DHCPD", "Enabled", c.Services.Dhcp.Enabled) - fmt.Printf("%-15s %15s : %s = %s\n", c.Id, "DHCPD", "Template", c.Services.Dhcp.Template) - fmt.Printf("%-15s %15s : %s = %s\n", c.Id, "DHCPD", "ConfigFile", c.Services.Dhcp.ConfigFile) - fmt.Printf("%-15s %15s : %s = %s\n", c.Id, "DHCPD", "RangeStart", c.Services.Dhcp.RangeStart) - fmt.Printf("%-15s %15s : %s = %s\n", c.Id, "DHCPD", "RangeEnd", c.Services.Dhcp.RangeEnd) - fmt.Printf("%-15s %15s : %s = %s\n", c.Id, "DHCPD", "Enable CMD", c.Services.Dhcp.EnableCmd) - fmt.Printf("%-15s %15s : %s = %s\n", c.Id, "DHCPD", "Restart CMD", c.Services.Dhcp.RestartCmd) - fmt.Printf("%-15s %15s : %s = %t\n", c.Id, "TFTP", "Enabled", c.Services.Tftp.Enabled) - fmt.Printf("%-15s %15s : %s = %s\n", c.Id, "TFTP", "TftpRoot", c.Services.Tftp.TftpRoot) - fmt.Printf("%-15s %15s : %s = %s\n", c.Id, "TFTP", "Enable CMD", c.Services.Tftp.EnableCmd) - fmt.Printf("%-15s %15s : %s = %s\n", c.Id, "TFTP", "Restart CMD", c.Services.Tftp.RestartCmd) - fmt.Printf("%-15s %15s : %s = %t\n", c.Id, "NFS", "Enabled", c.Services.Nfs.Enabled) - for _, e := range c.Services.Nfs.Exports { - fmt.Printf("%-15s %15s : %s = %s\n", c.Id, "NFS", "Exports", e) + if c.Services.Dhcp.Enabled == true { + fmt.Printf("%-15s %15s : %s = %s\n", c.Id, "DHCPD", "Template", c.Services.Dhcp.Template) + fmt.Printf("%-15s %15s : %s = %s\n", c.Id, "DHCPD", "ConfigFile", c.Services.Dhcp.ConfigFile) + fmt.Printf("%-15s %15s : %s = %s\n", c.Id, "DHCPD", "RangeStart", c.Services.Dhcp.RangeStart) + fmt.Printf("%-15s %15s : %s = %s\n", c.Id, "DHCPD", "RangeEnd", c.Services.Dhcp.RangeEnd) + fmt.Printf("%-15s %15s : %s = %s\n", c.Id, "DHCPD", "Enable CMD", c.Services.Dhcp.EnableCmd) + fmt.Printf("%-15s %15s : %s = %s\n", c.Id, "DHCPD", "Restart CMD", c.Services.Dhcp.RestartCmd) + } + fmt.Printf("%-15s %15s : %s = %t\n", c.Id, "TFTP", "Enabled", c.Services.Tftp.Enabled) + if c.Services.Tftp.Enabled == true { + fmt.Printf("%-15s %15s : %s = %s\n", c.Id, "TFTP", "TftpRoot", c.Services.Tftp.TftpRoot) + fmt.Printf("%-15s %15s : %s = %s\n", c.Id, "TFTP", "Enable CMD", c.Services.Tftp.EnableCmd) + fmt.Printf("%-15s %15s : %s = %s\n", c.Id, "TFTP", "Restart CMD", c.Services.Tftp.RestartCmd) + } + fmt.Printf("%-15s %15s : %s = %t\n", c.Id, "NFS", "Enabled", c.Services.Nfs.Enabled) + if c.Services.Nfs.Enabled == true { + for _, e := range c.Services.Nfs.Exports { + fmt.Printf("%-15s %15s : %s = %s\n", c.Id, "NFS", "Exports", e) + } + fmt.Printf("%-15s %15s : %s = %s\n", c.Id, "NFS", "Enable CMD", c.Services.Nfs.EnableCmd) + fmt.Printf("%-15s %15s : %s = %s\n", c.Id, "NFS", "Restart CMD", c.Services.Nfs.RestartCmd) } - fmt.Printf("%-15s %15s : %s = %s\n", c.Id, "NFS", "Enable CMD", c.Services.Nfs.EnableCmd) - fmt.Printf("%-15s %15s : %s = %s\n", c.Id, "NFS", "Restart CMD", c.Services.Nfs.RestartCmd) } } else { diff --git a/internal/app/wwctl/controller/set/main.go b/internal/app/wwctl/controller/set/main.go index d38ce4be..e7ed61d6 100644 --- a/internal/app/wwctl/controller/set/main.go +++ b/internal/app/wwctl/controller/set/main.go @@ -24,19 +24,18 @@ func CobraRunE(cmd *cobra.Command, args []string) error { os.Exit(1) } + if len(args) == 0 { + args = append(args, "localhost") + } + if SetAll == true { - var tmp []node.ControllerInfo - tmp, err = nodeDB.FindAllControllers() + controllers, err = nodeDB.FindAllControllers() if err != nil { wwlog.Printf(wwlog.ERROR, "%s\n", err) os.Exit(1) } - for _, c := range tmp { - controllers = append(controllers, c) - } - - } else if len(args) > 0 { + } else { var tmp []node.ControllerInfo tmp, err = nodeDB.FindAllControllers() if err != nil { @@ -51,10 +50,6 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } } } - - } else { - cmd.Usage() - os.Exit(1) } for _, c := range controllers { diff --git a/internal/app/wwctl/group/add/main.go b/internal/app/wwctl/group/add/main.go deleted file mode 100644 index 8b4bdadb..00000000 --- a/internal/app/wwctl/group/add/main.go +++ /dev/null @@ -1,29 +0,0 @@ -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) - } - - for _, g := range args { - err = nodeDB.AddGroup(SetController, g) - if err != nil { - wwlog.Printf(wwlog.ERROR, "%s\n", err) - os.Exit(1) - } - } - - nodeDB.Persist() - - return nil -} - diff --git a/internal/app/wwctl/group/add/root.go b/internal/app/wwctl/group/add/root.go deleted file mode 100644 index 972e1fe0..00000000 --- a/internal/app/wwctl/group/add/root.go +++ /dev/null @@ -1,24 +0,0 @@ -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, - Args: cobra.MinimumNArgs(1), - } - SetController string -) - -func init() { - baseCmd.PersistentFlags().StringVarP(&SetController, "controller", "c", "default", "Controller to add group to") - -} - -// GetRootCommand returns the root cobra.Command for the application. -func GetCommand() *cobra.Command { - return baseCmd -} diff --git a/internal/app/wwctl/group/delete/main.go b/internal/app/wwctl/group/delete/main.go deleted file mode 100644 index 5e3120c5..00000000 --- a/internal/app/wwctl/group/delete/main.go +++ /dev/null @@ -1,61 +0,0 @@ -package delete - -import ( - "fmt" - "github.com/hpcng/warewulf/internal/pkg/node" - "github.com/hpcng/warewulf/internal/pkg/wwlog" - "github.com/manifoldco/promptui" - "github.com/spf13/cobra" - "os" -) - -func CobraRunE(cmd *cobra.Command, args []string) error { - var count int - var numNodes int - - nodeDB, err := node.New() - if err != nil { - wwlog.Printf(wwlog.ERROR, "Failed to open node database: %s\n", err) - os.Exit(1) - } - - nodes, err := nodeDB. FindAllNodes() - if err != nil { - wwlog.Printf(wwlog.ERROR, "Could not load all nodes: %s\n", err) - os.Exit(1) - } - - for _, g := range args { - err := nodeDB.DelGroup(SetController, g) - if err != nil { - wwlog.Printf(wwlog.ERROR, "%s\n", err) - } else { - for _, n := range nodes { - if n.Gid.Get() == g { - numNodes ++ - } - } - count ++ - } - } - - if count > 0 { - q := fmt.Sprintf("Are you sure you want to delete %d group(s) (%d nodes)", count, numNodes) - - prompt := promptui.Prompt{ - Label: q, - IsConfirm: true, - } - - result, _ := prompt.Run() - - if result == "y" || result == "yes" { - nodeDB.Persist() - } - - } else { - wwlog.Printf(wwlog.INFO, "No groups found\n") - } - - return nil -} diff --git a/internal/app/wwctl/group/delete/root.go b/internal/app/wwctl/group/delete/root.go deleted file mode 100644 index bb343acd..00000000 --- a/internal/app/wwctl/group/delete/root.go +++ /dev/null @@ -1,22 +0,0 @@ -package delete - -import "github.com/spf13/cobra" - -var ( - baseCmd = &cobra.Command{ - Use: "delete", - Short: "Add a new node group", - Long: "Add a new node group ", - RunE: CobraRunE, - } - SetController string -) - -func init() { - baseCmd.PersistentFlags().StringVarP(&SetController, "controller", "c", "default", "Controller to add group to") -} - -// 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 deleted file mode 100644 index cbe06514..00000000 --- a/internal/app/wwctl/group/list/main.go +++ /dev/null @@ -1,45 +0,0 @@ -package list - -import ( - "fmt" - "github.com/hpcng/warewulf/internal/pkg/node" - "github.com/hpcng/warewulf/internal/pkg/wwlog" - "github.com/spf13/cobra" - "os" - "reflect" - "strings" -) - -func CobraRunE(cmd *cobra.Command, args []string) error { - nodeDB, err := node.New() - if err != nil { - wwlog.Printf(wwlog.ERROR, "Could not open node configuration: %s\n", err) - os.Exit(1) - } - - groups, err := nodeDB.FindAllGroups() - if err != nil { - wwlog.Printf(wwlog.ERROR, "Could not find all nodes: %s\n", err) - os.Exit(1) - } - - - if ShowAll == true { - for _, group := range groups { - v := reflect.ValueOf(group) - typeOfS := v.Type() - fmt.Printf("################################################################################\n") - for i := 0; i< v.NumField(); i++ { - fmt.Printf("%-25s %s = %v\n", group.Id, typeOfS.Field(i).Name, v.Field(i).Interface()) - } - } - } else { - fmt.Printf("%-22s %-16s %-16s %s\n", "GROUP NAME", "DOMAINNAME", "CONTROLLER", "PROFILES") - for _, g := range groups { - fmt.Printf("%-22s %-16s %-16s %s\n", g.Id, g.DomainName, g.Cid, strings.Join(g.Profiles, ",")) - } - } - - - return nil -} diff --git a/internal/app/wwctl/group/list/root.go b/internal/app/wwctl/group/list/root.go deleted file mode 100644 index 5d0183f8..00000000 --- a/internal/app/wwctl/group/list/root.go +++ /dev/null @@ -1,23 +0,0 @@ -package list - -import "github.com/spf13/cobra" - -var ( - baseCmd = &cobra.Command{ - Use: "list", - Short: "List group configurations", - Long: "List group configurations ", - RunE: CobraRunE, - } - ShowAll bool -) - -func init() { - baseCmd.PersistentFlags().BoolVarP(&ShowAll, "all", "a", false, "Show all node configurations") - -} - -// 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 deleted file mode 100644 index 98cf1ebb..00000000 --- a/internal/app/wwctl/group/root.go +++ /dev/null @@ -1,29 +0,0 @@ -package group - -import ( - "github.com/hpcng/warewulf/internal/app/wwctl/group/add" - "github.com/hpcng/warewulf/internal/app/wwctl/group/delete" - "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()) - baseCmd.AddCommand(delete.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 deleted file mode 100644 index bce863a2..00000000 --- a/internal/app/wwctl/group/set/main.go +++ /dev/null @@ -1,188 +0,0 @@ -package set - -import ( - "fmt" - "github.com/hpcng/warewulf/internal/pkg/node" - "github.com/hpcng/warewulf/internal/pkg/util" - "github.com/hpcng/warewulf/internal/pkg/wwlog" - "github.com/manifoldco/promptui" - "github.com/spf13/cobra" - "os" -) - -func CobraRunE(cmd *cobra.Command, args []string) error { - var err error - var groups []node.GroupInfo - - nodeDB, err := node.New() - if err != nil { - wwlog.Printf(wwlog.ERROR, "Could not open node configuration: %s\n", err) - os.Exit(1) - } - - if err != nil { - wwlog.Printf(wwlog.ERROR, "Cloud not get nodeList: %s\n", err) - os.Exit(1) - } - - if SetGroupAll == true { - var tmp []node.GroupInfo - tmp, err = nodeDB.FindAllGroups() - if err != nil { - wwlog.Printf(wwlog.ERROR, "%s\n", err) - os.Exit(1) - } - - for _, g := range tmp { - groups = append(groups, g) - } - - } else if len(args) > 0 { - var tmp []node.GroupInfo - tmp, err = nodeDB.FindAllGroups() - if err != nil { - wwlog.Printf(wwlog.ERROR, "%s\n", err) - os.Exit(1) - } - - for _, a := range args { - for _, g := range tmp { - if g.Id == a { - groups = append(groups, g) - } - } - } - - } else { - cmd.Usage() - os.Exit(1) - } - - for _, g := range groups { - - if SetDomainName != "" { - wwlog.Printf(wwlog.VERBOSE, "Group: %s, Setting domain name to: %s\n", g.Id, SetDomainName) - - g.DomainName = SetDomainName - err := nodeDB.GroupUpdate(g) - if err != nil { - wwlog.Printf(wwlog.ERROR, "%s\n", err) - os.Exit(1) - } - } - if SetVnfs != "" { - wwlog.Printf(wwlog.VERBOSE, "Group: %s, Setting VNFS to: %s\n", g.Id, SetVnfs) - - g.Vnfs = SetVnfs - err := nodeDB.GroupUpdate(g) - if err != nil { - wwlog.Printf(wwlog.ERROR, "%s\n", err) - os.Exit(1) - } - } - if SetKernel != "" { - wwlog.Printf(wwlog.VERBOSE, "Group: %s, Setting kernel to: %s\n", g.Id, SetKernel) - - g.KernelVersion = SetKernel - err := nodeDB.GroupUpdate(g) - if err != nil { - wwlog.Printf(wwlog.ERROR, "%s\n", err) - os.Exit(1) - } - } - if SetIpmiNetmask != "" { - wwlog.Printf(wwlog.VERBOSE, "Group: %s, Setting IPMI username to: %s\n", g.Id, SetIpmiNetmask) - - g.IpmiNetmask = SetIpmiNetmask - err := nodeDB.GroupUpdate(g) - if err != nil { - wwlog.Printf(wwlog.ERROR, "%s\n", err) - os.Exit(1) - } - } - if SetIpmiUsername != "" { - wwlog.Printf(wwlog.VERBOSE, "Group: %s, Setting IPMI username to: %s\n", g.Id, SetIpmiUsername) - - g.IpmiUserName = SetIpmiUsername - err := nodeDB.GroupUpdate(g) - if err != nil { - wwlog.Printf(wwlog.ERROR, "%s\n", err) - os.Exit(1) - } - } - if SetIpmiPassword != "" { - wwlog.Printf(wwlog.VERBOSE, "Group: %s, Setting IPMI password to: %s\n", g.Id, SetIpmiPassword) - - g.IpmiPassword = SetIpmiPassword - err := nodeDB.GroupUpdate(g) - if err != nil { - wwlog.Printf(wwlog.ERROR, "%s\n", err) - os.Exit(1) - } - } - if SetSystemOverlay != "" { - wwlog.Printf(wwlog.VERBOSE, "Group: %s, Setting system overlay to: %s\n", g.Id, SetSystemOverlay) - - g.SystemOverlay = SetSystemOverlay - err := nodeDB.GroupUpdate(g) - if err != nil { - wwlog.Printf(wwlog.ERROR, "%s\n", err) - os.Exit(1) - } - } - if SetRuntimeOverlay != "" { - wwlog.Printf(wwlog.VERBOSE, "Group: %s, Setting runtime overlay to: %s\n", g.Id, SetRuntimeOverlay) - - g.RuntimeOverlay = SetRuntimeOverlay - err := nodeDB.GroupUpdate(g) - 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, "Adding profile to '%s': '%s'\n", g.Id, p) - g.Profiles = util.SliceAddUniqueElement(g.Profiles, p) - } - err := nodeDB.GroupUpdate(g) - if err != nil { - wwlog.Printf(wwlog.ERROR, "%s\n", err) - os.Exit(1) - } - } - if len(SetDelProfile) > 0 { - for _, p := range SetDelProfile { - wwlog.Printf(wwlog.VERBOSE, "Removing profile to '%s': '%s'\n", g.Id, p) - g.Profiles = util.SliceRemoveElement(g.Profiles, p) - } - err := nodeDB.GroupUpdate(g) - if err != nil { - wwlog.Printf(wwlog.ERROR, "%s\n", err) - os.Exit(1) - } - } - - } - - if len(groups) > 0 { - q := fmt.Sprintf("Are you sure you want to modify %d group(s)", len(groups)) - - prompt := promptui.Prompt{ - Label: q, - IsConfirm: true, - } - - result, _ := prompt.Run() - - if result == "y" || result == "yes" { - nodeDB.Persist() - } - - } else { - fmt.Printf("No groups found\n") - } - - return nil -} diff --git a/internal/app/wwctl/group/set/root.go b/internal/app/wwctl/group/set/root.go deleted file mode 100644 index e0fd632b..00000000 --- a/internal/app/wwctl/group/set/root.go +++ /dev/null @@ -1,49 +0,0 @@ -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 - SetDomainName string - SetIpxe string - SetRuntimeOverlay string - SetSystemOverlay string - SetClearNodes bool - SetIpmiNetmask string - SetIpmiUsername string - SetIpmiPassword string - SetGroupAll bool - SetAddProfile []string - SetDelProfile []string -) - -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") - baseCmd.PersistentFlags().StringVarP(&SetDomainName, "domain", "D", "", "Set the node's domain name") - baseCmd.PersistentFlags().StringVarP(&SetIpxe, "ipxe", "P", "", "Set the node's iPXE template name") - baseCmd.PersistentFlags().StringVarP(&SetRuntimeOverlay, "runtime", "R", "", "Set the node's runtime overlay") - baseCmd.PersistentFlags().StringVarP(&SetSystemOverlay, "system", "S", "", "Set the node's system overlay") - baseCmd.PersistentFlags().StringVar(&SetIpmiNetmask, "ipminetmask", "", "Set the node's IPMI netmask") - baseCmd.PersistentFlags().StringVar(&SetIpmiUsername, "ipmiuser", "", "Set the node's IPMI username") - baseCmd.PersistentFlags().StringVar(&SetIpmiPassword, "ipmipass", "", "Set the node's IPMI password") - - baseCmd.PersistentFlags().StringSliceVarP(&SetAddProfile, "addprofile", "p", []string{}, "Add Profile(s) to group") - baseCmd.PersistentFlags().StringSliceVarP(&SetDelProfile, "delprofile", "r", []string{}, "Remove Profile(s) to group") - - baseCmd.PersistentFlags().BoolVarP(&SetClearNodes, "clear", "c", false, "Clear node configurations when setting parent group") - baseCmd.PersistentFlags().BoolVarP(&SetGroupAll, "all", "a", false, "Set all nodes") - -} - -// GetRootCommand returns the root cobra.Command for the application. -func GetCommand() *cobra.Command { - return baseCmd -} diff --git a/internal/app/wwctl/kernel/build/main.go b/internal/app/wwctl/kernel/build/main.go index 9d40d23f..25d0ef01 100644 --- a/internal/app/wwctl/kernel/build/main.go +++ b/internal/app/wwctl/kernel/build/main.go @@ -28,7 +28,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error { for _, node := range nodes { if node.KernelVersion.Defined() == true { - set[node.KernelVersion.Get()] ++ + set[node.KernelVersion.Get()]++ } } @@ -41,14 +41,14 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } for _, node := range nodes { - wwlog.Printf(wwlog.DEBUG, "evaluating node/kernel: %s/%s\n", node.Fqdn.Get(), node.KernelVersion.String()) + wwlog.Printf(wwlog.DEBUG, "evaluating node/kernel: %s/%s\n", node.Id.Get(), node.KernelVersion.Get()) if node.KernelVersion.Defined() == true { - set[node.KernelVersion.Get()] ++ + set[node.KernelVersion.Get()]++ } } } else if len(args) == 1 { - set[args[0]] ++ + set[args[0]]++ } else { cmd.Usage() os.Exit(1) @@ -64,4 +64,4 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } return nil -} \ No newline at end of file +} diff --git a/internal/app/wwctl/kernel/list/main.go b/internal/app/wwctl/kernel/list/main.go index 0e10f4e0..87b25e76 100644 --- a/internal/app/wwctl/kernel/list/main.go +++ b/internal/app/wwctl/kernel/list/main.go @@ -13,13 +13,12 @@ import ( ) func CobraRunE(cmd *cobra.Command, args []string) error { - config := config.New() nconfig, _ := node.New() nodes, _ := nconfig.FindAllNodes() nodemap := make(map[string]int) for _, n := range nodes { - nodemap[n.KernelVersion.String()] ++ + nodemap[n.KernelVersion.Get()]++ } images, _ := ioutil.ReadDir(config.KernelParentDir()) @@ -31,11 +30,11 @@ func CobraRunE(cmd *cobra.Command, args []string) error { if util.IsDir(path.Join(config.KernelParentDir(), file.Name())) { var kernel_size int64 var kmods_size int64 - if util.IsFile( config.KernelImage(file.Name())) { + if util.IsFile(config.KernelImage(file.Name())) { s, _ := os.Stat(config.KernelImage(file.Name())) kernel_size = s.Size() / 1024 } - if util.IsFile( config.KmodsImage(file.Name())) { + if util.IsFile(config.KmodsImage(file.Name())) { s, _ := os.Stat(config.KmodsImage(file.Name())) kmods_size = s.Size() / 1024 } @@ -48,6 +47,5 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } } - return nil -} \ No newline at end of file +} diff --git a/internal/app/wwctl/node/add/main.go b/internal/app/wwctl/node/add/main.go index 232ee268..22937985 100644 --- a/internal/app/wwctl/node/add/main.go +++ b/internal/app/wwctl/node/add/main.go @@ -16,15 +16,95 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } for _, a := range args { - err = nodeDB.AddNode(SetController, SetGroup, a) + n, err := nodeDB.AddNode(a) if err != nil { wwlog.Printf(wwlog.ERROR, "%s\n", err) os.Exit(1) } fmt.Printf("Added node: %s\n", a) + + if SetIpaddr != "" { + if SetNetDev == "" { + wwlog.Printf(wwlog.ERROR, "You must include the '--netdev' option\n") + os.Exit(1) + } + + if _, ok := n.NetDevs[SetNetDev]; !ok { + var netdev node.NetDevEntry + n.NetDevs[SetNetDev] = &netdev + } + + wwlog.Printf(wwlog.VERBOSE, "Node: %s:%s, Setting Ipaddr to: %s\n", n.Id, SetNetDev, SetIpaddr) + + n.NetDevs[SetNetDev].Ipaddr.Set(SetIpaddr) + n.NetDevs[SetNetDev].Default.SetB(true) + err := nodeDB.NodeUpdate(n) + if err != nil { + wwlog.Printf(wwlog.ERROR, "%s\n", err) + os.Exit(1) + } + } + if SetNetmask != "" { + if SetNetDev == "" { + wwlog.Printf(wwlog.ERROR, "You must include the '--netdev' option\n") + os.Exit(1) + } + + if _, ok := n.NetDevs[SetNetDev]; !ok { + wwlog.Printf(wwlog.ERROR, "Network Device doesn't exist: %s\n", SetNetDev) + os.Exit(1) + } + wwlog.Printf(wwlog.VERBOSE, "Node: %s:%s, Setting netmask to: %s\n", n.Id, SetNetDev, SetNetmask) + + n.NetDevs[SetNetDev].Netmask.Set(SetNetmask) + err := nodeDB.NodeUpdate(n) + if err != nil { + wwlog.Printf(wwlog.ERROR, "%s\n", err) + os.Exit(1) + } + } + if SetGateway != "" { + if SetNetDev == "" { + wwlog.Printf(wwlog.ERROR, "You must include the '--netdev' option\n") + os.Exit(1) + } + + if _, ok := n.NetDevs[SetNetDev]; !ok { + wwlog.Printf(wwlog.ERROR, "Network Device doesn't exist: %s\n", SetNetDev) + os.Exit(1) + } + wwlog.Printf(wwlog.VERBOSE, "Node: %s:%s, Setting gateway to: %s\n", n.Id, SetNetDev, SetGateway) + + n.NetDevs[SetNetDev].Gateway.Set(SetGateway) + err := nodeDB.NodeUpdate(n) + if err != nil { + wwlog.Printf(wwlog.ERROR, "%s\n", err) + os.Exit(1) + } + } + if SetHwaddr != "" { + if SetNetDev == "" { + wwlog.Printf(wwlog.ERROR, "You must include the '--netdev' option\n") + os.Exit(1) + } + + if _, ok := n.NetDevs[SetNetDev]; !ok { + wwlog.Printf(wwlog.ERROR, "Network Device doesn't exist: %s\n", SetNetDev) + os.Exit(1) + } + wwlog.Printf(wwlog.VERBOSE, "Node: %s:%s, Setting HW address to: %s\n", n.Id, SetNetDev, SetHwaddr) + + n.NetDevs[SetNetDev].Hwaddr.Set(SetHwaddr) + err := nodeDB.NodeUpdate(n) + if err != nil { + wwlog.Printf(wwlog.ERROR, "%s\n", err) + os.Exit(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 index e394fa72..f794ef80 100644 --- a/internal/app/wwctl/node/add/root.go +++ b/internal/app/wwctl/node/add/root.go @@ -4,19 +4,30 @@ import "github.com/spf13/cobra" var ( baseCmd = &cobra.Command{ - Use: "add", - Short: "Add new node", - Long: "Add new node ", - RunE: CobraRunE, - Args: cobra.MinimumNArgs(1), + Use: "add", + Short: "Add new node", + Long: "Add new node ", + RunE: CobraRunE, + Args: cobra.MinimumNArgs(1), } - SetGroup string + SetGroup string SetController string + SetNetDev string + SetIpaddr string + SetNetmask string + SetGateway string + SetHwaddr string ) func init() { baseCmd.PersistentFlags().StringVarP(&SetGroup, "group", "g", "default", "Group to add nodes to") - baseCmd.PersistentFlags().StringVarP(&SetController, "controller", "c", "default", "Controller to add nodes to") + baseCmd.PersistentFlags().StringVarP(&SetController, "controller", "c", "localhost", "Controller to add nodes to") + baseCmd.PersistentFlags().StringVarP(&SetNetDev, "netdev", "n", "eth0", "Define the network device to configure") + baseCmd.PersistentFlags().StringVarP(&SetIpaddr, "ipaddr", "I", "", "Set the node's network device IP address") + 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") + } // GetRootCommand returns the root cobra.Command for the application. diff --git a/internal/app/wwctl/node/delete/main.go b/internal/app/wwctl/node/delete/main.go index e20ea7f9..2730c967 100644 --- a/internal/app/wwctl/node/delete/main.go +++ b/internal/app/wwctl/node/delete/main.go @@ -21,11 +21,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error { nodeList, err := nodeDB.SearchByNameList(args) for _, n := range nodeList { - if SetGroup != "" && SetGroup != n.Gid.String() { - wwlog.Printf(wwlog.DEBUG, "skipping node of different group: %s/%s\n", n.Gid, n.Id) - continue - } - err := nodeDB.DelNode(n.Cid.Get(), n.Gid.Get(), n.Id.Get()) + err := nodeDB.DelNode(n.Id.Get()) if err != nil { wwlog.Printf(wwlog.ERROR, "%s\n", err) } else { diff --git a/internal/app/wwctl/node/list/main.go b/internal/app/wwctl/node/list/main.go index 3c0e88a7..13fcdc7e 100644 --- a/internal/app/wwctl/node/list/main.go +++ b/internal/app/wwctl/node/list/main.go @@ -6,6 +6,7 @@ import ( "github.com/hpcng/warewulf/internal/pkg/wwlog" "github.com/spf13/cobra" "os" + "sort" "strings" ) @@ -29,31 +30,42 @@ func CobraRunE(cmd *cobra.Command, args []string) error { os.Exit(1) } + sort.Slice(nodes, func(i, j int) bool { + if nodes[i].DomainName.Get() < nodes[j].DomainName.Get() { + return true + } else if nodes[i].DomainName.Get() == nodes[j].DomainName.Get() { + if nodes[i].Id.Get() < nodes[j].Id.Get() { + return true + } + } + return false + }) + if ShowAll == true { for _, node := range nodes { fmt.Printf("################################################################################\n") - fmt.Printf("%-20s %-18s %8s: %s\n", node.Fqdn.Get(), "Id", node.Id.Source(), node.Id.String()) - fmt.Printf("%-20s %-18s %8s: %s\n", node.Fqdn.Get(), "Comment", node.Comment.Source(), node.Comment.String()) - fmt.Printf("%-20s %-18s %8s: %s\n", node.Fqdn.Get(), "GroupName", node.Gid.Source(), node.Gid.String()) - fmt.Printf("%-20s %-18s %8s: %s\n", node.Fqdn.Get(), "DomainName", node.DomainName.Source(), node.DomainName.String()) - fmt.Printf("%-20s %-18s %8s: %s\n", node.Fqdn.Get(), "Profiles (Group)", "group", strings.Join(node.GroupProfiles, ",")) - fmt.Printf("%-20s %-18s %8s: %s\n", node.Fqdn.Get(), "Profiles (Node)", "node", strings.Join(node.Profiles, ",")) + fmt.Printf("%-20s %-18s %-12s %s\n", "NODE", "FIELD", "PROFILE", "VALUE") + fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "Id", node.Id.Source(), node.Id.Print()) + fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "Comment", node.Comment.Source(), node.Comment.Print()) + fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "DomainName", node.DomainName.Source(), node.DomainName.Print()) + fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "Profiles", "--", strings.Join(node.Profiles, ",")) - fmt.Printf("%-20s %-18s %8s: %s\n", node.Fqdn.Get(), "Vnfs", node.Vnfs.Source(), node.Vnfs.String()) - fmt.Printf("%-20s %-18s %8s: %s\n", node.Fqdn.Get(), "KernelVersion", node.KernelVersion.Source(), node.KernelVersion.String()) - fmt.Printf("%-20s %-18s %8s: %s\n", node.Fqdn.Get(), "KernelArgs", node.KernelArgs.Source(), node.KernelArgs.String()) - fmt.Printf("%-20s %-18s %8s: %s\n", node.Fqdn.Get(), "RuntimeOverlay", node.RuntimeOverlay.Source(), node.RuntimeOverlay.String()) - fmt.Printf("%-20s %-18s %8s: %s\n", node.Fqdn.Get(), "SystemOverlay", node.SystemOverlay.Source(), node.SystemOverlay.String()) - fmt.Printf("%-20s %-18s %8s: %s\n", node.Fqdn.Get(), "Ipxe", node.Ipxe.Source(), node.Ipxe.String()) - fmt.Printf("%-20s %-18s %8s: %s\n", node.Fqdn.Get(), "IpmiIpaddr", node.IpmiIpaddr.Source(), node.IpmiIpaddr.String()) - fmt.Printf("%-20s %-18s %8s: %s\n", node.Fqdn.Get(), "IpmiNetmask", node.IpmiNetmask.Source(), node.IpmiNetmask.String()) - fmt.Printf("%-20s %-18s %8s: %s\n", node.Fqdn.Get(), "IpmiUserName", node.IpmiUserName.Source(), node.IpmiUserName.String()) + fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "Vnfs", node.Vnfs.Source(), node.Vnfs.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()) + fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "RuntimeOverlay", node.RuntimeOverlay.Source(), node.RuntimeOverlay.Print()) + fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "SystemOverlay", node.SystemOverlay.Source(), node.SystemOverlay.Print()) + fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "Ipxe", node.Ipxe.Source(), node.Ipxe.Print()) + fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "IpmiIpaddr", node.IpmiIpaddr.Source(), node.IpmiIpaddr.Print()) + fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "IpmiNetmask", node.IpmiNetmask.Source(), node.IpmiNetmask.Print()) + fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "IpmiUserName", node.IpmiUserName.Source(), node.IpmiUserName.Print()) for name, netdev := range node.NetDevs { - fmt.Printf("%-20s %-18s %8s: %s\n", node.Fqdn.Get(), name+":IPADDR", "node", netdev.Ipaddr) - fmt.Printf("%-20s %-18s %8s: %s\n", node.Fqdn.Get(), name+":NETMASK", "node", netdev.Netmask) - fmt.Printf("%-20s %-18s %8s: %s\n", node.Fqdn.Get(), name+":GATEWAY", "node", netdev.Gateway) - fmt.Printf("%-20s %-18s %8s: %s\n", node.Fqdn.Get(), name+":HWADDR", "node", netdev.Hwaddr) + fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), name+":HWADDR", netdev.Hwaddr.Source(), netdev.Hwaddr.Print()) + fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), name+":IPADDR", netdev.Ipaddr.Source(), netdev.Ipaddr.Print()) + fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), name+":NETMASK", netdev.Netmask.Source(), netdev.Netmask.Print()) + fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), name+":GATEWAY", netdev.Gateway.Source(), netdev.Gateway.Print()) + fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), name+":TYPE", netdev.Type.Source(), netdev.Type.Print()) } // v := reflect.ValueOf(node) @@ -71,10 +83,10 @@ func CobraRunE(cmd *cobra.Command, args []string) error { for _, node := range nodes { if len(node.NetDevs) > 0 { for name, dev := range node.NetDevs { - fmt.Printf("%-22s %-6s %-18s %-15s %-15s\n", node.Fqdn.Get(), name, dev.Hwaddr, dev.Ipaddr, dev.Gateway) + fmt.Printf("%-22s %-6s %-18s %-15s %-15s\n", node.Id.Get(), name, dev.Hwaddr, dev.Ipaddr, dev.Gateway) } } else { - fmt.Printf("%-22s %-6s %-18s %-15s %-15s\n", node.Fqdn.Get(), "--", "--", "--", "--") + fmt.Printf("%-22s %-6s %-18s %-15s %-15s\n", node.Id.Get(), "--", "--", "--", "--") } } @@ -83,23 +95,30 @@ func CobraRunE(cmd *cobra.Command, args []string) error { fmt.Println(strings.Repeat("=", 80)) for _, node := range nodes { - fmt.Printf("%-22s %-16s %-20s %-20s\n", node.Fqdn.Get(), node.IpmiIpaddr.String(), node.IpmiUserName.String(), node.IpmiPassword.String()) + fmt.Printf("%-22s %-16s %-20s %-20s\n", node.Id.Get(), node.IpmiIpaddr.Print(), node.IpmiUserName.Print(), node.IpmiPassword.Print()) } } else if ShowLong == true { - fmt.Printf("%-22s %-12s %-26s %-35s %s\n", "NODE NAME", "GROUP NAME", "KERNEL VERSION", "VNFS IMAGE", "OVERLAYS (S/R)") + fmt.Printf("%-22s %-26s %-35s %s\n", "NODE NAME", "KERNEL VERSION", "VNFS IMAGE", "OVERLAYS (S/R)") fmt.Println(strings.Repeat("=", 120)) for _, node := range nodes { - fmt.Printf("%-22s %-12s %-26s %-35s %s\n", node.Fqdn.Get(), node.Gid.String(), node.KernelVersion.String(), node.Vnfs.String(), node.SystemOverlay.String()+"/"+node.RuntimeOverlay.String()) + fmt.Printf("%-22s %-26s %-35s %s\n", node.Id.Get(), node.KernelVersion.Print(), node.Vnfs.Print(), node.SystemOverlay.Print()+"/"+node.RuntimeOverlay.Print()) } } else { - fmt.Printf("%-22s %-30s %s\n", "NODE NAME", "VNFS", "PROFILES") - fmt.Println(strings.Repeat("=", 80)) + fmt.Printf("%-22s %-26s %s\n", "NODE NAME", "PROFILES", "NETWORK") for _, node := range nodes { - fmt.Printf("%-22s %-30s %s\n", node.Fqdn.Get(), node.Vnfs.String(), strings.Join(append(node.GroupProfiles, node.Profiles...), ",")) + var netdevs []string + if len(node.NetDevs) > 0 { + for name, dev := range node.NetDevs { + netdevs = append(netdevs, fmt.Sprintf("%s:%s", name, dev.Ipaddr.Get())) + } + } + sort.Strings(netdevs) + + fmt.Printf("%-22s %-26s %s\n", node.Id.Get(), strings.Join(node.Profiles, ","), strings.Join(netdevs, ", ")) } } diff --git a/internal/app/wwctl/node/poweroff/power.go b/internal/app/wwctl/node/poweroff/power.go index 9b17a2e6..42a13c91 100644 --- a/internal/app/wwctl/node/poweroff/power.go +++ b/internal/app/wwctl/node/poweroff/power.go @@ -34,13 +34,13 @@ func CobraRunE(cmd *cobra.Command, args []string) error { for _, node := range nodeList { - if node.IpmiIpaddr.String() == "" { - wwlog.Printf(wwlog.ERROR, "%s: No IPMI IP address\n", node.HostName) + if node.IpmiIpaddr.Get() == "" { + wwlog.Printf(wwlog.ERROR, "%s: No IPMI IP address\n", node.Id.Get()) continue } ipmiCmd := power.IPMI{ - HostName: node.IpmiIpaddr.String(), + HostName: node.IpmiIpaddr.Get(), User: "ADMIN", Password: "ADMIN", AuthType: "MD5", @@ -49,12 +49,12 @@ func CobraRunE(cmd *cobra.Command, args []string) error { out, err := ipmiCmd.PowerOff() if err != nil { - wwlog.Printf(wwlog.ERROR, "%s: %s\n", node.HostName, out) + wwlog.Printf(wwlog.ERROR, "%s: %s\n", node.Id.Get(), out) returnErr = err continue } - wwlog.Printf(wwlog.INFO, "%s: %s\n", node.HostName, out) + wwlog.Printf(wwlog.INFO, "%s: %s\n", node.Id.Get(), out) } return returnErr diff --git a/internal/app/wwctl/node/poweron/power.go b/internal/app/wwctl/node/poweron/power.go index b7590712..8232ecc4 100644 --- a/internal/app/wwctl/node/poweron/power.go +++ b/internal/app/wwctl/node/poweron/power.go @@ -36,13 +36,13 @@ func CobraRunE(cmd *cobra.Command, args []string) error { var powerCmd power.PowerOnInterface - if node.IpmiIpaddr.String() == "" { - wwlog.Printf(wwlog.ERROR, "%s: No IPMI IP address\n", node.HostName) + if node.IpmiIpaddr.Get() == "" { + wwlog.Printf(wwlog.ERROR, "%s: No IPMI IP address\n", node.Id.Get()) continue } ipmiCmd := power.IPMI{ - HostName: node.IpmiIpaddr.String(), + HostName: node.IpmiIpaddr.Get(), User: "ADMIN", Password: "ADMIN", AuthType: "MD5", @@ -53,12 +53,12 @@ func CobraRunE(cmd *cobra.Command, args []string) error { out, err := powerCmd.PowerOn() if err != nil { - wwlog.Printf(wwlog.ERROR, "%s: %s\n", node.HostName, out) + wwlog.Printf(wwlog.ERROR, "%s: %s\n", node.Id.Get(), out) returnErr = err continue } - wwlog.Printf(wwlog.INFO, "%s: %s\n", node.HostName, out) + wwlog.Printf(wwlog.INFO, "%s: %s\n", node.Id.Get(), out) } return returnErr diff --git a/internal/app/wwctl/node/powerstatus/power.go b/internal/app/wwctl/node/powerstatus/power.go index 960550f4..69b063ac 100644 --- a/internal/app/wwctl/node/powerstatus/power.go +++ b/internal/app/wwctl/node/powerstatus/power.go @@ -34,13 +34,13 @@ func CobraRunE(cmd *cobra.Command, args []string) error { for _, node := range nodeList { - if node.IpmiIpaddr.String() == "" { - wwlog.Printf(wwlog.ERROR, "%s: No IPMI IP address\n", node.HostName) + if node.IpmiIpaddr.Get() == "" { + wwlog.Printf(wwlog.ERROR, "%s: No IPMI IP address\n", node.Id.Get()) continue } ipmiCmd := power.IPMI{ - HostName: node.IpmiIpaddr.String(), + HostName: node.IpmiIpaddr.Get(), User: "ADMIN", Password: "ADMIN", AuthType: "MD5", @@ -49,12 +49,12 @@ func CobraRunE(cmd *cobra.Command, args []string) error { out, err := ipmiCmd.PowerStatus() if err != nil { - wwlog.Printf(wwlog.ERROR, "%s: %s\n", node.HostName, out) + wwlog.Printf(wwlog.ERROR, "%s: %s\n", node.Id.Get(), out) returnErr = err continue } - wwlog.Printf(wwlog.INFO, "%s: %s\n", node.HostName, out) + wwlog.Printf(wwlog.INFO, "%s: %s\n", node.Id.Get(), out) } return returnErr diff --git a/internal/app/wwctl/node/set/main.go b/internal/app/wwctl/node/set/main.go index 9d45ca21..e9c3a79c 100644 --- a/internal/app/wwctl/node/set/main.go +++ b/internal/app/wwctl/node/set/main.go @@ -44,10 +44,20 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } for _, n := range nodes { - wwlog.Printf(wwlog.VERBOSE, "Evaluating node: %s\n", n.Fqdn.String()) + wwlog.Printf(wwlog.VERBOSE, "Evaluating node: %s\n", n.Id.Get()) + if SetComment != "" { + wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting comment to: %s\n", n.Id.Get(), SetComment) + + n.Comment.Set(SetComment) + err := nodeDB.NodeUpdate(n) + if err != nil { + wwlog.Printf(wwlog.ERROR, "%s\n", err) + os.Exit(1) + } + } if SetVnfs != "" { - wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting vnfs to: %s\n", n.Fqdn.String(), SetVnfs) + wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting vnfs to: %s\n", n.Id.Get(), SetVnfs) n.Vnfs.Set(SetVnfs) err := nodeDB.NodeUpdate(n) @@ -57,7 +67,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } } if SetKernel != "" { - wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting kernel to: %s\n", n.Fqdn.String(), SetKernel) + wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting kernel to: %s\n", n.Id.Get(), SetKernel) n.KernelVersion.Set(SetKernel) err := nodeDB.NodeUpdate(n) @@ -67,7 +77,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } } if SetDomainName != "" { - wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting domain name to: %s\n", n.Fqdn, SetDomainName) + wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting domain name to: %s\n", n.Id.Get(), SetDomainName) n.DomainName.Set(SetDomainName) err := nodeDB.NodeUpdate(n) @@ -77,7 +87,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } } if SetIpxe != "" { - wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting iPXE template to: %s\n", n.Fqdn, SetIpxe) + wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting iPXE template to: %s\n", n.Id.Get(), SetIpxe) n.Ipxe.Set(SetIpxe) err := nodeDB.NodeUpdate(n) @@ -87,7 +97,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } } if SetRuntimeOverlay != "" { - wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting runtime overlay to: %s\n", n.Fqdn, SetRuntimeOverlay) + wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting runtime overlay to: %s\n", n.Id.Get(), SetRuntimeOverlay) n.RuntimeOverlay.Set(SetRuntimeOverlay) err := nodeDB.NodeUpdate(n) @@ -97,7 +107,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } } if SetSystemOverlay != "" { - wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting system overlay to: %s\n", n.Fqdn, SetSystemOverlay) + wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting system overlay to: %s\n", n.Id.Get(), SetSystemOverlay) n.SystemOverlay.Set(SetSystemOverlay) err := nodeDB.NodeUpdate(n) @@ -106,18 +116,8 @@ func CobraRunE(cmd *cobra.Command, args []string) error { os.Exit(1) } } - if SetHostname != "" { - wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting hostname to: %s\n", n.Fqdn, SetHostname) - - n.HostName.Set(SetHostname) - err := nodeDB.NodeUpdate(n) - if err != nil { - wwlog.Printf(wwlog.ERROR, "%s\n", err) - os.Exit(1) - } - } if SetIpmiIpaddr != "" { - wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting IPMI IP address to: %s\n", n.Fqdn, SetIpmiIpaddr) + wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting IPMI IP address to: %s\n", n.Id.Get(), SetIpmiIpaddr) n.IpmiIpaddr.Set(SetIpmiIpaddr) err := nodeDB.NodeUpdate(n) @@ -127,7 +127,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } } if SetIpmiNetmask != "" { - wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting IPMI netmask to: %s\n", n.Fqdn, SetIpmiNetmask) + wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting IPMI netmask to: %s\n", n.Id.Get(), SetIpmiNetmask) n.IpmiNetmask.Set(SetIpmiNetmask) err := nodeDB.NodeUpdate(n) @@ -137,7 +137,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } } if SetIpmiUsername != "" { - wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting IPMI IP username to: %s\n", n.Fqdn, SetIpmiUsername) + wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting IPMI IP username to: %s\n", n.Id.Get(), SetIpmiUsername) n.IpmiUserName.Set(SetIpmiUsername) err := nodeDB.NodeUpdate(n) @@ -147,7 +147,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } } if SetIpmiPassword != "" { - wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting IPMI IP password to: %s\n", n.Fqdn, SetIpmiPassword) + wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting IPMI IP password to: %s\n", n.Id.Get(), SetIpmiPassword) n.IpmiPassword.Set(SetIpmiPassword) err := nodeDB.NodeUpdate(n) @@ -159,7 +159,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error { if len(SetAddProfile) > 0 { for _, p := range SetAddProfile { - wwlog.Printf(wwlog.VERBOSE, "Node: %s, adding profile to '%s'\n", n.Fqdn, p) + wwlog.Printf(wwlog.VERBOSE, "Node: %s, adding profile to '%s'\n", n.Id.Get(), p) n.Profiles = util.SliceAddUniqueElement(n.Profiles, p) } err := nodeDB.NodeUpdate(n) @@ -170,7 +170,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } if len(SetDelProfile) > 0 { for _, p := range SetDelProfile { - wwlog.Printf(wwlog.VERBOSE, "Node: %s, deleting profile from '%s'\n", n.Fqdn, p) + wwlog.Printf(wwlog.VERBOSE, "Node: %s, deleting profile from '%s'\n", n.Id.Get(), p) n.Profiles = util.SliceRemoveElement(n.Profiles, p) } err := nodeDB.NodeUpdate(n) @@ -185,13 +185,14 @@ func CobraRunE(cmd *cobra.Command, args []string) error { wwlog.Printf(wwlog.ERROR, "You must include the '--netdev' option\n") os.Exit(1) } - wwlog.Printf(wwlog.VERBOSE, "Node: %s, Deleting network device: %s\n", n.Fqdn, SetNetDev) if _, ok := n.NetDevs[SetNetDev]; !ok { wwlog.Printf(wwlog.ERROR, "Network Device doesn't exist: %s\n", SetNetDev) os.Exit(1) } + wwlog.Printf(wwlog.VERBOSE, "Node: %s, Deleting network device: %s\n", n.Id.Get(), SetNetDev) + delete(n.NetDevs, SetNetDev) err := nodeDB.NodeUpdate(n) if err != nil { @@ -206,12 +207,13 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } if _, ok := n.NetDevs[SetNetDev]; !ok { - wwlog.Printf(wwlog.ERROR, "Network Device doesn't exist: %s\n", SetNetDev) - os.Exit(1) + var nd node.NetDevEntry + n.NetDevs[SetNetDev] = &nd } - wwlog.Printf(wwlog.VERBOSE, "Node: %s:%s, Setting Ipaddr to: %s\n", n.Fqdn, SetNetDev, SetIpaddr) - n.NetDevs[SetNetDev].Ipaddr = SetIpaddr + wwlog.Printf(wwlog.VERBOSE, "Node: %s:%s, Setting Ipaddr to: %s\n", n.Id.Get(), SetNetDev, SetIpaddr) + + n.NetDevs[SetNetDev].Ipaddr.Set(SetIpaddr) err := nodeDB.NodeUpdate(n) if err != nil { wwlog.Printf(wwlog.ERROR, "%s\n", err) @@ -225,12 +227,13 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } if _, ok := n.NetDevs[SetNetDev]; !ok { - wwlog.Printf(wwlog.ERROR, "Network Device doesn't exist: %s\n", SetNetDev) - os.Exit(1) + var nd node.NetDevEntry + n.NetDevs[SetNetDev] = &nd } - wwlog.Printf(wwlog.VERBOSE, "Node: %s:%s, Setting netmask to: %s\n", n.Fqdn, SetNetDev, SetNetmask) - n.NetDevs[SetNetDev].Netmask = SetNetmask + wwlog.Printf(wwlog.VERBOSE, "Node: %s:%s, Setting netmask to: %s\n", n.Id.Get(), SetNetDev, SetNetmask) + + n.NetDevs[SetNetDev].Netmask.Set(SetNetmask) err := nodeDB.NodeUpdate(n) if err != nil { wwlog.Printf(wwlog.ERROR, "%s\n", err) @@ -244,12 +247,13 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } if _, ok := n.NetDevs[SetNetDev]; !ok { - wwlog.Printf(wwlog.ERROR, "Network Device doesn't exist: %s\n", SetNetDev) - os.Exit(1) + var nd node.NetDevEntry + n.NetDevs[SetNetDev] = &nd } - wwlog.Printf(wwlog.VERBOSE, "Node: %s:%s, Setting gateway to: %s\n", n.Fqdn, SetNetDev, SetGateway) - n.NetDevs[SetNetDev].Gateway = SetGateway + wwlog.Printf(wwlog.VERBOSE, "Node: %s:%s, Setting gateway to: %s\n", n.Id.Get(), SetNetDev, SetGateway) + + n.NetDevs[SetNetDev].Gateway.Set(SetGateway) err := nodeDB.NodeUpdate(n) if err != nil { wwlog.Printf(wwlog.ERROR, "%s\n", err) @@ -263,12 +267,13 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } if _, ok := n.NetDevs[SetNetDev]; !ok { - wwlog.Printf(wwlog.ERROR, "Network Device doesn't exist: %s\n", SetNetDev) - os.Exit(1) + var nd node.NetDevEntry + n.NetDevs[SetNetDev] = &nd } - wwlog.Printf(wwlog.VERBOSE, "Node: %s:%s, Setting HW address to: %s\n", n.Fqdn, SetNetDev, SetHwaddr) - n.NetDevs[SetNetDev].Hwaddr = SetHwaddr + wwlog.Printf(wwlog.VERBOSE, "Node: %s:%s, Setting HW address to: %s\n", n.Id.Get(), SetNetDev, SetHwaddr) + + n.NetDevs[SetNetDev].Hwaddr.Set(SetHwaddr) err := nodeDB.NodeUpdate(n) if err != nil { wwlog.Printf(wwlog.ERROR, "%s\n", err) diff --git a/internal/app/wwctl/node/set/root.go b/internal/app/wwctl/node/set/root.go index 0f97c81b..900ce28f 100644 --- a/internal/app/wwctl/node/set/root.go +++ b/internal/app/wwctl/node/set/root.go @@ -9,6 +9,7 @@ var ( Long: "Set node configurations ", RunE: CobraRunE, } + SetComment string SetVnfs string SetKernel string SetNetDev string @@ -21,7 +22,6 @@ var ( SetIpxe string SetRuntimeOverlay string SetSystemOverlay string - SetHostname string SetIpmiIpaddr string SetIpmiNetmask string SetIpmiUsername string @@ -33,13 +33,13 @@ var ( ) func init() { + baseCmd.PersistentFlags().StringVarP(&SetComment, "comment", "C", "", "Set a comment for this node") baseCmd.PersistentFlags().StringVarP(&SetVnfs, "vnfs", "V", "", "Set node Virtual Node File System (VNFS)") baseCmd.PersistentFlags().StringVarP(&SetKernel, "kernel", "K", "", "Set Kernel version for nodes") baseCmd.PersistentFlags().StringVarP(&SetDomainName, "domain", "D", "", "Set the node's domain name") baseCmd.PersistentFlags().StringVarP(&SetIpxe, "ipxe", "P", "", "Set the node's iPXE template name") baseCmd.PersistentFlags().StringVarP(&SetRuntimeOverlay, "runtime", "R", "", "Set the node's runtime overlay") baseCmd.PersistentFlags().StringVarP(&SetSystemOverlay, "system", "S", "", "Set the node's system overlay") - baseCmd.PersistentFlags().StringVarP(&SetHostname, "hostname", "N", "", "Set the node's hostname") baseCmd.PersistentFlags().StringVar(&SetIpmiIpaddr, "ipmi", "", "Set the node's IPMI IP address") baseCmd.PersistentFlags().StringVar(&SetIpmiNetmask, "ipminetmask", "", "Set the node's IPMI netmask") baseCmd.PersistentFlags().StringVar(&SetIpmiUsername, "ipmiuser", "", "Set the node's IPMI username") @@ -53,7 +53,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(&SetNetDevDel, "delete", false, "Delete the node's network device") + baseCmd.PersistentFlags().BoolVar(&SetNetDevDel, "netdel", false, "Delete the node's network device") baseCmd.PersistentFlags().BoolVarP(&SetNodeAll, "all", "a", false, "Set all nodes") baseCmd.PersistentFlags().BoolVarP(&SetYes, "yes", "y", false, "Set 'yes' to all questions asked") diff --git a/internal/app/wwctl/overlay/build/main.go b/internal/app/wwctl/overlay/build/main.go index bf8a3b4f..761a2f77 100644 --- a/internal/app/wwctl/overlay/build/main.go +++ b/internal/app/wwctl/overlay/build/main.go @@ -25,9 +25,9 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } for _, node := range nodes { - if SystemOverlay == true && node.SystemOverlay.String() == args[0] { + if SystemOverlay == true && node.SystemOverlay.Get() == args[0] { updateNodes = append(updateNodes, node) - } else if node.RuntimeOverlay.String() == args[0] { + } else if node.RuntimeOverlay.Get() == args[0] { updateNodes = append(updateNodes, node) } } @@ -59,4 +59,4 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } return nil -} \ No newline at end of file +} diff --git a/internal/app/wwctl/overlay/chmod/main.go b/internal/app/wwctl/overlay/chmod/main.go index a13b480b..0621a10c 100644 --- a/internal/app/wwctl/overlay/chmod/main.go +++ b/internal/app/wwctl/overlay/chmod/main.go @@ -13,7 +13,6 @@ import ( ) func CobraRunE(cmd *cobra.Command, args []string) error { - config := config.New() var overlaySourceDir string overlayName := args[0] fileName := args[2] @@ -64,9 +63,9 @@ func CobraRunE(cmd *cobra.Command, args []string) error { var updateNodes []node.NodeInfo for _, node := range nodes { - if SystemOverlay == true && node.SystemOverlay.String() == overlayName { + if SystemOverlay == true && node.SystemOverlay.Get() == overlayName { updateNodes = append(updateNodes, node) - } else if node.RuntimeOverlay.String() == overlayName { + } else if node.RuntimeOverlay.Get() == overlayName { updateNodes = append(updateNodes, node) } } @@ -81,4 +80,4 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } return nil -} \ No newline at end of file +} diff --git a/internal/app/wwctl/overlay/create/main.go b/internal/app/wwctl/overlay/create/main.go index c4a62062..dab21898 100644 --- a/internal/app/wwctl/overlay/create/main.go +++ b/internal/app/wwctl/overlay/create/main.go @@ -8,8 +8,6 @@ import ( "os" ) - - func CobraRunE(cmd *cobra.Command, args []string) error { if len(args) < 1 { cmd.Help() @@ -48,9 +46,9 @@ func CobraRunE(cmd *cobra.Command, args []string) error { var updateNodes []node.NodeInfo for _, node := range nodes { - if SystemOverlay == true && node.SystemOverlay.String() == args[0] { + if SystemOverlay == true && node.SystemOverlay.Get() == args[0] { updateNodes = append(updateNodes, node) - } else if node.RuntimeOverlay.String() == args[0] { + } else if node.RuntimeOverlay.Get() == args[0] { updateNodes = append(updateNodes, node) } } @@ -64,6 +62,5 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } } - return nil -} \ No newline at end of file +} diff --git a/internal/app/wwctl/overlay/delete/main.go b/internal/app/wwctl/overlay/delete/main.go index a8199efb..606f910a 100644 --- a/internal/app/wwctl/overlay/delete/main.go +++ b/internal/app/wwctl/overlay/delete/main.go @@ -14,7 +14,6 @@ import ( func CobraRunE(cmd *cobra.Command, args []string) error { var overlayPath string - config := config.New() if SystemOverlay == true { overlayPath = config.SystemOverlaySource(args[0]) @@ -110,9 +109,9 @@ func CobraRunE(cmd *cobra.Command, args []string) error { var updateNodes []node.NodeInfo for _, node := range nodes { - if SystemOverlay == true && node.SystemOverlay.String() == args[0] { + if SystemOverlay == true && node.SystemOverlay.Get() == args[0] { updateNodes = append(updateNodes, node) - } else if node.RuntimeOverlay.String() == args[0] { + } else if node.RuntimeOverlay.Get() == args[0] { updateNodes = append(updateNodes, node) } } @@ -127,4 +126,4 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } return nil -} \ No newline at end of file +} diff --git a/internal/app/wwctl/overlay/edit/main.go b/internal/app/wwctl/overlay/edit/main.go index 89e08d27..7f308a83 100644 --- a/internal/app/wwctl/overlay/edit/main.go +++ b/internal/app/wwctl/overlay/edit/main.go @@ -14,8 +14,7 @@ import ( ) func CobraRunE(cmd *cobra.Command, args []string) error { - config := config.New() - editor := config.Editor + editor := os.Getenv("EDITOR") var overlaySourceDir string if SystemOverlay == true { @@ -107,9 +106,9 @@ func CobraRunE(cmd *cobra.Command, args []string) error { var updateNodes []node.NodeInfo for _, node := range nodes { - if SystemOverlay == true && node.SystemOverlay.String() == args[0] { + if SystemOverlay == true && node.SystemOverlay.Get() == args[0] { updateNodes = append(updateNodes, node) - } else if node.RuntimeOverlay.String() == args[0] { + } else if node.RuntimeOverlay.Get() == args[0] { updateNodes = append(updateNodes, node) } } diff --git a/internal/app/wwctl/overlay/imprt/main.go b/internal/app/wwctl/overlay/imprt/main.go index 9b1228ee..08d67af4 100644 --- a/internal/app/wwctl/overlay/imprt/main.go +++ b/internal/app/wwctl/overlay/imprt/main.go @@ -12,7 +12,6 @@ import ( ) func CobraRunE(cmd *cobra.Command, args []string) error { - config := config.New() overlayName := args[0] source := args[1] var dest string @@ -60,9 +59,9 @@ func CobraRunE(cmd *cobra.Command, args []string) error { var updateNodes []node.NodeInfo for _, node := range nodes { - if SystemOverlay == true && node.SystemOverlay.String() == overlayName { + if SystemOverlay == true && node.SystemOverlay.Get() == overlayName { updateNodes = append(updateNodes, node) - } else if node.RuntimeOverlay.String() == overlayName { + } else if node.RuntimeOverlay.Get() == overlayName { updateNodes = append(updateNodes, node) } } @@ -78,4 +77,4 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } return nil -} \ No newline at end of file +} diff --git a/internal/app/wwctl/overlay/list/main.go b/internal/app/wwctl/overlay/list/main.go index c5a7bfdc..918df167 100644 --- a/internal/app/wwctl/overlay/list/main.go +++ b/internal/app/wwctl/overlay/list/main.go @@ -13,7 +13,6 @@ import ( ) func CobraRunE(cmd *cobra.Command, args []string) error { - config := config.New() set := make(map[string]int) var o []string var err error @@ -54,11 +53,11 @@ func CobraRunE(cmd *cobra.Command, args []string) error { for _, node := range nodeList { if SystemOverlay == true { if node.SystemOverlay.Get() != "" { - set[node.SystemOverlay.Get()] ++ + set[node.SystemOverlay.Get()]++ } } else { if node.RuntimeOverlay.Get() != "" { - set[node.RuntimeOverlay.Get()] ++ + set[node.RuntimeOverlay.Get()]++ } } } diff --git a/internal/app/wwctl/overlay/mkdir/main.go b/internal/app/wwctl/overlay/mkdir/main.go index 3cb77f6d..fee39fd4 100644 --- a/internal/app/wwctl/overlay/mkdir/main.go +++ b/internal/app/wwctl/overlay/mkdir/main.go @@ -13,10 +13,8 @@ import ( ) func CobraRunE(cmd *cobra.Command, args []string) error { - config := config.New() var overlaySourceDir string -// mode := uint32(strconv.ParseUint(PermMode, 8, 32)) - + // mode := uint32(strconv.ParseUint(PermMode, 8, 32)) if SystemOverlay == true { overlaySourceDir = config.SystemOverlaySource(args[0]) @@ -57,9 +55,9 @@ func CobraRunE(cmd *cobra.Command, args []string) error { var updateNodes []node.NodeInfo for _, node := range nodes { - if SystemOverlay == true && node.SystemOverlay.String() == args[0] { + if SystemOverlay == true && node.SystemOverlay.Get() == args[0] { updateNodes = append(updateNodes, node) - } else if node.RuntimeOverlay.String() == args[0] { + } else if node.RuntimeOverlay.Get() == args[0] { updateNodes = append(updateNodes, node) } } @@ -74,4 +72,4 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } return nil -} \ No newline at end of file +} diff --git a/internal/app/wwctl/overlay/show/main.go b/internal/app/wwctl/overlay/show/main.go index d75485e1..5d08b3bd 100644 --- a/internal/app/wwctl/overlay/show/main.go +++ b/internal/app/wwctl/overlay/show/main.go @@ -12,7 +12,6 @@ import ( ) func CobraRunE(cmd *cobra.Command, args []string) error { - config := config.New() var overlaySourceDir string overlayName := args[0] fileName := args[1] @@ -44,4 +43,4 @@ func CobraRunE(cmd *cobra.Command, args []string) error { fmt.Print(string(f)) return nil -} \ No newline at end of file +} diff --git a/internal/app/wwctl/profile/add/main.go b/internal/app/wwctl/profile/add/main.go index b5c61387..f21e6e69 100644 --- a/internal/app/wwctl/profile/add/main.go +++ b/internal/app/wwctl/profile/add/main.go @@ -15,7 +15,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } for _, p := range args { - err = nodeDB.AddProfile(p) + _, err := nodeDB.AddProfile(p) if err != nil { wwlog.Printf(wwlog.ERROR, "%s\n", err) os.Exit(1) @@ -25,4 +25,4 @@ func CobraRunE(cmd *cobra.Command, args []string) error { nodeDB.Persist() return nil -} \ No newline at end of file +} diff --git a/internal/app/wwctl/profile/delete/main.go b/internal/app/wwctl/profile/delete/main.go index ffab3be5..6909d34b 100644 --- a/internal/app/wwctl/profile/delete/main.go +++ b/internal/app/wwctl/profile/delete/main.go @@ -15,7 +15,6 @@ func CobraRunE(cmd *cobra.Command, args []string) error { var numNodes int var numGroups int - nodeDB, err := node.New() if err != nil { wwlog.Printf(wwlog.ERROR, "Failed to open node database: %s\n", err) @@ -27,12 +26,6 @@ func CobraRunE(cmd *cobra.Command, args []string) error { wwlog.Printf(wwlog.ERROR, "Could not load all nodes: %s\n", err) os.Exit(1) } - groups, err := nodeDB.FindAllGroups() - if err != nil { - wwlog.Printf(wwlog.ERROR, "Could not load all groups: %s\n", err) - os.Exit(1) - } - for _, p := range args { err := nodeDB.DelProfile(p) @@ -44,22 +37,12 @@ func CobraRunE(cmd *cobra.Command, args []string) error { for _, np := range n.Profiles { if np == p { numNodes++ - wwlog.Printf(wwlog.VERBOSE, "Removing profile from node %s: %s\n", n.Fqdn.Get(), p) + wwlog.Printf(wwlog.VERBOSE, "Removing profile from node %s: %s\n", n.Id.Get(), p) n.Profiles = util.SliceRemoveElement(n.Profiles, p) nodeDB.NodeUpdate(n) } } } - for _, g := range groups { - for _, np := range g.Profiles { - if np == p { - numGroups++ - wwlog.Printf(wwlog.VERBOSE, "Removing profile from group %s: %s\n", g.Id, p) - g.Profiles = util.SliceRemoveElement(g.Profiles, p) - nodeDB.GroupUpdate(g) - } - } - } count++ } diff --git a/internal/app/wwctl/profile/list/main.go b/internal/app/wwctl/profile/list/main.go index 93a78486..ab0416b2 100644 --- a/internal/app/wwctl/profile/list/main.go +++ b/internal/app/wwctl/profile/list/main.go @@ -6,7 +6,7 @@ import ( "github.com/hpcng/warewulf/internal/pkg/wwlog" "github.com/spf13/cobra" "os" - "reflect" + "sort" ) func CobraRunE(cmd *cobra.Command, args []string) error { @@ -23,14 +23,37 @@ func CobraRunE(cmd *cobra.Command, args []string) error { os.Exit(1) } - for _, group := range profiles { - v := reflect.ValueOf(group) - typeOfS := v.Type() + sort.Slice(profiles, func(i, j int) bool { + if profiles[i].Id.Get() < profiles[j].Id.Get() { + return true + } + return false + }) + + for _, node := range profiles { fmt.Printf("################################################################################\n") - for i := 0; i< v.NumField(); i++ { - fmt.Printf("%-25s %s = %v\n", group.Id, typeOfS.Field(i).Name, v.Field(i).Interface()) + fmt.Printf("%-20s %-18s: %s\n", node.Id.Get(), "Id", node.Id.Print()) + fmt.Printf("%-20s %-18s: %s\n", node.Id.Get(), "Comment", node.Comment.Print()) + + fmt.Printf("%-20s %-18s: %s\n", node.Id.Get(), "Vnfs", node.Vnfs.Print()) + fmt.Printf("%-20s %-18s: %s\n", node.Id.Get(), "KernelVersion", node.KernelVersion.Print()) + fmt.Printf("%-20s %-18s: %s\n", node.Id.Get(), "KernelArgs", node.KernelArgs.Print()) + fmt.Printf("%-20s %-18s: %s\n", node.Id.Get(), "RuntimeOverlay", node.RuntimeOverlay.Print()) + fmt.Printf("%-20s %-18s: %s\n", node.Id.Get(), "SystemOverlay", node.SystemOverlay.Print()) + fmt.Printf("%-20s %-18s: %s\n", node.Id.Get(), "Ipxe", node.Ipxe.Print()) + fmt.Printf("%-20s %-18s: %s\n", node.Id.Get(), "IpmiIpaddr", node.IpmiIpaddr.Print()) + fmt.Printf("%-20s %-18s: %s\n", node.Id.Get(), "IpmiNetmask", node.IpmiNetmask.Print()) + fmt.Printf("%-20s %-18s: %s\n", node.Id.Get(), "IpmiUserName", node.IpmiUserName.Print()) + + for name, netdev := range node.NetDevs { + fmt.Printf("%-20s %-18s: %s\n", node.Id.Get(), name+":IPADDR", netdev.Ipaddr.Print()) + fmt.Printf("%-20s %-18s: %s\n", node.Id.Get(), name+":NETMASK", netdev.Netmask.Print()) + fmt.Printf("%-20s %-18s: %s\n", node.Id.Get(), name+":GATEWAY", netdev.Gateway.Print()) + fmt.Printf("%-20s %-18s: %s\n", node.Id.Get(), name+":HWADDR", netdev.Hwaddr.Print()) + fmt.Printf("%-20s %-18s: %s\n", node.Id.Get(), name+":TYPE", netdev.Hwaddr.Print()) + } } return nil -} \ No newline at end of file +} diff --git a/internal/app/wwctl/profile/set/main.go b/internal/app/wwctl/profile/set/main.go index f1c1cbd9..53daaf02 100644 --- a/internal/app/wwctl/profile/set/main.go +++ b/internal/app/wwctl/profile/set/main.go @@ -11,7 +11,7 @@ import ( func CobraRunE(cmd *cobra.Command, args []string) error { var err error - var profiles []node.ProfileInfo + var profiles []node.NodeInfo nodeDB, err := node.New() if err != nil { @@ -19,25 +19,18 @@ func CobraRunE(cmd *cobra.Command, args []string) error { os.Exit(1) } - if err != nil { - wwlog.Printf(wwlog.ERROR, "Cloud not get nodeList: %s\n", err) - os.Exit(1) + if len(args) == 0 { + args = append(args, "default") } if SetAll == true { - var tmp []node.ProfileInfo - tmp, err = nodeDB.FindAllProfiles() + profiles, err = nodeDB.FindAllProfiles() if err != nil { wwlog.Printf(wwlog.ERROR, "%s\n", err) os.Exit(1) } - - for _, p := range tmp { - profiles = append(profiles, p) - } - - } else if len(args) > 0 { - var tmp []node.ProfileInfo + } else { + var tmp []node.NodeInfo tmp, err = nodeDB.FindAllProfiles() if err != nil { wwlog.Printf(wwlog.ERROR, "%s\n", err) @@ -46,23 +39,30 @@ func CobraRunE(cmd *cobra.Command, args []string) error { for _, a := range args { for _, p := range tmp { - if p.Id == a { + if p.Id.Get() == a { profiles = append(profiles, p) } } } - - } else { - cmd.Usage() - os.Exit(1) } for _, p := range profiles { + wwlog.Printf(wwlog.VERBOSE, "Modifying profile: %s\n", p.Id.Get()) + if SetComment != "" { + wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting comment to: %s\n", p.Id, SetComment) + + p.Comment.Set(SetComment) + err := nodeDB.ProfileUpdate(p) + if err != nil { + wwlog.Printf(wwlog.ERROR, "%s\n", err) + os.Exit(1) + } + } if SetDomainName != "" { wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting domain name to: %s\n", p.Id, SetDomainName) - p.DomainName = SetDomainName + p.DomainName.Set(SetDomainName) err := nodeDB.ProfileUpdate(p) if err != nil { wwlog.Printf(wwlog.ERROR, "%s\n", err) @@ -72,7 +72,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error { if SetVnfs != "" { wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting VNFS to: %s\n", p.Id, SetVnfs) - p.Vnfs = SetVnfs + p.Vnfs.Set(SetVnfs) err := nodeDB.ProfileUpdate(p) if err != nil { wwlog.Printf(wwlog.ERROR, "%s\n", err) @@ -82,7 +82,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error { if SetKernel != "" { wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting Kernel version to: %s\n", p.Id, SetKernel) - p.KernelVersion = SetKernel + p.KernelVersion.Set(SetKernel) err := nodeDB.ProfileUpdate(p) if err != nil { wwlog.Printf(wwlog.ERROR, "%s\n", err) @@ -92,7 +92,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error { if SetIpxe != "" { wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting iPXE template to: %s\n", p.Id, SetIpxe) - p.Ipxe = SetIpxe + p.Ipxe.Set(SetIpxe) err := nodeDB.ProfileUpdate(p) if err != nil { wwlog.Printf(wwlog.ERROR, "%s\n", err) @@ -102,7 +102,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error { if SetRuntimeOverlay != "" { wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting runtime overlay to: %s\n", p.Id, SetRuntimeOverlay) - p.RuntimeOverlay = SetRuntimeOverlay + p.RuntimeOverlay.Set(SetRuntimeOverlay) err := nodeDB.ProfileUpdate(p) if err != nil { wwlog.Printf(wwlog.ERROR, "%s\n", err) @@ -112,7 +112,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error { if SetSystemOverlay != "" { wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting system overlay to: %s\n", p.Id, SetSystemOverlay) - p.SystemOverlay = SetSystemOverlay + p.SystemOverlay.Set(SetSystemOverlay) err := nodeDB.ProfileUpdate(p) if err != nil { wwlog.Printf(wwlog.ERROR, "%s\n", err) @@ -122,7 +122,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error { if SetIpmiNetmask != "" { wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting IPMI username to: %s\n", p.Id, SetIpmiNetmask) - p.IpmiNetmask = SetIpmiNetmask + p.IpmiNetmask.Set(SetIpmiNetmask) err := nodeDB.ProfileUpdate(p) if err != nil { wwlog.Printf(wwlog.ERROR, "%s\n", err) @@ -132,7 +132,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error { if SetIpmiUsername != "" { wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting IPMI username to: %s\n", p.Id, SetIpmiUsername) - p.IpmiUserName = SetIpmiUsername + p.IpmiUserName.Set(SetIpmiUsername) err := nodeDB.ProfileUpdate(p) if err != nil { wwlog.Printf(wwlog.ERROR, "%s\n", err) @@ -142,7 +142,108 @@ func CobraRunE(cmd *cobra.Command, args []string) error { if SetIpmiPassword != "" { wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting IPMI username to: %s\n", p.Id, SetIpmiPassword) - p.IpmiPassword = SetIpmiPassword + p.IpmiPassword.Set(SetIpmiPassword) + err := nodeDB.ProfileUpdate(p) + if err != nil { + wwlog.Printf(wwlog.ERROR, "%s\n", err) + os.Exit(1) + } + } + + if SetNetDevDel == true { + if SetNetDev == "" { + wwlog.Printf(wwlog.ERROR, "You must include the '--netdev' option\n") + os.Exit(1) + } + + if _, ok := p.NetDevs[SetNetDev]; !ok { + wwlog.Printf(wwlog.ERROR, "Profile '%s': network Device doesn't exist: %s\n", p.Id.Get(), SetNetDev) + os.Exit(1) + } + + wwlog.Printf(wwlog.VERBOSE, "Profile %s: Deleting network device: %s\n", p.Id.Get(), SetNetDev) + + delete(p.NetDevs, SetNetDev) + err := nodeDB.ProfileUpdate(p) + if err != nil { + wwlog.Printf(wwlog.ERROR, "%s\n", err) + os.Exit(1) + } + } + if SetIpaddr != "" { + if SetNetDev == "" { + wwlog.Printf(wwlog.ERROR, "You must include the '--netdev' option\n") + os.Exit(1) + } + + if _, ok := p.NetDevs[SetNetDev]; !ok { + var nd node.NetDevEntry + p.NetDevs[SetNetDev] = &nd + } + + wwlog.Printf(wwlog.VERBOSE, "Profile '%s': Setting IP address to: %s:%s\n", p.Id.Get(), SetNetDev, SetHwaddr) + + p.NetDevs[SetNetDev].Ipaddr.Set(SetIpaddr) + err := nodeDB.ProfileUpdate(p) + if err != nil { + wwlog.Printf(wwlog.ERROR, "%s\n", err) + os.Exit(1) + } + } + if SetNetmask != "" { + if SetNetDev == "" { + wwlog.Printf(wwlog.ERROR, "You must include the '--netdev' option\n") + os.Exit(1) + } + + if _, ok := p.NetDevs[SetNetDev]; !ok { + var nd node.NetDevEntry + p.NetDevs[SetNetDev] = &nd + } + + wwlog.Printf(wwlog.VERBOSE, "Profile '%s': Setting netmask to: %s:%s\n", p.Id.Get(), SetNetDev, SetHwaddr) + + p.NetDevs[SetNetDev].Netmask.Set(SetNetmask) + err := nodeDB.ProfileUpdate(p) + if err != nil { + wwlog.Printf(wwlog.ERROR, "%s\n", err) + os.Exit(1) + } + } + if SetGateway != "" { + if SetNetDev == "" { + wwlog.Printf(wwlog.ERROR, "You must include the '--netdev' option\n") + os.Exit(1) + } + + if _, ok := p.NetDevs[SetNetDev]; !ok { + var nd node.NetDevEntry + p.NetDevs[SetNetDev] = &nd + } + + wwlog.Printf(wwlog.VERBOSE, "Profile '%s': Setting gateway to: %s:%s\n", p.Id.Get(), SetNetDev, SetHwaddr) + + p.NetDevs[SetNetDev].Gateway.Set(SetGateway) + err := nodeDB.ProfileUpdate(p) + if err != nil { + wwlog.Printf(wwlog.ERROR, "%s\n", err) + os.Exit(1) + } + } + if SetHwaddr != "" { + if SetNetDev == "" { + wwlog.Printf(wwlog.ERROR, "You must include the '--netdev' option\n") + os.Exit(1) + } + + if _, ok := p.NetDevs[SetNetDev]; !ok { + var nd node.NetDevEntry + p.NetDevs[SetNetDev] = &nd + } + + wwlog.Printf(wwlog.VERBOSE, "Profile '%s': Setting HW address to: %s:%s\n", p.Id.Get(), SetNetDev, SetHwaddr) + + p.NetDevs[SetNetDev].Hwaddr.Set(SetHwaddr) err := nodeDB.ProfileUpdate(p) if err != nil { wwlog.Printf(wwlog.ERROR, "%s\n", err) diff --git a/internal/app/wwctl/profile/set/root.go b/internal/app/wwctl/profile/set/root.go index 1a3197f3..a2f38815 100644 --- a/internal/app/wwctl/profile/set/root.go +++ b/internal/app/wwctl/profile/set/root.go @@ -10,6 +10,7 @@ var ( RunE: CobraRunE, } SetAll bool + SetComment string SetVnfs string SetKernel string SetDomainName string @@ -19,9 +20,16 @@ var ( SetIpmiNetmask string SetIpmiUsername string SetIpmiPassword string + SetNetDev string + SetIpaddr string + SetNetmask string + SetGateway string + SetHwaddr string + SetNetDevDel bool ) func init() { + baseCmd.PersistentFlags().StringVarP(&SetComment, "comment", "C", "", "Set a comment for this node") baseCmd.PersistentFlags().StringVarP(&SetVnfs, "vnfs", "V", "", "Set node Virtual Node File System (VNFS)") baseCmd.PersistentFlags().StringVarP(&SetKernel, "kernel", "K", "", "Set Kernel version for nodes") baseCmd.PersistentFlags().StringVarP(&SetDomainName, "domain", "D", "", "Set the node's domain name") @@ -32,6 +40,13 @@ func init() { baseCmd.PersistentFlags().StringVar(&SetIpmiUsername, "ipmiuser", "", "Set the node's IPMI username") baseCmd.PersistentFlags().StringVar(&SetIpmiPassword, "ipmipass", "", "Set the node's IPMI password") + baseCmd.PersistentFlags().StringVarP(&SetNetDev, "netdev", "n", "", "Define the network device to configure") + baseCmd.PersistentFlags().StringVarP(&SetIpaddr, "ipaddr", "I", "", "Set the node's network device IP address") + 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(&SetNetDevDel, "netdel", false, "Delete the node's network device") + baseCmd.PersistentFlags().BoolVarP(&SetAll, "all", "a", false, "Set all profiles") } diff --git a/internal/app/wwctl/ready/main.go b/internal/app/wwctl/ready/main.go new file mode 100644 index 00000000..af7e7ef0 --- /dev/null +++ b/internal/app/wwctl/ready/main.go @@ -0,0 +1,97 @@ +package ready + +import ( + "fmt" + "github.com/hpcng/warewulf/internal/pkg/config" + "github.com/hpcng/warewulf/internal/pkg/node" + "github.com/hpcng/warewulf/internal/pkg/util" + "github.com/hpcng/warewulf/internal/pkg/vnfs" + "github.com/hpcng/warewulf/internal/pkg/wwlog" + "github.com/spf13/cobra" + "os" +) + +func CobraRunE(cmd *cobra.Command, args []string) error { + + n, err := node.New() + if err != nil { + wwlog.Printf(wwlog.ERROR, "Could not open node configuration: %s\n", err) + os.Exit(1) + } + + nodes, err := n.FindAllNodes() + if err != nil { + wwlog.Printf(wwlog.ERROR, "Cloud not get nodeList: %s\n", err) + os.Exit(1) + } + + fmt.Printf("%-25s %-10s %-6s %-6s %-6s %-6s %-6s\n", "NODE NAME", "STATUS", "VNFS", "KERNEL", "KMODS", "SYS-OL", "RUN-OL") + + for _, node := range nodes { + var vnfs_good bool + var kernel_good bool + var kmods_good bool + var systemo_good bool + var runtimeo_good bool + status := true + + if node.Vnfs.Get() != "" { + v, _ := vnfs.Load(node.Vnfs.Get()) + if util.IsFile(v.Image) == true { + vnfs_good = true + } else { + status = false + wwlog.Printf(wwlog.VERBOSE, "VNFS not found: %s, %s\n", node.Id.Get(), v.Source) + } + } else { + status = false + wwlog.Printf(wwlog.VERBOSE, "Node Kernel not defined: %s\n", node.Id.Get()) + } + + if node.KernelVersion.Get() != "" { + if util.IsFile(config.KernelImage(node.KernelVersion.Get())) == true { + kernel_good = true + } else { + status = false + wwlog.Printf(wwlog.VERBOSE, "Node Kernel not found: %s, %s\n", node.Id.Get(), node.KernelVersion.Get()) + } + if util.IsFile(config.KmodsImage(node.KernelVersion.Get())) == true { + kmods_good = true + } else { + status = false + wwlog.Printf(wwlog.VERBOSE, "Node Kmods not found: %s, %s\n", node.Id.Get(), node.KernelVersion.Get()) + } + } else { + status = false + wwlog.Printf(wwlog.VERBOSE, "Node Kernel version not defined: %s\n", node.Id.Get()) + } + + if node.SystemOverlay.Get() != "" { + if util.IsFile(config.SystemOverlayImage(node.Id.Get())) == true { + systemo_good = true + } else { + status = false + wwlog.Printf(wwlog.VERBOSE, "System Overlay not found: %s\n", config.SystemOverlayImage(node.Id.Get())) + } + } else { + status = false + wwlog.Printf(wwlog.VERBOSE, "System Overlay not defined: %s\n", node.Id.Get()) + } + + if node.RuntimeOverlay.Get() != "" { + if util.IsFile(config.RuntimeOverlayImage(node.Id.Get())) == true { + runtimeo_good = true + } else { + status = false + wwlog.Printf(wwlog.VERBOSE, "Runtime Overlay not found: %s\n", config.RuntimeOverlaySource(node.Id.Get())) + } + } else { + status = false + wwlog.Printf(wwlog.VERBOSE, "Runtime Overlay not defined: %s\n", node.Id.Get()) + } + + fmt.Printf("%-25s %-10t %-6t %-6t %-6t %-6t %-6t\n", node.Id.Get(), status, vnfs_good, kernel_good, kmods_good, systemo_good, runtimeo_good) + } + + return nil +} diff --git a/internal/app/wwctl/ready/root.go b/internal/app/wwctl/ready/root.go new file mode 100644 index 00000000..221b6d65 --- /dev/null +++ b/internal/app/wwctl/ready/root.go @@ -0,0 +1,22 @@ +package ready + +import ( + "github.com/spf13/cobra" +) + +var ( + baseCmd = &cobra.Command{ + Use: "ready", + Short: "Warewulf Status Check", + Long: "Warewulf Status Check", + 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/root.go b/internal/app/wwctl/root.go index 014ae234..03efec60 100644 --- a/internal/app/wwctl/root.go +++ b/internal/app/wwctl/root.go @@ -1,12 +1,11 @@ package wwctl import ( - "github.com/hpcng/warewulf/internal/app/wwctl/controller" - "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" "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/vnfs" @@ -32,13 +31,14 @@ func init() { //rootCmd.AddCommand(build.GetCommand()) rootCmd.AddCommand(overlay.GetCommand()) - rootCmd.AddCommand(controller.GetCommand()) + // rootCmd.AddCommand(controller.GetCommand()) rootCmd.AddCommand(vnfs.GetCommand()) rootCmd.AddCommand(node.GetCommand()) rootCmd.AddCommand(kernel.GetCommand()) - rootCmd.AddCommand(group.GetCommand()) + // rootCmd.AddCommand(group.GetCommand()) rootCmd.AddCommand(profile.GetCommand()) rootCmd.AddCommand(service.GetCommand()) + rootCmd.AddCommand(ready.GetCommand()) } diff --git a/internal/app/wwctl/service/dhcp/main.go b/internal/app/wwctl/service/dhcp/main.go index 9507af42..74c6aab4 100644 --- a/internal/app/wwctl/service/dhcp/main.go +++ b/internal/app/wwctl/service/dhcp/main.go @@ -5,6 +5,7 @@ import ( "github.com/brotherpowers/ipsubnet" "github.com/hpcng/warewulf/internal/pkg/node" "github.com/hpcng/warewulf/internal/pkg/util" + "github.com/hpcng/warewulf/internal/pkg/warewulfconf" "github.com/hpcng/warewulf/internal/pkg/wwlog" "github.com/spf13/cobra" "net" @@ -28,125 +29,120 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } func ConfigureDHCP() error { + var d dhcpTemplate + var templateFile string + nodeDB, err := node.New() if err != nil { wwlog.Printf(wwlog.ERROR, "Could not open node configuration: %s\n", err) os.Exit(1) } - controllers, err := nodeDB.FindAllControllers() + controller, err := warewulfconf.New() + if err != nil { + wwlog.Printf(wwlog.ERROR, "%s\n", err) + os.Exit(1) + } + + if controller.Ipaddr == "" { + wwlog.Printf(wwlog.ERROR, "The Warewulf IP Address is not properly configured\n") + os.Exit(1) + } + + if controller.Netmask == "" { + wwlog.Printf(wwlog.ERROR, "The Warewulf Netmask is not properly configured\n") + os.Exit(1) + } + + if controller.Dhcp.Enabled == false { + wwlog.Printf(wwlog.INFO, "This system is not configured as a Warewulf DHCP controller\n") + os.Exit(1) + } + + if controller.Dhcp.RangeStart == "" { + wwlog.Printf(wwlog.ERROR, "Configuration is not defined: `dhcpd range start`\n") + os.Exit(1) + } + + if controller.Dhcp.RangeEnd == "" { + wwlog.Printf(wwlog.ERROR, "Configuration is not defined: `dhcpd range end`\n") + os.Exit(1) + } + + if controller.Dhcp.ConfigFile == "" { + controller.Dhcp.ConfigFile = "/etc/dhcp/dhcpd.conf" + } + + nodes, err := nodeDB.FindAllNodes() if err != nil { wwlog.Printf(wwlog.ERROR, "Could not find all controllers: %s\n", err) os.Exit(1) } - for _, controller := range controllers { - var templateFile string - var d dhcpTemplate - var configured bool + for _, node := range nodes { + d.Nodes = append(d.Nodes, node) + } - addrs, err := net.InterfaceAddrs() - if err != nil { - wwlog.Printf(wwlog.ERROR, "Could not get network interfaces: %s\n", err) - os.Exit(1) - } - - for _, address := range addrs { - if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { - if ipnet.IP.String() == controller.Ipaddr { - m, _ := ipnet.Mask.Size() - sub := ipsubnet.SubnetCalculator(ipnet.IP.String(), m) - - d.Ipaddr = ipnet.IP.String() - d.Network = sub.GetNetworkPortion() - d.Netmask = sub.GetSubnetMask() - d.RangeStart = controller.Services.Dhcp.RangeStart - d.RangeEnd = controller.Services.Dhcp.RangeEnd - configured = true - break - } - } - } - - hostname, err := os.Hostname() - if err != nil { - wwlog.Printf(wwlog.ERROR, "Could not obtain system's hostname\n") - os.Exit(1) - } - if hostname != controller.Fqdn { - wwlog.Printf(wwlog.WARN, "The system hostname does not match Warewulf config: %s != %s\n", hostname, controller.Fqdn) - } - - if configured == false { - wwlog.Printf(wwlog.ERROR, "Could not identify this system in the Warewulf configuration by it's IP address\n") - os.Exit(1) - } - - if controller.Services.Dhcp.ConfigFile == "" { - wwlog.Printf(wwlog.ERROR, "Could not locate the DHCP configuration file for this controller\n") - os.Exit(1) - } - - if _, ok := nodeDB.Controllers[controller.Id]; !ok { - wwlog.Printf(wwlog.ERROR, "We should never get here, but since we did, Hello! %s\n", err) - os.Exit(1) - } - - nodes, err := nodeDB.FindAllNodes() - if err != nil { - wwlog.Printf(wwlog.ERROR, "Could not find all controllers: %s\n", err) - os.Exit(1) - } - - for _, node := range nodes { - d.Nodes = append(d.Nodes, node) - } - - if controller.Services.Dhcp.Template == "" { - templateFile = "/etc/warewulf/dhcp/default-dhcpd.conf" + if controller.Dhcp.Template == "" { + templateFile = "/etc/warewulf/dhcp/default-dhcpd.conf" + } else { + if strings.HasPrefix(controller.Dhcp.Template, "/") { + templateFile = controller.Dhcp.Template } else { - if strings.HasPrefix(controller.Services.Dhcp.Template, "/") { - templateFile = controller.Services.Dhcp.Template - } else { - templateFile = fmt.Sprintf("/etc/warewulf/dhcp/%s-dhcpd.conf", controller.Services.Dhcp.Template) - } + templateFile = fmt.Sprintf("/etc/warewulf/dhcp/%s-dhcpd.conf", controller.Dhcp.Template) } + } - tmpl, err := template.New(path.Base(templateFile)).ParseFiles(templateFile) + tmpl, err := template.New(path.Base(templateFile)).ParseFiles(templateFile) + if err != nil { + wwlog.Printf(wwlog.ERROR, "%s\n", err) + os.Exit(1) + } + + mask := net.IPMask(net.ParseIP(controller.Netmask).To4()) + size, _ := mask.Size() + + sub := ipsubnet.SubnetCalculator(controller.Ipaddr, size) + + d.Ipaddr = controller.Ipaddr + d.Network = sub.GetNetworkPortion() + d.Netmask = sub.GetSubnetMask() + d.RangeStart = controller.Dhcp.RangeStart + d.RangeEnd = controller.Dhcp.RangeEnd + + if DoConfig == true { + fmt.Printf("Writing the DHCP configuration file\n") + configWriter, err := os.OpenFile(controller.Dhcp.ConfigFile, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0640) + if err != nil { + wwlog.Printf(wwlog.ERROR, "%s\n", err) + os.Exit(1) + } + defer configWriter.Close() + err = tmpl.Execute(configWriter, d) if err != nil { wwlog.Printf(wwlog.ERROR, "%s\n", err) os.Exit(1) } - if DoConfig == true { - fmt.Printf("Writing the DHCP configuration file\n") - configWriter, err := os.OpenFile(controller.Services.Dhcp.ConfigFile, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0640) - if err != nil { - wwlog.Printf(wwlog.ERROR, "%s\n", err) - os.Exit(1) - } - defer configWriter.Close() - err = tmpl.Execute(configWriter, d) - if err != nil { - wwlog.Printf(wwlog.ERROR, "%s\n", err) - os.Exit(1) - } - - fmt.Printf("Enabling and restarting the DHCP services\n") - util.ExecInteractive("/bin/sh", "-c", controller.Services.Dhcp.EnableCmd) - util.ExecInteractive("/bin/sh", "-c", controller.Services.Dhcp.RestartCmd) - + fmt.Printf("Enabling and restarting the DHCP services\n") + if controller.Dhcp.Enable != "" { + util.ExecInteractive("/bin/sh", "-c", controller.Dhcp.Enable) } else { - err = tmpl.Execute(os.Stdout, d) - if err != nil { - wwlog.Printf(wwlog.ERROR, "%s\n", err) - os.Exit(1) - } - + util.ExecInteractive("/bin/sh", "-c", "systemctl enable dhcpd") + } + if controller.Dhcp.Restart != "" { + util.ExecInteractive("/bin/sh", "-c", controller.Dhcp.Restart) + } else { + util.ExecInteractive("/bin/sh", "-c", "systemctl restart dhcpd") + } + + } else { + err = tmpl.Execute(os.Stdout, d) + if err != nil { + wwlog.Printf(wwlog.ERROR, "%s\n", err) + os.Exit(1) } - // Just in case we get here, we've now finished the loop - break } return nil diff --git a/internal/app/wwctl/service/root.go b/internal/app/wwctl/service/root.go index d29b2ffe..56599008 100644 --- a/internal/app/wwctl/service/root.go +++ b/internal/app/wwctl/service/root.go @@ -9,7 +9,7 @@ var ( baseCmd = &cobra.Command{ Use: "service", Short: "Initialize Warewulf services", - Long: "Warewulf Initialization", + Long: "Warewulf Service Initialization", } ) diff --git a/internal/app/wwctl/vnfs/build/main.go b/internal/app/wwctl/vnfs/build/main.go index 4b48fc09..5952aba4 100644 --- a/internal/app/wwctl/vnfs/build/main.go +++ b/internal/app/wwctl/vnfs/build/main.go @@ -29,7 +29,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error { for _, node := range nodes { if node.Vnfs.Defined() == true { - set[node.Vnfs.Get()] ++ + set[node.Vnfs.Get()]++ } } @@ -43,12 +43,13 @@ func CobraRunE(cmd *cobra.Command, args []string) error { for _, node := range nodes { if node.Vnfs.Defined() == true { - set[node.Vnfs.Get()] ++ + wwlog.Printf(wwlog.VERBOSE, "Adding VNFS to list: %s (%s)\n", node.Vnfs.Get(), node.Id.Get()) + set[node.Vnfs.Get()]++ } } } else if len(args) == 1 { - set[args[0]] ++ + set[args[0]]++ } else { cmd.Usage() os.Exit(1) @@ -64,4 +65,4 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } return nil -} \ No newline at end of file +} diff --git a/internal/app/wwctl/vnfs/list/main.go b/internal/app/wwctl/vnfs/list/main.go index 85bf6296..212fcbdf 100644 --- a/internal/app/wwctl/vnfs/list/main.go +++ b/internal/app/wwctl/vnfs/list/main.go @@ -14,13 +14,12 @@ import ( ) func CobraRunE(cmd *cobra.Command, args []string) error { - config := config.New() nconfig, _ := node.New() nodes, _ := nconfig.FindAllNodes() nodemap := make(map[string]int) for _, n := range nodes { - nodemap[n.Vnfs.Get()] ++ + nodemap[n.Vnfs.Get()]++ } images, _ := ioutil.ReadDir(config.VnfsImageParentDir()) @@ -32,7 +31,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error { v, err := vnfs.Load(file.Name()) if err == nil { var vnfs_size int64 - if util.IsFile( config.VnfsImage(file.Name())) { + if util.IsFile(config.VnfsImage(file.Name())) { s, _ := os.Stat(config.VnfsImage(file.Name())) vnfs_size = s.Size() / 1024 } @@ -48,7 +47,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error { if util.IsDir(path.Join(config.VnfsImageParentDir(), file.Name())) { var vnfs_size int64 - if util.IsFile( config.VnfsImage(file.Name())) { + if util.IsFile(config.VnfsImage(file.Name())) { s, _ := os.Stat(config.VnfsImage(file.Name())) vnfs_size = s.Size() / 1024 } @@ -61,4 +60,4 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } } return nil -} \ No newline at end of file +} diff --git a/internal/pkg/config/config.go b/internal/pkg/config/config.go index 6743347b..8586e396 100644 --- a/internal/pkg/config/config.go +++ b/internal/pkg/config/config.go @@ -4,99 +4,42 @@ import ( "fmt" "github.com/hpcng/warewulf/internal/pkg/util" "github.com/hpcng/warewulf/internal/pkg/wwlog" - "github.com/kelseyhightower/envconfig" - "gopkg.in/yaml.v2" - "io/ioutil" - "os" "path" ) +const ( + LocalStateDir = "/var/warewulf" +) -type Config struct { - Port int `yaml:"warewulfd port", envconfig:"WAREWULFD_PORT"` - Ipaddr string `yaml:"warewulfd ipaddr", envconfig:"WAREWULFD_IPADDR"` - InsecureRuntime bool `yaml:"insecure runtime"` - Debug bool `yaml:"debug"` - SysConfDir string `yaml:"system config dir"` - LocalStateDir string `yaml:"local state dir"` - Editor string `yaml:"default editor", envconfig:"EDITOR"` +func NodeConfig() string { + return fmt.Sprintf("%s/nodes.conf", LocalStateDir) } -var c Config - -func init() { - fd, err := ioutil.ReadFile("/etc/warewulf/warewulf.conf") - if err != nil { - wwlog.Printf(wwlog.ERROR, "Could not read config file: %s\n", err) - os.Exit(255) - } - - err = yaml.Unmarshal(fd, &c) - if err != nil { - wwlog.Printf(wwlog.ERROR, "Could not unmarshal config file: %s\n", err) - os.Exit(255) - } - - err = envconfig.Process("", &c) - if err != nil { - wwlog.Printf(wwlog.ERROR, "Could not obtain environment configuration: %s\n", err) - os.Exit(255) - } - - if c.Ipaddr == "" { - fmt.Printf("ERROR: 'warewulf ipaddr' has not been set in /etc/warewulf/warewulf.conf\n") - } - - if c.SysConfDir == "" { - c.SysConfDir = "/etc/warewulf" - } - if c.LocalStateDir == "" { - c.LocalStateDir = "/var/warewulf" - } - if c.Editor == "" { - c.Editor = "vi" - } - - util.ValidateOrDie("warewulfd ipaddr", c.Ipaddr, "^[0-9]+.[0-9]+.[0-9]+.[0-9]+$") - util.ValidateOrDie("system config dir", c.SysConfDir, "^[a-zA-Z0-9-._:/]+$") - util.ValidateOrDie("local state dir", c.LocalStateDir, "^[a-zA-Z0-9-._:/]+$") - util.ValidateOrDie("default editor", c.LocalStateDir, "^[a-zA-Z0-9-._:/]+$") - +func OverlayDir() string { + return fmt.Sprintf("%s/overlays/", LocalStateDir) } -func New() (Config) { - return c +func SystemOverlayDir() string { + return path.Join(OverlayDir(), "/system") } -func (self *Config) NodeConfig() string { - return fmt.Sprintf("%s/nodes.conf", self.LocalStateDir) +func RuntimeOverlayDir() string { + return path.Join(OverlayDir(), "/runtime") } -func (self *Config) OverlayDir() string { - return fmt.Sprintf("%s/overlays/", self.LocalStateDir) +func VnfsImageParentDir() string { + return fmt.Sprintf("%s/provision/vnfs/", LocalStateDir) } -func (self *Config) SystemOverlayDir() string { - return path.Join(self.OverlayDir(), "/system") +func VnfsChrootParentDir() string { + return fmt.Sprintf("%s/chroot/", LocalStateDir) } -func (self *Config) RuntimeOverlayDir() string { - return path.Join(self.OverlayDir(), "/runtime") +func KernelParentDir() string { + return fmt.Sprintf("%s/provision/kernel/", LocalStateDir) } -func (self *Config) VnfsImageParentDir() string { - return fmt.Sprintf("%s/provision/vnfs/", self.LocalStateDir) -} - -func (self *Config) VnfsChrootParentDir() string { - return fmt.Sprintf("%s/chroot/", self.LocalStateDir) -} - -func (self *Config) KernelParentDir() string { - return fmt.Sprintf("%s/provision/kernel/", self.LocalStateDir) -} - -func (self *Config) SystemOverlaySource(overlayName string) string { +func SystemOverlaySource(overlayName string) string { if overlayName == "" { wwlog.Printf(wwlog.ERROR, "System overlay name is not defined\n") return "" @@ -107,11 +50,10 @@ func (self *Config) SystemOverlaySource(overlayName string) string { return "" } - return path.Join(self.SystemOverlayDir(), overlayName) + return path.Join(SystemOverlayDir(), overlayName) } - -func (self *Config) RuntimeOverlaySource(overlayName string) string { +func RuntimeOverlaySource(overlayName string) string { if overlayName == "" { wwlog.Printf(wwlog.ERROR, "Runtime overlay name is not defined\n") return "" @@ -122,10 +64,10 @@ func (self *Config) RuntimeOverlaySource(overlayName string) string { return "" } - return path.Join(self.RuntimeOverlayDir(), overlayName) + return path.Join(RuntimeOverlayDir(), overlayName) } -func (self *Config) KernelImage(kernelVersion string) string { +func KernelImage(kernelVersion string) string { if kernelVersion == "" { wwlog.Printf(wwlog.ERROR, "Kernel Version is not defined\n") return "" @@ -136,10 +78,10 @@ func (self *Config) KernelImage(kernelVersion string) string { return "" } - return path.Join(self.KernelParentDir(), kernelVersion, "vmlinuz") + return path.Join(KernelParentDir(), kernelVersion, "vmlinuz") } -func (self *Config) KmodsImage(kernelVersion string) string { +func KmodsImage(kernelVersion string) string { if kernelVersion == "" { wwlog.Printf(wwlog.ERROR, "Kernel Version is not defined\n") return "" @@ -150,10 +92,10 @@ func (self *Config) KmodsImage(kernelVersion string) string { return "" } - return path.Join(self.KernelParentDir(), kernelVersion, "kmods.img") + return path.Join(KernelParentDir(), kernelVersion, "kmods.img") } -func (self *Config) SystemOverlayImage(nodeName string) string { +func SystemOverlayImage(nodeName string) string { if nodeName == "" { wwlog.Printf(wwlog.ERROR, "Node name is not defined\n") return "" @@ -164,10 +106,10 @@ func (self *Config) SystemOverlayImage(nodeName string) string { return "" } - return fmt.Sprintf("%s/provision/overlays/system/%s.img", self.LocalStateDir, nodeName) + return fmt.Sprintf("%s/provision/overlays/system/%s.img", LocalStateDir, nodeName) } -func (self *Config) RuntimeOverlayImage(nodeName string) string { +func RuntimeOverlayImage(nodeName string) string { if nodeName == "" { wwlog.Printf(wwlog.ERROR, "Node name is not defined\n") return "" @@ -178,10 +120,10 @@ func (self *Config) RuntimeOverlayImage(nodeName string) string { return "" } - return fmt.Sprintf("%s/provision/overlays/runtime/%s.img", self.LocalStateDir, nodeName) + return fmt.Sprintf("%s/provision/overlays/runtime/%s.img", LocalStateDir, nodeName) } -func (self *Config) VnfsImageDir(uri string) string { +func VnfsImageDir(uri string) string { if uri == "" { wwlog.Printf(wwlog.ERROR, "VNFS URI is not defined\n") return "" @@ -192,14 +134,14 @@ func (self *Config) VnfsImageDir(uri string) string { return "" } - return path.Join(self.VnfsImageParentDir(), uri) + return path.Join(VnfsImageParentDir(), uri) } -func (self *Config) VnfsImage(uri string) string { - return path.Join(self.VnfsImageDir(uri), "image") +func VnfsImage(uri string) string { + return path.Join(VnfsImageDir(uri), "image") } -func (self *Config) VnfsChroot(uri string) string { +func VnfsChroot(uri string) string { if uri == "" { wwlog.Printf(wwlog.ERROR, "VNFS name is not defined\n") return "" @@ -210,5 +152,5 @@ func (self *Config) VnfsChroot(uri string) string { return "" } - return path.Join(self.VnfsChrootParentDir(), uri) + return path.Join(VnfsChrootParentDir(), uri) } diff --git a/internal/pkg/kernel/kernel.go b/internal/pkg/kernel/kernel.go index 9f451e42..26109458 100644 --- a/internal/pkg/kernel/kernel.go +++ b/internal/pkg/kernel/kernel.go @@ -12,7 +12,6 @@ import ( ) func Build(kernelVersion string) error { - config := config.New() kernelImage := "/boot/vmlinuz-" + kernelVersion kernelDrivers := "/lib/modules/" + kernelVersion diff --git a/internal/pkg/node/constructors.go b/internal/pkg/node/constructors.go index ccaa4f14..cf9a6860 100644 --- a/internal/pkg/node/constructors.go +++ b/internal/pkg/node/constructors.go @@ -7,8 +7,11 @@ import ( "gopkg.in/yaml.v2" "io/ioutil" "regexp" + "strings" ) +const ConfigFile = "/etc/warewulf/nodes.conf" + func New() (nodeYaml, error) { var ret nodeYaml @@ -19,211 +22,149 @@ func New() (nodeYaml, error) { return ret, err } + wwlog.Printf(wwlog.DEBUG, "Unmarshaling the node configuration\n") err = yaml.Unmarshal(data, &ret) if err != nil { return ret, err } + wwlog.Printf(wwlog.DEBUG, "Returning node object\n") + return ret, nil } func (self *nodeYaml) FindAllNodes() ([]NodeInfo, error) { var ret []NodeInfo - for controllername, controller := range self.Controllers { - for groupname, group := range controller.NodeGroups { - for nodename, node := range group.Nodes { - var n NodeInfo - var allProfiles []string + wwlog.Printf(wwlog.DEBUG, "Finding all nodes...\n") + for nodename, node := range self.Nodes { + var n NodeInfo - if node.Disabled == true || group.Disabled == true { - wwlog.Printf(wwlog.VERBOSE, "Skipping disabled node: %s/%s\n", groupname, nodename) - continue + wwlog.Printf(wwlog.DEBUG, "In node loop: %s\n", nodename) + n.NetDevs = make(map[string]*NetDevEntry) + n.SystemOverlay.SetDefault("default") + n.RuntimeOverlay.SetDefault("default") + n.Ipxe.SetDefault("default") + + fullname := strings.SplitN(nodename, ".", 2) + if len(fullname) > 1 { + n.DomainName.SetDefault(fullname[1]) + } + + if len(node.Profiles) == 0 { + n.Profiles = []string{"default"} + } else { + n.Profiles = node.Profiles + } + + n.Id.Set(nodename) + n.Comment.Set(node.Comment) + n.Vnfs.Set(node.Vnfs) + n.KernelVersion.Set(node.KernelVersion) + n.KernelArgs.Set(node.KernelArgs) + n.DomainName.Set(node.DomainName) + n.Ipxe.Set(node.Ipxe) + n.IpmiIpaddr.Set(node.IpmiIpaddr) + n.IpmiNetmask.Set(node.IpmiNetmask) + n.IpmiUserName.Set(node.IpmiUserName) + n.IpmiPassword.Set(node.IpmiPassword) + n.SystemOverlay.Set(node.SystemOverlay) + n.RuntimeOverlay.Set(node.RuntimeOverlay) + + for devname, netdev := range node.NetDevs { + if _, ok := n.NetDevs[devname]; !ok { + var netdev NetDevEntry + n.NetDevs[devname] = &netdev + } + + n.NetDevs[devname].Ipaddr.Set(netdev.Ipaddr) + n.NetDevs[devname].Netmask.Set(netdev.Netmask) + n.NetDevs[devname].Hwaddr.Set(netdev.Hwaddr) + n.NetDevs[devname].Gateway.Set(netdev.Gateway) + n.NetDevs[devname].Type.Set(netdev.Type) + n.NetDevs[devname].Default.SetB(netdev.Default) + } + + for _, p := range n.Profiles { + if _, ok := self.NodeProfiles[p]; !ok { + wwlog.Printf(wwlog.WARN, "Profile not found for node '%s': %s\n", nodename, p) + continue + } + + wwlog.Printf(wwlog.VERBOSE, "Merging profile into node: %s <- %s\n", nodename, p) + + pstring := fmt.Sprintf("%s", p) + + n.Comment.SetAlt(self.NodeProfiles[p].Comment, pstring) + n.DomainName.SetAlt(self.NodeProfiles[p].DomainName, pstring) + n.Vnfs.SetAlt(self.NodeProfiles[p].Vnfs, pstring) + n.KernelVersion.SetAlt(self.NodeProfiles[p].KernelVersion, pstring) + n.KernelArgs.SetAlt(self.NodeProfiles[p].KernelArgs, pstring) + n.Ipxe.SetAlt(self.NodeProfiles[p].Ipxe, pstring) + n.IpmiIpaddr.SetAlt(self.NodeProfiles[p].IpmiIpaddr, pstring) + n.IpmiNetmask.SetAlt(self.NodeProfiles[p].IpmiNetmask, pstring) + n.IpmiUserName.SetAlt(self.NodeProfiles[p].IpmiUserName, pstring) + n.IpmiPassword.SetAlt(self.NodeProfiles[p].IpmiPassword, pstring) + n.SystemOverlay.SetAlt(self.NodeProfiles[p].SystemOverlay, pstring) + n.RuntimeOverlay.SetAlt(self.NodeProfiles[p].RuntimeOverlay, pstring) + + for devname, netdev := range self.NodeProfiles[p].NetDevs { + if _, ok := n.NetDevs[devname]; !ok { + var netdev NetDevEntry + n.NetDevs[devname] = &netdev } + wwlog.Printf(wwlog.DEBUG, "Updating profile (%s) netdev: %s\n", p, devname) - n.Id.Set(nodename) - n.Gid.Set(groupname) - n.Cid.Set(controllername) - n.HostName.Set(node.Hostname) - n.IpmiIpaddr.Set(node.IpmiIpaddr) - n.IpmiNetmask.Set(node.IpmiNetmask) - n.DomainName.Set(node.DomainName) - n.Vnfs.Set(node.Vnfs) - n.KernelVersion.Set(node.KernelVersion) - n.KernelArgs.Set(node.KernelArgs) - n.Ipxe.Set(node.Ipxe) - n.IpmiUserName.Set(node.IpmiUserName) - n.IpmiPassword.Set(node.IpmiPassword) - n.SystemOverlay.Set(node.SystemOverlay) - n.RuntimeOverlay.Set(node.RuntimeOverlay) - - n.DomainName.SetGroup(group.DomainName) - n.Vnfs.SetGroup(group.Vnfs) - n.KernelVersion.SetGroup(group.KernelVersion) - n.KernelArgs.SetGroup(group.KernelArgs) - n.Ipxe.SetGroup(group.Ipxe) - n.IpmiNetmask.SetGroup(group.IpmiNetmask) - n.IpmiUserName.SetGroup(group.IpmiUserName) - n.IpmiPassword.SetGroup(group.IpmiPassword) - n.SystemOverlay.SetGroup(group.SystemOverlay) - n.RuntimeOverlay.SetGroup(group.RuntimeOverlay) - - n.RuntimeOverlay.SetDefault("default") - n.SystemOverlay.SetDefault("default") - n.Ipxe.SetDefault("default") - n.KernelArgs.SetDefault("crashkernel=no quiet") - - n.GroupProfiles = group.Profiles - n.Profiles = node.Profiles - - allProfiles = append(allProfiles, group.Profiles...) - allProfiles = append(allProfiles, node.Profiles...) - - for _, p := range allProfiles { - if _, ok := self.NodeProfiles[p]; !ok { - wwlog.Printf(wwlog.WARN, "Profile not found for node '%s': %s\n", nodename, p) - continue - } - - n.DomainName.SetProfile(self.NodeProfiles[p].DomainName) - n.Vnfs.SetProfile(self.NodeProfiles[p].Vnfs) - n.KernelVersion.SetProfile(self.NodeProfiles[p].KernelVersion) - n.KernelArgs.SetProfile(self.NodeProfiles[p].KernelArgs) - n.Ipxe.SetProfile(self.NodeProfiles[p].Ipxe) - n.IpmiNetmask.SetProfile(self.NodeProfiles[p].IpmiNetmask) - n.IpmiUserName.SetProfile(self.NodeProfiles[p].IpmiUserName) - n.IpmiPassword.SetProfile(self.NodeProfiles[p].IpmiPassword) - n.SystemOverlay.SetProfile(self.NodeProfiles[p].SystemOverlay) - n.RuntimeOverlay.SetProfile(self.NodeProfiles[p].RuntimeOverlay) - } - - if n.DomainName.Defined() == true { - n.Fqdn.Set(node.Hostname + "." + n.DomainName.Get()) - } else { - n.Fqdn.Set(node.Hostname) - } - - n.NetDevs = node.NetDevs - - ret = append(ret, n) + n.NetDevs[devname].Ipaddr.SetAlt(netdev.Ipaddr, pstring) + n.NetDevs[devname].Netmask.SetAlt(netdev.Netmask, pstring) + n.NetDevs[devname].Hwaddr.SetAlt(netdev.Hwaddr, pstring) + n.NetDevs[devname].Gateway.SetAlt(netdev.Gateway, pstring) + n.NetDevs[devname].Type.SetAlt(netdev.Type, pstring) + n.NetDevs[devname].Default.SetAltB(netdev.Default, pstring) } } + + ret = append(ret, n) + } return ret, nil } -func (self *nodeYaml) FindAllGroups() ([]GroupInfo, error) { - var ret []GroupInfo - - for controllername, controller := range self.Controllers { - for groupname, group := range controller.NodeGroups { - var g GroupInfo - - g.Id = groupname - g.Cid = controllername - g.DomainName = group.DomainName - g.Comment = group.Comment - g.Vnfs = group.Vnfs - g.KernelVersion = group.KernelVersion - g.KernelArgs = group.KernelArgs - g.IpmiNetmask = group.IpmiNetmask - g.IpmiPassword = group.IpmiPassword - g.IpmiUserName = group.IpmiUserName - g.SystemOverlay = group.SystemOverlay - g.RuntimeOverlay = group.RuntimeOverlay - - g.Profiles = group.Profiles - - // TODO: Validate or die on all inputs - - ret = append(ret, g) - } - } - return ret, nil -} - -func (self *nodeYaml) FindAllControllers() ([]ControllerInfo, error) { - var ret []ControllerInfo - - for controllername, controller := range self.Controllers { - var c ControllerInfo - - c.Id = controllername - c.Ipaddr = controller.Ipaddr - c.Comment = controller.Comment - c.Fqdn = controller.Fqdn - - //TODO: Is there a better way to do this, cause EWWW! - c.Services = struct { - Warewulfd struct { - Port string - Secure bool - StartCmd string - RestartCmd string - EnableCmd string - } - Dhcp struct { - Enabled bool - Template string - RangeStart string - RangeEnd string - ConfigFile string - StartCmd string - RestartCmd string - EnableCmd string - } - Tftp struct { - Enabled bool - TftpRoot string - StartCmd string - RestartCmd string - EnableCmd string - } - Nfs struct { - Enabled bool - Exports []string - StartCmd string - RestartCmd string - EnableCmd string - } - }(controller.Services) - - // Validations // - - if c.Ipaddr == "" { - wwlog.Printf(wwlog.WARN, "Controller IP address is unset: %s\n", c.Id) - } - - if c.Services.Warewulfd.Port == "" { - c.Services.Warewulfd.Port = "987" - } - - // TODO: Validate or die on all inputs - - ret = append(ret, c) - } - return ret, nil -} - -func (self *nodeYaml) FindAllProfiles() ([]ProfileInfo, error) { - var ret []ProfileInfo +func (self *nodeYaml) FindAllProfiles() ([]NodeInfo, error) { + var ret []NodeInfo for name, profile := range self.NodeProfiles { - var p ProfileInfo + var p NodeInfo + p.NetDevs = make(map[string]*NetDevEntry) - p.Id = name - p.Comment = profile.Comment - p.Vnfs = profile.Vnfs - p.Ipxe = profile.Ipxe - p.KernelVersion = profile.KernelVersion - p.KernelArgs = profile.KernelArgs - p.IpmiNetmask = profile.IpmiNetmask - p.IpmiUserName = profile.IpmiUserName - p.IpmiPassword = profile.IpmiPassword - p.DomainName = profile.DomainName - p.RuntimeOverlay = profile.RuntimeOverlay - p.SystemOverlay = profile.SystemOverlay + p.Id.Set(name) + p.Comment.Set(profile.Comment) + p.Vnfs.Set(profile.Vnfs) + p.Ipxe.Set(profile.Ipxe) + p.KernelVersion.Set(profile.KernelVersion) + p.KernelArgs.Set(profile.KernelArgs) + p.IpmiNetmask.Set(profile.IpmiNetmask) + p.IpmiUserName.Set(profile.IpmiUserName) + p.IpmiPassword.Set(profile.IpmiPassword) + p.RuntimeOverlay.Set(profile.RuntimeOverlay) + p.SystemOverlay.Set(profile.SystemOverlay) + + for devname, netdev := range profile.NetDevs { + if _, ok := p.NetDevs[devname]; !ok { + var netdev NetDevEntry + p.NetDevs[devname] = &netdev + } + + wwlog.Printf(wwlog.DEBUG, "Updating profile netdev: %s\n", devname) + + p.NetDevs[devname].Ipaddr.Set(netdev.Ipaddr) + p.NetDevs[devname].Netmask.Set(netdev.Netmask) + p.NetDevs[devname].Hwaddr.Set(netdev.Hwaddr) + p.NetDevs[devname].Gateway.Set(netdev.Gateway) + p.NetDevs[devname].Type.Set(netdev.Type) + p.NetDevs[devname].Default.SetB(netdev.Default) + } // TODO: Validate or die on all inputs @@ -239,7 +180,7 @@ func (self *nodeYaml) FindByHwaddr(hwa string) (NodeInfo, error) { for _, node := range n { for _, dev := range node.NetDevs { - if dev.Hwaddr == hwa { + if dev.Hwaddr.Get() == hwa { return node, nil } } @@ -255,7 +196,7 @@ func (self *nodeYaml) FindByIpaddr(ipaddr string) (NodeInfo, error) { for _, node := range n { for _, dev := range node.NetDevs { - if dev.Ipaddr == ipaddr { + if dev.Ipaddr.Get() == ipaddr { return node, nil } } @@ -270,7 +211,7 @@ func (nodes *nodeYaml) SearchByName(search string) ([]NodeInfo, error) { n, _ := nodes.FindAllNodes() for _, node := range n { - b, _ := regexp.MatchString(search, node.Fqdn.Get()) + b, _ := regexp.MatchString(search, node.Id.Get()) if b == true { ret = append(ret, node) } @@ -286,7 +227,7 @@ func (nodes *nodeYaml) SearchByNameList(searchList []string) ([]NodeInfo, error) for _, search := range searchList { for _, node := range n { - b, _ := regexp.MatchString(search, node.Fqdn.Get()) + b, _ := regexp.MatchString(search, node.Id.Get()) if b == true { ret = append(ret, node) } diff --git a/internal/pkg/node/datastructure.go b/internal/pkg/node/datastructure.go index 9999fcac..54ad3c7f 100644 --- a/internal/pkg/node/datastructure.go +++ b/internal/pkg/node/datastructure.go @@ -11,98 +11,26 @@ import ( ******/ type nodeYaml struct { - NodeProfiles map[string]*ProfileConf - Controllers map[string]*ControllerConf `yaml:"control"` -} - -type ProfileConf struct { - Comment string `yaml:"comment"` - Vnfs string `yaml:"vnfs,omitempty"` - Ipxe string `yaml:"ipxe template,omitempty"` - KernelVersion string `yaml:"kernel version,omitempty"` - KernelArgs string `yaml:"kernel args,omitempty"` - IpmiNetmask string `yaml:"ipmi netmask,omitempty"` - IpmiUserName string `yaml:"ipmi username,omitempty"` - IpmiPassword string `yaml:"ipmi password,omitempty"` - DomainName string `yaml:"domain name,omitempty"` - RuntimeOverlay string `yaml:"runtime overlay files,omitempty"` - SystemOverlay string `yaml:"system overlay files,omitempty"` -} - -type ControllerConf struct { - Comment string `yaml:"comment"` - Ipaddr string `yaml:"ipaddr"` - Fqdn string `yaml:"fqdn"` - Services struct { - Warewulfd struct { - Port string `yaml:"port"` - Secure bool `yaml:"secure,omitempty"` - StartCmd string `yaml:"start command,omitempty"` - RestartCmd string `yaml:"restart command,omitempty"` - EnableCmd string `yaml:"enable command,omitempty"` - } `yaml:"warewulf"` - Dhcp struct { - Enabled bool `yaml:"enabled,omitempty"` - Template string `yaml:"template,omitempty"` - RangeStart string `yaml:"range start,omitempty"` - RangeEnd string `yaml:"range end,omitempty"` - ConfigFile string `yaml:"config file,omitempty"` - StartCmd string `yaml:"start command,omitempty"` - RestartCmd string `yaml:"restart command,omitempty"` - EnableCmd string `yaml:"enable command,omitempty"` - } `yaml:"dhcp,omitempty"` - Tftp struct { - Enabled bool `yaml:"enabled,omitempty"` - TftpRoot string `yaml:"tftp root,omitempty"` - StartCmd string `yaml:"start command,omitempty"` - RestartCmd string `yaml:"restart command,omitempty"` - EnableCmd string `yaml:"enable command,omitempty"` - } `yaml:"tftp,omitempty"` - Nfs struct { - Enabled bool `yaml:"enabled,omitempty"` - Exports []string `yaml:"exports,omitempty"` - StartCmd string `yaml:"start command,omitempty"` - RestartCmd string `yaml:"restart command,omitempty"` - EnableCmd string `yaml:"enable command,omitempty"` - } `yaml:"nfs,omitempty"` - } `yaml:"services"` - NodeGroups map[string]*GroupConf -} - -type GroupConf struct { - Comment string `yaml:"comment"` - Disabled bool `yaml:"disabled,omitempty"` - DomainName string `yaml:"domain name"` - Vnfs string `yaml:"vnfs,omitempty"` - Ipxe string `yaml:"ipxe template,omitempty"` - KernelVersion string `yaml:"kernel version,omitempty"` - KernelArgs string `yaml:"kernel args,omitempty"` - IpmiNetmask string `yaml:"ipmi netmask,omitempty"` - IpmiUserName string `yaml:"ipmi username,omitempty"` - IpmiPassword string `yaml:"ipmi password,omitempty"` - RuntimeOverlay string `yaml:"runtime overlay files,omitempty"` - SystemOverlay string `yaml:"system overlay files,omitempty"` - Profiles []string `yaml:"profiles,omitempty"` - Nodes map[string]*NodeConf + NodeProfiles map[string]*NodeConf + Nodes map[string]*NodeConf } type NodeConf struct { - Comment string `yaml:"comment,omitempty"` - Disabled bool `yaml:"disabled,omitempty"` - Hostname string `yaml:"hostname,omitempty"` - DomainName string `yaml:"domain name,omitempty"` - Vnfs string `yaml:"vnfs,omitempty"` - Ipxe string `yaml:"ipxe template,omitempty"` - KernelVersion string `yaml:"kernel version,omitempty"` - KernelArgs string `yaml:"kernel args,omitempty"` - IpmiUserName string `yaml:"ipmi username,omitempty"` - IpmiPassword string `yaml:"ipmi password,omitempty"` - IpmiIpaddr string `yaml:"ipmi ipaddr,omitempty"` - IpmiNetmask string `yaml:"ipmi netmask,omitempty"` - RuntimeOverlay string `yaml:"runtime overlay files,omitempty"` - SystemOverlay string `yaml:"system overlay files,omitempty"` - Profiles []string `yaml:"profiles,omitempty"` - NetDevs map[string]*NetDevs + Comment string `yaml:"comment,omitempty"` + Disabled bool `yaml:"disabled,omitempty"` + DomainName string `yaml:"domain name,omitempty"` + Vnfs string `yaml:"vnfs,omitempty"` + Ipxe string `yaml:"ipxe template,omitempty"` + KernelVersion string `yaml:"kernel version,omitempty"` + KernelArgs string `yaml:"kernel args,omitempty"` + IpmiUserName string `yaml:"ipmi username,omitempty"` + IpmiPassword string `yaml:"ipmi password,omitempty"` + IpmiIpaddr string `yaml:"ipmi ipaddr,omitempty"` + IpmiNetmask string `yaml:"ipmi netmask,omitempty"` + RuntimeOverlay string `yaml:"runtime overlay files,omitempty"` + SystemOverlay string `yaml:"system overlay files,omitempty"` + Profiles []string `yaml:"profiles,omitempty"` + NetDevs map[string]*NetDevs `yaml:"network devices,omitempty"` } type NetDevs struct { @@ -115,115 +43,47 @@ type NetDevs struct { } /****** - * Code internal data representations + * Internal code data representations ******/ -type NodeInfoEntry struct { - value string - profile string - group string - controller string - def string +type Entry struct { + value string + altvalue string + bool bool + altbool bool + from string + def string } type NodeInfo struct { - Id NodeInfoEntry - Gid NodeInfoEntry - Cid NodeInfoEntry - Comment NodeInfoEntry - HostName NodeInfoEntry - Fqdn NodeInfoEntry - DomainName NodeInfoEntry - Vnfs NodeInfoEntry - Ipxe NodeInfoEntry - KernelVersion NodeInfoEntry - KernelArgs NodeInfoEntry - IpmiIpaddr NodeInfoEntry - IpmiNetmask NodeInfoEntry - IpmiUserName NodeInfoEntry - IpmiPassword NodeInfoEntry - RuntimeOverlay NodeInfoEntry - SystemOverlay NodeInfoEntry + Id Entry + Cid Entry + Comment Entry + DomainName Entry + Vnfs Entry + Ipxe Entry + KernelVersion Entry + KernelArgs Entry + IpmiIpaddr Entry + IpmiNetmask Entry + IpmiUserName Entry + IpmiPassword Entry + RuntimeOverlay Entry + SystemOverlay Entry Profiles []string GroupProfiles []string - NetDevs map[string]*NetDevs + NetDevs map[string]*NetDevEntry } -type ControllerInfo struct { - Id string - Comment string - Ipaddr string - Fqdn string - DomainName string - Services struct { - Warewulfd struct { - Port string - Secure bool - StartCmd string - RestartCmd string - EnableCmd string - } - Dhcp struct { - Enabled bool - Template string - RangeStart string - RangeEnd string - ConfigFile string - StartCmd string - RestartCmd string - EnableCmd string - } - Tftp struct { - Enabled bool - TftpRoot string - StartCmd string - RestartCmd string - EnableCmd string - } - Nfs struct { - Enabled bool - Exports []string - StartCmd string - RestartCmd string - EnableCmd string - } - } +type NetDevEntry struct { + Type Entry `yaml:"type,omitempty"` + Default Entry `yaml:"default"` + Hwaddr Entry + Ipaddr Entry + Netmask Entry + Gateway Entry `yaml:"gateway,omitempty"` } -type GroupInfo struct { - Id string - Cid string - Comment string - Vnfs string - Ipxe string - KernelVersion string - KernelArgs string - IpmiNetmask string - IpmiUserName string - IpmiPassword string - DomainName string - RuntimeOverlay string - SystemOverlay string - Profiles []string -} - -type ProfileInfo struct { - Id string - Comment string - Vnfs string - Ipxe string - KernelVersion string - KernelArgs string - IpmiNetmask string - IpmiUserName string - IpmiPassword string - DomainName string - RuntimeOverlay string - SystemOverlay string -} - -const ConfigFile = "/etc/warewulf/nodes.conf" - func init() { //TODO: Check to make sure nodes.conf is found if util.IsFile(ConfigFile) == false { diff --git a/internal/pkg/node/methods.go b/internal/pkg/node/methods.go index 011b9026..caa221f7 100644 --- a/internal/pkg/node/methods.go +++ b/internal/pkg/node/methods.go @@ -4,18 +4,101 @@ import ( "strings" ) -func (self *NodeInfoEntry) String() string { +/********** + * + * Sets + * + *********/ + +func (self *Entry) Set(val string) { + if val == "" { + return + } + + if strings.ToUpper(val) == "DELETE" { + self.value = "" + } else { + self.value = val + } + + return +} + +func (self *Entry) SetB(val bool) { + self.bool = val + return +} + +func (self *Entry) SetAlt(val string, from string) { + if val == "" { + return + } + + self.altvalue = val + self.from = from + + return +} + +func (self *Entry) SetAltB(val bool, from string) { + self.altbool = val + self.from = from + return +} + +func (self *Entry) SetDefault(val string) { + if val == "" { + return + } + + self.def = val + + return +} + +/********** + * + * Gets + * + *********/ + +func (self *Entry) Get() string { if self.value != "" { return self.value } - if self.group != "" { - return self.group + if self.altvalue != "" { + return self.altvalue } - if self.profile != "" { - return self.profile + if self.def != "" { + return self.def } - if self.controller != "" { - return self.controller + return "" +} + +func (self *Entry) GetB() bool { + return self.bool +} + +func (self *Entry) GetReal() string { + return self.value +} + +func (self *Entry) GetRealB() bool { + return self.bool +} + +/********** + * + * Misc + * + *********/ + +func (self *Entry) Print() string { + if self.value != "" { + return self.value + } + if self.altvalue != "" { + return self.altvalue } if self.def != "" { return self.def @@ -23,93 +106,25 @@ func (self *NodeInfoEntry) String() string { return "--" } -func (self *NodeInfoEntry) Source() string { +func (self *Entry) Source() string { + if self.value != "" && self.altvalue != "" { + return "SUPERSEDED" + //return fmt.Sprintf("[%s]", self.from) + } else if self.from == "" { + return "--" + } + return self.from +} + +func (self *Entry) Defined() bool { if self.value != "" { - return "node" + return true } - if self.group != "" { - return "group" - } - if self.profile != "" { - return "profile" - } - if self.controller != "" { - return "controller" + if self.altvalue != "" { + return true } if self.def != "" { - return "default" + return true } - return "" + return false } - -func (self *NodeInfoEntry) Get() string { - if self.value != "" { - return self.value - } - if self.group != "" { - return self.group - } - if self.profile != "" { - return self.profile - } - if self.controller != "" { - return self.controller - } - if self.def != "" { - return self.def - } - return "" -} - -func (self *NodeInfoEntry) Defined() bool { - if self.Get() == "" { - return false - } - - return true -} - -func (self *NodeInfoEntry) SetDefault(value string) { - if value == "" { - return - } - self.def = value -} - -func (self *NodeInfoEntry) SetGroup(value string) { - if value == "" { - return - } - self.group = value -} - -func (self *NodeInfoEntry) SetProfile(value string) { - if value == "" { - return - } - self.profile = value -} - -func (self *NodeInfoEntry) SetController(value string) { - if value == "" { - return - } - self.controller = value -} - -func (self *NodeInfoEntry) Set(value string) { - if value == "" { - return - } else if strings.ToUpper(value) == "UNDEF" { - value = "" - } - self.value = value -} - -func (self *NodeInfoEntry) Unset() { - self.value = "" -} - -func (self *NodeInfoEntry) GetReal() string { - return self.value -} \ No newline at end of file diff --git a/internal/pkg/node/modifiers.go b/internal/pkg/node/modifiers.go index 55c0cb36..6b9fa751 100644 --- a/internal/pkg/node/modifiers.go +++ b/internal/pkg/node/modifiers.go @@ -3,7 +3,6 @@ package node import ( "github.com/hpcng/warewulf/internal/pkg/errors" "github.com/hpcng/warewulf/internal/pkg/wwlog" - "gopkg.in/yaml.v2" "os" ) @@ -14,225 +13,73 @@ import ( * ****/ -func (self *nodeYaml) AddNode(controllerID string, groupID string, nodeID string) error { +func (self *nodeYaml) AddNode(nodeID string) (NodeInfo, error) { var node NodeConf + var n NodeInfo - wwlog.Printf(wwlog.VERBOSE, "Adding new node: %s/%s\n", groupID, nodeID) + wwlog.Printf(wwlog.VERBOSE, "Adding new node: %s\n", nodeID) - if _, ok := self.Controllers[controllerID]; !ok { - return errors.New("Controller does not exist: " + controllerID) + if _, ok := self.Nodes[nodeID]; ok { + return n, errors.New("Nodename already exists: " + nodeID) } - if _, ok := self.Controllers[controllerID].NodeGroups[groupID]; !ok { - return errors.New("Group does not exist: " + groupID) - } + self.Nodes[nodeID] = &node + self.Nodes[nodeID].Profiles = []string{"default"} + self.Nodes[nodeID].NetDevs = make(map[string]*NetDevs) - if _, ok := self.Controllers[controllerID].NodeGroups[groupID].Nodes[groupID]; ok { - return errors.New("Nodename already exists in group: " + nodeID) - } + n.Id.Set(nodeID) + n.Profiles = []string{"default"} + n.NetDevs = make(map[string]*NetDevEntry) - self.Controllers[controllerID].NodeGroups[groupID].Nodes[nodeID] = &node - self.Controllers[controllerID].NodeGroups[groupID].Nodes[nodeID].Hostname = nodeID - - return nil + return n, nil } -func (self *nodeYaml) DelNode(controllerID string, groupID string, nodeID string) error { +func (self *nodeYaml) DelNode(nodeID string) error { - if _, ok := self.Controllers[controllerID]; !ok { - return errors.New("Controller does not exist: " + controllerID) + if _, ok := self.Nodes[nodeID]; !ok { + return errors.New("Nodename does not exist: " + nodeID) } - if _, ok := self.Controllers[controllerID].NodeGroups[groupID]; !ok { - return errors.New("Group does not exist: " + groupID) - } - - if _, ok := self.Controllers[controllerID].NodeGroups[groupID].Nodes[groupID]; ok { - return errors.New("Nodename does not exist in group: " + nodeID) - } - - wwlog.Printf(wwlog.VERBOSE, "Deleting node network device: %s/%s\n", groupID, nodeID) - delete(self.Controllers[controllerID].NodeGroups[groupID].Nodes, nodeID) + wwlog.Printf(wwlog.VERBOSE, "Deleting node: %s\n", nodeID) + delete(self.Nodes, nodeID) return nil } func (self *nodeYaml) NodeUpdate(node NodeInfo) error { - controllerID := node.Cid.Get() - groupID := node.Gid.Get() nodeID := node.Id.Get() - if _, ok := self.Controllers[controllerID]; !ok { - return errors.New("Controller does not exist: " + controllerID) + if _, ok := self.Nodes[nodeID]; !ok { + return errors.New("Nodename does not exist: " + nodeID) } - if _, ok := self.Controllers[controllerID].NodeGroups[groupID]; !ok { - return errors.New("Group does not exist: " + groupID) + self.Nodes[nodeID].Comment = node.Comment.GetReal() + self.Nodes[nodeID].Vnfs = node.Vnfs.GetReal() + self.Nodes[nodeID].DomainName = node.DomainName.GetReal() + self.Nodes[nodeID].Ipxe = node.Ipxe.GetReal() + self.Nodes[nodeID].KernelVersion = node.KernelVersion.GetReal() + self.Nodes[nodeID].KernelArgs = node.KernelArgs.GetReal() + self.Nodes[nodeID].IpmiIpaddr = node.IpmiIpaddr.GetReal() + self.Nodes[nodeID].IpmiNetmask = node.IpmiNetmask.GetReal() + self.Nodes[nodeID].IpmiUserName = node.IpmiUserName.GetReal() + self.Nodes[nodeID].IpmiPassword = node.IpmiPassword.GetReal() + self.Nodes[nodeID].RuntimeOverlay = node.RuntimeOverlay.GetReal() + self.Nodes[nodeID].SystemOverlay = node.SystemOverlay.GetReal() + self.Nodes[nodeID].Profiles = node.Profiles + self.Nodes[nodeID].NetDevs = make(map[string]*NetDevs) + + for devname, netdev := range node.NetDevs { + var newdev NetDevs + self.Nodes[nodeID].NetDevs[devname] = &newdev + + self.Nodes[nodeID].NetDevs[devname].Ipaddr = netdev.Ipaddr.GetReal() + self.Nodes[nodeID].NetDevs[devname].Netmask = netdev.Netmask.GetReal() + self.Nodes[nodeID].NetDevs[devname].Hwaddr = netdev.Hwaddr.GetReal() + self.Nodes[nodeID].NetDevs[devname].Gateway = netdev.Gateway.GetReal() + self.Nodes[nodeID].NetDevs[devname].Type = netdev.Type.GetReal() + self.Nodes[nodeID].NetDevs[devname].Default = netdev.Default.GetRealB() } - if _, ok := self.Controllers[controllerID].NodeGroups[groupID].Nodes[groupID]; !ok { - return errors.New("Nodename does not exist in group: " + nodeID) - } - - self.Controllers[controllerID].NodeGroups[groupID].Nodes[nodeID].Hostname = node.HostName.GetReal() - self.Controllers[controllerID].NodeGroups[groupID].Nodes[nodeID].Vnfs = node.Vnfs.GetReal() - self.Controllers[controllerID].NodeGroups[groupID].Nodes[nodeID].DomainName = node.DomainName.GetReal() - self.Controllers[controllerID].NodeGroups[groupID].Nodes[nodeID].Ipxe = node.Ipxe.GetReal() - self.Controllers[controllerID].NodeGroups[groupID].Nodes[nodeID].KernelVersion = node.KernelVersion.GetReal() - self.Controllers[controllerID].NodeGroups[groupID].Nodes[nodeID].KernelArgs = node.KernelArgs.GetReal() - self.Controllers[controllerID].NodeGroups[groupID].Nodes[nodeID].IpmiIpaddr = node.IpmiIpaddr.GetReal() - self.Controllers[controllerID].NodeGroups[groupID].Nodes[nodeID].IpmiNetmask = node.IpmiNetmask.GetReal() - self.Controllers[controllerID].NodeGroups[groupID].Nodes[nodeID].IpmiUserName = node.IpmiUserName.GetReal() - self.Controllers[controllerID].NodeGroups[groupID].Nodes[nodeID].IpmiPassword = node.IpmiPassword.GetReal() - self.Controllers[controllerID].NodeGroups[groupID].Nodes[nodeID].RuntimeOverlay = node.RuntimeOverlay.GetReal() - self.Controllers[controllerID].NodeGroups[groupID].Nodes[nodeID].SystemOverlay = node.SystemOverlay.GetReal() - self.Controllers[controllerID].NodeGroups[groupID].Nodes[nodeID].Profiles = node.Profiles - self.Controllers[controllerID].NodeGroups[groupID].Nodes[nodeID].NetDevs = node.NetDevs - - return nil -} - -/**** - * - * GROUP MODIFIERS - * -****/ - -func (self *nodeYaml) AddGroup(controllerID string, groupID string) error { - var group GroupConf - - wwlog.Printf(wwlog.VERBOSE, "Adding new group: %s/%s\n", groupID) - - if _, ok := self.Controllers[controllerID]; !ok { - return errors.New("Controller does not exist: " + controllerID) - } - - if _, ok := self.Controllers[controllerID].NodeGroups[groupID]; ok { - return errors.New("Group already exists: " + groupID) - } - - self.Controllers[controllerID].NodeGroups[groupID] = &group - self.Controllers[controllerID].NodeGroups[groupID].DomainName = groupID - self.Controllers[controllerID].NodeGroups[groupID].Profiles = []string{"default"} - - return nil -} - -func (self *nodeYaml) DelGroup(controllerID string, groupID string) error { - - if _, ok := self.Controllers[controllerID]; !ok { - return errors.New("Controller does not exist: " + controllerID) - } - - if _, ok := self.Controllers[controllerID].NodeGroups[groupID]; !ok { - return errors.New("Group does not exist: " + groupID) - } - - wwlog.Printf(wwlog.VERBOSE, "Deleting group: %s\n", groupID) - delete(self.Controllers[controllerID].NodeGroups, groupID) - - return nil -} - -func (self *nodeYaml) GroupUpdate(group GroupInfo) error { - controllerID := group.Cid - groupID := group.Id - - if _, ok := self.Controllers[controllerID]; !ok { - return errors.New("Controller does not exist: " + controllerID) - } - - if _, ok := self.Controllers[controllerID].NodeGroups[groupID]; !ok { - return errors.New("Group does not exist: " + groupID) - } - - self.Controllers[controllerID].NodeGroups[groupID].DomainName = group.DomainName - self.Controllers[controllerID].NodeGroups[groupID].Vnfs = group.Vnfs - self.Controllers[controllerID].NodeGroups[groupID].KernelVersion = group.KernelVersion - self.Controllers[controllerID].NodeGroups[groupID].KernelArgs = group.KernelArgs - self.Controllers[controllerID].NodeGroups[groupID].Ipxe = group.Ipxe - self.Controllers[controllerID].NodeGroups[groupID].IpmiNetmask = group.IpmiNetmask - self.Controllers[controllerID].NodeGroups[groupID].IpmiUserName = group.IpmiUserName - self.Controllers[controllerID].NodeGroups[groupID].IpmiPassword = group.IpmiPassword - self.Controllers[controllerID].NodeGroups[groupID].RuntimeOverlay = group.RuntimeOverlay - self.Controllers[controllerID].NodeGroups[groupID].SystemOverlay = group.SystemOverlay - self.Controllers[controllerID].NodeGroups[groupID].Profiles = group.Profiles - - return nil -} - -/**** - * - * CONTROLLER MODIFIERS - * -****/ - -func (self *nodeYaml) AddController(controllerID string) error { - var controller ControllerConf - var group GroupConf - - wwlog.Printf(wwlog.VERBOSE, "Adding new controller: %s/%s\n", controllerID) - - if _, ok := self.Controllers[controllerID]; ok { - return errors.New("Controller already exists: " + controllerID) - } - - self.Controllers[controllerID] = &controller - self.Controllers[controllerID].NodeGroups = make(map[string]*GroupConf) - self.Controllers[controllerID].NodeGroups["default"] = &group - - return nil -} - -func (self *nodeYaml) DelController(controllerID string) error { - - if _, ok := self.Controllers[controllerID]; !ok { - return errors.New("Controller does not exist: " + controllerID) - } - - wwlog.Printf(wwlog.VERBOSE, "Deleting controller: %s\n", controllerID) - delete(self.Controllers, controllerID) - - return nil -} - -func (self *nodeYaml) ControllerUpdate(controller ControllerInfo) error { - controllerID := controller.Id - - if _, ok := self.Controllers[controllerID]; !ok { - return errors.New("Controller does not exist: " + controllerID) - } - - self.Controllers[controllerID].Ipaddr = controller.Ipaddr - self.Controllers[controllerID].Comment = controller.Comment - self.Controllers[controllerID].Fqdn = controller.Fqdn - - self.Controllers[controllerID].Services.Warewulfd.Port = controller.Services.Warewulfd.Port - self.Controllers[controllerID].Services.Warewulfd.Secure = controller.Services.Warewulfd.Secure - self.Controllers[controllerID].Services.Warewulfd.StartCmd = controller.Services.Warewulfd.StartCmd - self.Controllers[controllerID].Services.Warewulfd.RestartCmd = controller.Services.Warewulfd.RestartCmd - self.Controllers[controllerID].Services.Warewulfd.EnableCmd = controller.Services.Warewulfd.EnableCmd - - self.Controllers[controllerID].Services.Dhcp.Enabled = controller.Services.Dhcp.Enabled - self.Controllers[controllerID].Services.Dhcp.ConfigFile = controller.Services.Dhcp.ConfigFile - self.Controllers[controllerID].Services.Dhcp.RangeStart = controller.Services.Dhcp.RangeStart - self.Controllers[controllerID].Services.Dhcp.RangeEnd = controller.Services.Dhcp.RangeEnd - self.Controllers[controllerID].Services.Dhcp.StartCmd = controller.Services.Dhcp.StartCmd - self.Controllers[controllerID].Services.Dhcp.RestartCmd = controller.Services.Dhcp.RestartCmd - self.Controllers[controllerID].Services.Dhcp.EnableCmd = controller.Services.Dhcp.EnableCmd - - self.Controllers[controllerID].Services.Nfs.Enabled = controller.Services.Nfs.Enabled - self.Controllers[controllerID].Services.Nfs.Exports = controller.Services.Nfs.Exports - self.Controllers[controllerID].Services.Nfs.StartCmd = controller.Services.Nfs.StartCmd - self.Controllers[controllerID].Services.Nfs.RestartCmd = controller.Services.Nfs.RestartCmd - self.Controllers[controllerID].Services.Nfs.EnableCmd = controller.Services.Nfs.EnableCmd - - self.Controllers[controllerID].Services.Tftp.Enabled = controller.Services.Tftp.Enabled - self.Controllers[controllerID].Services.Tftp.TftpRoot = controller.Services.Tftp.TftpRoot - self.Controllers[controllerID].Services.Tftp.StartCmd = controller.Services.Tftp.StartCmd - self.Controllers[controllerID].Services.Tftp.RestartCmd = controller.Services.Tftp.RestartCmd - self.Controllers[controllerID].Services.Tftp.EnableCmd = controller.Services.Tftp.EnableCmd - return nil } @@ -242,23 +89,27 @@ func (self *nodeYaml) ControllerUpdate(controller ControllerInfo) error { * ****/ -func (self *nodeYaml) AddProfile(profileID string) error { - var profile ProfileConf +func (self *nodeYaml) AddProfile(profileID string) (NodeInfo, error) { + var node NodeConf + var n NodeInfo - wwlog.Printf(wwlog.VERBOSE, "Adding new profile: %s/%s\n", profileID) + wwlog.Printf(wwlog.VERBOSE, "Adding new profile: %s\n", profileID) if _, ok := self.NodeProfiles[profileID]; ok { - return errors.New("Profile name already exists: " + profileID) + return n, errors.New("Profile name already exists: " + profileID) } - self.NodeProfiles[profileID] = &profile + self.NodeProfiles[profileID] = &node - return nil + n.Id.Set(profileID) + + return n, nil } func (self *nodeYaml) DelProfile(profileID string) error { + if _, ok := self.NodeProfiles[profileID]; !ok { - return errors.New("Group '" + profileID + "' was not found") + return errors.New("Profile does not exist: " + profileID) } wwlog.Printf(wwlog.VERBOSE, "Deleting profile: %s\n", profileID) @@ -267,22 +118,37 @@ func (self *nodeYaml) DelProfile(profileID string) error { return nil } -func (self *nodeYaml) ProfileUpdate(profile ProfileInfo) error { - profileID := profile.Id +func (self *nodeYaml) ProfileUpdate(profile NodeInfo) error { + profileID := profile.Id.Get() if _, ok := self.NodeProfiles[profileID]; !ok { - return errors.New("Group '" + profileID + "' was not found") + return errors.New("Profile name does not exist: " + profileID) } + self.NodeProfiles[profileID].Comment = profile.Comment.GetReal() + self.NodeProfiles[profileID].Vnfs = profile.Vnfs.GetReal() + self.NodeProfiles[profileID].Ipxe = profile.Ipxe.GetReal() + self.NodeProfiles[profileID].KernelVersion = profile.KernelVersion.GetReal() + self.NodeProfiles[profileID].KernelArgs = profile.KernelArgs.GetReal() + self.NodeProfiles[profileID].IpmiIpaddr = profile.IpmiIpaddr.GetReal() + self.NodeProfiles[profileID].IpmiNetmask = profile.IpmiNetmask.GetReal() + self.NodeProfiles[profileID].IpmiUserName = profile.IpmiUserName.GetReal() + self.NodeProfiles[profileID].IpmiPassword = profile.IpmiPassword.GetReal() + self.NodeProfiles[profileID].RuntimeOverlay = profile.RuntimeOverlay.GetReal() + self.NodeProfiles[profileID].SystemOverlay = profile.SystemOverlay.GetReal() + self.NodeProfiles[profileID].Profiles = profile.Profiles + self.NodeProfiles[profileID].NetDevs = make(map[string]*NetDevs) - self.NodeProfiles[profileID].DomainName = profile.DomainName - self.NodeProfiles[profileID].Vnfs = profile.Vnfs - self.NodeProfiles[profileID].Ipxe = profile.Ipxe - self.NodeProfiles[profileID].KernelVersion = profile.KernelVersion - self.NodeProfiles[profileID].IpmiNetmask = profile.IpmiNetmask - self.NodeProfiles[profileID].IpmiUserName = profile.IpmiUserName - self.NodeProfiles[profileID].IpmiPassword = profile.IpmiPassword - self.NodeProfiles[profileID].RuntimeOverlay = profile.RuntimeOverlay - self.NodeProfiles[profileID].SystemOverlay = profile.SystemOverlay + for devname, netdev := range profile.NetDevs { + var newdev NetDevs + self.NodeProfiles[profileID].NetDevs[devname] = &newdev + + self.NodeProfiles[profileID].NetDevs[devname].Ipaddr = netdev.Ipaddr.GetReal() + self.NodeProfiles[profileID].NetDevs[devname].Netmask = netdev.Netmask.GetReal() + self.NodeProfiles[profileID].NetDevs[devname].Hwaddr = netdev.Hwaddr.GetReal() + self.NodeProfiles[profileID].NetDevs[devname].Gateway = netdev.Gateway.GetReal() + self.NodeProfiles[profileID].NetDevs[devname].Type = netdev.Type.GetReal() + self.NodeProfiles[profileID].NetDevs[devname].Default = netdev.Default.GetRealB() + } return nil } diff --git a/internal/pkg/overlay/overlay.go b/internal/pkg/overlay/overlay.go index 528e3017..9f1e938b 100644 --- a/internal/pkg/overlay/overlay.go +++ b/internal/pkg/overlay/overlay.go @@ -19,7 +19,7 @@ import ( type TemplateStruct struct { Self struct { - Fqdn string + Id string Hostname string GroupName string Vnfs string @@ -57,7 +57,6 @@ func RuntimeOverlayInit(name string) error { } func findAllOverlays(overlayType string) ([]string, error) { - config := config.New() var ret []string var files []os.FileInfo var err error @@ -89,7 +88,6 @@ func findAllOverlays(overlayType string) ([]string, error) { func overlayInit(name string, overlayType string) error { var path string - config := config.New() if overlayType == "system" { wwlog.Printf(wwlog.DEBUG, "Looking for system overlays...") @@ -112,49 +110,56 @@ func overlayInit(name string, overlayType string) error { } func buildOverlay(nodeList []node.NodeInfo, overlayType string) error { - config := config.New() nodeDB, _ := node.New() allNodes, _ := nodeDB.FindAllNodes() - for _, node := range nodeList { + for _, n := range nodeList { var t TemplateStruct var OverlayDir string var OverlayFile string if overlayType == "runtime" { - OverlayDir = config.RuntimeOverlaySource(node.RuntimeOverlay.Get()) - OverlayFile = config.RuntimeOverlayImage(node.Fqdn.Get()) + OverlayDir = config.RuntimeOverlaySource(n.RuntimeOverlay.Get()) + OverlayFile = config.RuntimeOverlayImage(n.Id.Get()) } else if overlayType == "system" { - OverlayDir = config.SystemOverlaySource(node.RuntimeOverlay.Get()) - OverlayFile = config.SystemOverlayImage(node.Fqdn.Get()) + OverlayDir = config.SystemOverlaySource(n.RuntimeOverlay.Get()) + OverlayFile = config.SystemOverlayImage(n.Id.Get()) } else { wwlog.Printf(wwlog.ERROR, "overlayType requested is not supported: %s\n", overlayType) os.Exit(1) } - wwlog.Printf(wwlog.DEBUG, "Processing overlay for node: %s\n", node.Fqdn.Get()) + wwlog.Printf(wwlog.DEBUG, "Processing overlay for node: %s\n", n.Id.Get()) - t.Self.Fqdn = node.Fqdn.Get() - t.Self.Hostname = node.HostName.Get() - t.Self.GroupName = node.Gid.Get() - t.Self.Vnfs = node.Vnfs.Get() - t.Self.IpmiIpaddr = node.IpmiIpaddr.Get() - t.Self.IpmiNetmask = node.IpmiNetmask.Get() - t.Self.IpmiUserName = node.IpmiUserName.Get() - t.Self.IpmiPassword = node.IpmiPassword.Get() - t.Self.NetDevs = node.NetDevs + t.Self.Id = n.Id.Get() + t.Self.Hostname = n.Id.Get() + t.Self.Vnfs = n.Vnfs.Get() + t.Self.IpmiIpaddr = n.IpmiIpaddr.Get() + t.Self.IpmiNetmask = n.IpmiNetmask.Get() + t.Self.IpmiUserName = n.IpmiUserName.Get() + t.Self.IpmiPassword = n.IpmiPassword.Get() + t.Self.NetDevs = make(map[string]*node.NetDevs) + for devname, netdev := range n.NetDevs { + var nd node.NetDevs + t.Self.NetDevs[devname] = &nd + t.Self.NetDevs[devname].Hwaddr = netdev.Hwaddr.Get() + t.Self.NetDevs[devname].Ipaddr = netdev.Ipaddr.Get() + t.Self.NetDevs[devname].Netmask = netdev.Netmask.Get() + t.Self.NetDevs[devname].Gateway = netdev.Gateway.Get() + t.Self.NetDevs[devname].Type = netdev.Type.Get() + } t.AllNodes = allNodes - if overlayType == "runtime" && node.RuntimeOverlay.Defined() == false { - wwlog.Printf(wwlog.WARN, "Undefined runtime overlay, skipping node: %s\n", node.Fqdn.Get()) + if overlayType == "runtime" && n.RuntimeOverlay.Defined() == false { + wwlog.Printf(wwlog.WARN, "Undefined runtime overlay, skipping node: %s\n", n.Id.Get()) } - if overlayType == "system" && node.SystemOverlay.Defined() == false { - wwlog.Printf(wwlog.WARN, "Undefined system overlay, skipping node: %s\n", node.Fqdn.Get()) + if overlayType == "system" && n.SystemOverlay.Defined() == false { + wwlog.Printf(wwlog.WARN, "Undefined system overlay, skipping node: %s\n", n.Id.Get()) } wwlog.Printf(wwlog.DEBUG, "Checking to see if overlay directory exists: %s\n", OverlayDir) if util.IsDir(OverlayDir) == false { - wwlog.Printf(wwlog.WARN, "%-35s: Skipped (runtime overlay template not found)\n", node.Fqdn.Get()) + wwlog.Printf(wwlog.WARN, "%-35s: Skipped (runtime overlay template not found)\n", n.Id.Get()) continue } @@ -203,7 +208,7 @@ func buildOverlay(nodeList []node.NodeInfo, overlayType string) error { }).ParseGlob(path.Join(OverlayDir, destFile+".ww*")) if err != nil { wwlog.Printf(wwlog.ERROR, "%s\n", err) - return err + return nil } w, err := os.OpenFile(path.Join(tmpDir, destFile), os.O_RDWR|os.O_CREATE, info.Mode()) @@ -216,7 +221,7 @@ func buildOverlay(nodeList []node.NodeInfo, overlayType string) error { err = tmpl.Execute(w, t) if err != nil { wwlog.Printf(wwlog.ERROR, "%s\n", err) - return err + return nil } } else if b, _ := regexp.MatchString(`\.ww[a-zA-Z0-9\-\._]*$`, location); b == true { @@ -235,7 +240,7 @@ func buildOverlay(nodeList []node.NodeInfo, overlayType string) error { return nil }) - wwlog.Printf(wwlog.VERBOSE, "Finished generating overlay directory for: %s\n", node.Fqdn.Get()) + wwlog.Printf(wwlog.VERBOSE, "Finished generating overlay directory for: %s\n", n.Id.Get()) cmd := fmt.Sprintf("cd \"%s\"; find . | cpio --quiet -o -H newc -F \"%s\"", tmpDir, OverlayFile) wwlog.Printf(wwlog.DEBUG, "RUNNING: %s\n", cmd) @@ -244,7 +249,7 @@ func buildOverlay(nodeList []node.NodeInfo, overlayType string) error { wwlog.Printf(wwlog.ERROR, "Could not generate runtime image overlay: %s\n", err) continue } - wwlog.Printf(wwlog.INFO, "%-35s: Done\n", node.Fqdn.Get()) + wwlog.Printf(wwlog.INFO, "%-35s: Done\n", n.Id.Get()) wwlog.Printf(wwlog.DEBUG, "Removing temporary directory: %s\n", tmpDir) os.RemoveAll(tmpDir) diff --git a/internal/pkg/util/util.go b/internal/pkg/util/util.go index a25896c7..f1c537f5 100644 --- a/internal/pkg/util/util.go +++ b/internal/pkg/util/util.go @@ -11,7 +11,6 @@ import ( "path/filepath" "regexp" "time" - // "strings" ) @@ -90,8 +89,9 @@ func CopyFile(source string, dest string) error { //TODO: func CopyRecursive ... +func IsDir(path string) bool { + wwlog.Printf(wwlog.DEBUG, "Chcking if path exists as a directory: %s\n", path) -func IsDir(path string) (bool) { if path == "" { return false } @@ -101,7 +101,9 @@ func IsDir(path string) (bool) { return false } -func IsFile(path string) (bool) { +func IsFile(path string) bool { + wwlog.Printf(wwlog.DEBUG, "Chcking if path exists as a file: %s\n", path) + if path == "" { return false } @@ -112,7 +114,6 @@ func IsFile(path string) (bool) { return false } - func TaintCheck(pattern string, expr string) bool { if b, _ := regexp.MatchString(expr, pattern); b == true { return true @@ -148,7 +149,7 @@ func FindFiles(path string) []string { if IsDir(location) == true { wwlog.Printf(wwlog.DEBUG, "FindFiles() found directory: %s\n", location) - ret = append(ret, location +"/") + ret = append(ret, location+"/") } else { wwlog.Printf(wwlog.DEBUG, "FindFiles() found file: %s\n", location) ret = append(ret, location) @@ -163,7 +164,7 @@ func FindFiles(path string) []string { return ret } -func ExecInteractive(command string, a...string) error { +func ExecInteractive(command string, a ...string) error { wwlog.Printf(wwlog.DEBUG, "ExecInteractive(%s, %s)\n", command, a) c := exec.Command(command, a...) c.Stdin = os.Stdin @@ -173,8 +174,6 @@ func ExecInteractive(command string, a...string) error { return err } - - func ShaSumFile(file string) (string, error) { var ret string @@ -192,7 +191,6 @@ func ShaSumFile(file string) (string, error) { return fmt.Sprintf("%x", h.Sum(nil)), nil } - func SliceRemoveElement(array []string, remove string) []string { var ret []string @@ -225,4 +223,4 @@ func SliceAddUniqueElement(array []string, add string) []string { } return ret -} \ No newline at end of file +} diff --git a/internal/pkg/vnfs/docker.go b/internal/pkg/vnfs/docker.go index e46abf81..a060c406 100644 --- a/internal/pkg/vnfs/docker.go +++ b/internal/pkg/vnfs/docker.go @@ -10,10 +10,8 @@ import ( "path" ) - func BuildDocker(vnfs VnfsObject, buildForce bool) { wwlog.Printf(wwlog.VERBOSE, "Building OCI Container: %s\n", vnfs.Source) - config := config.New() OciCacheDir := config.LocalStateDir + "/oci" VnfsHashDir := config.LocalStateDir + "/oci/vnfs" @@ -73,12 +71,12 @@ func BuildDocker(vnfs VnfsObject, buildForce bool) { // Setup links from OCI image to provision path _ = os.Remove(vnfs.Image + "-link") - err = os.Symlink(hashDestination, vnfs.Image + "-link") + err = os.Symlink(hashDestination, vnfs.Image+"-link") if err != nil { wwlog.Printf(wwlog.ERROR, "Could not create symlink for Image: %s\n", err) os.Exit(1) } - err = os.Rename(vnfs.Image + "-link", vnfs.Image) + err = os.Rename(vnfs.Image+"-link", vnfs.Image) if err != nil { wwlog.Printf(wwlog.ERROR, "Could not rename link: %s\n", err) os.Exit(1) @@ -86,20 +84,18 @@ func BuildDocker(vnfs VnfsObject, buildForce bool) { // Setup links from OCI rootfs to chroot path _ = os.Remove(vnfs.Chroot + "-link") - err = os.Symlink(sourcePath, vnfs.Chroot + "-link") + err = os.Symlink(sourcePath, vnfs.Chroot+"-link") if err != nil { wwlog.Printf(wwlog.ERROR, "Could not create symlink for Chroot: %s\n", err) os.Exit(1) } - err = os.Rename(vnfs.Chroot + "-link", vnfs.Chroot) + err = os.Rename(vnfs.Chroot+"-link", vnfs.Chroot) if err != nil { wwlog.Printf(wwlog.ERROR, "Could not rename link: %s\n", err) os.Exit(1) } - wwlog.Printf(wwlog.INFO, "%-35s: Done\n", vnfs.Source) return } - diff --git a/internal/pkg/vnfs/vnfs.go b/internal/pkg/vnfs/vnfs.go index 5bcf49f4..32454fb9 100644 --- a/internal/pkg/vnfs/vnfs.go +++ b/internal/pkg/vnfs/vnfs.go @@ -13,15 +13,14 @@ import ( ) type VnfsObject struct { - Name string + Name string Source string Chroot string - Image string + Image string Config string } -func Load (name string) (VnfsObject, error) { - config := config.New() +func Load(name string) (VnfsObject, error) { var ret VnfsObject if name == "" { @@ -68,7 +67,6 @@ func CleanName(source string) string { func New(source string) (VnfsObject, error) { var ret VnfsObject - config := config.New() if source == "" { wwlog.Printf(wwlog.DEBUG, "Called vnfs.Load() without a name, returning error\n") @@ -122,11 +120,6 @@ func (self *VnfsObject) SaveConfig() error { return nil } - - - - - func Build(name string, force bool) error { vnfs, err := New(name) @@ -154,12 +147,6 @@ func Build(name string, force bool) error { return nil } - - - - - - func (self *VnfsObject) Nameold() string { if self.Source == "" { return "" @@ -183,4 +170,4 @@ func NameClean1(SourcePath string) string { uri := strings.Split(SourcePath, "://") return strings.ReplaceAll(uri[0]+":"+uri[1], "/", "_") -} \ No newline at end of file +} diff --git a/internal/pkg/warewulfconf/constructors.go b/internal/pkg/warewulfconf/constructors.go new file mode 100644 index 00000000..93bce4d8 --- /dev/null +++ b/internal/pkg/warewulfconf/constructors.go @@ -0,0 +1,33 @@ +package warewulfconf + +import ( + "fmt" + "github.com/hpcng/warewulf/internal/pkg/wwlog" + "gopkg.in/yaml.v2" + "io/ioutil" +) + +func New() (ControllerConf, error) { + var ret ControllerConf + + wwlog.Printf(wwlog.DEBUG, "Opening Warewulf configuration file: %s\n", ConfigFile) + data, err := ioutil.ReadFile(ConfigFile) + if err != nil { + fmt.Printf("error reading node configuration file\n") + return ret, err + } + + wwlog.Printf(wwlog.DEBUG, "Unmarshaling the Warewulf configuration\n") + err = yaml.Unmarshal(data, &ret) + if err != nil { + return ret, err + } + + if ret.Warewulf.Port == 0 { + ret.Warewulf.Port = 9873 + } + + wwlog.Printf(wwlog.DEBUG, "Returning node object\n") + + return ret, nil +} diff --git a/internal/pkg/warewulfconf/datastructure.go b/internal/pkg/warewulfconf/datastructure.go new file mode 100644 index 00000000..ca5c2cda --- /dev/null +++ b/internal/pkg/warewulfconf/datastructure.go @@ -0,0 +1,59 @@ +package warewulfconf + +import ( + "github.com/hpcng/warewulf/internal/pkg/util" + "github.com/hpcng/warewulf/internal/pkg/wwlog" + "os" +) + +const ConfigFile = "/etc/warewulf/warewulf.conf" + +type ControllerConf struct { + Comment string `yaml:"comment"` + Ipaddr string `yaml:"ipaddr"` + Netmask string `yaml:"netmask,omitempty"` + Fqdn string `yaml:"fqdn,omitempty"` + Warewulf *WarewulfConf `yaml:"warewulf"` + Dhcp *DhcpConf `yaml:"dhcp"` + Tftp *TftpConf `yaml:"tftp"` + Nfs *NfsConf `yaml:"nfs"` +} + +type WarewulfConf struct { + Port int `yaml:"port,omitempty"` + Secure bool `yaml:"secure,omitempty"` + Enable string `yaml:"enable command,omitempty"` + Restart string `yaml:"restart command,omitempty"` +} + +type DhcpConf struct { + Enabled bool `yaml:"enabled"` + Template string `yaml:"template,omitempty"` + RangeStart string `yaml:"range start,omitempty"` + RangeEnd string `yaml:"range end,omitempty"` + ConfigFile string `yaml:"config file,omitempty"` + Enable string `yaml:"enable command,omitempty"` + Restart string `yaml:"restart command,omitempty"` +} + +type TftpConf struct { + Enabled bool `yaml:"enabled"` + Root string `yaml:"root,omitempty"` + Enable string `yaml:"enable command,omitempty"` + Restart string `yaml:"restart command,omitempty"` +} + +type NfsConf struct { + Enabled bool `yaml:"enabled"` + Exports []string `yaml:"exports,omitempty"` + Enable string `yaml:"enable command,omitempty"` + Restart string `yaml:"restart command,omitempty"` +} + +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) + } +} diff --git a/internal/pkg/warewulfconf/modifiers.go b/internal/pkg/warewulfconf/modifiers.go new file mode 100644 index 00000000..f50e329e --- /dev/null +++ b/internal/pkg/warewulfconf/modifiers.go @@ -0,0 +1,30 @@ +package warewulfconf + +import ( + "github.com/hpcng/warewulf/internal/pkg/wwlog" + "gopkg.in/yaml.v2" + "os" +) + +func (self *ControllerConf) Persist() error { + + out, err := yaml.Marshal(self) + if err != nil { + return err + } + + file, err := os.OpenFile(ConfigFile, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) + if err != nil { + wwlog.Printf(wwlog.ERROR, "%s\n", err) + os.Exit(1) + } + + defer file.Close() + + _, err = file.WriteString(string(out)) + if err != nil { + return err + } + + return nil +} diff --git a/overlays/runtime/default/etc/hosts.ww b/overlays/runtime/default/etc/hosts.ww index e1549f3f..8d6e22e8 100644 --- a/overlays/runtime/default/etc/hosts.ww +++ b/overlays/runtime/default/etc/hosts.ww @@ -3,10 +3,10 @@ {{range $node := $.AllNodes}} -# Entry for {{$node.Fqdn}} +# Entry for {{$node.Id}} {{- range $devname, $netdev := $node.NetDevs}} {{- if $netdev.Default}} -{{$netdev.Ipaddr}} {{$node.Fqdn}} +{{$netdev.Ipaddr}} {{$node.Id}} {{- else}} {{$netdev.Ipaddr}} {{$node.Fqdn}}-{{$devname}} {{- end}} diff --git a/overlays/system/default/etc/hostname.ww b/overlays/system/default/etc/hostname.ww index c6b7c67e..5bbffc40 100644 --- a/overlays/system/default/etc/hostname.ww +++ b/overlays/system/default/etc/hostname.ww @@ -1 +1 @@ -{{$.Self.Fqdn}} +{{$.Self.Id}} diff --git a/overlays/system/default/etc/sysconfig/network.ww b/overlays/system/default/etc/sysconfig/network.ww index c2ce4854..bcbd324d 100644 --- a/overlays/system/default/etc/sysconfig/network.ww +++ b/overlays/system/default/etc/sysconfig/network.ww @@ -1,2 +1,2 @@ NETWORKING=yes -HOSTNAME={{$.Self.Fqdn}} +HOSTNAME={{$.Self.Id}}