The caching functionality of nodes.conf, and the optional persistence functionality that came with it, appears to have been preventing actually writing the configuration to disk in all cases. This change fixes the ability to write to nodes.conf. Somewhat opinionatedly, this change removes the caching functionality of nodes.conf. The tests have also been updated to use real files for i/o rather than tying into the caching system, making them more accurately test the ability of Warewulf to actually read and write its configuration. Fixes #779 Signed-off-by: Jonathon Anderson <janderson@ciq.co>
148 lines
2.9 KiB
Go
148 lines
2.9 KiB
Go
package node
|
|
|
|
import (
|
|
"os"
|
|
|
|
"github.com/pkg/errors"
|
|
"gopkg.in/yaml.v2"
|
|
|
|
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
|
)
|
|
|
|
/****
|
|
*
|
|
* NODE MODIFIERS
|
|
*
|
|
****/
|
|
|
|
func (config *NodeYaml) AddNode(nodeID string) (NodeInfo, error) {
|
|
var node NodeConf
|
|
var n NodeInfo
|
|
|
|
wwlog.Verbose("Adding new node: %s", nodeID)
|
|
|
|
if _, ok := config.Nodes[nodeID]; ok {
|
|
return n, errors.New("Nodename already exists: " + nodeID)
|
|
}
|
|
|
|
config.Nodes[nodeID] = &node
|
|
config.Nodes[nodeID].Profiles = []string{"default"}
|
|
config.Nodes[nodeID].NetDevs = make(map[string]*NetDevs)
|
|
n.Id.Set(nodeID)
|
|
n.Profiles.SetSlice([]string{"default"})
|
|
n.NetDevs = make(map[string]*NetDevEntry)
|
|
n.Ipmi = new(IpmiEntry)
|
|
n.Kernel = new(KernelEntry)
|
|
|
|
return n, nil
|
|
}
|
|
|
|
func (config *NodeYaml) DelNode(nodeID string) error {
|
|
|
|
if _, ok := config.Nodes[nodeID]; !ok {
|
|
return errors.New("Nodename does not exist: " + nodeID)
|
|
}
|
|
|
|
wwlog.Verbose("Deleting node: %s", nodeID)
|
|
delete(config.Nodes, nodeID)
|
|
|
|
return nil
|
|
}
|
|
|
|
func (config *NodeYaml) NodeUpdate(node NodeInfo) error {
|
|
nodeID := node.Id.Get()
|
|
|
|
if _, ok := config.Nodes[nodeID]; !ok {
|
|
return errors.New("Nodename does not exist: " + nodeID)
|
|
}
|
|
config.Nodes[nodeID].GetRealFrom(node)
|
|
return nil
|
|
}
|
|
|
|
/****
|
|
*
|
|
* PROFILE MODIFIERS
|
|
*
|
|
****/
|
|
|
|
func (config *NodeYaml) AddProfile(profileID string) (NodeInfo, error) {
|
|
var node NodeConf
|
|
var n NodeInfo
|
|
|
|
wwlog.Verbose("Adding new profile: %s", profileID)
|
|
|
|
if _, ok := config.NodeProfiles[profileID]; ok {
|
|
return n, errors.New("Profile name already exists: " + profileID)
|
|
}
|
|
|
|
config.NodeProfiles[profileID] = &node
|
|
|
|
n.Id.Set(profileID)
|
|
|
|
return n, nil
|
|
}
|
|
|
|
func (config *NodeYaml) DelProfile(profileID string) error {
|
|
|
|
if _, ok := config.NodeProfiles[profileID]; !ok {
|
|
return errors.New("Profile does not exist: " + profileID)
|
|
}
|
|
|
|
wwlog.Verbose("Deleting profile: %s", profileID)
|
|
delete(config.NodeProfiles, profileID)
|
|
|
|
return nil
|
|
}
|
|
|
|
/*
|
|
Update the the config for the given profile so that it can unmarshalled.
|
|
*/
|
|
func (config *NodeYaml) ProfileUpdate(profile NodeInfo) error {
|
|
profileID := profile.Id.Get()
|
|
|
|
if _, ok := config.NodeProfiles[profileID]; !ok {
|
|
return errors.New("Profile name does not exist: " + profileID)
|
|
}
|
|
config.NodeProfiles[profileID].GetRealFrom(profile)
|
|
return nil
|
|
}
|
|
|
|
/****
|
|
*
|
|
* PERSISTENCE
|
|
*
|
|
****/
|
|
/*
|
|
Write the the NodeYaml to disk.
|
|
*/
|
|
func (config *NodeYaml) Persist() error {
|
|
out, dumpErr := config.Dump()
|
|
if dumpErr != nil {
|
|
wwlog.Error("%s", dumpErr)
|
|
os.Exit(1)
|
|
}
|
|
file, err := os.OpenFile(ConfigFile, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
|
|
if err != nil {
|
|
wwlog.Error("%s", err)
|
|
os.Exit(1)
|
|
}
|
|
defer file.Close()
|
|
_, err = file.WriteString(string(out))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
|
|
func (config *NodeYaml) Dump() ([]byte, error) {
|
|
// flatten out profiles and nodes
|
|
for _, val := range config.NodeProfiles {
|
|
val.Flatten()
|
|
}
|
|
for _, val := range config.Nodes {
|
|
val.Flatten()
|
|
}
|
|
return yaml.Marshal(config)
|
|
}
|