Merge pull request #539 from mslacken/default-conf

Read the defaults for a node from defaults.conf
This commit is contained in:
Christian Goll
2022-10-12 21:22:59 +02:00
committed by GitHub
8 changed files with 220 additions and 15 deletions

View File

@@ -14,11 +14,34 @@ import (
)
var ConfigFile string
var DefaultConfig string
// used as fallback if DefaultConfig can't be read
var FallBackConf = `
defaultnode:
runtime overlay:
- generic
system overlay:
- wwinit
kernel:
args: quiet crashkernel=no vga=791 net.naming-scheme=v238
init: /sbin/init
root: initramfs
profiles:
- default
network devices:
dummy:
device: eth0
type: ethernet
netmask: 255.255.255.0`
func init() {
if ConfigFile == "" {
ConfigFile = path.Join(buildconfig.SYSCONFDIR(), "warewulf/nodes.conf")
}
if DefaultConfig == "" {
DefaultConfig = path.Join(buildconfig.SYSCONFDIR(), "warewulf/defaults.conf")
}
}
func New() (NodeYaml, error) {
@@ -54,6 +77,30 @@ func (config *NodeYaml) FindAllNodes() ([]NodeInfo, error) {
return ret, err
}
*/
var defConf map[string]*NodeConf
wwlog.Verbose("Opening defaults failed %s\n", DefaultConfig)
defData, err := ioutil.ReadFile(DefaultConfig)
if err != nil {
wwlog.Verbose("Couldn't read DefaultConfig :%s\n", err)
}
wwlog.Debug("Unmarshalling default config\n")
err = yaml.Unmarshal(defData, &defConf)
if err != nil {
wwlog.Verbose("Couldn't unmarshall defaults from file :%s\n", err)
wwlog.Verbose("Using building defaults")
err = yaml.Unmarshal([]byte(FallBackConf), &defConf)
if err != nil {
wwlog.Warn("Could not get any defaults")
}
}
var defConfNet *NetDevs
if _, ok := defConf["defaultnode"]; ok {
if _, ok := defConf["defaultnode"].NetDevs["dummy"]; ok {
defConfNet = defConf["defaultnode"].NetDevs["dummy"]
}
defConf["defaultnode"].NetDevs = nil
}
wwlog.Debug("Finding all nodes...\n")
for nodename, node := range config.Nodes {
var n NodeInfo
@@ -63,13 +110,7 @@ func (config *NodeYaml) FindAllNodes() ([]NodeInfo, error) {
n.Tags = make(map[string]*Entry)
n.Kernel = new(KernelEntry)
n.Ipmi = new(IpmiEntry)
n.SystemOverlay.SetDefault("wwinit")
n.RuntimeOverlay.SetDefault("generic")
n.Ipxe.SetDefault("default")
n.Init.SetDefault("/sbin/init")
n.Root.SetDefault("initramfs")
n.Kernel.Args.SetDefault("quiet crashkernel=no vga=791")
n.SetDefFrom(defConf["defaultnode"])
fullname := strings.SplitN(nodename, ".", 2)
if len(fullname) > 1 {
n.ClusterName.SetDefault(fullname[1])
@@ -80,14 +121,18 @@ func (config *NodeYaml) FindAllNodes() ([]NodeInfo, error) {
} else {
n.Profiles.SetSlice(node.Profiles)
}
// node explciti nodename field in NodeConf
// node explicitly nodename field in NodeConf
n.Id.Set(nodename)
// backward compatibilty
// backward compatibility
for keyname, key := range node.Keys {
node.Tags[keyname] = key
delete(node.Keys, keyname)
}
n.SetFrom(node)
// only now the netdevs start to exist so that default values can be set
for _, netdev := range n.NetDevs {
netdev.SetDefFrom(defConfNet)
}
// set default/primary network is just one network exist
if len(n.NetDevs) == 1 {
// only way to get the key

View File

@@ -1,10 +1,5 @@
package node
import (
"github.com/hpcng/warewulf/internal/pkg/util"
"github.com/hpcng/warewulf/internal/pkg/wwlog"
)
/******
* YAML data representations
******/
@@ -163,6 +158,8 @@ type NetDevEntry struct {
// string which is printed if no value is set
const NoValue = "--"
/*
Has no real purpose as only New() needs it
func init() {
// Check that nodes.conf is found
if !util.IsFile(ConfigFile) {
@@ -171,3 +168,4 @@ func init() {
return
}
}
*/

View File

@@ -303,6 +303,20 @@ func (node *NodeInfo) SetAltFrom(n *NodeConf, profileName string) {
node.setterFrom(n, profileName, (*Entry).SetAlt, (*Entry).SetAltSlice)
}
/*
Populates all fields of NodeInfo with SetDefault from the
values of NodeConf.
*/
func (node *NodeInfo) SetDefFrom(n *NodeConf) {
setWrap := func(entr *Entry, val string, nameArg string) {
entr.SetDefault(val)
}
setSliceWrap := func(entr *Entry, val []string, nameArg string) {
entr.SetDefaultSlice(val)
}
node.setterFrom(n, "", setWrap, setSliceWrap)
}
/*
Abstract function which populates a NodeInfo from a NodeConf via
setter functionns.
@@ -438,3 +452,71 @@ func (info *NodeConf) Flatten() {
}
}
}
/*
Populates all fields of NetDevEntry with Set from the
values of NetDevs.
Actually not used, just for completeness.
*/
func (netDev *NetDevEntry) SetFrom(netYaml *NetDevs) {
setWrap := func(entr *Entry, val string, nameArg string) {
entr.Set(val)
}
setSliceWrap := func(entr *Entry, val []string, nameArg string) {
entr.SetSlice(val)
}
netDev.setterFrom(netYaml, "", setWrap, setSliceWrap)
}
/*
Populates all fields of NetDevEntry with SetAlt from the
values of NetDevs. The string profileName is used to
destermine from which source/NodeInfo the entry came
from.
Actually not used, just for completeness.
*/
func (netDev *NetDevEntry) SetAltFrom(netYaml *NetDevs, profileName string) {
netDev.setterFrom(netYaml, profileName, (*Entry).SetAlt, (*Entry).SetAltSlice)
}
/*
Populates all fields of NodeInfo with SetDefault from the
values of NodeConf.
*/
func (netDev *NetDevEntry) SetDefFrom(netYaml *NetDevs) {
setWrap := func(entr *Entry, val string, nameArg string) {
entr.SetDefault(val)
}
setSliceWrap := func(entr *Entry, val []string, nameArg string) {
entr.SetDefaultSlice(val)
}
netDev.setterFrom(netYaml, "", setWrap, setSliceWrap)
}
/*
Abstract function for setting a NetDevEntry from a NetDevs
*/
func (netDev *NetDevEntry) setterFrom(netYaml *NetDevs, nameArg string,
setter func(*Entry, string, string),
setterSlice func(*Entry, []string, string)) {
netValues := reflect.ValueOf(netDev)
netInfoType := reflect.TypeOf(*netYaml)
netInfoVal := reflect.ValueOf(*netYaml)
for j := 0; j < netInfoType.NumField(); j++ {
netVal := netValues.Elem().FieldByName(netInfoType.Field(j).Name)
if netVal.IsValid() {
if netInfoVal.Field(j).Type().Kind() == reflect.String {
setter(netVal.Addr().Interface().((*Entry)), netInfoVal.Field(j).String(), nameArg)
} else if netVal.Type() == reflect.TypeOf(map[string]string{}) {
// danger zone following code is not tested
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)
}
}
}
}
}