added update_configuration

This commit is contained in:
Christian Goll
2022-04-11 15:58:00 +02:00
parent 75e075ab52
commit 4641b947db
5 changed files with 482 additions and 1 deletions

View File

@@ -0,0 +1,212 @@
package main
import (
"flag"
"fmt"
"io/ioutil"
"os"
"github.com/hpcng/warewulf/cmd/update_configuration/vers42"
"github.com/hpcng/warewulf/cmd/update_configuration/vers43"
"github.com/hpcng/warewulf/internal/pkg/buildconfig"
"github.com/hpcng/warewulf/internal/pkg/util"
"gopkg.in/yaml.v2"
)
var nowrite bool
var confFile string
type nodeVersionOnly struct {
WWInternal int `yaml:"WW_INTERNAL"`
}
func saveConf(conf interface{}) {
out, err := yaml.Marshal(conf)
if err != nil {
fmt.Printf("Error in marshal of conf: %s\n", err)
os.Exit(1)
}
if nowrite {
fmt.Println(string(out))
} else {
err = util.CopyFile(confFile, confFile+".bak")
if err != nil {
fmt.Printf("Could write file: %s\n", err)
os.Exit(1)
}
info, err := os.Stat(confFile)
if err != nil {
fmt.Printf("Could not get file mode: %s\n", err)
os.Exit(1)
}
err = ioutil.WriteFile(confFile, out, info.Mode())
}
}
func printB(x bool) string {
if x {
return "true"
}
return "false"
}
func main() {
var endVers int
var startVers int
flag.StringVar(&confFile, "f", "", "Config file for update")
flag.IntVar(&endVers, "e", buildconfig.WWVer, "Final version of configuration file")
flag.IntVar(&startVers, "s", 0, "Start version of configuration file, 0 is for autodetection")
flag.BoolVar(&nowrite, "n", false, "Do not write, just print new conf to terminal")
flag.Parse()
if confFile == "" {
fmt.Printf("No config file given\n!")
os.Exit(1)
}
fmt.Printf("Opening node configuration file: %s\n", confFile)
data, err := ioutil.ReadFile(confFile)
if err != nil {
fmt.Printf("Could open file %v\n", err)
os.Exit(1)
}
if startVers == 0 {
var getConf nodeVersionOnly
fmt.Printf("Unmarshaling the node configuration\n")
err = yaml.Unmarshal(data, &getConf)
if err != nil {
fmt.Printf("Could not unmarshall: %v\n", err)
}
fmt.Printf("Got version %v in %s\n", getConf.WWInternal, confFile)
if getConf.WWInternal == 0 {
startVers = 42
}
}
var conf42 vers42.NodeYaml
conf42.NodeProfiles = make(map[string]*vers42.NodeConf)
conf42.Nodes = make(map[string]*vers42.NodeConf)
var conf43 vers43.NodeYaml
conf43.NodeProfiles = make(map[string]*vers43.NodeConf)
conf43.Nodes = make(map[string]*vers43.NodeConf)
conf43.WWInternal = 43
if startVers == 42 {
fmt.Printf("Unmarshaling the node configuration vers 42\n")
err = yaml.Unmarshal(data, &conf42)
if err != nil {
fmt.Printf("Could not unmarshall version 42: %v\n", err)
}
for pname, profile := range conf42.NodeProfiles {
profileConf := vers43.NodeConf{
Comment: profile.Comment,
ClusterName: profile.ClusterName,
ContainerName: profile.ContainerName,
Init: profile.Init,
Root: profile.Root,
Discoverable: printB(profile.Discoverable),
Profiles: profile.Profiles,
Ipxe: profile.Ipxe}
conf43.NodeProfiles[pname] = &profileConf
if profile.RuntimeOverlay != "" {
conf43.NodeProfiles[pname].RuntimeOverlay = []string{profile.RuntimeOverlay}
}
if profile.SystemOverlay != "" {
conf43.NodeProfiles[pname].SystemOverlay = []string{profile.SystemOverlay}
}
if profile.KernelArgs != "" || profile.KernelVersion != "" {
conf43.NodeProfiles[pname].Kernel = new(vers43.KernelConf)
conf43.NodeProfiles[pname].Kernel.Override = profile.KernelVersion
conf43.NodeProfiles[pname].Kernel.Args = profile.KernelArgs
}
if profile.IpmiUserName != "" || profile.IpmiPassword != "" || profile.IpmiIpaddr != "" ||
profile.IpmiNetmask != "" || profile.IpmiPort != "" || profile.IpmiGateway != "" ||
profile.IpmiInterface != "" {
conf43.NodeProfiles[pname].Ipmi = new(vers43.IpmiConf)
conf43.NodeProfiles[pname].Ipmi.UserName = profile.IpmiUserName
conf43.NodeProfiles[pname].Ipmi.Password = profile.IpmiPassword
conf43.NodeProfiles[pname].Ipmi.Ipaddr = profile.IpmiIpaddr
conf43.NodeProfiles[pname].Ipmi.Netmask = profile.IpmiNetmask
conf43.NodeProfiles[pname].Ipmi.Port = profile.IpmiPort
conf43.NodeProfiles[pname].Ipmi.Gateway = profile.IpmiGateway
conf43.NodeProfiles[pname].Ipmi.Interface = profile.IpmiInterface
}
if len(profile.Keys) != 0 {
conf43.NodeProfiles[pname].Keys = map[string]string{}
for k, v := range profile.Keys {
conf43.NodeProfiles[pname].Keys[k] = v
}
}
conf43.NodeProfiles[pname].NetDevs = make(map[string]*vers43.NetDevs)
for devn, netdev := range profile.NetDevs {
var device vers43.NetDevs = vers43.NetDevs{
Type: netdev.Type,
Default: printB(netdev.Default),
Hwaddr: netdev.Hwaddr,
Ipaddr: netdev.Ipaddr,
IpCIDR: netdev.IpCIDR,
Prefix: netdev.Prefix,
Netmask: netdev.Netmask,
Gateway: netdev.Gateway}
conf43.NodeProfiles[pname].NetDevs[devn] = &device
}
}
for nname, node := range conf42.Nodes {
nodeConf := vers43.NodeConf{
Comment: node.Comment,
ClusterName: node.ClusterName,
ContainerName: node.ContainerName,
Init: node.Init,
Root: node.Root,
Discoverable: printB(node.Discoverable),
Profiles: node.Profiles,
Ipxe: node.Ipxe}
conf43.Nodes[nname] = &nodeConf
if node.RuntimeOverlay != "" {
conf43.Nodes[nname].RuntimeOverlay = []string{node.RuntimeOverlay}
}
if node.SystemOverlay != "" {
conf43.Nodes[nname].SystemOverlay = []string{node.SystemOverlay}
}
if node.KernelArgs != "" || node.KernelVersion != "" {
conf43.Nodes[nname].Kernel = new(vers43.KernelConf)
conf43.Nodes[nname].Kernel.Override = node.KernelVersion
conf43.Nodes[nname].Kernel.Args = node.KernelArgs
}
if node.IpmiUserName != "" || node.IpmiPassword != "" || node.IpmiIpaddr != "" ||
node.IpmiNetmask != "" || node.IpmiPort != "" || node.IpmiGateway != "" ||
node.IpmiInterface != "" {
conf43.Nodes[nname].Ipmi = new(vers43.IpmiConf)
conf43.Nodes[nname].Ipmi.UserName = node.IpmiUserName
conf43.Nodes[nname].Ipmi.Password = node.IpmiPassword
conf43.Nodes[nname].Ipmi.Ipaddr = node.IpmiIpaddr
conf43.Nodes[nname].Ipmi.Netmask = node.IpmiNetmask
conf43.Nodes[nname].Ipmi.Port = node.IpmiPort
conf43.Nodes[nname].Ipmi.Gateway = node.IpmiGateway
conf43.Nodes[nname].Ipmi.Interface = node.IpmiInterface
}
if len(node.Keys) != 0 {
conf43.Nodes[nname].Keys = map[string]string{}
for k, v := range node.Keys {
conf43.Nodes[nname].Keys[k] = v
}
}
conf43.Nodes[nname].NetDevs = make(map[string]*vers43.NetDevs)
for devn, netdev := range node.NetDevs {
var device vers43.NetDevs = vers43.NetDevs{
Type: netdev.Type,
Default: printB(netdev.Default),
Hwaddr: netdev.Hwaddr,
Ipaddr: netdev.Ipaddr,
IpCIDR: netdev.IpCIDR,
Prefix: netdev.Prefix,
Netmask: netdev.Netmask,
Gateway: netdev.Gateway}
conf43.Nodes[nname].NetDevs[devn] = &device
}
}
saveConf(conf43)
}
}

View File

@@ -0,0 +1,97 @@
package vers42
/******
* YAML data representations
******/
//type nodeYaml struct {
type NodeYaml struct {
NodeProfiles map[string]*NodeConf
Nodes map[string]*NodeConf
}
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"`
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"`
RuntimeOverlay string `yaml:"runtime overlay,omitempty"`
SystemOverlay string `yaml:"system overlay,omitempty"`
Init string `yaml:"init,omitempty"`
Root string `yaml:"root,omitempty"`
Discoverable bool `yaml:"discoverable,omitempty"`
Profiles []string `yaml:"profiles,omitempty"`
NetDevs map[string]*NetDevs `yaml:"network devices,omitempty"`
Keys map[string]string `yaml:"keys,omitempty"`
}
type NetDevs struct {
Type string `yaml:"type,omitempty"`
Default bool `yaml:"default"`
Hwaddr string
Ipaddr string
IpCIDR string
Prefix string
Netmask string
Gateway string `yaml:"gateway,omitempty"`
}
/******
* Internal code data representations
******/
type Entry struct {
value string
altvalue string
bool bool
altbool bool
from string
def string
}
type NodeInfo struct {
Id Entry
Cid Entry
Comment Entry
ClusterName Entry
ContainerName Entry
Ipxe Entry
KernelVersion Entry
KernelArgs Entry
IpmiIpaddr Entry
IpmiNetmask Entry
IpmiPort Entry
IpmiGateway Entry
IpmiUserName Entry
IpmiPassword Entry
IpmiInterface Entry
RuntimeOverlay Entry
SystemOverlay Entry
Root Entry
Discoverable Entry
Init Entry //TODO: Finish adding this...
Profiles []string
GroupProfiles []string
NetDevs map[string]*NetDevEntry
Keys map[string]*Entry
}
type NetDevEntry struct {
Type Entry `yaml:"type,omitempty"`
Default Entry `yaml:"default"`
Hwaddr Entry
Ipaddr Entry
IpCIDR Entry
Prefix Entry
Netmask Entry
Gateway Entry `yaml:"gateway,omitempty"`
}

View File

@@ -0,0 +1,27 @@
nodeprofiles:
default:
comment: This profile is automatically included for each node
runtime overlay:
- generic
discoverable: "false"
leap:
comment: openSUSE leap
kernel:
override: 5.14.21
ipmi:
netmask: 255.255.255.0
discoverable: "false"
keys:
foo: baar
network devices:
lan1:
gateway: 1.1.1.1
nodes:
node01:
system overlay:
- nodeover
discoverable: "true"
network devices:
eth0:
ipaddr: 1.2.3.4
default: "true"

View File

@@ -0,0 +1,139 @@
package vers43
/******
* YAML data representations
******/
//type nodeYaml struct {
type NodeYaml struct { // <- needs to be exported
WWInternal int `yaml:"WW_INTERNAL"`
NodeProfiles map[string]*NodeConf
Nodes map[string]*NodeConf
}
/*
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"`
RuntimeOverlay []string `yaml:"runtime overlay,omitempty"`
SystemOverlay []string `yaml:"system overlay,omitempty"`
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"`
NetDevs map[string]*NetDevs `yaml:"network devices,omitempty"`
Tags map[string]string `yaml:"tags,omitempty"`
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 bool `yaml:"write,omitempty"`
}
type KernelConf struct {
Version string `yaml:"version,omitempty"`
Override string `yaml:"override,omitempty"`
Args string `yaml:"args,omitempty"`
}
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"`
IpCIDR string `yaml:"ipcidr,omitempty"`
Ipaddr6 string `yaml:"ip6addr,omitempty"`
Prefix string `yaml:"prefix,omitempty"`
Netmask string `yaml:"netmask,omitempty"`
Gateway string `yaml:"gateway,omitempty"`
Default string `yaml:"default,omitempty"`
Tags map[string]string `yaml:"tags,omitempty"`
}
/******
* Internal code data representations
******/
/*
Holds string values, when accessed via Get, its value
is returned which is the default or if set the value
from the profile or if set the value of the node itself
*/
type Entry struct {
value []string
altvalue []string
from string
def []string
}
/*
NodeInfo is the in memory datastructure, which can containe
a default value, which is overwritten by the overlay from the
overlay (altvalue) which is overwitten by the value of the
node itself, for all values of type Entry.
*/
type NodeInfo struct {
Id Entry
Cid Entry
Comment Entry
ClusterName Entry
ContainerName Entry
Ipxe Entry
RuntimeOverlay Entry
SystemOverlay Entry
Root Entry
Discoverable Entry
Init Entry //TODO: Finish adding this...
AssetKey Entry
Kernel *KernelEntry
Ipmi *IpmiEntry
Profiles []string
GroupProfiles []string
NetDevs map[string]*NetDevEntry
Tags map[string]*Entry
}
type IpmiEntry struct {
Ipaddr Entry
Netmask Entry
Port Entry
Gateway Entry
UserName Entry
Password Entry
Interface Entry
Write Entry
}
type KernelEntry struct {
Version Entry
Override Entry
Args Entry
}
type NetDevEntry struct {
Type Entry
OnBoot Entry
Device Entry
Hwaddr Entry
Ipaddr Entry
Ipaddr6 Entry
IpCIDR Entry
Prefix Entry
Netmask Entry
Gateway Entry
Default Entry
Tags map[string]*Entry
}