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 } /* update the node in the database */ func (config *NodeYaml) NodeUpdate(node NodeInfo) error { nodeID := node.Id.Get() wwlog.Debug("updating node %s: %v", nodeID, node) if _, ok := config.Nodes[nodeID]; !ok { return errors.New("Nodename does not exist: " + nodeID) } // maps may have deleted elements which will not be updated // so we delete the node and call GetRealFrom on an empty NodeConv delete(config.Nodes, nodeID) config.Nodes[nodeID] = new(NodeConf) 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 config.NodeProfiles[profileID].NetDevs = make(map[string]*NetDevs) n.Id.Set(profileID) n.NetDevs = make(map[string]*NetDevEntry) 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) } // maps may have deleted elements which will not be updated // so we delete the profile and call GetRealFrom on an empty NodeConv delete(config.NodeProfiles, profileID) config.NodeProfiles[profileID] = new(NodeConf) 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, 0o644) 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 } // Dump returns a YAML document representing the nodeDb // instance. Passes through any errors generated by yaml.Marshal. 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) }