Merge pull request #495 from mslacken/reflections-cmdline

Use reflection for node and profile manipulation
This commit is contained in:
Christian Goll
2022-09-12 16:36:39 +02:00
committed by GitHub
32 changed files with 2000 additions and 3158 deletions

View File

@@ -376,4 +376,4 @@ func getSystemContext() (sCtx *types.SystemContext, err error) {
}
return sCtx, nil
}
}

View File

@@ -163,7 +163,8 @@ func ContainerImport(cip *wwapiv1.ContainerImportParameter) (containerName strin
wwlog.Error(err.Error())
return
}
} else if strings.HasPrefix(cip.Source, "docker://") || strings.HasPrefix(cip.Source, "docker-daemon://") {
} else if strings.HasPrefix(cip.Source, "docker://") || strings.HasPrefix(cip.Source, "docker-daemon://") ||
strings.HasPrefix(cip.Source, "file://") || util.IsFile(cip.Source) {
var sCtx *types.SystemContext
sCtx, err = getSystemContext()
if err != nil {

View File

@@ -0,0 +1,178 @@
package apinode
import (
"fmt"
"reflect"
"sort"
"strings"
"github.com/hpcng/warewulf/internal/pkg/api/routes/wwapiv1"
"github.com/hpcng/warewulf/internal/pkg/node"
"github.com/hpcng/warewulf/pkg/hostlist"
)
/*
NodeList lists all to none of the nodes managed by Warewulf. Returns
a formated string slice, with each line as separate string
*/
func NodeList(nodeGet *wwapiv1.GetNodeList) (nodeList wwapiv1.NodeList, err error) {
// nil is okay for nodeNames
nodeDB, err := node.New()
if err != nil {
return
}
nodes, err := nodeDB.FindAllNodes()
if err != nil {
return
}
nodeGet.Nodes = hostlist.Expand(nodeGet.Nodes)
sort.Strings(nodeGet.Nodes)
if nodeGet.Type == wwapiv1.GetNodeList_Simple {
nodeList.Output = append(nodeList.Output,
fmt.Sprintf("%-22s %-26s %s", "NODE NAME", "PROFILES", "NETWORK"))
nodeList.Output = append(nodeList.Output, (strings.Repeat("=", 80)))
for _, n := range node.FilterByName(nodes, nodeGet.Nodes) {
var netNames []string
for k := range n.NetDevs {
netNames = append(netNames, k)
}
nodeList.Output = append(nodeList.Output,
fmt.Sprintf("%-22s %-26s %s", n.Id.Print(), n.Profiles.Print(), strings.Join(netNames, ", ")))
}
} else if nodeGet.Type == wwapiv1.GetNodeList_Network {
nodeList.Output = append(nodeList.Output,
fmt.Sprintf("%-22s %-8s %-18s %-15s %-15s %-15s", "NODE NAME", "NAME", "HWADDR", "IPADDR", "GATEWAY", "DEVICE"),
strings.Repeat("=", 90))
for _, n := range node.FilterByName(nodes, nodeGet.Nodes) {
if len(n.NetDevs) > 0 {
for name := range n.NetDevs {
nodeList.Output = append(nodeList.Output,
fmt.Sprintf("%-22s %-8s %-18s %-15s %-15s %-15s", n.Id.Print(), name,
n.NetDevs[name].Hwaddr.Print(),
n.NetDevs[name].Ipaddr.Print(),
n.NetDevs[name].Gateway.Print(),
n.NetDevs[name].Device.Print()))
}
} else {
fmt.Printf("%-22s %-6s %-18s %-15s %-15s", n.Id.Print(), "--", "--", "--", "--")
}
}
} else if nodeGet.Type == wwapiv1.GetNodeList_Ipmi {
nodeList.Output = append(nodeList.Output,
fmt.Sprintf("%-22s %-16s %-10s %-20s %-14s", "NODE NAME", "IPMI IPADDR", "IPMI PORT", "IPMI USERNAME", "IPMI INTERFACE"),
strings.Repeat("=", 98))
for _, n := range node.FilterByName(nodes, nodeGet.Nodes) {
nodeList.Output = append(nodeList.Output,
fmt.Sprintf("%-22s %-16s %-10s %-20s %-14s", n.Id.Print(),
n.Ipmi.Ipaddr.Print(),
n.Ipmi.Port.Print(),
n.Ipmi.UserName.Print(),
n.Ipmi.Interface.Print()))
}
} else if nodeGet.Type == wwapiv1.GetNodeList_Long {
nodeList.Output = append(nodeList.Output,
fmt.Sprintf("%-22s %-16s %-16s %s", "NODE NAME", "KERNEL OVERRIDE", "CONTAINER", "OVERLAYS (S/R)"),
strings.Repeat("=", 85))
for _, n := range node.FilterByName(nodes, nodeGet.Nodes) {
nodeList.Output = append(nodeList.Output,
fmt.Sprintf("%-22s %-16s %-16s %s", n.Id.Print(),
n.Kernel.Override.Print(),
n.ContainerName.Print(),
n.SystemOverlay.Print()+"/"+n.RuntimeOverlay.Print()))
}
} else if nodeGet.Type == wwapiv1.GetNodeList_All {
for _, n := range node.FilterByName(nodes, nodeGet.Nodes) {
nodeList.Output = append(nodeList.Output,
fmt.Sprintf("%-20s %-18s %-12s %s", "NODE", "FIELD", "PROFILE", "VALUE"), strings.Repeat("=", 85))
nType := reflect.TypeOf(n)
nVal := reflect.ValueOf(n)
nConfType := reflect.TypeOf(node.NodeConf{})
for i := 0; i < nType.NumField(); i++ {
var fieldName, fieldSource, fieldVal string
nConfField, ok := nConfType.FieldByName(nType.Field(i).Name)
if ok {
fieldName = nConfField.Tag.Get("lopt")
} else {
fieldName = nType.Field(i).Name
}
if nType.Field(i).Type == reflect.TypeOf(node.Entry{}) {
entr := nVal.Field(i).Interface().(node.Entry)
fieldSource = entr.Source()
fieldVal = entr.Print()
nodeList.Output = append(nodeList.Output,
fmt.Sprintf("%-20s %-18s %-12s %s", n.Id.Print(), fieldName, fieldSource, fieldVal))
} else if nType.Field(i).Type == reflect.TypeOf(map[string]*node.Entry{}) {
entrMap := nVal.Field(i).Interface().(map[string]*node.Entry)
for key, val := range entrMap {
nodeList.Output = append(nodeList.Output,
fmt.Sprintf("%-20s %-18s %-12s %s", n.Id.Print(), key, val.Source(), val.Print()))
}
} else if nType.Field(i).Type == reflect.TypeOf(map[string]*node.NetDevEntry{}) {
netDevs := nVal.Field(i).Interface().(map[string]*node.NetDevEntry)
for netName, netWork := range netDevs {
netInfoType := reflect.TypeOf(*netWork)
netInfoVal := reflect.ValueOf(*netWork)
netConfType := reflect.TypeOf(node.NetDevs{})
for j := 0; j < netInfoType.NumField(); j++ {
netConfField, ok := netConfType.FieldByName(netInfoType.Field(j).Name)
if ok {
fieldName = netName + ":" + netConfField.Tag.Get("lopt")
} else {
fieldName = netName + ":" + netInfoType.Field(j).Name
}
if netInfoType.Field(j).Type == reflect.TypeOf(node.Entry{}) {
entr := netInfoVal.Field(j).Interface().(node.Entry)
fieldSource = entr.Source()
fieldVal = entr.Print()
// only print fields with lopt
if netConfField.Tag.Get("lopt") != "" {
nodeList.Output = append(nodeList.Output,
fmt.Sprintf("%-20s %-18s %-12s %s", n.Id.Print(), fieldName, fieldSource, fieldVal))
}
} else if netInfoType.Field(j).Type == reflect.TypeOf(map[string]*node.Entry{}) {
for key, val := range netInfoVal.Field(j).Interface().(map[string]*node.Entry) {
keyfieldName := fieldName + ":" + key
fieldSource = val.Source()
fieldVal = val.Print()
nodeList.Output = append(nodeList.Output,
fmt.Sprintf("%-20s %-18s %-12s %s", n.Id.Print(), keyfieldName, fieldSource, fieldVal))
}
}
}
}
} else if nType.Field(i).Type.Kind() == reflect.Ptr {
nestInfoType := reflect.TypeOf(nVal.Field(i).Interface())
nestInfoVal := reflect.ValueOf(nVal.Field(i).Interface())
// nestConfType := reflect.TypeOf(nConfField.Type.Elem().FieldByName())
for j := 0; j < nestInfoType.Elem().NumField(); j++ {
nestConfField, ok := nConfField.Type.Elem().FieldByName(nestInfoType.Elem().Field(j).Name)
if ok {
fieldName = nestConfField.Tag.Get("lopt")
} else {
fieldName = nestInfoType.Elem().Field(j).Name
}
if nestInfoType.Elem().Field(j).Type == reflect.TypeOf(node.Entry{}) {
entr := nestInfoVal.Elem().Field(j).Interface().(node.Entry)
fieldSource = entr.Source()
fieldVal = entr.Print()
nodeList.Output = append(nodeList.Output,
fmt.Sprintf("%-20s %-18s %-12s %s", n.Id.Print(), fieldName, fieldSource, fieldVal))
} else if nestInfoType.Elem().Field(j).Type == reflect.TypeOf(map[string]*node.Entry{}) {
for key, val := range nestInfoVal.Elem().Field(j).Interface().(map[string]*node.Entry) {
fieldName = fieldName + ":" + key
fieldSource = val.Source()
fieldVal = val.Print()
nodeList.Output = append(nodeList.Output,
fmt.Sprintf("%-20s %-18s %-12s %s", n.Id.Print(), fieldName, fieldSource, fieldVal))
}
}
}
}
}
}
}
return
}

View File

@@ -0,0 +1,79 @@
package apinode
import (
"fmt"
"reflect"
"strings"
"github.com/hpcng/warewulf/internal/pkg/api/routes/wwapiv1"
"github.com/hpcng/warewulf/internal/pkg/node"
)
/*
Get the all the fields of a NodeInfo, keys are the lopt of NodeConf.
func GetFields(n interface{}) map[string]*wwapiv1.NodeField {
return getFieldsOf(n, node.NodeConf{})
}
*/
func GetFields(n interface{}) map[string]*wwapiv1.NodeField {
nodeType := reflect.TypeOf(n)
nodeVal := reflect.ValueOf(n)
fieldMap := make(map[string]*wwapiv1.NodeField)
for i := 0; i < nodeType.NumField(); i++ {
switch nodeType.Field(i).Type {
case reflect.TypeOf(node.Entry{}):
var myField wwapiv1.NodeField
entry := nodeVal.Field(i).Interface().(node.Entry)
myField.Source = entry.Source()
myField.Value = entry.Get()
myField.Print = entry.Print()
fieldMap[nodeType.Field(i).Name] = &myField
case reflect.TypeOf([]string{}):
var myField wwapiv1.NodeField
entry := nodeVal.Field(i).Interface().([]string)
if len(entry) == 0 {
myField.Value = node.NoValue
myField.Print = node.NoValue
myField.Source = node.NoValue
} else {
myField.Value = strings.Join(entry, ",")
myField.Print = strings.Join(entry, ",")
myField.Source = node.NoValue
fieldMap[nodeType.Field(i).Name] = &myField
}
case reflect.TypeOf((*node.KernelEntry)(nil)):
entry := nodeVal.Field(i).Elem().Interface().(node.KernelEntry)
kernelMap := GetFields(entry)
for key, val := range kernelMap {
fieldMap["KernelEntry:"+key] = val
}
case reflect.TypeOf((*node.IpmiEntry)(nil)):
entry := nodeVal.Field(i).Elem().Interface().(node.IpmiEntry)
kernelMap := GetFields(entry)
for key, val := range kernelMap {
fieldMap["IpmiEntry:"+key] = val
}
case reflect.TypeOf(map[string]*node.Entry(nil)):
keyMap := nodeVal.Field(i).Interface().(map[string]*node.Entry)
for key, entr := range keyMap {
var myField wwapiv1.NodeField
myField.Source = entr.Source()
myField.Value = entr.Get()
myField.Print = entr.Print()
fieldMap["key:"+key] = &myField
}
case reflect.TypeOf(map[string]*node.NetDevEntry(nil)):
netMap := nodeVal.Field(i).Interface().(map[string]*node.NetDevEntry)
for net, netdev := range netMap {
netMapEntr := GetFields(*netdev)
for key, val := range netMapEntr {
fieldMap["NetDevEntry:"+net+":"+key] = val
}
}
default:
panic(fmt.Sprintf("Can't handle: %s\n", nodeType.Field(i).Type))
}
}
return fieldMap
}

View File

@@ -1,13 +1,10 @@
package node
package apinode
import (
"encoding/json"
"fmt"
"net"
"net/http"
"os"
"strconv"
"strings"
"github.com/hpcng/warewulf/internal/pkg/api/routes/wwapiv1"
"github.com/hpcng/warewulf/internal/pkg/node"
@@ -16,6 +13,7 @@ import (
"github.com/hpcng/warewulf/internal/pkg/wwlog"
"github.com/hpcng/warewulf/pkg/hostlist"
"github.com/pkg/errors"
"gopkg.in/yaml.v2"
"github.com/hpcng/warewulf/internal/pkg/warewulfd"
)
@@ -27,13 +25,17 @@ func NodeAdd(nap *wwapiv1.NodeAddParameter) (err error) {
return fmt.Errorf("NodeAddParameter is nil")
}
var count uint
nodeDB, err := node.New()
if err != nil {
return errors.Wrap(err, "failed to open node database")
}
node_args := hostlist.Expand(nap.NodeNames)
var nodeConf node.NodeConf
err = yaml.Unmarshal([]byte(nap.NodeConfYaml), &nodeConf)
if err != nil {
return errors.Wrap(err, "Failed to decode nodeConf")
}
for _, a := range node_args {
var n node.NodeInfo
@@ -42,133 +44,30 @@ func NodeAdd(nap *wwapiv1.NodeAddParameter) (err error) {
return errors.Wrap(err, "failed to add node")
}
wwlog.Printf(wwlog.INFO, "Added node: %s\n", a)
if nap.Cluster != "" {
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting cluster name to: %s\n", n.Id.Get(), nap.Cluster)
n.ClusterName.Set(nap.Cluster)
err = nodeDB.NodeUpdate(n)
if err != nil {
return errors.Wrap(err, "failed to update node")
}
var netName string
for netName = range nodeConf.NetDevs {
// as map should only have key this should give is the first and
// only key
}
// setting node from the received yaml
n.SetFrom(&nodeConf)
if netName != "" && nodeConf.NetDevs[netName].Ipaddr != "" {
// if more nodes are added increment IPv4 address
nodeConf.NetDevs[netName].Ipaddr = util.IncrementIPv4(nodeConf.NetDevs[netName].Ipaddr, 1)
if nap.Netdev != "" {
err = checkNetNameRequired(nap.Netname)
if err != nil {
return
}
if _, ok := n.NetDevs[nap.Netname]; !ok {
var netdev node.NetDevEntry
n.NetDevs[nap.Netname] = &netdev
}
wwlog.Printf(wwlog.VERBOSE, "Node: %s:%s, Setting Device to: %s\n", n.Id.Get(), nap.Netname, nap.Netdev)
n.NetDevs[nap.Netname].Device.Set(nap.Netdev)
n.NetDevs[nap.Netname].OnBoot.SetB(true)
wwlog.Verbose("Incremented IP addr to %s\n", nodeConf.NetDevs[netName].Ipaddr)
}
if nap.Ipaddr != "" {
err = checkNetNameRequired(nap.Netname)
if err != nil {
return
}
NewIpaddr := util.IncrementIPv4(nap.Ipaddr, count)
if _, ok := n.NetDevs[nap.Netname]; !ok {
var netdev node.NetDevEntry
n.NetDevs[nap.Netname] = &netdev
}
wwlog.Printf(wwlog.VERBOSE, "Node: %s:%s, Setting Ipaddr to: %s\n", n.Id.Get(), nap.Netname, NewIpaddr)
n.NetDevs[nap.Netname].Ipaddr.Set(NewIpaddr)
n.NetDevs[nap.Netname].OnBoot.SetB(true)
if nodeConf.Ipmi != nil && nodeConf.Ipmi.Ipaddr != "" {
// if more nodes are added increment IPv4 address
nodeConf.Ipmi.Ipaddr = util.IncrementIPv4(nodeConf.Ipmi.Ipaddr, 1)
wwlog.Verbose("Incremented IP addr to %s\n", nodeConf.Ipmi.Ipaddr)
}
if nap.Netmask != "" {
err = checkNetNameRequired(nap.Netname)
if err != nil {
return
}
if _, ok := n.NetDevs[nap.Netname]; !ok {
return errors.New("network device does not exist: " + nap.Netname)
}
wwlog.Printf(wwlog.VERBOSE, "Node: %s:%s, Setting netmask to: %s\n", n.Id.Get(), nap.Netname, nap.Netmask)
n.NetDevs[nap.Netname].Netmask.Set(nap.Netmask)
}
if nap.Gateway != "" {
err = checkNetNameRequired(nap.Netname)
if err != nil {
return
}
if _, ok := n.NetDevs[nap.Netname]; !ok {
return errors.New("network device does not exist: " + nap.Netname)
}
wwlog.Printf(wwlog.VERBOSE, "Node: %s:%s, Setting gateway to: %s\n", n.Id.Get(), nap.Netname, nap.Gateway)
n.NetDevs[nap.Netname].Gateway.Set(nap.Gateway)
}
if nap.Hwaddr != "" {
if nap.Netname == "" {
return errors.New("you must include the '--netname' option")
}
if _, ok := n.NetDevs[nap.Netname]; !ok {
return errors.New("network device does not exist: " + nap.Netname)
}
wwlog.Printf(wwlog.VERBOSE, "Node: %s:%s, Setting HW address to: %s\n", n.Id.Get(), nap.Netname, nap.Hwaddr)
n.NetDevs[nap.Netname].Hwaddr.Set(nap.Hwaddr)
n.NetDevs[nap.Netname].OnBoot.SetB(true)
}
if nap.Type != "" {
if nap.Netname == "" {
return errors.New("you must include the '--netname' option")
}
if _, ok := n.NetDevs[nap.Netname]; !ok {
return errors.New("network device does not exist: " + nap.Netname)
}
wwlog.Printf(wwlog.VERBOSE, "Node: %s:%s, Setting Type to: %s\n", n.Id.Get(), nap.Netname, nap.Type)
n.NetDevs[nap.Netname].Type.Set(nap.Type)
}
if nap.Ipaddr6 != "" {
if nap.Netname == "" {
return errors.New("you must include the '--netname' option")
}
if _, ok := n.NetDevs[nap.Netname]; !ok {
return errors.New("network device does not exist: " + nap.Netname)
}
// just check if address is a valid ipv6 CIDR address
if _, _, err := net.ParseCIDR(nap.Ipaddr6); err != nil {
return errors.Errorf("%s is not a valid ipv6 address in CIDR notation", nap.Ipaddr6)
}
}
if nap.Discoverable {
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting node to discoverable\n", n.Id.Get())
n.Discoverable.SetB(true)
}
err = nodeDB.NodeUpdate(n)
if err != nil {
return errors.Wrap(err, "failed to update nodedb")
}
count++
} // end for
}
err = nodeDB.Persist()
if err != nil {
@@ -263,208 +162,6 @@ func NodeDeleteParameterCheck(ndp *wwapiv1.NodeDeleteParameter, console bool) (n
return
}
// NodeList lists all to none of the nodes managed by Warewulf.
func NodeList(nodeNames []string) (nodeInfo []*wwapiv1.NodeInfo, err error) {
// nil is okay for nodeNames
nodeDB, err := node.New()
if err != nil {
return
}
nodes, err := nodeDB.FindAllNodes()
if err != nil {
return
}
nodeNames = hostlist.Expand(nodeNames)
// Translate to the protobuf structure so wwapiv1 can use this across the wire.
// This is the same logic as was in wwctl.
for _, node := range node.FilterByName(nodes, nodeNames) {
var ni wwapiv1.NodeInfo
ni.Id = &wwapiv1.NodeField{
Source: node.Id.Source(),
Value: node.Id.Get(),
Print: node.Id.Print(),
}
ni.Comment = &wwapiv1.NodeField{
Source: node.Comment.Source(),
Value: node.Comment.Get(),
Print: node.Comment.Print(),
}
ni.Cluster = &wwapiv1.NodeField{
Source: node.ClusterName.Source(),
Value: node.ClusterName.Get(),
Print: node.ClusterName.Print(),
}
ni.Profiles = node.Profiles
ni.Discoverable = &wwapiv1.NodeField{
Source: node.Discoverable.Source(),
Value: strconv.FormatBool(node.Discoverable.GetB()),
Print: node.Discoverable.PrintB(),
}
ni.Container = &wwapiv1.NodeField{
Source: node.ContainerName.Source(),
Value: node.ContainerName.Get(),
Print: node.ContainerName.Print(),
}
ni.KernelOverride = &wwapiv1.NodeField{
Source: node.Kernel.Override.Source(),
Value: node.Kernel.Override.Get(),
Print: node.Kernel.Override.Print(),
}
ni.KernelArgs = &wwapiv1.NodeField{
Source: node.Kernel.Args.Source(),
Value: node.Kernel.Args.Get(),
Print: node.Kernel.Args.Print(),
}
ni.SystemOverlay = &wwapiv1.NodeField{
Source: node.SystemOverlay.Source(),
Value: node.SystemOverlay.Get(),
Print: node.SystemOverlay.Print(),
}
ni.RuntimeOverlay = &wwapiv1.NodeField{
Source: node.RuntimeOverlay.Source(),
Value: node.RuntimeOverlay.Get(),
Print: node.RuntimeOverlay.Print(),
}
ni.Ipxe = &wwapiv1.NodeField{
Source: node.Ipxe.Source(),
Value: node.Ipxe.Get(),
Print: node.Ipxe.Print(),
}
ni.Init = &wwapiv1.NodeField{
Source: node.Init.Source(),
Value: node.Init.Get(),
Print: node.Init.Print(),
}
ni.Root = &wwapiv1.NodeField{
Source: node.Root.Source(),
Value: node.Root.Get(),
Print: node.Root.Print(),
}
ni.AssetKey = &wwapiv1.NodeField{
Source: node.AssetKey.Source(),
Value: node.AssetKey.Get(),
Print: node.AssetKey.Print(),
}
ni.IpmiIpaddr = &wwapiv1.NodeField{
Source: node.Ipmi.Ipaddr.Source(),
Value: node.Ipmi.Ipaddr.Get(),
Print: node.Ipmi.Ipaddr.Print(),
}
ni.IpmiNetmask = &wwapiv1.NodeField{
Source: node.Ipmi.Netmask.Source(),
Value: node.Ipmi.Netmask.Get(),
Print: node.Ipmi.Netmask.Print(),
}
ni.IpmiPort = &wwapiv1.NodeField{
Source: node.Ipmi.Port.Source(),
Value: node.Ipmi.Port.Get(),
Print: node.Ipmi.Port.Print(),
}
ni.IpmiGateway = &wwapiv1.NodeField{
Source: node.Ipmi.Gateway.Source(),
Value: node.Ipmi.Gateway.Get(),
Print: node.Ipmi.Gateway.Print(),
}
ni.IpmiUserName = &wwapiv1.NodeField{
Source: node.Ipmi.UserName.Source(),
Value: node.Ipmi.UserName.Get(),
Print: node.Ipmi.UserName.Print(),
}
ni.IpmiPassword = &wwapiv1.NodeField{
Source: node.Ipmi.Password.Source(),
Value: node.Ipmi.Password.Get(),
Print: node.Ipmi.Password.Print(), // TODO: Password was removed from pprinted output, at least in some places.
}
ni.IpmiInterface = &wwapiv1.NodeField{
Source: node.Ipmi.Interface.Source(),
Value: node.Ipmi.Interface.Get(),
Print: node.Ipmi.Interface.Print(),
}
for keyname, keyvalue := range node.Tags {
ni.Tags[keyname].Source = keyvalue.Source()
ni.Tags[keyname].Value = keyvalue.Get()
ni.Tags[keyname].Print = keyvalue.Print()
}
ni.NetDevs = map[string]*wwapiv1.NetDev{}
for name, netdev := range node.NetDevs {
ni.NetDevs[name] = &wwapiv1.NetDev{
Device: &wwapiv1.NodeField{
Source: netdev.Device.Source(),
Value: netdev.Device.Get(),
Print: netdev.Device.Print(),
},
Hwaddr: &wwapiv1.NodeField{
Source: netdev.Hwaddr.Source(),
Value: netdev.Hwaddr.Get(),
Print: netdev.Hwaddr.Print(),
},
Ipaddr: &wwapiv1.NodeField{
Source: netdev.Ipaddr.Source(),
Value: netdev.Ipaddr.Get(),
Print: netdev.Ipaddr.Print(),
},
Netmask: &wwapiv1.NodeField{
Source: netdev.Netmask.Source(),
Value: netdev.Netmask.Get(),
Print: netdev.Netmask.Print(),
},
Gateway: &wwapiv1.NodeField{
Source: netdev.Gateway.Source(),
Value: netdev.Gateway.Get(),
Print: netdev.Gateway.Print(),
},
Type: &wwapiv1.NodeField{
Source: netdev.Type.Source(),
Value: netdev.Type.Get(),
Print: netdev.Type.Print(),
},
Onboot: &wwapiv1.NodeField{
Source: netdev.OnBoot.Source(),
Value: strconv.FormatBool(netdev.OnBoot.GetB()),
Print: netdev.OnBoot.PrintB(),
},
Primary: &wwapiv1.NodeField{
Source: netdev.Primary.Source(),
Value: strconv.FormatBool(netdev.Primary.GetB()),
Print: netdev.Primary.PrintB(),
},
}
}
nodeInfo = append(nodeInfo, &ni)
}
return
}
// NodeSet is the wwapiv1 implmentation for updating node fields.
func NodeSet(set *wwapiv1.NodeSetParameter) (err error) {
@@ -477,7 +174,7 @@ func NodeSet(set *wwapiv1.NodeSetParameter) (err error) {
if err != nil {
return
}
return nodeDbSave(&nodeDB)
return DbSave(&nodeDB)
}
// NodeSetParameterCheck does error checking on NodeSetParameter.
@@ -487,7 +184,7 @@ func NodeSet(set *wwapiv1.NodeSetParameter) (err error) {
func NodeSetParameterCheck(set *wwapiv1.NodeSetParameter, console bool) (nodeDB node.NodeYaml, nodeCount uint, err error) {
if set == nil {
err = fmt.Errorf("Node set parameter is nil")
err = fmt.Errorf("node set parameter is nil")
if console {
fmt.Printf("%v\n", err)
return
@@ -495,7 +192,7 @@ func NodeSetParameterCheck(set *wwapiv1.NodeSetParameter, console bool) (nodeDB
}
if set.NodeNames == nil {
err = fmt.Errorf("Node set parameter: NodeNames is nil")
err = fmt.Errorf("node set parameter: NodeNames is nil")
if console {
fmt.Printf("%v\n", err)
return
@@ -533,336 +230,36 @@ func NodeSetParameterCheck(set *wwapiv1.NodeSetParameter, console bool) (nodeDB
for _, n := range nodes {
wwlog.Printf(wwlog.VERBOSE, "Evaluating node: %s\n", n.Id.Get())
if set.Comment != "" {
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting comment to: %s\n", n.Id.Get(), set.Comment)
n.Comment.Set(set.Comment)
var nodeConf node.NodeConf
err = yaml.Unmarshal([]byte(set.NodeConfYaml), &nodeConf)
if err != nil {
wwlog.Printf(wwlog.ERROR, fmt.Sprintf("%v\n", err.Error()))
return
}
if set.Container != "" {
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting container name to: %s\n", n.Id.Get(), set.Container)
n.ContainerName.Set(set.Container)
}
if set.Init != "" {
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting init command to: %s\n", n.Id.Get(), set.Init)
n.Init.Set(set.Init)
}
if set.Root != "" {
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting root to: %s\n", n.Id.Get(), set.Root)
n.Root.Set(set.Root)
}
if set.AssetKey != "" {
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting asset key to: %s\n", n.Id.Get(), set.AssetKey)
n.AssetKey.Set(set.AssetKey)
}
if set.KernelOverride != "" {
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting kernel override to: %s\n", n.Id.Get(), set.KernelOverride)
n.Kernel.Override.Set(set.KernelOverride)
}
if set.KernelArgs != "" {
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting kernel args to: %s\n", n.Id.Get(), set.KernelArgs)
n.Kernel.Args.Set(set.KernelArgs)
}
if set.Cluster != "" {
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting cluster name to: %s\n", n.Id.Get(), set.Cluster)
n.ClusterName.Set(set.Cluster)
}
if set.Ipxe != "" {
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting iPXE template to: %s\n", n.Id.Get(), set.Ipxe)
n.Ipxe.Set(set.Ipxe)
}
if len(set.RuntimeOverlay) != 0 {
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting runtime overlay to: %s\n", n.Id.Get(), set.RuntimeOverlay)
n.RuntimeOverlay.SetSlice(set.RuntimeOverlay)
}
if len(set.SystemOverlay) != 0 {
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting system overlay to: %s\n", n.Id.Get(), set.SystemOverlay)
n.SystemOverlay.SetSlice(set.SystemOverlay)
}
if set.IpmiIpaddr != "" {
newIpaddr := util.IncrementIPv4(set.IpmiIpaddr, nodeCount)
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting IPMI IP address to: %s\n", n.Id.Get(), newIpaddr)
n.Ipmi.Ipaddr.Set(newIpaddr)
}
if set.IpmiNetmask != "" {
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting IPMI netmask to: %s\n", n.Id.Get(), set.IpmiNetmask)
n.Ipmi.Netmask.Set(set.IpmiNetmask)
}
if set.IpmiPort != "" {
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting IPMI port to: %s\n", n.Id.Get(), set.IpmiPort)
n.Ipmi.Port.Set(set.IpmiPort)
}
if set.IpmiGateway != "" {
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting IPMI gateway to: %s\n", n.Id.Get(), set.IpmiGateway)
n.Ipmi.Gateway.Set(set.IpmiGateway)
}
if set.IpmiUsername != "" {
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting IPMI IP username to: %s\n", n.Id.Get(), set.IpmiUsername)
n.Ipmi.UserName.Set(set.IpmiUsername)
}
if set.IpmiPassword != "" {
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting IPMI IP password to: %s\n", n.Id.Get(), set.IpmiPassword)
n.Ipmi.Password.Set(set.IpmiPassword)
}
if set.IpmiInterface != "" {
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting IPMI IP interface to: %s\n", n.Id.Get(), set.IpmiInterface)
n.Ipmi.Interface.Set(set.IpmiInterface)
}
if set.IpmiWrite == "yes" || set.Onboot == "y" || set.Onboot == "1" || set.Onboot == "true" {
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting Ipmiwrite to %s\n", n.Id.Get(), set.IpmiWrite)
n.Ipmi.Write.SetB(true)
} else {
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting Ipmiwrite to %s\n", n.Id.Get(), set.IpmiWrite)
n.Ipmi.Write.SetB(false)
}
if set.Discoverable {
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting node to discoverable\n", n.Id.Get())
n.Discoverable.SetB(true)
}
if set.Undiscoverable {
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting node to undiscoverable\n", n.Id.Get())
n.Discoverable.SetB(false)
}
if set.Profile != "" {
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting profiles to: %s\n", n.Id.Get(), set.Profile)
n.Profiles = []string{set.Profile}
}
if len(set.ProfileAdd) > 0 {
for _, p := range set.ProfileAdd {
wwlog.Printf(wwlog.VERBOSE, "Node: %s, adding profile '%s'\n", n.Id.Get(), p)
n.Profiles = util.SliceAddUniqueElement(n.Profiles, p)
}
}
if len(set.ProfileDelete) > 0 {
for _, p := range set.ProfileDelete {
wwlog.Printf(wwlog.VERBOSE, "Node: %s, deleting profile '%s'\n", n.Id.Get(), p)
n.Profiles = util.SliceRemoveElement(n.Profiles, p)
}
}
if set.Netname != "" {
if _, ok := n.NetDevs[set.Netname]; !ok {
var nd node.NetDevEntry
nd.Tags = make(map[string]*node.Entry)
n.NetDevs[set.Netname] = &nd
if set.Netdev == "" {
n.NetDevs[set.Netname].Device.Set(set.Netname)
}
}
var def bool = true
// NOTE: This is overriding parameters passed in by the caller.
set.Onboot = "yes"
for _, n := range n.NetDevs {
if n.Primary.GetB() {
def = false
}
}
if def {
set.NetDefault = "yes"
}
}
if set.Netdev != "" {
err = checkNetNameRequired(set.Netname)
if err != nil {
return
}
wwlog.Printf(wwlog.VERBOSE, "Node: %s:%s, Setting net Device to: %s\n", n.Id.Get(), set.Netname, set.Netdev)
n.NetDevs[set.Netname].Device.Set(set.Netdev)
}
if set.Ipaddr != "" {
err = checkNetNameRequired(set.Netname)
if err != nil {
return
}
newIpaddr := util.IncrementIPv4(set.Ipaddr, nodeCount)
wwlog.Printf(wwlog.VERBOSE, "Node: %s:%s, Setting Ipaddr to: %s\n", n.Id.Get(), set.Netname, newIpaddr)
n.NetDevs[set.Netname].Ipaddr.Set(newIpaddr)
}
if set.Netmask != "" {
err = checkNetNameRequired(set.Netname)
if err != nil {
return
}
wwlog.Printf(wwlog.VERBOSE, "Node: %s:%s, Setting netmask to: %s\n", n.Id.Get(), set.Netname, set.Netmask)
n.NetDevs[set.Netname].Netmask.Set(set.Netmask)
}
if set.Gateway != "" {
err = checkNetNameRequired(set.Netname)
if err != nil {
return
}
wwlog.Printf(wwlog.VERBOSE, "Node: %s:%s, Setting gateway to: %s\n", n.Id.Get(), set.Netname, set.Gateway)
n.NetDevs[set.Netname].Gateway.Set(set.Gateway)
}
if set.Hwaddr != "" {
err = checkNetNameRequired(set.Netname)
if err != nil {
return
}
wwlog.Printf(wwlog.VERBOSE, "Node: %s:%s, Setting HW address to: %s\n", n.Id.Get(), set.Netname, set.Hwaddr)
n.NetDevs[set.Netname].Hwaddr.Set(strings.ToLower(set.Hwaddr))
}
if set.Type != "" {
err = checkNetNameRequired(set.Netname)
if err != nil {
return
}
wwlog.Printf(wwlog.VERBOSE, "Node: %s:%s, Setting Type %s\n", n.Id.Get(), set.Netname, set.Type)
n.NetDevs[set.Netname].Type.Set(set.Type)
}
if set.Onboot != "" {
err = checkNetNameRequired(set.Netname)
if err != nil {
return
}
if set.Onboot == "yes" || set.Onboot == "y" || set.Onboot == "1" || set.Onboot == "true" {
wwlog.Printf(wwlog.VERBOSE, "Node: %s:%s, Setting ONBOOT\n", n.Id.Get(), set.Netname)
n.NetDevs[set.Netname].OnBoot.SetB(true)
} else {
wwlog.Printf(wwlog.VERBOSE, "Node: %s:%s, Unsetting ONBOOT\n", n.Id.Get(), set.Netname)
n.NetDevs[set.Netname].OnBoot.SetB(false)
}
}
if set.NetDefault != "" {
if set.Netname == "" {
err = fmt.Errorf("You must include the '--netname' option")
n.SetFrom(&nodeConf)
if set.NetdevDelete != "" {
if _, ok := n.NetDevs[set.NetdevDelete]; !ok {
err = fmt.Errorf("network device name doesn't exist: %s", set.NetdevDelete)
wwlog.Printf(wwlog.ERROR, fmt.Sprintf("%v\n", err.Error()))
return
}
if set.NetDefault == "yes" || set.NetDefault == "y" || set.NetDefault == "1" || set.NetDefault == "true" {
// Set all other devices to non-default
for _, n := range n.NetDevs {
n.Primary.SetB(false)
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Deleting network device: %s\n", n.Id.Get(), set.NetdevDelete)
delete(n.NetDevs, set.NetdevDelete)
}
for _, key := range nodeConf.TagsDel {
delete(n.Tags, key)
}
for _, key := range nodeConf.Ipmi.TagsDel {
delete(n.Ipmi.Tags, key)
}
for net := range nodeConf.NetDevs {
for _, key := range nodeConf.NetDevs[net].TagsDel {
if _, ok := n.NetDevs[net]; ok {
delete(n.NetDevs[net].Tags, key)
}
wwlog.Printf(wwlog.VERBOSE, "Node: %s:%s, Setting PRIMARY\n", n.Id.Get(), set.Netname)
n.NetDevs[set.Netname].Primary.SetB(true)
} else {
wwlog.Printf(wwlog.VERBOSE, "Node: %s:%s, Unsetting PRIMARY\n", n.Id.Get(), set.Netname)
n.NetDevs[set.Netname].Primary.SetB(false)
}
}
if set.NetdevDelete {
err = checkNetNameRequired(set.Netname)
if err != nil {
return
}
if _, ok := n.NetDevs[set.Netname]; !ok {
err = fmt.Errorf("Network device name doesn't exist: %s", set.Netname)
wwlog.Printf(wwlog.ERROR, fmt.Sprintf("%v\n", err.Error()))
return
}
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Deleting network device: %s\n", n.Id.Get(), set.Netname)
delete(n.NetDevs, set.Netname)
}
if len(set.Tags) > 0 {
for _, t := range set.Tags {
keyval := strings.SplitN(t, "=", 2)
key := keyval[0]
val := keyval[1]
if _, ok := n.Tags[key]; !ok {
var nd node.Entry
n.Tags[key] = &nd
}
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting Tag '%s'='%s'\n", n.Id.Get(), key, val)
n.Tags[key].Set(val)
}
}
if len(set.TagsDelete) > 0 {
for _, t := range set.TagsDelete {
keyval := strings.SplitN(t, "=", 1)
key := keyval[0]
if _, ok := n.Tags[key]; !ok {
wwlog.Printf(wwlog.WARN, "Key does not exist: %s\n", key)
os.Exit(1)
}
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Deleting tag: %s\n", n.Id.Get(), key)
delete(n.Tags, key)
}
}
if len(set.NetTags) > 0 {
for _, t := range set.NetTags {
keyval := strings.SplitN(t, "=", 2)
key := keyval[0]
val := keyval[1]
if _, ok := n.NetDevs[set.Netname].Tags[key]; !ok {
var nd node.Entry
n.NetDevs[set.Netname].Tags[key] = &nd
}
wwlog.Printf(wwlog.VERBOSE, "Node: %s:%s, Setting NETTAG '%s'='%s'\n", n.Id.Get(), set.Netname, key, val)
n.NetDevs[set.Netname].Tags[key].Set(val)
}
}
if len(set.NetDeleteTags) > 0 {
for _, t := range set.NetDeleteTags {
keyval := strings.SplitN(t, "=", 1)
key := keyval[0]
if _, ok := n.NetDevs[set.Netname].Tags[key]; !ok {
wwlog.Printf(wwlog.WARN, "Node: %s:%s Key %s does not exist\n", n.Id.Get(), set.Netname, key)
os.Exit(1)
}
wwlog.Printf(wwlog.VERBOSE, "Node: %s:%s, Deleting Tag %s\n", n.Id.Get(), set.Netname, key)
delete(n.NetDevs[set.Netname].Tags, key)
}
}
err := nodeDB.NodeUpdate(n)
if err != nil {
wwlog.Printf(wwlog.ERROR, "%s\n", err)
@@ -900,7 +297,7 @@ func NodeStatus(nodeNames []string) (nodeStatusResponse *wwapiv1.NodeStatusRespo
}
if controller.Ipaddr == "" {
err = fmt.Errorf("The Warewulf Server IP Address is not properly configured")
err = fmt.Errorf("the Warewulf Server IP Address is not properly configured")
wwlog.Printf(wwlog.ERROR, fmt.Sprintf("%v\n", err.Error()))
return
}
@@ -958,31 +355,3 @@ func NodeStatus(nodeNames []string) (nodeStatusResponse *wwapiv1.NodeStatusRespo
}
return
}
// checkNetNameRequired is a helper for determining if netname is set.
// Certain settings require it.
func checkNetNameRequired(netname string) (err error) {
if netname == "" {
err = fmt.Errorf("You must include the '--netname' option")
wwlog.Printf(wwlog.ERROR, fmt.Sprintf("%v\n", err.Error()))
}
return
}
// nodeDbSave persists the nodeDB to disk and restarts warewulfd.
// TODO: We will likely need locking around anything changing nodeDB
// or restarting warewulfd. Determine if the reason for restart is
// just to reinitialize warewulfd with the new nodeDB or if there is
// something more to it.
func nodeDbSave(nodeDB *node.NodeYaml) (err error) {
err = nodeDB.Persist()
if err != nil {
return errors.Wrap(err, "failed to persist nodedb")
}
err = warewulfd.DaemonReload()
if err != nil {
return errors.Wrap(err, "failed to reload warewulf daemon")
}
return
}

View File

@@ -0,0 +1,61 @@
package apinode
import (
"strings"
"github.com/hpcng/warewulf/internal/pkg/node"
"github.com/hpcng/warewulf/internal/pkg/warewulfd"
"github.com/pkg/errors"
)
// nodeDbSave persists the nodeDB to disk and restarts warewulfd.
// TODO: We will likely need locking around anything changing nodeDB
// or restarting warewulfd. Determine if the reason for restart is
// just to reinitialize warewulfd with the new nodeDB or if there is
// something more to it.
func DbSave(nodeDB *node.NodeYaml) (err error) {
err = nodeDB.Persist()
if err != nil {
return errors.Wrap(err, "failed to persist nodedb")
}
err = warewulfd.DaemonReload()
if err != nil {
return errors.Wrap(err, "failed to reload warewulf daemon")
}
return
}
/*
Add the netname to the options map, as its only known after the
command line options have been read out, but its needing for setting
the values. Returns the manipulated map and a bool which is true if
networks specific values were set, but no netname was given.
*/
func AddNetname(theMap map[string]*string) (map[string]*string, bool) {
netname := ""
netvalues := false
retMap := make(map[string]*string)
for key, val := range theMap {
if key == "NetDevs" && *val != "" {
netname = *val
}
}
for key, val := range theMap {
keys := strings.Split(key, ".")
myVal := *val
if len(keys) >= 2 && keys[0] == "NetDevs" {
if *val != "" {
netvalues = true
}
if netname != "" {
retMap[keys[0]+"."+netname+"."+strings.Join(keys[1:], ".")] = &myVal
}
} else {
retMap[key] = &myVal
}
}
return retMap, netvalues && netname == ""
}

View File

@@ -0,0 +1,144 @@
package apiprofile
import (
"fmt"
"os"
apinode "github.com/hpcng/warewulf/internal/pkg/api/node"
"github.com/hpcng/warewulf/internal/pkg/api/routes/wwapiv1"
"github.com/hpcng/warewulf/internal/pkg/node"
"github.com/hpcng/warewulf/internal/pkg/util"
"github.com/hpcng/warewulf/internal/pkg/wwlog"
"github.com/pkg/errors"
"gopkg.in/yaml.v2"
)
// NodeSet is the wwapiv1 implmentation for updating nodeinfo fields.
func ProfileSet(set *wwapiv1.NodeSetParameter) (err error) {
if set == nil {
return fmt.Errorf("NodeAddParameter is nil")
}
var nodeDB node.NodeYaml
nodeDB, _, err = ProfileSetParameterCheck(set, false)
if err != nil {
return errors.Wrap(err, "Could not open database")
}
return apinode.DbSave(&nodeDB)
}
// ProfileSetParameterCheck does error checking on ProfileSetParameter.
// Output to the console if console is true.
// TODO: Determine if the console switch does wwlog or not.
// - console may end up being textOutput?
func ProfileSetParameterCheck(set *wwapiv1.NodeSetParameter, console bool) (nodeDB node.NodeYaml, profileCount uint, err error) {
if set == nil {
err = fmt.Errorf("profile set parameter is nil")
if console {
fmt.Printf("%v\n", err)
return
}
}
if set.NodeNames == nil {
err = fmt.Errorf("profile set parameter: ProfileNames is nil")
if console {
fmt.Printf("%v\n", err)
return
}
}
nodeDB, err = node.New()
if err != nil {
wwlog.Error("Could not open configuration: %s\n", err)
return
}
profiles, err := nodeDB.FindAllProfiles()
if err != nil {
wwlog.Error("Could not get profile list: %s\n", err)
return
}
// Note: This does not do expansion on the nodes.
if set.AllNodes || (len(set.NodeNames) == 0) {
if console {
fmt.Printf("\n*** WARNING: This command will modify all profiles! ***\n\n")
}
}
if len(profiles) == 0 {
if console {
fmt.Printf("No profiles found\n")
}
return
}
var pConf node.NodeConf
err = yaml.Unmarshal([]byte(set.NodeConfYaml), &pConf)
if err != nil {
wwlog.Printf(wwlog.ERROR, fmt.Sprintf("%v\n", err.Error()))
return
}
for _, p := range profiles {
if util.InSlice(set.NodeNames, p.Id.Get()) {
wwlog.Printf(wwlog.VERBOSE, "Evaluating profile: %s\n", p.Id.Get())
p.SetFrom(&pConf)
if set.NetdevDelete != "" {
if _, ok := p.NetDevs[set.NetdevDelete]; !ok {
err = fmt.Errorf("network device name doesn't exist: %s", set.NetdevDelete)
wwlog.Error(fmt.Sprintf("%v\n", err.Error()))
return
}
wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Deleting network device: %s\n", p.Id.Get(), set.NetdevDelete)
delete(p.NetDevs, set.NetdevDelete)
}
for _, key := range pConf.TagsDel {
delete(p.Tags, key)
}
for _, key := range pConf.Ipmi.TagsDel {
delete(p.Ipmi.Tags, key)
}
for net := range pConf.NetDevs {
for _, key := range pConf.NetDevs[net].TagsDel {
if _, ok := p.NetDevs[net]; ok {
delete(p.NetDevs[net].Tags, key)
}
}
}
err := nodeDB.ProfileUpdate(p)
if err != nil {
wwlog.Error("%s\n", err)
os.Exit(1)
}
profileCount++
}
}
return
}
/*
Adds a new profile with the given name
*/
func AddProfile(set *wwapiv1.NodeSetParameter, console bool) error {
nodeDB, err := node.New()
if err != nil {
return errors.Wrap(err, "Could not open database")
}
if util.InSlice(nodeDB.ListAllProfiles(), set.NodeNames[0]) {
return errors.New(fmt.Sprintf("profile with name %s allready exists", set.NodeNames[0]))
}
_, err = nodeDB.AddProfile(set.NodeNames[0])
if err != nil {
return errors.Wrap(err, "Could not create new profile")
}
err = apinode.DbSave(&nodeDB)
if err != nil {
return errors.Wrap(err, "Could not persist new profile")
}
return nil
}

View File

@@ -84,42 +84,13 @@ message NodeField {
// NetDev is network devices (NICs) on a node.
message NetDev {
NodeField type = 1;
NodeField onboot = 2;
NodeField device = 3;
NodeField hwaddr = 4;
NodeField ipaddr = 5;
NodeField netmask = 6;
NodeField gateway = 7;
NodeField primary = 8;
map<string, NodeField> Field = 1;
map<string, NodeField> Tags = 9;
}
// NodeInfo contains details about a node managed by Warewulf/
message NodeInfo {
NodeField id = 1;
NodeField comment = 2;
NodeField cluster = 3;
NodeField discoverable = 4;
NodeField container = 5;
NodeField kernelOverride = 6;
NodeField kernelArgs = 7;
NodeField systemOverlay = 8;
NodeField runtimeOverlay = 9;
NodeField ipxe = 10;
NodeField init = 11;
NodeField root = 12;
NodeField assetKey = 13;
NodeField ipmiIpaddr = 14;
NodeField ipmiNetmask = 15;
NodeField ipmiPort = 16;
NodeField ipmiGateway = 17;
NodeField ipmiUserName = 18;
NodeField ipmiInterface = 19;
NodeField ipmiPassword = 20;
repeated string profiles = 21;
repeated string groupProfiles = 22;
map<string, NodeField> Fields = 1;
map<string, NetDev> NetDevs = 23;
map<string, NodeField> Tags = 24;
@@ -131,20 +102,28 @@ message NodeListResponse {
repeated NodeInfo nodes = 1;
}
// Request a node list
message GetNodeList {
enum ListType {
Simple = 0;
Ipmi = 1;
Network = 2;
Long = 3;
All = 4;
}
ListType type = 7;
repeated string Nodes = 8;
}
message NodeList {
repeated string Output = 1;
}
// NodeAddParameter contains all input for adding a node to be managed by
// Warewulf.
message NodeAddParameter {
string cluster = 1;
bool discoverable = 2;
string gateway = 3;
string hwaddr = 4;
string ipaddr = 5;
string netdev = 6;
string netmask = 7;
string netname = 8;
string type = 9;
string nodeConfYaml = 1;
repeated string nodeNames = 10;
string ipaddr6 = 11;
}
// NodeDeleteParameter contains input for removing nodes from Warewulf
@@ -157,48 +136,12 @@ message NodeDeleteParameter {
// NodeSetParameter contains all fields for updating aspects of nodes managed
// by Warewulf.
message NodeSetParameter {
string comment = 1;
string nodeConfYaml = 1;
string container = 2;
string kernelOverride = 3;
string kernelArgs = 4;
string netname = 5;
string netdev = 6;
string ipaddr = 7;
string netmask = 8;
string gateway = 9;
string hwaddr = 10;
string type = 11;
string onboot = 12;
string netDefault = 13;
bool netdevDelete = 14;
string cluster = 15;
string ipxe = 16;
string initOverlay = 17;
repeated string runtimeOverlay = 18;
repeated string systemOverlay = 19;
string ipmiIpaddr = 20;
string ipmiNetmask = 21;
string ipmiPort = 22;
string ipmiGateway = 23;
string ipmiUsername = 24;
string ipmiPassword = 25;
string ipmiInterface = 26;
string netdevDelete = 14;
bool allNodes = 27;
string profile = 28;
repeated string profileAdd = 29;
repeated string profileDelete = 30;
bool force = 31;
string init = 32;
bool discoverable = 33;
bool undiscoverable = 34;
string root = 35;
repeated string tags = 36;
repeated string tagsDelete = 37;
string assetKey = 38;
repeated string nodeNames = 39;
string ipmiWrite = 40;
repeated string NetTags = 41;
repeated string NetDeleteTags = 42;
}
// NodeStatus contains information about the imaging status per node.

File diff suppressed because it is too large Load Diff

View File

@@ -13,6 +13,7 @@ import (
"io"
"net/http"
"github.com/golang/protobuf/ptypes/empty"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"github.com/grpc-ecosystem/grpc-gateway/v2/utilities"
"google.golang.org/grpc"
@@ -21,7 +22,6 @@ import (
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/emptypb"
)
// Suppress "imported and not used" errors
@@ -137,7 +137,7 @@ func local_request_WWApi_ContainerImport_0(ctx context.Context, marshaler runtim
}
func request_WWApi_ContainerList_0(ctx context.Context, marshaler runtime.Marshaler, client WWApiClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq emptypb.Empty
var protoReq empty.Empty
var metadata runtime.ServerMetadata
msg, err := client.ContainerList(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
@@ -146,7 +146,7 @@ func request_WWApi_ContainerList_0(ctx context.Context, marshaler runtime.Marsha
}
func local_request_WWApi_ContainerList_0(ctx context.Context, marshaler runtime.Marshaler, server WWApiServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq emptypb.Empty
var protoReq empty.Empty
var metadata runtime.ServerMetadata
msg, err := server.ContainerList(ctx, &protoReq)
@@ -367,7 +367,7 @@ func local_request_WWApi_NodeStatus_0(ctx context.Context, marshaler runtime.Mar
}
func request_WWApi_Version_0(ctx context.Context, marshaler runtime.Marshaler, client WWApiClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq emptypb.Empty
var protoReq empty.Empty
var metadata runtime.ServerMetadata
msg, err := client.Version(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
@@ -376,7 +376,7 @@ func request_WWApi_Version_0(ctx context.Context, marshaler runtime.Marshaler, c
}
func local_request_WWApi_Version_0(ctx context.Context, marshaler runtime.Marshaler, server WWApiServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq emptypb.Empty
var protoReq empty.Empty
var metadata runtime.ServerMetadata
msg, err := server.Version(ctx, &protoReq)
@@ -396,13 +396,12 @@ func RegisterWWApiHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
var err error
ctx, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/wwapi.v1.WWApi/ContainerBuild", runtime.WithHTTPPathPattern("/v1/containerbuild"))
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/wwapi.v1.WWApi/ContainerBuild", runtime.WithHTTPPathPattern("/v1/containerbuild"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_WWApi_ContainerBuild_0(ctx, inboundMarshaler, server, req, pathParams)
resp, md, err := local_request_WWApi_ContainerBuild_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
@@ -420,13 +419,12 @@ func RegisterWWApiHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
var err error
ctx, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/wwapi.v1.WWApi/ContainerDelete", runtime.WithHTTPPathPattern("/v1/container"))
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/wwapi.v1.WWApi/ContainerDelete", runtime.WithHTTPPathPattern("/v1/container"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_WWApi_ContainerDelete_0(ctx, inboundMarshaler, server, req, pathParams)
resp, md, err := local_request_WWApi_ContainerDelete_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
@@ -444,13 +442,12 @@ func RegisterWWApiHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
var err error
ctx, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/wwapi.v1.WWApi/ContainerImport", runtime.WithHTTPPathPattern("/v1/container"))
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/wwapi.v1.WWApi/ContainerImport", runtime.WithHTTPPathPattern("/v1/container"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_WWApi_ContainerImport_0(ctx, inboundMarshaler, server, req, pathParams)
resp, md, err := local_request_WWApi_ContainerImport_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
@@ -468,13 +465,12 @@ func RegisterWWApiHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
var err error
ctx, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/wwapi.v1.WWApi/ContainerList", runtime.WithHTTPPathPattern("/v1/container"))
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/wwapi.v1.WWApi/ContainerList", runtime.WithHTTPPathPattern("/v1/container"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_WWApi_ContainerList_0(ctx, inboundMarshaler, server, req, pathParams)
resp, md, err := local_request_WWApi_ContainerList_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
@@ -492,13 +488,12 @@ func RegisterWWApiHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
var err error
ctx, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/wwapi.v1.WWApi/ContainerShow", runtime.WithHTTPPathPattern("/v1/containershow"))
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/wwapi.v1.WWApi/ContainerShow", runtime.WithHTTPPathPattern("/v1/containershow"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_WWApi_ContainerShow_0(ctx, inboundMarshaler, server, req, pathParams)
resp, md, err := local_request_WWApi_ContainerShow_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
@@ -516,13 +511,12 @@ func RegisterWWApiHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
var err error
ctx, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/wwapi.v1.WWApi/NodeAdd", runtime.WithHTTPPathPattern("/v1/node"))
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/wwapi.v1.WWApi/NodeAdd", runtime.WithHTTPPathPattern("/v1/node"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_WWApi_NodeAdd_0(ctx, inboundMarshaler, server, req, pathParams)
resp, md, err := local_request_WWApi_NodeAdd_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
@@ -540,13 +534,12 @@ func RegisterWWApiHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
var err error
ctx, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/wwapi.v1.WWApi/NodeDelete", runtime.WithHTTPPathPattern("/v1/node"))
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/wwapi.v1.WWApi/NodeDelete", runtime.WithHTTPPathPattern("/v1/node"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_WWApi_NodeDelete_0(ctx, inboundMarshaler, server, req, pathParams)
resp, md, err := local_request_WWApi_NodeDelete_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
@@ -564,13 +557,12 @@ func RegisterWWApiHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
var err error
ctx, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/wwapi.v1.WWApi/NodeList", runtime.WithHTTPPathPattern("/v1/node"))
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/wwapi.v1.WWApi/NodeList", runtime.WithHTTPPathPattern("/v1/node"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_WWApi_NodeList_0(ctx, inboundMarshaler, server, req, pathParams)
resp, md, err := local_request_WWApi_NodeList_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
@@ -588,13 +580,12 @@ func RegisterWWApiHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
var err error
ctx, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/wwapi.v1.WWApi/NodeSet", runtime.WithHTTPPathPattern("/v1/nodeset"))
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/wwapi.v1.WWApi/NodeSet", runtime.WithHTTPPathPattern("/v1/nodeset"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_WWApi_NodeSet_0(ctx, inboundMarshaler, server, req, pathParams)
resp, md, err := local_request_WWApi_NodeSet_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
@@ -612,13 +603,12 @@ func RegisterWWApiHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
var err error
ctx, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/wwapi.v1.WWApi/NodeStatus", runtime.WithHTTPPathPattern("/v1/nodestatus"))
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/wwapi.v1.WWApi/NodeStatus", runtime.WithHTTPPathPattern("/v1/nodestatus"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_WWApi_NodeStatus_0(ctx, inboundMarshaler, server, req, pathParams)
resp, md, err := local_request_WWApi_NodeStatus_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
@@ -636,13 +626,12 @@ func RegisterWWApiHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
var err error
ctx, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/wwapi.v1.WWApi/Version", runtime.WithHTTPPathPattern("/version"))
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/wwapi.v1.WWApi/Version", runtime.WithHTTPPathPattern("/version"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_WWApi_Version_0(ctx, inboundMarshaler, server, req, pathParams)
resp, md, err := local_request_WWApi_Version_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
@@ -699,13 +688,12 @@ func RegisterWWApiHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
var err error
ctx, err = runtime.AnnotateContext(ctx, mux, req, "/wwapi.v1.WWApi/ContainerBuild", runtime.WithHTTPPathPattern("/v1/containerbuild"))
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/wwapi.v1.WWApi/ContainerBuild", runtime.WithHTTPPathPattern("/v1/containerbuild"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_WWApi_ContainerBuild_0(ctx, inboundMarshaler, client, req, pathParams)
resp, md, err := request_WWApi_ContainerBuild_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
@@ -720,13 +708,12 @@ func RegisterWWApiHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
var err error
ctx, err = runtime.AnnotateContext(ctx, mux, req, "/wwapi.v1.WWApi/ContainerDelete", runtime.WithHTTPPathPattern("/v1/container"))
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/wwapi.v1.WWApi/ContainerDelete", runtime.WithHTTPPathPattern("/v1/container"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_WWApi_ContainerDelete_0(ctx, inboundMarshaler, client, req, pathParams)
resp, md, err := request_WWApi_ContainerDelete_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
@@ -741,13 +728,12 @@ func RegisterWWApiHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
var err error
ctx, err = runtime.AnnotateContext(ctx, mux, req, "/wwapi.v1.WWApi/ContainerImport", runtime.WithHTTPPathPattern("/v1/container"))
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/wwapi.v1.WWApi/ContainerImport", runtime.WithHTTPPathPattern("/v1/container"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_WWApi_ContainerImport_0(ctx, inboundMarshaler, client, req, pathParams)
resp, md, err := request_WWApi_ContainerImport_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
@@ -762,13 +748,12 @@ func RegisterWWApiHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
var err error
ctx, err = runtime.AnnotateContext(ctx, mux, req, "/wwapi.v1.WWApi/ContainerList", runtime.WithHTTPPathPattern("/v1/container"))
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/wwapi.v1.WWApi/ContainerList", runtime.WithHTTPPathPattern("/v1/container"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_WWApi_ContainerList_0(ctx, inboundMarshaler, client, req, pathParams)
resp, md, err := request_WWApi_ContainerList_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
@@ -783,13 +768,12 @@ func RegisterWWApiHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
var err error
ctx, err = runtime.AnnotateContext(ctx, mux, req, "/wwapi.v1.WWApi/ContainerShow", runtime.WithHTTPPathPattern("/v1/containershow"))
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/wwapi.v1.WWApi/ContainerShow", runtime.WithHTTPPathPattern("/v1/containershow"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_WWApi_ContainerShow_0(ctx, inboundMarshaler, client, req, pathParams)
resp, md, err := request_WWApi_ContainerShow_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
@@ -804,13 +788,12 @@ func RegisterWWApiHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
var err error
ctx, err = runtime.AnnotateContext(ctx, mux, req, "/wwapi.v1.WWApi/NodeAdd", runtime.WithHTTPPathPattern("/v1/node"))
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/wwapi.v1.WWApi/NodeAdd", runtime.WithHTTPPathPattern("/v1/node"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_WWApi_NodeAdd_0(ctx, inboundMarshaler, client, req, pathParams)
resp, md, err := request_WWApi_NodeAdd_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
@@ -825,13 +808,12 @@ func RegisterWWApiHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
var err error
ctx, err = runtime.AnnotateContext(ctx, mux, req, "/wwapi.v1.WWApi/NodeDelete", runtime.WithHTTPPathPattern("/v1/node"))
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/wwapi.v1.WWApi/NodeDelete", runtime.WithHTTPPathPattern("/v1/node"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_WWApi_NodeDelete_0(ctx, inboundMarshaler, client, req, pathParams)
resp, md, err := request_WWApi_NodeDelete_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
@@ -846,13 +828,12 @@ func RegisterWWApiHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
var err error
ctx, err = runtime.AnnotateContext(ctx, mux, req, "/wwapi.v1.WWApi/NodeList", runtime.WithHTTPPathPattern("/v1/node"))
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/wwapi.v1.WWApi/NodeList", runtime.WithHTTPPathPattern("/v1/node"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_WWApi_NodeList_0(ctx, inboundMarshaler, client, req, pathParams)
resp, md, err := request_WWApi_NodeList_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
@@ -867,13 +848,12 @@ func RegisterWWApiHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
var err error
ctx, err = runtime.AnnotateContext(ctx, mux, req, "/wwapi.v1.WWApi/NodeSet", runtime.WithHTTPPathPattern("/v1/nodeset"))
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/wwapi.v1.WWApi/NodeSet", runtime.WithHTTPPathPattern("/v1/nodeset"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_WWApi_NodeSet_0(ctx, inboundMarshaler, client, req, pathParams)
resp, md, err := request_WWApi_NodeSet_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
@@ -888,13 +868,12 @@ func RegisterWWApiHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
var err error
ctx, err = runtime.AnnotateContext(ctx, mux, req, "/wwapi.v1.WWApi/NodeStatus", runtime.WithHTTPPathPattern("/v1/nodestatus"))
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/wwapi.v1.WWApi/NodeStatus", runtime.WithHTTPPathPattern("/v1/nodestatus"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_WWApi_NodeStatus_0(ctx, inboundMarshaler, client, req, pathParams)
resp, md, err := request_WWApi_NodeStatus_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
@@ -909,13 +888,12 @@ func RegisterWWApiHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
var err error
ctx, err = runtime.AnnotateContext(ctx, mux, req, "/wwapi.v1.WWApi/Version", runtime.WithHTTPPathPattern("/version"))
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/wwapi.v1.WWApi/Version", runtime.WithHTTPPathPattern("/version"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_WWApi_Version_0(ctx, inboundMarshaler, client, req, pathParams)
resp, md, err := request_WWApi_Version_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)

View File

@@ -1,17 +1,17 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.2.0
// - protoc v3.21.1
// - protoc v3.9.2
// source: routes.proto
package wwapiv1
import (
context "context"
empty "github.com/golang/protobuf/ptypes/empty"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
emptypb "google.golang.org/protobuf/types/known/emptypb"
)
// This is a compile-time assertion to ensure that this generated file
@@ -26,18 +26,18 @@ type WWApiClient interface {
// ContainerBuild builds zero or more containers.
ContainerBuild(ctx context.Context, in *ContainerBuildParameter, opts ...grpc.CallOption) (*ContainerListResponse, error)
// ContainerDelete removes one or more container from Warewulf management.
ContainerDelete(ctx context.Context, in *ContainerDeleteParameter, opts ...grpc.CallOption) (*emptypb.Empty, error)
ContainerDelete(ctx context.Context, in *ContainerDeleteParameter, opts ...grpc.CallOption) (*empty.Empty, error)
// ContainerImport imports a container to Warewulf.
ContainerImport(ctx context.Context, in *ContainerImportParameter, opts ...grpc.CallOption) (*ContainerListResponse, error)
// ContainerList lists ContainerInfo for each container.
ContainerList(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*ContainerListResponse, error)
ContainerList(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*ContainerListResponse, error)
// ContainerShow lists ContainerShow for each container.
ContainerShow(ctx context.Context, in *ContainerShowParameter, opts ...grpc.CallOption) (*ContainerShowResponse, error)
// NodeAdd adds one or more nodes for management by Warewulf and returns
// the added nodes. Node fields may be shimmed in per profiles.
NodeAdd(ctx context.Context, in *NodeAddParameter, opts ...grpc.CallOption) (*NodeListResponse, error)
// NodeDelete removes one or more nodes from Warewulf management.
NodeDelete(ctx context.Context, in *NodeDeleteParameter, opts ...grpc.CallOption) (*emptypb.Empty, error)
NodeDelete(ctx context.Context, in *NodeDeleteParameter, opts ...grpc.CallOption) (*empty.Empty, error)
// NodeList lists some or all nodes managed by Warewulf.
NodeList(ctx context.Context, in *NodeNames, opts ...grpc.CallOption) (*NodeListResponse, error)
// NodeSet updates node fields for one or more nodes.
@@ -47,7 +47,7 @@ type WWApiClient interface {
NodeStatus(ctx context.Context, in *NodeNames, opts ...grpc.CallOption) (*NodeStatusResponse, error)
// Version returns the wwapi version, the api prefix, and the Warewulf
// version. This is also useful for testing if the service is up.
Version(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*VersionResponse, error)
Version(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*VersionResponse, error)
}
type wWApiClient struct {
@@ -67,8 +67,8 @@ func (c *wWApiClient) ContainerBuild(ctx context.Context, in *ContainerBuildPara
return out, nil
}
func (c *wWApiClient) ContainerDelete(ctx context.Context, in *ContainerDeleteParameter, opts ...grpc.CallOption) (*emptypb.Empty, error) {
out := new(emptypb.Empty)
func (c *wWApiClient) ContainerDelete(ctx context.Context, in *ContainerDeleteParameter, opts ...grpc.CallOption) (*empty.Empty, error) {
out := new(empty.Empty)
err := c.cc.Invoke(ctx, "/wwapi.v1.WWApi/ContainerDelete", in, out, opts...)
if err != nil {
return nil, err
@@ -85,7 +85,7 @@ func (c *wWApiClient) ContainerImport(ctx context.Context, in *ContainerImportPa
return out, nil
}
func (c *wWApiClient) ContainerList(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*ContainerListResponse, error) {
func (c *wWApiClient) ContainerList(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*ContainerListResponse, error) {
out := new(ContainerListResponse)
err := c.cc.Invoke(ctx, "/wwapi.v1.WWApi/ContainerList", in, out, opts...)
if err != nil {
@@ -112,8 +112,8 @@ func (c *wWApiClient) NodeAdd(ctx context.Context, in *NodeAddParameter, opts ..
return out, nil
}
func (c *wWApiClient) NodeDelete(ctx context.Context, in *NodeDeleteParameter, opts ...grpc.CallOption) (*emptypb.Empty, error) {
out := new(emptypb.Empty)
func (c *wWApiClient) NodeDelete(ctx context.Context, in *NodeDeleteParameter, opts ...grpc.CallOption) (*empty.Empty, error) {
out := new(empty.Empty)
err := c.cc.Invoke(ctx, "/wwapi.v1.WWApi/NodeDelete", in, out, opts...)
if err != nil {
return nil, err
@@ -148,7 +148,7 @@ func (c *wWApiClient) NodeStatus(ctx context.Context, in *NodeNames, opts ...grp
return out, nil
}
func (c *wWApiClient) Version(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*VersionResponse, error) {
func (c *wWApiClient) Version(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*VersionResponse, error) {
out := new(VersionResponse)
err := c.cc.Invoke(ctx, "/wwapi.v1.WWApi/Version", in, out, opts...)
if err != nil {
@@ -164,18 +164,18 @@ type WWApiServer interface {
// ContainerBuild builds zero or more containers.
ContainerBuild(context.Context, *ContainerBuildParameter) (*ContainerListResponse, error)
// ContainerDelete removes one or more container from Warewulf management.
ContainerDelete(context.Context, *ContainerDeleteParameter) (*emptypb.Empty, error)
ContainerDelete(context.Context, *ContainerDeleteParameter) (*empty.Empty, error)
// ContainerImport imports a container to Warewulf.
ContainerImport(context.Context, *ContainerImportParameter) (*ContainerListResponse, error)
// ContainerList lists ContainerInfo for each container.
ContainerList(context.Context, *emptypb.Empty) (*ContainerListResponse, error)
ContainerList(context.Context, *empty.Empty) (*ContainerListResponse, error)
// ContainerShow lists ContainerShow for each container.
ContainerShow(context.Context, *ContainerShowParameter) (*ContainerShowResponse, error)
// NodeAdd adds one or more nodes for management by Warewulf and returns
// the added nodes. Node fields may be shimmed in per profiles.
NodeAdd(context.Context, *NodeAddParameter) (*NodeListResponse, error)
// NodeDelete removes one or more nodes from Warewulf management.
NodeDelete(context.Context, *NodeDeleteParameter) (*emptypb.Empty, error)
NodeDelete(context.Context, *NodeDeleteParameter) (*empty.Empty, error)
// NodeList lists some or all nodes managed by Warewulf.
NodeList(context.Context, *NodeNames) (*NodeListResponse, error)
// NodeSet updates node fields for one or more nodes.
@@ -185,7 +185,7 @@ type WWApiServer interface {
NodeStatus(context.Context, *NodeNames) (*NodeStatusResponse, error)
// Version returns the wwapi version, the api prefix, and the Warewulf
// version. This is also useful for testing if the service is up.
Version(context.Context, *emptypb.Empty) (*VersionResponse, error)
Version(context.Context, *empty.Empty) (*VersionResponse, error)
mustEmbedUnimplementedWWApiServer()
}
@@ -196,13 +196,13 @@ type UnimplementedWWApiServer struct {
func (UnimplementedWWApiServer) ContainerBuild(context.Context, *ContainerBuildParameter) (*ContainerListResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ContainerBuild not implemented")
}
func (UnimplementedWWApiServer) ContainerDelete(context.Context, *ContainerDeleteParameter) (*emptypb.Empty, error) {
func (UnimplementedWWApiServer) ContainerDelete(context.Context, *ContainerDeleteParameter) (*empty.Empty, error) {
return nil, status.Errorf(codes.Unimplemented, "method ContainerDelete not implemented")
}
func (UnimplementedWWApiServer) ContainerImport(context.Context, *ContainerImportParameter) (*ContainerListResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ContainerImport not implemented")
}
func (UnimplementedWWApiServer) ContainerList(context.Context, *emptypb.Empty) (*ContainerListResponse, error) {
func (UnimplementedWWApiServer) ContainerList(context.Context, *empty.Empty) (*ContainerListResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ContainerList not implemented")
}
func (UnimplementedWWApiServer) ContainerShow(context.Context, *ContainerShowParameter) (*ContainerShowResponse, error) {
@@ -211,7 +211,7 @@ func (UnimplementedWWApiServer) ContainerShow(context.Context, *ContainerShowPar
func (UnimplementedWWApiServer) NodeAdd(context.Context, *NodeAddParameter) (*NodeListResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method NodeAdd not implemented")
}
func (UnimplementedWWApiServer) NodeDelete(context.Context, *NodeDeleteParameter) (*emptypb.Empty, error) {
func (UnimplementedWWApiServer) NodeDelete(context.Context, *NodeDeleteParameter) (*empty.Empty, error) {
return nil, status.Errorf(codes.Unimplemented, "method NodeDelete not implemented")
}
func (UnimplementedWWApiServer) NodeList(context.Context, *NodeNames) (*NodeListResponse, error) {
@@ -223,7 +223,7 @@ func (UnimplementedWWApiServer) NodeSet(context.Context, *NodeSetParameter) (*No
func (UnimplementedWWApiServer) NodeStatus(context.Context, *NodeNames) (*NodeStatusResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method NodeStatus not implemented")
}
func (UnimplementedWWApiServer) Version(context.Context, *emptypb.Empty) (*VersionResponse, error) {
func (UnimplementedWWApiServer) Version(context.Context, *empty.Empty) (*VersionResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method Version not implemented")
}
func (UnimplementedWWApiServer) mustEmbedUnimplementedWWApiServer() {}
@@ -294,7 +294,7 @@ func _WWApi_ContainerImport_Handler(srv interface{}, ctx context.Context, dec fu
}
func _WWApi_ContainerList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(emptypb.Empty)
in := new(empty.Empty)
if err := dec(in); err != nil {
return nil, err
}
@@ -306,7 +306,7 @@ func _WWApi_ContainerList_Handler(srv interface{}, ctx context.Context, dec func
FullMethod: "/wwapi.v1.WWApi/ContainerList",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(WWApiServer).ContainerList(ctx, req.(*emptypb.Empty))
return srv.(WWApiServer).ContainerList(ctx, req.(*empty.Empty))
}
return interceptor(ctx, in, info, handler)
}
@@ -420,7 +420,7 @@ func _WWApi_NodeStatus_Handler(srv interface{}, ctx context.Context, dec func(in
}
func _WWApi_Version_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(emptypb.Empty)
in := new(empty.Empty)
if err := dec(in); err != nil {
return nil, err
}
@@ -432,7 +432,7 @@ func _WWApi_Version_Handler(srv interface{}, ctx context.Context, dec func(inter
FullMethod: "/wwapi.v1.WWApi/Version",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(WWApiServer).Version(ctx, req.(*emptypb.Empty))
return srv.(WWApiServer).Version(ctx, req.(*empty.Empty))
}
return interceptor(ctx, in, info, handler)
}

View File

@@ -2,15 +2,12 @@ package node
import (
"errors"
"fmt"
"io/ioutil"
"net"
"path"
"sort"
"strings"
"github.com/hpcng/warewulf/internal/pkg/buildconfig"
"github.com/hpcng/warewulf/internal/pkg/warewulfconf"
"github.com/hpcng/warewulf/internal/pkg/wwlog"
"gopkg.in/yaml.v2"
@@ -51,10 +48,12 @@ for every node
*/
func (config *NodeYaml) FindAllNodes() ([]NodeInfo, error) {
var ret []NodeInfo
wwconfig, err := warewulfconf.New()
if err != nil {
return ret, err
}
/*
wwconfig, err := warewulfconf.New()
if err != nil {
return ret, err
}
*/
wwlog.Printf(wwlog.DEBUG, "Finding all nodes...\n")
for nodename, node := range config.Nodes {
var n NodeInfo
@@ -75,20 +74,28 @@ func (config *NodeYaml) FindAllNodes() ([]NodeInfo, error) {
if len(fullname) > 1 {
n.ClusterName.SetDefault(fullname[1])
}
// special handling for profile to get the default one
if len(node.Profiles) == 0 {
n.Profiles = []string{"default"}
n.Profiles.SetSlice([]string{"default"})
} else {
n.Profiles = node.Profiles
n.Profiles.SetSlice(node.Profiles)
}
// node explciti nodename field in NodeConf
n.Id.Set(nodename)
n.Comment.Set(node.Comment)
n.ContainerName.Set(node.ContainerName)
n.ClusterName.Set(node.ClusterName)
n.Ipxe.Set(node.Ipxe)
n.Init.Set(node.Init)
// backward compatibility for old Ipmi config
// backward compatibilty
for keyname, key := range node.Keys {
node.Tags[keyname] = key
delete(node.Keys, keyname)
}
n.SetFrom(node)
// set default/primary network is just one network exist
if len(n.NetDevs) == 1 {
// only way to get the key
for key := range node.NetDevs {
n.NetDevs[key].Primary.SetB(true)
}
}
// backward compatibility
n.Ipmi.Ipaddr.Set(node.IpmiIpaddr)
n.Ipmi.Netmask.Set(node.IpmiNetmask)
n.Ipmi.Port.Set(node.IpmiPort)
@@ -97,7 +104,10 @@ func (config *NodeYaml) FindAllNodes() ([]NodeInfo, error) {
n.Ipmi.Password.Set(node.IpmiPassword)
n.Ipmi.Interface.Set(node.IpmiInterface)
n.Ipmi.Write.Set(node.IpmiWrite)
// delete deprectated structures so that they do not get unmarshalled
n.Kernel.Args.Set(node.KernelArgs)
n.Kernel.Override.Set(node.KernelOverride)
n.Kernel.Override.Set(node.KernelVersion)
// delete deprecated structures so that they do not get unmarshalled
node.IpmiIpaddr = ""
node.IpmiNetmask = ""
node.IpmiGateway = ""
@@ -105,197 +115,24 @@ func (config *NodeYaml) FindAllNodes() ([]NodeInfo, error) {
node.IpmiPassword = ""
node.IpmiInterface = ""
node.IpmiWrite = ""
if node.Ipmi != nil {
n.Ipmi.Ipaddr.Set(node.Ipmi.Ipaddr)
n.Ipmi.Netmask.Set(node.Ipmi.Netmask)
n.Ipmi.Port.Set(node.Ipmi.Port)
n.Ipmi.Gateway.Set(node.Ipmi.Gateway)
n.Ipmi.UserName.Set(node.Ipmi.UserName)
n.Ipmi.Password.Set(node.Ipmi.Password)
n.Ipmi.Interface.Set(node.Ipmi.Interface)
n.Ipmi.Write.Set(node.Ipmi.Write)
}
n.SystemOverlay.SetSlice(node.SystemOverlay)
n.RuntimeOverlay.SetSlice(node.RuntimeOverlay)
n.Root.Set(node.Root)
n.AssetKey.Set(node.AssetKey)
n.Discoverable.Set(node.Discoverable)
// backward compatibility
n.Kernel.Args.Set(node.KernelArgs)
n.Kernel.Override.Set(node.KernelOverride)
n.Kernel.Override.Set(node.KernelVersion)
node.KernelArgs = ""
node.KernelOverride = ""
node.KernelVersion = ""
if node.Kernel != nil {
n.Kernel.Args.Set(node.Kernel.Args)
if node.Kernel.Override != "" {
n.Kernel.Override.Set(node.Kernel.Override)
} else if node.Kernel.Version != "" {
n.Kernel.Override.Set(node.Kernel.Version)
}
}
for devname, netdev := range node.NetDevs {
if _, ok := n.NetDevs[devname]; !ok {
var netdev NetDevEntry
n.NetDevs[devname] = &netdev
}
n.NetDevs[devname].Device.Set(netdev.Device)
n.NetDevs[devname].Ipaddr.Set(netdev.Ipaddr)
n.NetDevs[devname].Ipaddr6.Set(netdev.Ipaddr6)
// Derive value of ipv6 address from ipv4 if not explicitly set
if wwconfig.Ipaddr6 != "" && netdev.Ipaddr != "" {
ipv4Arr := strings.Split(netdev.Ipaddr, ".")
// error can be ignored as check was done at init
_, ipv6Net, _ := net.ParseCIDR(wwconfig.Ipaddr6)
mSize, _ := ipv6Net.Mask.Size()
ipv6str := fmt.Sprintf("%s%s:%s:%s:%s/%v",
ipv6Net.IP.String(), ipv4Arr[0], ipv4Arr[1], ipv4Arr[2], ipv4Arr[3], mSize)
if strings.Count(ipv6Net.IP.String(), ":") == 5 {
ipv6str = strings.Replace(ipv6str, "::", ":", -1)
}
n.NetDevs[devname].Ipaddr6.SetDefault(ipv6str)
}
n.NetDevs[devname].Netmask.Set(netdev.Netmask)
n.NetDevs[devname].Netmask.SetDefault("255.255.255.0")
n.NetDevs[devname].Hwaddr.Set(strings.ToLower(netdev.Hwaddr))
n.NetDevs[devname].Gateway.Set(netdev.Gateway)
n.NetDevs[devname].Type.Set(netdev.Type)
n.NetDevs[devname].OnBoot.Set(netdev.OnBoot)
n.NetDevs[devname].Primary.Set(netdev.Primary)
n.NetDevs[devname].Primary.Set(netdev.Default) // backwards compatibility
// for just one netdev, it is always the primary
if len(node.NetDevs) == 1 {
n.NetDevs[devname].Primary.Set("true")
}
n.NetDevs[devname].Tags = make(map[string]*Entry)
for keyname, key := range netdev.Tags {
if _, ok := n.Tags[keyname]; !ok {
var keyVar Entry
n.NetDevs[devname].Tags[keyname] = &keyVar
}
n.NetDevs[devname].Tags[keyname].Set(key)
}
n.NetDevs[devname].Tags = make(map[string]*Entry)
for keyname, key := range netdev.Tags {
if _, ok := n.Tags[keyname]; !ok {
var keyVar Entry
n.NetDevs[devname].Tags[keyname] = &keyVar
}
n.NetDevs[devname].Tags[keyname].Set(key)
}
}
// Merge Keys into Tags for backwards compatibility
if len(node.Tags) == 0 {
node.Tags = make(map[string]string)
}
for keyname, key := range node.Keys {
node.Tags[keyname] = key
delete(node.Keys, keyname)
}
for keyname, key := range node.Tags {
if _, ok := n.Tags[keyname]; !ok {
var key Entry
n.Tags[keyname] = &key
}
n.Tags[keyname].Set(key)
}
for _, p := range n.Profiles {
if _, ok := config.NodeProfiles[p]; !ok {
wwlog.Printf(wwlog.WARN, "Profile not found for node '%s': %s\n", nodename, p)
for _, profileName := range n.Profiles.GetSlice() {
if _, ok := config.NodeProfiles[profileName]; !ok {
wwlog.Printf(wwlog.WARN, "Profile not found for node '%s': %s\n", nodename, profileName)
continue
}
wwlog.Printf(wwlog.VERBOSE, "Merging profile into node: %s <- %s\n", nodename, p)
n.Comment.SetAlt(config.NodeProfiles[p].Comment, p)
n.ClusterName.SetAlt(config.NodeProfiles[p].ClusterName, p)
n.ContainerName.SetAlt(config.NodeProfiles[p].ContainerName, p)
if config.NodeProfiles[p].Kernel != nil {
n.Kernel.Args.SetAlt(config.NodeProfiles[p].Kernel.Args, p)
}
n.Ipxe.SetAlt(config.NodeProfiles[p].Ipxe, p)
n.Init.SetAlt(config.NodeProfiles[p].Init, p)
if config.NodeProfiles[p].Ipmi != nil {
n.Ipmi.Ipaddr.SetAlt(config.NodeProfiles[p].Ipmi.Ipaddr, p)
n.Ipmi.Netmask.SetAlt(config.NodeProfiles[p].Ipmi.Netmask, p)
n.Ipmi.Port.SetAlt(config.NodeProfiles[p].Ipmi.Port, p)
n.Ipmi.Gateway.SetAlt(config.NodeProfiles[p].Ipmi.Gateway, p)
n.Ipmi.UserName.SetAlt(config.NodeProfiles[p].Ipmi.UserName, p)
n.Ipmi.Password.SetAlt(config.NodeProfiles[p].Ipmi.Password, p)
n.Ipmi.Interface.SetAlt(config.NodeProfiles[p].Ipmi.Interface, p)
n.Ipmi.Write.SetAlt(config.NodeProfiles[p].Ipmi.Write, p)
}
n.SystemOverlay.SetAltSlice(config.NodeProfiles[p].SystemOverlay, p)
n.RuntimeOverlay.SetAltSlice(config.NodeProfiles[p].RuntimeOverlay, p)
n.Root.SetAlt(config.NodeProfiles[p].Root, p)
n.AssetKey.SetAlt(config.NodeProfiles[p].AssetKey, p)
n.Discoverable.SetAlt(config.NodeProfiles[p].Discoverable, p)
if config.NodeProfiles[p].Kernel != nil {
if config.NodeProfiles[p].Kernel.Override != "" {
n.Kernel.Override.SetAlt(config.NodeProfiles[p].Kernel.Override, p)
} else if config.NodeProfiles[p].Kernel.Version != "" {
n.Kernel.Override.SetAlt(config.NodeProfiles[p].Kernel.Version, p)
}
}
for devname, netdev := range config.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.NetDevs[devname].Device.SetAlt(netdev.Device, p)
n.NetDevs[devname].Ipaddr.SetAlt(netdev.Ipaddr, p) //FIXME? <- Ipaddr must be uniq
n.NetDevs[devname].Netmask.SetAlt(netdev.Netmask, p)
n.NetDevs[devname].Hwaddr.SetAlt(strings.ToLower(netdev.Hwaddr), p)
n.NetDevs[devname].Gateway.SetAlt(netdev.Gateway, p)
n.NetDevs[devname].Type.SetAlt(netdev.Type, p)
n.NetDevs[devname].OnBoot.SetAlt(netdev.OnBoot, p)
n.NetDevs[devname].Primary.SetAlt(netdev.Primary, p)
if len(netdev.Tags) != 0 {
if len(n.NetDevs[devname].Tags) == 0 {
n.NetDevs[devname].Tags = make(map[string]*Entry)
}
for keyname, key := range netdev.Tags {
if _, ok := n.NetDevs[devname].Tags[keyname]; !ok {
var keyVar Entry
n.NetDevs[devname].Tags[keyname] = &keyVar
}
n.NetDevs[devname].Tags[keyname].SetAlt(key, p)
}
}
}
// Merge Keys into Tags for backwards compatibility
if len(config.NodeProfiles[p].Tags) == 0 {
config.NodeProfiles[p].Tags = make(map[string]string)
}
for keyname, key := range config.NodeProfiles[p].Keys {
config.NodeProfiles[p].Tags[keyname] = key
delete(config.NodeProfiles[p].Keys, keyname)
}
for keyname, key := range config.NodeProfiles[p].Tags {
if _, ok := n.Tags[keyname]; !ok {
var key Entry
n.Tags[keyname] = &key
}
n.Tags[keyname].SetAlt(key, p)
}
// can't call setFrom() as we have to use SetAlt instead of Set for an Entry
wwlog.Printf(wwlog.VERBOSE, "Merging profile into node: %s <- %s\n", nodename, profileName)
n.SetAltFrom(config.NodeProfiles[profileName], profileName)
}
ret = append(ret, n)
}
sort.Slice(ret, func(i, j int) bool {
@@ -312,6 +149,9 @@ func (config *NodeYaml) FindAllNodes() ([]NodeInfo, error) {
return ret, nil
}
/*
Return all profiles as NodeInfo
*/
func (config *NodeYaml) FindAllProfiles() ([]NodeInfo, error) {
var ret []NodeInfo
@@ -322,27 +162,12 @@ func (config *NodeYaml) FindAllProfiles() ([]NodeInfo, error) {
p.Kernel = new(KernelEntry)
p.Ipmi = new(IpmiEntry)
p.Id.Set(name)
p.Comment.Set(profile.Comment)
p.ClusterName.Set(profile.ClusterName)
p.ContainerName.Set(profile.ContainerName)
p.Ipxe.Set(profile.Ipxe)
p.Init.Set(profile.Init)
// backward compatibility
p.Kernel.Args.Set(profile.KernelArgs)
p.Kernel.Override.Set(profile.KernelOverride)
p.Kernel.Override.Set(profile.KernelVersion)
profile.KernelArgs = ""
profile.KernelOverride = ""
profile.KernelVersion = ""
if profile.Kernel != nil {
p.Kernel.Args.Set(profile.Kernel.Args)
if profile.Kernel.Override != "" {
p.Kernel.Override.Set(profile.Kernel.Override)
} else if profile.Kernel.Version != "" {
p.Kernel.Override.Set(profile.Kernel.Version)
}
for keyname, key := range profile.Keys {
profile.Tags[keyname] = key
delete(profile.Keys, keyname)
}
// backward compatibility for old Ipmi config
p.SetFrom(profile)
p.Ipmi.Ipaddr.Set(profile.IpmiIpaddr)
p.Ipmi.Netmask.Set(profile.IpmiNetmask)
p.Ipmi.Port.Set(profile.IpmiPort)
@@ -351,7 +176,10 @@ func (config *NodeYaml) FindAllProfiles() ([]NodeInfo, error) {
p.Ipmi.Password.Set(profile.IpmiPassword)
p.Ipmi.Interface.Set(profile.IpmiInterface)
p.Ipmi.Write.Set(profile.IpmiWrite)
// delete deprectated structures so that they do not get unmarshalled
p.Kernel.Args.Set(profile.KernelArgs)
p.Kernel.Override.Set(profile.KernelOverride)
p.Kernel.Override.Set(profile.KernelVersion)
// delete deprecated stuff
profile.IpmiIpaddr = ""
profile.IpmiNetmask = ""
profile.IpmiGateway = ""
@@ -359,77 +187,16 @@ func (config *NodeYaml) FindAllProfiles() ([]NodeInfo, error) {
profile.IpmiPassword = ""
profile.IpmiInterface = ""
profile.IpmiWrite = ""
if profile.Ipmi != nil {
p.Ipmi.Netmask.Set(profile.Ipmi.Netmask)
p.Ipmi.Port.Set(profile.Ipmi.Port)
p.Ipmi.Gateway.Set(profile.Ipmi.Gateway)
p.Ipmi.UserName.Set(profile.Ipmi.UserName)
p.Ipmi.Password.Set(profile.Ipmi.Password)
p.Ipmi.Interface.Set(profile.Ipmi.Interface)
p.Ipmi.Write.Set(profile.Ipmi.Write)
}
p.RuntimeOverlay.SetSlice(profile.RuntimeOverlay)
p.SystemOverlay.SetSlice(profile.SystemOverlay)
p.Root.Set(profile.Root)
p.AssetKey.Set(profile.AssetKey)
p.Discoverable.Set(profile.Discoverable)
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].Device.Set(netdev.Device)
p.NetDevs[devname].Netmask.Set(netdev.Netmask)
p.NetDevs[devname].Gateway.Set(netdev.Gateway)
p.NetDevs[devname].Type.Set(netdev.Type)
p.NetDevs[devname].OnBoot.Set(netdev.OnBoot)
p.NetDevs[devname].Primary.Set(netdev.Primary)
p.NetDevs[devname].Primary.Set(netdev.Default) // backwards compatibility
// The following should not be set in a profile.
if netdev.Ipaddr != "" {
wwlog.Printf(wwlog.WARN, "Ignoring ip address %v in profile %v\n", netdev.Ipaddr, name)
}
if netdev.Hwaddr != "" {
wwlog.Printf(wwlog.WARN, "Ignoring hardware address %v in profile %v\n", netdev.Hwaddr, name)
}
p.NetDevs[devname].Tags = make(map[string]*Entry)
for keyname, key := range netdev.Tags {
if _, ok := p.Tags[keyname]; !ok {
var keyVar Entry
p.NetDevs[devname].Tags[keyname] = &keyVar
}
p.NetDevs[devname].Tags[keyname].Set(key)
}
}
profile.KernelArgs = ""
profile.KernelOverride = ""
profile.KernelVersion = ""
// Merge Keys into Tags for backwards compatibility
if len(profile.Tags) == 0 {
profile.Tags = make(map[string]string)
}
for keyname, key := range profile.Keys {
profile.Tags[keyname] = key
delete(profile.Keys, keyname)
}
for keyname, key := range profile.Tags {
if _, ok := p.Tags[keyname]; !ok {
var key Entry
p.Tags[keyname] = &key
}
p.Tags[keyname].Set(key)
}
// TODO: Validate or die on all inputs
ret = append(ret, p)
}
sort.Slice(ret, func(i, j int) bool {
if ret[i].ClusterName.Get() < ret[j].ClusterName.Get() {
return true
@@ -444,6 +211,17 @@ func (config *NodeYaml) FindAllProfiles() ([]NodeInfo, error) {
return ret, nil
}
/*
Return the names of all available profiles
*/
func (config *NodeYaml) ListAllProfiles() []string {
var ret []string
for name := range config.NodeProfiles {
ret = append(ret, name)
}
return ret
}
func (config *NodeYaml) FindDiscoverableNode() (NodeInfo, string, error) {
var ret NodeInfo

View File

@@ -19,65 +19,73 @@ type NodeYaml struct {
NodeConf is the datastructure which is stored on disk.
*/
type NodeConf struct {
Comment string `yaml:"comment,omitempty"`
ClusterName string `yaml:"cluster name,omitempty"`
ContainerName string `yaml:"container name,omitempty"`
Ipxe string `yaml:"ipxe template,omitempty"`
KernelVersion string `yaml:"kernel version,omitempty"`
KernelOverride string `yaml:"kernel override,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"`
IpmiPort string `yaml:"ipmi port,omitempty"`
IpmiGateway string `yaml:"ipmi gateway,omitempty"`
IpmiInterface string `yaml:"ipmi interface,omitempty"`
IpmiWrite string `yaml:"ipmi write,omitempty"`
RuntimeOverlay []string `yaml:"runtime overlay,omitempty"`
SystemOverlay []string `yaml:"system overlay,omitempty"`
Comment string `yaml:"comment,omitempty" lopt:"comment" comment:"Set arbitrary string comment"`
ClusterName string `yaml:"cluster name,omitempty" lopt:"cluster" sopt:"c" comment:"Set cluster group"`
ContainerName string `yaml:"container name,omitempty" lopt:"container" sopt:"C" comment:"Set container name"`
Ipxe string `yaml:"ipxe template,omitempty" lopt:"ipxe" comment:"Set the iPXE template name"`
// Deprecated start
// Kernel settings here are deprecated and here for backward comptability
KernelVersion string `yaml:"kernel version,omitempty"`
KernelOverride string `yaml:"kernel override,omitempty"`
KernelArgs string `yaml:"kernel args,omitempty"`
// Ipmi settings herer are deprecated and here for backward comptability
IpmiUserName string `yaml:"ipmi username,omitempty"`
IpmiPassword string `yaml:"ipmi password,omitempty"`
IpmiIpaddr string `yaml:"ipmi ipaddr,omitempty"`
IpmiNetmask string `yaml:"ipmi netmask,omitempty"`
IpmiPort string `yaml:"ipmi port,omitempty"`
IpmiGateway string `yaml:"ipmi gateway,omitempty"`
IpmiInterface string `yaml:"ipmi interface,omitempty"`
IpmiWrite string `yaml:"ipmi write,omitempty"`
// Deprecated end
RuntimeOverlay []string `yaml:"runtime overlay,omitempty" lopt:"runtime" sopt:"R" comment:"Set the runtime overlay"`
SystemOverlay []string `yaml:"system overlay,omitempty" lopt:"wwinit" sopt:"O" comment:"Set the system overlay"`
Kernel *KernelConf `yaml:"kernel,omitempty"`
Ipmi *IpmiConf `yaml:"ipmi,omitempty"`
Init string `yaml:"init,omitempty"`
Root string `yaml:"root,omitempty"`
AssetKey string `yaml:"asset key,omitempty"`
Discoverable string `yaml:"discoverable,omitempty"`
Profiles []string `yaml:"profiles,omitempty"`
Init string `yaml:"init,omitempty" lopt:"init" sopt:"i" comment:"Define the init process to boot the container"`
Root string `yaml:"root,omitempty" lopt:"root" comment:"Define the rootfs" `
AssetKey string `yaml:"asset key,omitempty" lopt:"asset" comment:"Set the node's Asset tag (key)"`
Discoverable string `yaml:"discoverable,omitempty" lopt:"discoverable" comment:"Make discoverable in given network (yes/no)"`
Profiles []string `yaml:"profiles,omitempty" lopt:"profile" sopt:"P" comment:"Set the node's profile members (comma separated)"`
NetDevs map[string]*NetDevs `yaml:"network devices,omitempty"`
Tags map[string]string `yaml:"tags,omitempty"`
Keys map[string]string `yaml:"keys,omitempty"` // Reverse compatibility
Tags map[string]string `yaml:"tags,omitempty" lopt:"tagadd" comment:"base key"`
TagsDel []string `yaml:"tagsdel,omitempty" lopt:"tagdel" comment:"remove this tags"` // should not go to disk only to wire
Keys map[string]string `yaml:"keys,omitempty"` // Reverse compatibility
}
type IpmiConf struct {
UserName string `yaml:"username,omitempty"`
Password string `yaml:"password,omitempty"`
Ipaddr string `yaml:"ipaddr,omitempty"`
Netmask string `yaml:"netmask,omitempty"`
Port string `yaml:"port,omitempty"`
Gateway string `yaml:"gateway,omitempty"`
Interface string `yaml:"interface,omitempty"`
Write string `yaml:"write,omitempty"`
UserName string `yaml:"username,omitempty" lopt:"ipmiuser" comment:"Set the IPMI username"`
Password string `yaml:"password,omitempty" lopt:"ipmipass" comment:"Set the IPMI password"`
Ipaddr string `yaml:"ipaddr,omitempty" lopt:"ipmiaddr" comment:"Set the IPMI IP address"`
Netmask string `yaml:"netmask,omitempty" lopt:"ipminetmask" comment:"Set the IPMI netmask"`
Port string `yaml:"port,omitempty" lopt:"ipmiport" comment:"Set the IPMI port"`
Gateway string `yaml:"gateway,omitempty" lopt:"ipmigateway" comment:"Set the IPMI gateway"`
Interface string `yaml:"interface,omitempty" lopt:"ipmiinterface" comment:"Set the node's IPMI interface (defaults: 'lan')"`
Write string `yaml:"write,omitempty" lopt:"ipmiwrite" comment:"Enable the write of impi configuration (yes/no)"`
Tags map[string]string `yaml:"tags,omitempty" lopt:"ipmitagadd" comment:"add ipmitags"`
TagsDel []string `yaml:"tagsdel,omitempty" lopt:"ipmitagdel" comment:"remove ipmitags"` // should not go to disk only to wire
}
type KernelConf struct {
Version string `yaml:"version,omitempty"`
Override string `yaml:"override,omitempty"`
Args string `yaml:"args,omitempty"`
Override string `yaml:"override,omitempty" lopt:"kerneloverride" sopt:"K" comment:"Set kernel override version"`
Args string `yaml:"args,omitempty" lopt:"kernelargs" sopt:"A" comment:"Set Kernel argument"`
}
type NetDevs struct {
Type string `yaml:"type,omitempty"`
OnBoot string `yaml:"onboot,omitempty"`
Device string `yaml:"device,omitempty"`
Hwaddr string `yaml:"hwaddr,omitempty"`
Ipaddr string `yaml:"ipaddr,omitempty"`
Type string `yaml:"type,omitempty" lopt:"type" sopt:"T" comment:"Set device type of given network"`
OnBoot string `yaml:"onboot,omitempty" lopt:"onboot" comment:"Enable/disable network device (yes/no)"`
Device string `yaml:"device,omitempty" lopt:"netdev" sopt:"N" comment:"Set the device for given network"`
Hwaddr string `yaml:"hwaddr,omitempty" lopt:"hwaddr" sopt:"H" comment:"Set the device's HW address for given network"`
Ipaddr string `yaml:"ipaddr,omitempty" comment:"IPv4 address in given network" sopt:"I" lopt:"ipaddr"`
IpCIDR string `yaml:"ipcidr,omitempty"`
Ipaddr6 string `yaml:"ip6addr,omitempty"`
Ipaddr6 string `yaml:"ip6addr,omitempty" lopt:"ipaddr6" comment:"IPv6 address"`
Prefix string `yaml:"prefix,omitempty"`
Netmask string `yaml:"netmask,omitempty"`
Gateway string `yaml:"gateway,omitempty"`
Primary string `yaml:"primary,omitempty"`
Netmask string `yaml:"netmask,omitempty" lopt:"netmask" sopt:"M" comment:"Set the networks netmask"`
Gateway string `yaml:"gateway,omitempty" lopt:"gateway" sopt:"G" comment:"Set the node's network device gateway"`
Primary string `yaml:"primary,omitempty" lopt:"primary" comment:"Enable/disable network device as primary (yes/no)"`
Default string `yaml:"default,omitempty"` /* backward compatibility */
Tags map[string]string `yaml:"tags,omitempty"`
Tags map[string]string `yaml:"tags,omitempty" lopt:"nettagadd" comment:"network tags"`
TagsDel []string `yaml:"tagsdel,omitempty" lopt:"nettagdel" comment:"delete network tags"` // should not go to disk only to wire
}
/******
@@ -103,7 +111,6 @@ node itself, for all values of type Entry.
*/
type NodeInfo struct {
Id Entry
Cid Entry
Comment Entry
ClusterName Entry
ContainerName Entry
@@ -116,8 +123,7 @@ type NodeInfo struct {
AssetKey Entry
Kernel *KernelEntry
Ipmi *IpmiEntry
Profiles []string
GroupProfiles []string
Profiles Entry
NetDevs map[string]*NetDevEntry
Tags map[string]*Entry
}
@@ -131,10 +137,10 @@ type IpmiEntry struct {
Password Entry
Interface Entry
Write Entry
Tags map[string]*Entry
}
type KernelEntry struct {
Version Entry
Override Entry
Args Entry
}
@@ -154,6 +160,9 @@ type NetDevEntry struct {
Tags map[string]*Entry
}
// string which is printed if no value is set
const NoValue = "--"
func init() {
// Check that nodes.conf is found
if !util.IsFile(ConfigFile) {

View File

@@ -5,6 +5,7 @@ import (
"regexp"
"strings"
"github.com/hpcng/warewulf/internal/pkg/util"
"github.com/hpcng/warewulf/internal/pkg/wwlog"
)
@@ -13,6 +14,7 @@ import (
* Filters
*
*********/
/*
Filter a given slice of NodeInfo against a given
regular expression
@@ -47,10 +49,10 @@ func FilterByName(set []NodeInfo, searchList []string) []NodeInfo {
*********/
/*
Set value. If argument is 'UNDEF', 'DELETE',
'UNSET" or '--' the value is removed.
N.B. the '--' might never ever happen as '--'
is parsed out by cobra
Set value. If argument is 'UNDEF', 'DELETE',
'UNSET" or '--' the value is removed.
N.B. the '--' might never ever happen as '--'
is parsed out by cobra
*/
func (ent *Entry) Set(val string) {
if val == "" {
@@ -79,6 +81,8 @@ func (ent *Entry) SetB(val bool) {
func (ent *Entry) SetSlice(val []string) {
if len(val) == 0 {
return
} else if len(val) == 1 && val[0] == "" { // check also for an "empty" slice
return
}
if val[0] == "UNDEF" || val[0] == "DELETE" || val[0] == "UNSET" || val[0] == "--" {
ent.value = []string{}
@@ -144,6 +148,13 @@ func (ent *Entry) SetDefaultSlice(val []string) {
}
/*
Remove a element from a slice
*/
func (ent *Entry) SliceRemoveElement(val string) {
util.SliceRemoveElement(ent.value, val)
}
/**********
*
* Gets
@@ -299,3 +310,13 @@ func (ent *Entry) Defined() bool {
}
return false
}
/*
Create an empty node NodeConf
*/
func NewConf() (nodeconf NodeConf) {
nodeconf.Ipmi = new(IpmiConf)
nodeconf.Kernel = new(KernelConf)
nodeconf.NetDevs = map[string]*NetDevs{}
return nodeconf
}

View File

@@ -29,7 +29,7 @@ func (config *NodeYaml) AddNode(nodeID string) (NodeInfo, error) {
config.Nodes[nodeID].Profiles = []string{"default"}
config.Nodes[nodeID].NetDevs = make(map[string]*NetDevs)
n.Id.Set(nodeID)
n.Profiles = []string{"default"}
n.Profiles.SetSlice([]string{"default"})
n.NetDevs = make(map[string]*NetDevEntry)
n.Ipmi = new(IpmiEntry)
n.Kernel = new(KernelEntry)
@@ -55,68 +55,7 @@ func (config *NodeYaml) NodeUpdate(node NodeInfo) error {
if _, ok := config.Nodes[nodeID]; !ok {
return errors.New("Nodename does not exist: " + nodeID)
}
config.Nodes[nodeID].Comment = node.Comment.GetReal()
config.Nodes[nodeID].ContainerName = node.ContainerName.GetReal()
config.Nodes[nodeID].ClusterName = node.ClusterName.GetReal()
config.Nodes[nodeID].Ipxe = node.Ipxe.GetReal()
config.Nodes[nodeID].Init = node.Init.GetReal()
if node.Kernel != nil && (node.Kernel.Override.GotReal() || node.Kernel.Args.GotReal()) {
config.Nodes[nodeID].Kernel = new(KernelConf)
config.Nodes[nodeID].Kernel.Override = node.Kernel.Override.GetReal()
config.Nodes[nodeID].Kernel.Args = node.Kernel.Args.GetReal()
}
if node.Ipmi != nil && (node.Ipmi.Ipaddr.GotReal() || node.Ipmi.Netmask.GotReal() ||
node.Ipmi.Port.GotReal() || node.Ipmi.Gateway.GotReal() || node.Ipmi.UserName.GotReal() ||
node.Ipmi.Password.GotReal() || node.Ipmi.Interface.GotReal() || node.Ipmi.Write.GotReal()) {
config.Nodes[nodeID].Ipmi = new(IpmiConf)
config.Nodes[nodeID].Ipmi.Ipaddr = node.Ipmi.Ipaddr.GetReal()
config.Nodes[nodeID].Ipmi.Netmask = node.Ipmi.Netmask.GetReal()
config.Nodes[nodeID].Ipmi.Port = node.Ipmi.Port.GetReal()
config.Nodes[nodeID].Ipmi.Gateway = node.Ipmi.Gateway.GetReal()
config.Nodes[nodeID].Ipmi.UserName = node.Ipmi.UserName.GetReal()
config.Nodes[nodeID].Ipmi.Password = node.Ipmi.Password.GetReal()
config.Nodes[nodeID].Ipmi.Interface = node.Ipmi.Interface.GetReal()
config.Nodes[nodeID].Ipmi.Write = node.Ipmi.Write.GetReal()
}
config.Nodes[nodeID].RuntimeOverlay = node.RuntimeOverlay.GetRealSlice()
config.Nodes[nodeID].SystemOverlay = node.SystemOverlay.GetRealSlice()
config.Nodes[nodeID].Root = node.Root.GetReal()
config.Nodes[nodeID].AssetKey = node.AssetKey.GetReal()
config.Nodes[nodeID].Discoverable = node.Discoverable.GetReal()
config.Nodes[nodeID].Profiles = node.Profiles
config.Nodes[nodeID].NetDevs = make(map[string]*NetDevs)
for devname, netdev := range node.NetDevs {
var newdev NetDevs
config.Nodes[nodeID].NetDevs[devname] = &newdev
config.Nodes[nodeID].NetDevs[devname].Device = netdev.Device.GetReal()
config.Nodes[nodeID].NetDevs[devname].Ipaddr = netdev.Ipaddr.GetReal()
config.Nodes[nodeID].NetDevs[devname].Netmask = netdev.Netmask.GetReal()
config.Nodes[nodeID].NetDevs[devname].Hwaddr = netdev.Hwaddr.GetReal()
config.Nodes[nodeID].NetDevs[devname].Gateway = netdev.Gateway.GetReal()
config.Nodes[nodeID].NetDevs[devname].Type = netdev.Type.GetReal()
config.Nodes[nodeID].NetDevs[devname].OnBoot = netdev.OnBoot.GetReal()
config.Nodes[nodeID].NetDevs[devname].Primary = netdev.Primary.GetReal()
config.Nodes[nodeID].NetDevs[devname].Tags = make(map[string]string)
for keyname, key := range netdev.Tags {
if key.GetReal() != "" {
config.Nodes[nodeID].NetDevs[devname].Tags[keyname] = key.GetReal()
}
}
}
config.Nodes[nodeID].Tags = make(map[string]string)
for keyname, key := range node.Tags {
if key.GetReal() != "" {
config.Nodes[nodeID].Tags[keyname] = key.GetReal()
}
}
config.Nodes[nodeID].GetRealFrom(node)
return nil
}
@@ -164,61 +103,7 @@ func (config *NodeYaml) ProfileUpdate(profile NodeInfo) error {
if _, ok := config.NodeProfiles[profileID]; !ok {
return errors.New("Profile name does not exist: " + profileID)
}
config.NodeProfiles[profileID].Comment = profile.Comment.GetReal()
config.NodeProfiles[profileID].ContainerName = profile.ContainerName.GetReal()
config.NodeProfiles[profileID].Ipxe = profile.Ipxe.GetReal()
config.NodeProfiles[profileID].Init = profile.Init.GetReal()
config.NodeProfiles[profileID].ClusterName = profile.ClusterName.GetReal()
if profile.Kernel.Override.GotReal() || profile.Kernel.Args.GotReal() {
config.NodeProfiles[profileID].Kernel = new(KernelConf)
config.NodeProfiles[profileID].Kernel.Override = profile.Kernel.Override.GetReal()
config.NodeProfiles[profileID].Kernel.Args = profile.Kernel.Args.GetReal()
}
if profile.Ipmi.Ipaddr.GotReal() || profile.Ipmi.Netmask.GotReal() ||
profile.Ipmi.Port.GotReal() || profile.Ipmi.Gateway.GotReal() || profile.Ipmi.UserName.GotReal() ||
profile.Ipmi.Password.GotReal() || profile.Ipmi.Interface.GotReal() || profile.Ipmi.Write.GotReal() {
config.NodeProfiles[profileID].Ipmi = new(IpmiConf)
config.NodeProfiles[profileID].Ipmi.Ipaddr = profile.Ipmi.Ipaddr.GetReal()
config.NodeProfiles[profileID].Ipmi.Netmask = profile.Ipmi.Netmask.GetReal()
config.NodeProfiles[profileID].Ipmi.Port = profile.Ipmi.Port.GetReal()
config.NodeProfiles[profileID].Ipmi.Gateway = profile.Ipmi.Gateway.GetReal()
config.NodeProfiles[profileID].Ipmi.UserName = profile.Ipmi.UserName.GetReal()
config.NodeProfiles[profileID].Ipmi.Password = profile.Ipmi.Password.GetReal()
config.NodeProfiles[profileID].Ipmi.Interface = profile.Ipmi.Interface.GetReal()
config.NodeProfiles[profileID].Ipmi.Write = profile.Ipmi.Interface.GetReal()
}
config.NodeProfiles[profileID].RuntimeOverlay = profile.RuntimeOverlay.GetRealSlice()
config.NodeProfiles[profileID].SystemOverlay = profile.SystemOverlay.GetRealSlice()
config.NodeProfiles[profileID].Root = profile.Root.GetReal()
config.NodeProfiles[profileID].AssetKey = profile.AssetKey.GetReal()
config.NodeProfiles[profileID].Discoverable = profile.Discoverable.GetReal()
config.NodeProfiles[profileID].Profiles = profile.Profiles
config.NodeProfiles[profileID].NetDevs = make(map[string]*NetDevs)
for devname, netdev := range profile.NetDevs {
var newdev NetDevs
config.NodeProfiles[profileID].NetDevs[devname] = &newdev
config.NodeProfiles[profileID].NetDevs[devname].Device = netdev.Device.GetReal()
config.NodeProfiles[profileID].NetDevs[devname].Ipaddr = netdev.Ipaddr.GetReal()
config.NodeProfiles[profileID].NetDevs[devname].Netmask = netdev.Netmask.GetReal()
config.NodeProfiles[profileID].NetDevs[devname].Hwaddr = netdev.Hwaddr.GetReal()
config.NodeProfiles[profileID].NetDevs[devname].Gateway = netdev.Gateway.GetReal()
config.NodeProfiles[profileID].NetDevs[devname].Type = netdev.Type.GetReal()
config.NodeProfiles[profileID].NetDevs[devname].OnBoot = netdev.OnBoot.GetReal()
config.NodeProfiles[profileID].NetDevs[devname].Primary = netdev.Primary.GetReal()
config.NodeProfiles[profileID].NetDevs[devname].Tags = make(map[string]string)
for key := range netdev.Tags {
config.NodeProfiles[profileID].NetDevs[devname].Tags[key] = netdev.Tags[key].GetReal()
}
}
config.NodeProfiles[profileID].Tags = make(map[string]string)
for keyname, key := range profile.Tags {
config.NodeProfiles[profileID].Tags[keyname] = key.GetReal()
}
config.NodeProfiles[profileID].GetRealFrom(profile)
return nil
}
@@ -227,9 +112,17 @@ func (config *NodeYaml) ProfileUpdate(profile NodeInfo) error {
* PERSISTENCE
*
****/
/*
Write the the NodeYaml to disk.
*/
func (config *NodeYaml) Persist() error {
// flatten out profiles and nodes
for _, val := range config.NodeProfiles {
val.Flatten()
}
for _, val := range config.Nodes {
val.Flatten()
}
out, err := yaml.Marshal(config)
if err != nil {
return err

View File

@@ -0,0 +1,440 @@
package node
import (
"reflect"
"github.com/hpcng/warewulf/internal/pkg/util"
"github.com/spf13/cobra"
)
/*
Populates a NodeConf struct (the one which goes to disk) from a
NodeInfo (which just lives in memory), with the values from all
the underlying entries using GetReal, so just the explicit values
go do disk.
*/
func (nodeConf *NodeConf) GetRealFrom(nodeInfo NodeInfo) {
nodeConf.getterFrom(nodeInfo, (*Entry).GetReal, (*Entry).GetRealSlice)
}
/*
Populates a NodeConf struct from a NodeInfo, with the combined
values from the underlying entries using Get.
*/
func (nodeConf *NodeConf) GetFrom(nodeInfo NodeInfo) {
nodeConf.getterFrom(nodeInfo, (*Entry).Get, (*Entry).GetSlice)
}
/*
Abstract function which populates a NodeConf form the given NodeInfo
via getter functions.
*/
func (nodeConf *NodeConf) getterFrom(nodeInfo NodeInfo,
getter func(*Entry) string,
getterSlice func(*Entry) []string) {
nodeInfoType := reflect.TypeOf(nodeInfo)
nodeInfoVal := reflect.ValueOf(nodeInfo)
configVal := reflect.ValueOf(nodeConf)
// now iterate of every field
for i := 0; i < nodeInfoType.NumField(); i++ {
// found field with same name for Conf and Info
confField := configVal.Elem().FieldByName(nodeInfoType.Field(i).Name)
if confField.IsValid() {
if nodeInfoVal.Field(i).Type() == reflect.TypeOf(Entry{}) {
if confField.Type().Kind() == reflect.String {
newValue := (confField.Addr().Interface()).(*string)
entryVal := nodeInfoVal.Field(i).Interface().(Entry)
*newValue = getter(&entryVal)
} else if confField.Type() == reflect.TypeOf([]string{}) {
newValue := (confField.Addr().Interface()).(*[]string)
entryVal := nodeInfoVal.Field(i).Interface().(Entry)
*newValue = getterSlice(&entryVal)
}
} else if nodeInfoVal.Field(i).Type() == reflect.TypeOf(map[string]*Entry{}) {
entryMap := nodeInfoVal.Field(i).Interface().(map[string]*Entry)
confMap := confField.Interface().(map[string]string)
if len(confMap) > len(entryMap) {
for confKey := range confMap {
foundKey := false
for entrKey := range entryMap {
if confKey == entrKey {
foundKey = true
}
}
if !foundKey {
delete(confMap, confKey)
}
}
}
for key, val := range entryMap {
confMap[key] = getter(val)
}
} else if nodeInfoVal.Field(i).Type().Kind() == reflect.Ptr {
if confField.Addr().Elem().IsZero() {
switch confField.Addr().Elem().Type() {
case reflect.TypeOf((*KernelConf)(nil)):
var newConf KernelConf
newConfPtr := (confField.Addr().Elem().Addr().Interface()).(**KernelConf)
*newConfPtr = &newConf
case reflect.TypeOf((*IpmiConf)(nil)):
var newConf IpmiConf
newConfPtr := (confField.Addr().Elem().Addr().Interface()).(**IpmiConf)
*newConfPtr = &newConf
}
}
nestedInfoType := reflect.TypeOf(nodeInfoVal.Field(i).Interface())
nestedInfoVal := reflect.ValueOf(nodeInfoVal.Field(i).Interface())
nestedConfVal := reflect.ValueOf(confField.Interface())
for j := 0; j < nestedInfoType.Elem().NumField(); j++ {
nestedVal := nestedConfVal.Elem().FieldByName(nestedInfoType.Elem().Field(j).Name)
if nestedInfoVal.Elem().Field(j).Type() == reflect.TypeOf(Entry{}) {
if nestedVal.Type().Kind() == reflect.String {
newValue := (nestedVal.Addr().Interface()).(*string)
entryVal := nestedInfoVal.Elem().Field(j).Interface().(Entry)
*newValue = getter(&entryVal)
} else if nestedVal.Type() == reflect.TypeOf([]string{}) {
newValue := (nestedVal.Addr().Interface()).(*[]string)
entryVal := nestedInfoVal.Elem().Field(j).Interface().(Entry)
*newValue = getterSlice(&entryVal)
}
} else if nestedInfoVal.Elem().Field(j).Type() == reflect.TypeOf(map[string]*Entry{}) {
if nestedVal.IsNil() {
mapPtr := nestedVal.Addr().Interface().(*map[string]string)
*mapPtr = make(map[string]string)
}
entryMap := nestedInfoVal.Elem().Field(j).Interface().(map[string]*Entry)
confMap := nestedVal.Interface().(map[string]string)
if len(confMap) > len(entryMap) {
for confKey := range confMap {
foundKey := false
for entrKey := range entryMap {
if confKey == entrKey {
foundKey = true
}
}
if !foundKey {
delete(confMap, confKey)
}
}
}
for key, val := range entryMap {
confMap[key] = getter(val)
}
}
}
} else if nodeInfoVal.Field(i).Type() == reflect.TypeOf(map[string]*NetDevEntry{}) {
if confField.IsNil() {
netMapPtr := confField.Addr().Interface().(*map[string](*NetDevs))
*netMapPtr = make(map[string](*NetDevs))
}
nestedMap := nodeInfoVal.Field(i).Interface().(map[string]*NetDevEntry)
netMap := confField.Interface().(map[string](*NetDevs))
// check if a network was deleted
if len(netMap) > len(nestedMap) {
for netMapKey := range netMap {
foundKey := false
for nestedMapKey := range nestedMap {
if netMapKey == nestedMapKey {
foundKey = true
}
}
if !foundKey {
delete(netMap, netMapKey)
}
}
}
for netName, netVal := range nestedMap {
netValsType := reflect.ValueOf(netVal)
if _, ok := netMap[netName]; !ok {
netMap[netName] = new(NetDevs)
}
netConfType := reflect.TypeOf(*netMap[netName])
netConfVal := reflect.ValueOf(netMap[netName])
for j := 0; j < netConfType.NumField(); j++ {
netVal := netValsType.Elem().FieldByName(netConfType.Field(j).Name)
if netVal.IsValid() {
if netVal.Type() == reflect.TypeOf(Entry{}) {
newVal := netConfVal.Elem().Field(j).Addr().Interface().((*string))
*newVal = getter((netVal.Addr().Interface()).(*Entry))
} else if netVal.Type() == reflect.TypeOf(map[string]*Entry{}) {
entryMap := netVal.Interface().(map[string](*Entry))
confMap := netConfVal.Elem().Field(j).Interface().(map[string]string)
if len(confMap) > len(entryMap) {
for confMapKey := range confMap {
foundKey := false
for entryMapKey := range entryMap {
if confMapKey == entryMapKey {
foundKey = true
}
}
if !foundKey {
delete(netConfVal.Elem().Field(j).Interface().(map[string]string), confMapKey)
}
}
}
for key, val := range entryMap {
netConfVal.Elem().Field(j).Interface().(map[string]string)[key] = getter(val)
}
}
}
}
}
}
}
}
}
func (nodeConf *NodeConf) CreateFlags(baseCmd *cobra.Command, excludeList []string) {
nodeInfoType := reflect.TypeOf(nodeConf)
nodeInfoVal := reflect.ValueOf(nodeConf)
// now iterate of every field
for i := 0; i < nodeInfoVal.Elem().NumField(); i++ {
if nodeInfoType.Elem().Field(i).Tag.Get("comment") != "" &&
!util.InSlice(excludeList, nodeInfoType.Elem().Field(i).Tag.Get("lopt")) {
field := nodeInfoVal.Elem().Field(i)
createFlags(baseCmd, excludeList, nodeInfoType.Elem().Field(i), &field)
} else if nodeInfoType.Elem().Field(i).Type.Kind() == reflect.Ptr {
nestType := reflect.TypeOf(nodeInfoVal.Elem().Field(i).Interface())
nestVal := reflect.ValueOf(nodeInfoVal.Elem().Field(i).Interface())
for j := 0; j < nestType.Elem().NumField(); j++ {
field := nestVal.Elem().Field(j)
createFlags(baseCmd, excludeList, nestType.Elem().Field(j), &field)
}
} else if nodeInfoType.Elem().Field(i).Type == reflect.TypeOf(map[string]*NetDevs(nil)) {
netMap := nodeInfoVal.Elem().Field(i).Interface().(map[string]*NetDevs)
// add a default network so that it can hold values
key := "default"
if len(netMap) == 0 {
netMap[key] = new(NetDevs)
} else {
for keyIt := range netMap {
key = keyIt
break
}
}
netType := reflect.TypeOf(netMap[key])
netVal := reflect.ValueOf(netMap[key])
for j := 0; j < netType.Elem().NumField(); j++ {
field := netVal.Elem().Field(j)
createFlags(baseCmd, excludeList, netType.Elem().Field(j), &field)
}
}
}
}
/*
Helper function to create the different PerisitantFlags() for different types.
*/
func createFlags(baseCmd *cobra.Command, excludeList []string,
myType reflect.StructField, myVal *reflect.Value) {
if myType.Tag.Get("lopt") != "" {
if myType.Type.Kind() == reflect.String {
ptr := myVal.Addr().Interface().(*string)
if myType.Tag.Get("sopt") != "" {
baseCmd.PersistentFlags().StringVarP(ptr,
myType.Tag.Get("lopt"),
myType.Tag.Get("sopt"),
myType.Tag.Get("default"),
myType.Tag.Get("comment"))
} else if !util.InSlice(excludeList, myType.Tag.Get("lopt")) {
baseCmd.PersistentFlags().StringVar(ptr,
myType.Tag.Get("lopt"),
myType.Tag.Get("default"),
myType.Tag.Get("comment"))
}
} else if myType.Type == reflect.TypeOf([]string{}) {
ptr := myVal.Addr().Interface().(*[]string)
if myType.Tag.Get("sopt") != "" {
baseCmd.PersistentFlags().StringSliceVarP(ptr,
myType.Tag.Get("lopt"),
myType.Tag.Get("sopt"),
[]string{myType.Tag.Get("default")},
myType.Tag.Get("comment"))
} else if !util.InSlice(excludeList, myType.Tag.Get("lopt")) {
baseCmd.PersistentFlags().StringSliceVar(ptr,
myType.Tag.Get("lopt"),
[]string{myType.Tag.Get("default")},
myType.Tag.Get("comment"))
}
} else if myType.Type == reflect.TypeOf(map[string]string{}) {
ptr := myVal.Addr().Interface().(*map[string]string)
if myType.Tag.Get("sopt") != "" {
baseCmd.PersistentFlags().StringToStringVarP(ptr,
myType.Tag.Get("lopt"),
myType.Tag.Get("sopt"),
map[string]string{}, // empty default!
myType.Tag.Get("comment"))
} else if !util.InSlice(excludeList, myType.Tag.Get("lopt")) {
baseCmd.PersistentFlags().StringToStringVar(ptr,
myType.Tag.Get("lopt"),
map[string]string{}, // empty default!
myType.Tag.Get("comment"))
}
}
}
}
/*
Populates all fields of NodeInfo with Set from the
values of NodeConf.
*/
func (node *NodeInfo) SetFrom(n *NodeConf) {
setWrap := func(entr *Entry, val string, nameArg string) {
entr.Set(val)
}
setSliceWrap := func(entr *Entry, val []string, nameArg string) {
entr.SetSlice(val)
}
node.setterFrom(n, "", setWrap, setSliceWrap)
}
/*
Populates all fields of NodeInfo with SetAlt from the
values of NodeConf. The string profileName is used to
destermine from which source/NodeInfo the entry came
from.
*/
func (node *NodeInfo) SetAltFrom(n *NodeConf, profileName string) {
node.setterFrom(n, profileName, (*Entry).SetAlt, (*Entry).SetAltSlice)
}
/*
Abstract function which populates a NodeInfo from a NodeConf via
setter functionns.
*/
func (node *NodeInfo) setterFrom(n *NodeConf, nameArg string,
setter func(*Entry, string, string),
setterSlice func(*Entry, []string, string)) {
// get the full memory, taking the shortcut and init Ipmi and Kernel directly
if node.Kernel == nil {
node.Kernel = new(KernelEntry)
}
if node.Ipmi == nil {
node.Ipmi = new(IpmiEntry)
}
nodeInfoVal := reflect.ValueOf(node)
nodeInfoType := reflect.TypeOf(node)
nodeConfVal := reflect.ValueOf(n)
// now iterate of every field
for i := 0; i < nodeInfoType.Elem().NumField(); i++ {
valField := nodeConfVal.Elem().FieldByName(nodeInfoType.Elem().Field(i).Name)
if valField.IsValid() {
// found field with same name for Conf and Info
if nodeInfoType.Elem().Field(i).Type == reflect.TypeOf(Entry{}) {
if valField.Type().Kind() == reflect.String {
setter(nodeInfoVal.Elem().Field(i).Addr().Interface().(*Entry), valField.String(), nameArg)
} else if valField.Type() == reflect.TypeOf([]string{}) {
setterSlice(nodeInfoVal.Elem().Field(i).Addr().Interface().(*Entry), valField.Interface().([]string), nameArg)
}
} else if nodeInfoType.Elem().Field(i).Type.Kind() == reflect.Ptr && !valField.IsZero() {
nestedInfoType := reflect.TypeOf(nodeInfoVal.Elem().Field(i).Interface())
netstedInfoVal := reflect.ValueOf(nodeInfoVal.Elem().Field(i).Interface())
nestedConfVal := reflect.ValueOf(valField.Interface())
for j := 0; j < nestedInfoType.Elem().NumField(); j++ {
nestedVal := nestedConfVal.Elem().FieldByName(nestedInfoType.Elem().Field(j).Name)
if nestedVal.IsValid() {
if netstedInfoVal.Elem().Field(j).Type() == reflect.TypeOf(Entry{}) {
setter(netstedInfoVal.Elem().Field(j).Addr().Interface().(*Entry), nestedVal.String(), nameArg)
} else {
confMap := nestedVal.Interface().(map[string]string)
if netstedInfoVal.Elem().Field(j).IsNil() {
newMap := make(map[string]*Entry)
mapPtr := (netstedInfoVal.Elem().Field(j).Addr().Interface()).(*map[string](*Entry))
*mapPtr = newMap
}
for key, val := range confMap {
entr := new(Entry)
setter(entr, val, nameArg)
(netstedInfoVal.Elem().Field(j).Interface()).(map[string](*Entry))[key] = entr
}
}
}
}
} else if nodeInfoType.Elem().Field(i).Type == reflect.TypeOf(map[string](*Entry)(nil)) {
confMap := valField.Interface().(map[string]string)
for key, val := range confMap {
entr := new(Entry)
setter(entr, val, nameArg)
(nodeInfoVal.Elem().Field(i).Interface()).(map[string](*Entry))[key] = entr
}
} else if nodeInfoType.Elem().Field(i).Type == reflect.TypeOf(map[string](*NetDevEntry)(nil)) {
netValMap := valField.Interface().(map[string](*NetDevs))
for netName, netVals := range netValMap {
netValsType := reflect.ValueOf(netVals)
netMap := nodeInfoVal.Elem().Field(i).Interface().(map[string](*NetDevEntry))
if nodeInfoVal.Elem().Field(i).IsNil() {
netMap = make(map[string]*NetDevEntry)
}
if _, ok := netMap[netName]; !ok {
var newNet NetDevEntry
newNet.Tags = make(map[string]*Entry)
netMap[netName] = &newNet
}
netInfoType := reflect.TypeOf(*netMap[netName])
netInfoVal := reflect.ValueOf(netMap[netName])
for j := 0; j < netInfoType.NumField(); j++ {
netVal := netValsType.Elem().FieldByName(netInfoType.Field(j).Name)
if netVal.IsValid() {
if netVal.Type().Kind() == reflect.String {
setter(netInfoVal.Elem().Field(j).Addr().Interface().((*Entry)), netVal.String(), nameArg)
} else if netVal.Type() == reflect.TypeOf(map[string]string{}) {
for key, val := range (netVal.Interface()).(map[string]string) {
//netTagMap := netInfoVal.Elem().Field(j).Interface().((map[string](*Entry)))
if _, ok := netInfoVal.Elem().Field(j).Interface().((map[string](*Entry)))[key]; !ok {
netInfoVal.Elem().Field(j).Interface().((map[string](*Entry)))[key] = new(Entry)
}
setter(netInfoVal.Elem().Field(j).Interface().((map[string](*Entry)))[key], val, nameArg)
}
}
}
}
}
}
}
}
}
/*
Flattens out a NodeConf, which means if there are no explicit values in *IpmiConf
or *KernelConf, these pointer will set to nil. This will remove something like
ipmi: {} from nodes.conf
*/
func (info *NodeConf) Flatten() {
confType := reflect.TypeOf(info)
confVal := reflect.ValueOf(info)
for j := 0; j < confType.Elem().NumField(); j++ {
if confVal.Elem().Field(j).Type().Kind() == reflect.Ptr && !confVal.Elem().Field(j).IsNil() {
// iterate now over the ptr fields
setToNil := true
nestedType := reflect.TypeOf(confVal.Elem().Field(j).Interface())
nestedVal := reflect.ValueOf(confVal.Elem().Field(j).Interface())
for i := 0; i < nestedType.Elem().NumField(); i++ {
if nestedType.Elem().Field(i).Type.Kind() == reflect.String &&
nestedVal.Elem().Field(i).Interface().(string) != "" {
setToNil = false
} else if nestedType.Elem().Field(i).Type == reflect.TypeOf([]string{}) &&
len(nestedVal.Elem().Field(i).Interface().([]string)) != 0 {
setToNil = false
} else if nestedType.Elem().Field(i).Type == reflect.TypeOf(map[string]string{}) &&
len(nestedVal.Elem().Field(i).Interface().(map[string]string)) != 0 {
setToNil = false
}
}
if setToNil {
switch confType.Elem().Field(j).Type {
case reflect.TypeOf((*IpmiConf)(nil)):
ptr := confVal.Elem().Field(j).Addr().Interface().(**IpmiConf)
*ptr = (*IpmiConf)(nil)
case reflect.TypeOf((*KernelConf)(nil)):
ptr := confVal.Elem().Field(j).Addr().Interface().(**KernelConf)
*ptr = (*KernelConf)(nil)
}
}
}
}
}

View File

@@ -16,33 +16,25 @@ struct which contains the variables to which are available in
the templates.
*/
type TemplateStruct struct {
Id string
Hostname string
ClusterName string
Container string
Kernel *node.KernelConf
Init string
Root string
Ipmi *node.IpmiConf
RuntimeOverlay string
SystemOverlay string
NetDevs map[string]*node.NetDevs
Tags map[string]string
Keys map[string]string
AllNodes []node.NodeInfo
BuildHost string
BuildTime string
BuildTimeUnix string
BuildSource string
Ipaddr string
Ipaddr6 string
Netmask string
Network string
NetworkCIDR string
Ipv6 bool
Dhcp warewulfconf.DhcpConf
Nfs warewulfconf.NfsConf
Warewulf warewulfconf.WarewulfConf
Id string
Hostname string
BuildHost string
BuildTime string
BuildTimeUnix string
BuildSource string
Ipaddr string
Ipaddr6 string
Netmask string
Network string
NetworkCIDR string
Ipv6 bool
Dhcp warewulfconf.DhcpConf
Nfs warewulfconf.NfsConf
Warewulf warewulfconf.WarewulfConf
AllNodes []node.NodeInfo
node.NodeConf
// backward compatiblity
Container string
}
/*
@@ -65,63 +57,12 @@ func InitStruct(nodeInfo node.NodeInfo) TemplateStruct {
wwlog.Printf(wwlog.ERROR, "%s\n", err)
os.Exit(1)
}
tstruct.Kernel = new(node.KernelConf)
tstruct.Ipmi = new(node.IpmiConf)
// init some convininence vars
tstruct.Id = nodeInfo.Id.Get()
tstruct.Hostname = nodeInfo.Id.Get()
tstruct.Id = nodeInfo.Id.Get()
tstruct.Hostname = nodeInfo.Id.Get()
tstruct.ClusterName = nodeInfo.ClusterName.Get()
tstruct.Container = nodeInfo.ContainerName.Get()
tstruct.Kernel.Version = nodeInfo.Kernel.Override.Get()
tstruct.Kernel.Override = nodeInfo.Kernel.Override.Get()
tstruct.Kernel.Args = nodeInfo.Kernel.Args.Get()
tstruct.Init = nodeInfo.Init.Get()
tstruct.Root = nodeInfo.Root.Get()
tstruct.Ipmi.Ipaddr = nodeInfo.Ipmi.Ipaddr.Get()
tstruct.Ipmi.Netmask = nodeInfo.Ipmi.Netmask.Get()
tstruct.Ipmi.Port = nodeInfo.Ipmi.Port.Get()
tstruct.Ipmi.Gateway = nodeInfo.Ipmi.Gateway.Get()
tstruct.Ipmi.UserName = nodeInfo.Ipmi.UserName.Get()
tstruct.Ipmi.Password = nodeInfo.Ipmi.Password.Get()
tstruct.Ipmi.Interface = nodeInfo.Ipmi.Interface.Get()
tstruct.Ipmi.Write = nodeInfo.Ipmi.Write.Get()
tstruct.RuntimeOverlay = nodeInfo.RuntimeOverlay.Print()
tstruct.SystemOverlay = nodeInfo.SystemOverlay.Print()
tstruct.NetDevs = make(map[string]*node.NetDevs)
tstruct.Keys = make(map[string]string)
tstruct.Tags = make(map[string]string)
for devname, netdev := range nodeInfo.NetDevs {
var nd node.NetDevs
tstruct.NetDevs[devname] = &nd
tstruct.NetDevs[devname].Device = netdev.Device.Get()
tstruct.NetDevs[devname].Hwaddr = netdev.Hwaddr.Get()
tstruct.NetDevs[devname].Ipaddr = netdev.Ipaddr.Get()
tstruct.NetDevs[devname].Netmask = netdev.Netmask.Get()
tstruct.NetDevs[devname].Gateway = netdev.Gateway.Get()
tstruct.NetDevs[devname].Type = netdev.Type.Get()
tstruct.NetDevs[devname].OnBoot = netdev.OnBoot.Get()
tstruct.NetDevs[devname].Primary = netdev.Primary.Get()
mask := net.IPMask(net.ParseIP(netdev.Netmask.Get()).To4())
ipaddr := net.ParseIP(netdev.Ipaddr.Get()).To4()
netaddr := net.IPNet{IP: ipaddr, Mask: mask}
netPrefix, _ := net.IPMask(net.ParseIP(netdev.Netmask.Get()).To4()).Size()
tstruct.NetDevs[devname].Prefix = strconv.Itoa(netPrefix)
tstruct.NetDevs[devname].IpCIDR = netaddr.String()
tstruct.NetDevs[devname].Ipaddr6 = netdev.Ipaddr6.Get()
tstruct.NetDevs[devname].Tags = make(map[string]string)
for key, value := range netdev.Tags {
tstruct.NetDevs[devname].Tags[key] = value.Get()
}
}
// Backwards compatibility for templates using "Keys"
for keyname, key := range nodeInfo.Tags {
tstruct.Keys[keyname] = key.Get()
}
for keyname, key := range nodeInfo.Tags {
tstruct.Tags[keyname] = key.Get()
}
tstruct.AllNodes = allNodes
tstruct.Nfs = *controller.Nfs
tstruct.Dhcp = *controller.Dhcp
@@ -142,6 +83,17 @@ func InitStruct(nodeInfo node.NodeInfo) TemplateStruct {
dt := time.Now()
tstruct.BuildTime = dt.Format("01-02-2006 15:04:05 MST")
tstruct.BuildTimeUnix = strconv.FormatInt(dt.Unix(), 10)
tstruct.NodeConf.GetFrom(nodeInfo)
// FIXME: Set ipCIDR address at this point, will fail with
// invalid ipv4 addr
for _, network := range tstruct.NetDevs {
ipCIDR := net.IPNet{
IP: net.ParseIP(network.Ipaddr),
Mask: net.IPMask(net.ParseIP(network.Netmask))}
network.IpCIDR = ipCIDR.String()
}
// backward compatibilty
tstruct.Container = tstruct.ContainerName
return tstruct