From c0f7ecf35703732152616dc2477f13e6e3d16bf1 Mon Sep 17 00:00:00 2001 From: Christian Goll Date: Thu, 24 Mar 2022 19:45:51 +0100 Subject: [PATCH] store the ovelats as yaml list --- internal/app/wwctl/node/set/main.go | 8 +- internal/app/wwctl/node/set/root.go | 8 +- internal/app/wwctl/profile/set/main.go | 8 +- internal/app/wwctl/profile/set/root.go | 8 +- internal/pkg/node/constructors.go | 12 +- internal/pkg/node/datastructure.go | 16 ++- internal/pkg/node/methods.go | 178 ++++++++++++++++++------- internal/pkg/node/modifiers.go | 8 +- internal/pkg/overlay/datastructure.go | 4 + internal/pkg/overlay/overlay.go | 4 +- 10 files changed, 174 insertions(+), 80 deletions(-) diff --git a/internal/app/wwctl/node/set/main.go b/internal/app/wwctl/node/set/main.go index 6b9b4f8c..cdd0a360 100644 --- a/internal/app/wwctl/node/set/main.go +++ b/internal/app/wwctl/node/set/main.go @@ -90,14 +90,14 @@ func CobraRunE(cmd *cobra.Command, args []string) error { n.Ipxe.Set(SetIpxe) } - if SetRuntimeOverlay != "" { + if len(SetRuntimeOverlay) != 0 { wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting runtime overlay to: %s\n", n.Id.Get(), SetRuntimeOverlay) - n.RuntimeOverlay.Set(SetRuntimeOverlay) + n.RuntimeOverlay.SetSlice(SetRuntimeOverlay) } - if SetSystemOverlay != "" { + if len(SetSystemOverlay) != 0 { wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting system overlay to: %s\n", n.Id.Get(), SetSystemOverlay) - n.SystemOverlay.Set(SetSystemOverlay) + n.SystemOverlay.SetSlice(SetSystemOverlay) } if SetIpmiIpaddr != "" { diff --git a/internal/app/wwctl/node/set/root.go b/internal/app/wwctl/node/set/root.go index 133ecc4f..bf8dd547 100644 --- a/internal/app/wwctl/node/set/root.go +++ b/internal/app/wwctl/node/set/root.go @@ -49,8 +49,8 @@ var ( SetClusterName string SetIpxe string SetInitOverlay string - SetRuntimeOverlay string - SetSystemOverlay string + SetRuntimeOverlay []string + SetSystemOverlay []string SetIpmiIpaddr string SetIpmiNetmask string SetIpmiPort string @@ -97,14 +97,14 @@ func init() { baseCmd.PersistentFlags().StringVar(&SetRoot, "root", "", "Define the rootfs") baseCmd.PersistentFlags().StringVar(&SetAssetKey, "assetkey", "", "Set the node's Asset tag (key)") baseCmd.PersistentFlags().StringVarP(&SetInitOverlay, "wwinit", "O", "", "Set the node's initialization overlay") - baseCmd.PersistentFlags().StringVarP(&SetRuntimeOverlay, "runtime", "R", "", "Set the node's runtime overlay") + baseCmd.PersistentFlags().StringSliceVarP(&SetRuntimeOverlay, "runtime", "R", []string{}, "Set the node's runtime overlay") if err := baseCmd.RegisterFlagCompletionFunc("runtime", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { list, _ := overlay.FindOverlays() return list, cobra.ShellCompDirectiveNoFileComp }); err != nil { log.Println(err) } - baseCmd.PersistentFlags().StringVarP(&SetSystemOverlay, "system", "S", "", "Set the node's system overlay") + baseCmd.PersistentFlags().StringSliceVarP(&SetSystemOverlay, "system", "S", []string{}, "Set the node's system overlay") if err := baseCmd.RegisterFlagCompletionFunc("system", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { list, _ := overlay.FindOverlays() return list, cobra.ShellCompDirectiveNoFileComp diff --git a/internal/app/wwctl/profile/set/main.go b/internal/app/wwctl/profile/set/main.go index b1c50e22..13abf286 100644 --- a/internal/app/wwctl/profile/set/main.go +++ b/internal/app/wwctl/profile/set/main.go @@ -90,14 +90,14 @@ func CobraRunE(cmd *cobra.Command, args []string) error { p.Ipxe.Set(SetIpxe) } - if SetRuntimeOverlay != "" { + if len(SetRuntimeOverlay) != 0 { wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting runtime overlay to: %s\n", p.Id.Get(), SetRuntimeOverlay) - p.RuntimeOverlay.Set(SetRuntimeOverlay) + p.RuntimeOverlay.SetSlice(SetRuntimeOverlay) } - if SetSystemOverlay != "" { + if len(SetSystemOverlay) != 0 { wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting system overlay to: %s\n", p.Id.Get(), SetSystemOverlay) - p.SystemOverlay.Set(SetSystemOverlay) + p.SystemOverlay.SetSlice(SetSystemOverlay) } if SetIpmiNetmask != "" { diff --git a/internal/app/wwctl/profile/set/root.go b/internal/app/wwctl/profile/set/root.go index 8d485275..c7d2d4b9 100644 --- a/internal/app/wwctl/profile/set/root.go +++ b/internal/app/wwctl/profile/set/root.go @@ -42,8 +42,8 @@ var ( SetClusterName string SetIpxe string SetInitOverlay string - SetRuntimeOverlay string - SetSystemOverlay string + SetRuntimeOverlay []string + SetSystemOverlay []string SetIpmiNetmask string SetIpmiPort string SetIpmiGateway string @@ -91,7 +91,7 @@ func init() { baseCmd.PersistentFlags().StringVarP(&SetInit, "init", "i", "", "Define the init process to boot the container") baseCmd.PersistentFlags().StringVar(&SetRoot, "root", "", "Define the rootfs") baseCmd.PersistentFlags().StringVar(&SetAssetKey, "assetkey", "", "Set the node's Asset tag (key)") - baseCmd.PersistentFlags().StringVarP(&SetRuntimeOverlay, "runtime", "R", "", "Set the node's runtime overlay") + baseCmd.PersistentFlags().StringSliceVarP(&SetRuntimeOverlay, "runtime", "R", []string{}, "Set the node's runtime overlay") if err := baseCmd.RegisterFlagCompletionFunc("runtime", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { list, _ := overlay.FindOverlays() return list, cobra.ShellCompDirectiveNoFileComp @@ -99,7 +99,7 @@ func init() { log.Println(err) } - baseCmd.PersistentFlags().StringVarP(&SetSystemOverlay, "system", "S", "", "Set the node's system overlay") + baseCmd.PersistentFlags().StringSliceVarP(&SetSystemOverlay, "system", "S", []string{}, "Set the node's system overlay") if err := baseCmd.RegisterFlagCompletionFunc("system", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { list, _ := overlay.FindOverlays() return list, cobra.ShellCompDirectiveNoFileComp diff --git a/internal/pkg/node/constructors.go b/internal/pkg/node/constructors.go index 23877311..db353df7 100644 --- a/internal/pkg/node/constructors.go +++ b/internal/pkg/node/constructors.go @@ -95,8 +95,8 @@ func (config *nodeYaml) FindAllNodes() ([]NodeInfo, error) { n.IpmiPassword.Set(node.IpmiPassword) n.IpmiInterface.Set(node.IpmiInterface) n.IpmiWrite.SetB(node.IpmiWrite) - n.SystemOverlay.Set(node.SystemOverlay) - n.RuntimeOverlay.Set(node.RuntimeOverlay) + 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) @@ -181,8 +181,8 @@ func (config *nodeYaml) FindAllNodes() ([]NodeInfo, error) { n.IpmiPassword.SetAlt(config.NodeProfiles[p].IpmiPassword, p) n.IpmiInterface.SetAlt(config.NodeProfiles[p].IpmiInterface, p) n.IpmiWrite.SetB(config.NodeProfiles[p].IpmiWrite) - n.SystemOverlay.SetAlt(config.NodeProfiles[p].SystemOverlay, p) - n.RuntimeOverlay.SetAlt(config.NodeProfiles[p].RuntimeOverlay, 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) @@ -268,8 +268,8 @@ func (config *nodeYaml) FindAllProfiles() ([]NodeInfo, error) { p.IpmiPassword.Set(profile.IpmiPassword) p.IpmiInterface.Set(profile.IpmiInterface) p.IpmiWrite.SetB(profile.IpmiWrite) - p.RuntimeOverlay.Set(profile.RuntimeOverlay) - p.SystemOverlay.Set(profile.SystemOverlay) + 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) diff --git a/internal/pkg/node/datastructure.go b/internal/pkg/node/datastructure.go index 20610dfd..070dc0bd 100644 --- a/internal/pkg/node/datastructure.go +++ b/internal/pkg/node/datastructure.go @@ -30,8 +30,8 @@ type NodeConf struct { IpmiGateway string `yaml:"ipmi gateway,omitempty"` IpmiInterface string `yaml:"ipmi interface,omitempty"` IpmiWrite bool `yaml:"ipmi write,omitempty"` - RuntimeOverlay string `yaml:"runtime overlay,omitempty"` - SystemOverlay string `yaml:"system overlay,omitempty"` + RuntimeOverlay []string `yaml:"runtime overlay,omitempty"` + SystemOverlay []string `yaml:"system overlay,omitempty"` Init string `yaml:"init,omitempty"` Root string `yaml:"root,omitempty"` AssetKey string `yaml:"asset key,omitempty"` @@ -59,12 +59,16 @@ type NetDevs struct { /****** * Internal code data representations ******/ - +/* +Holds a strtng value, 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 + value []string + altvalue []string from string - def string + def []string } type NodeInfo struct { diff --git a/internal/pkg/node/methods.go b/internal/pkg/node/methods.go index 5b40739f..9b2dde52 100644 --- a/internal/pkg/node/methods.go +++ b/internal/pkg/node/methods.go @@ -10,7 +10,10 @@ import ( * Filters * *********/ - +/* +Filter a given slice of NodeInfo against a given +regular expression +*/ func FilterByName(set []NodeInfo, searchList []string) []NodeInfo { var ret []NodeInfo unique := make(map[string]NodeInfo) @@ -40,46 +43,94 @@ 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 +*/ func (ent *Entry) Set(val string) { if val == "" { return } if val == "UNDEF" || val == "DELETE" || val == "UNSET" || val == "--" { - ent.value = "" + ent.value = []string{} + } else { + ent.value = []string{val} + } +} + +/* +Set bool +*/ +func (ent *Entry) SetB(val bool) { + if val { + ent.value = []string{"true"} + } +} + +func (ent *Entry) SetSlice(val []string) { + if len(val) == 0 { + return + } + if val[0] == "UNDEF" || val[0] == "DELETE" || val[0] == "UNSET" || val[0] == "--" { + ent.value = []string{} } else { ent.value = val } } -func (ent *Entry) SetB(val bool) { - if val { - ent.value = "true" - } -} - +/* +Set alternative value +*/ func (ent *Entry) SetAlt(val string, from string) { if val == "" { return } - - ent.altvalue = val + ent.altvalue = []string{val} ent.from = from - } +/* +Sets alternative bool +*/ func (ent *Entry) SetAltB(val bool, from string) { if val { - ent.altvalue = "true" + ent.altvalue = []string{"true"} ent.from = from } } +/* +Sets alternative slice +*/ +func (ent *Entry) SetAltSlice(val []string, from string) { + if len(val) == 0 { + return + } + ent.altvalue = val + ent.from = from +} + +/* +Sets the default value of an entry. +*/ func (ent *Entry) SetDefault(val string) { if val == "" { return } + ent.def = []string{val} +} + +/* +Set the default entry as slice +*/ +func (ent *Entry) SetDefaultSlice(val []string) { + if len(val) == 0 { + return + } ent.def = val } @@ -89,23 +140,31 @@ func (ent *Entry) SetDefault(val string) { * Gets * *********/ - +/* +Gets the the entry of the value in folowing order +* node value if set +* profile value if set +* default value if set +*/ func (ent *Entry) Get() string { - if ent.value != "" { - return ent.value + if len(ent.value) != 0 { + return ent.value[0] } - if ent.altvalue != "" { - return ent.altvalue + if len(ent.altvalue) != 0 { + return ent.altvalue[0] } - if ent.def != "" { - return ent.def + if len(ent.def) != 0 { + return ent.def[0] } return "" } +/* +Get the bool value of an entry. +*/ func (ent *Entry) GetB() bool { - if ent.value == "false" || ent.value == "no" || ent.value == "" { - if ent.altvalue == "false" || ent.altvalue == "no" || ent.altvalue == "" { + if len(ent.value) == 0 || ent.value[0] == "false" || ent.value[0] == "no" { + if len(ent.altvalue) == 0 || ent.altvalue[0] == "false" || ent.altvalue[0] == "no" { return false } return false @@ -113,47 +172,63 @@ func (ent *Entry) GetB() bool { return true } -func (ent *Entry) GetReal() string { - return ent.value -} - /* Returns a string slice created from a comma seperated list of the value. */ func (ent *Entry) GetSlice() []string { var retval []string - if ent.value != "" { - //retval = util.SliceAppendUniq(retval, strings.Split(ent.value, ",")) - return strings.Split(ent.value, ",") + if len(ent.value) != 0 { + return ent.value } - if ent.altvalue != "" { - //retval = util.SliceAppendUniq(retval, strings.Split(ent.altvalue, ",")) - return strings.Split(ent.altvalue, ",") + if len(ent.altvalue) != 0 { + return ent.altvalue } - //if ent.def != "" && len(retval) == 0 { - if ent.def != "" { - //retval = util.SliceAppendUniq(retval, strings.Split(ent.def, ",")) - return strings.Split(ent.def, ",") - + if len(ent.def) != 0 { + return ent.def } return retval } +/* +Get the real value, not the alternative of default one. +*/ +func (ent *Entry) GetReal() string { + if len(ent.value) == 0 { + return "" + } + return ent.value[0] +} + +/* +Get the real value, not the alternative of default one. +*/ +func (ent *Entry) GetRealSlice() []string { + if len(ent.value) == 0 { + return []string{} + } + return ent.value +} + /********** * * Misc * *********/ +/* +Returns the value of Entry if it was defined set or +alternative is presend. Default value is in '()'. If +nothing is defined '--' is returned. +*/ func (ent *Entry) Print() string { - if ent.value != "" { - return ent.value + if len(ent.value) != 0 { + return strings.Join(ent.value, ",") } - if ent.altvalue != "" { - return ent.altvalue + if len(ent.altvalue) != 0 { + return strings.Join(ent.altvalue, ",") } - if ent.def != "" { - return "(" + ent.def + ")" + if len(ent.def) != 0 { + return "(" + strings.Join(ent.def, ",") + ")" } return "--" } @@ -168,12 +243,20 @@ func (ent *Entry) PrintComb() string { return ent.Print() } */ + +/* +same as GetB() +*/ func (ent *Entry) PrintB() bool { return ent.GetB() } +/* +Returns SUPERSEDED if value was set per node or +per profile. Else -- is returned. +*/ func (ent *Entry) Source() string { - if ent.value != "" && ent.altvalue != "" { + if len(ent.value) != 0 && len(ent.altvalue) != 0 { return "SUPERSEDED" //return fmt.Sprintf("[%s]", ent.from) } else if ent.from == "" { @@ -182,14 +265,17 @@ func (ent *Entry) Source() string { return ent.from } +/* +Check if value was defined. +*/ func (ent *Entry) Defined() bool { - if ent.value != "" { + if len(ent.value) != 0 { return true } - if ent.altvalue != "" { + if len(ent.altvalue) != 0 { return true } - if ent.def != "" { + if len(ent.def) != 0 { return true } return false diff --git a/internal/pkg/node/modifiers.go b/internal/pkg/node/modifiers.go index 1af7cdfc..8137903d 100644 --- a/internal/pkg/node/modifiers.go +++ b/internal/pkg/node/modifiers.go @@ -70,8 +70,8 @@ func (config *nodeYaml) NodeUpdate(node NodeInfo) error { config.Nodes[nodeID].IpmiPassword = node.IpmiPassword.GetReal() config.Nodes[nodeID].IpmiInterface = node.IpmiInterface.GetReal() config.Nodes[nodeID].IpmiWrite = node.IpmiWrite.GetB() - config.Nodes[nodeID].RuntimeOverlay = node.RuntimeOverlay.GetReal() - config.Nodes[nodeID].SystemOverlay = node.SystemOverlay.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() @@ -159,8 +159,8 @@ func (config *nodeYaml) ProfileUpdate(profile NodeInfo) error { config.NodeProfiles[profileID].IpmiPassword = profile.IpmiPassword.GetReal() config.NodeProfiles[profileID].IpmiInterface = profile.IpmiInterface.GetReal() config.NodeProfiles[profileID].IpmiWrite = profile.IpmiInterface.GetB() - config.NodeProfiles[profileID].RuntimeOverlay = profile.RuntimeOverlay.GetReal() - config.NodeProfiles[profileID].SystemOverlay = profile.SystemOverlay.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() diff --git a/internal/pkg/overlay/datastructure.go b/internal/pkg/overlay/datastructure.go index e0697883..a8bfb276 100644 --- a/internal/pkg/overlay/datastructure.go +++ b/internal/pkg/overlay/datastructure.go @@ -5,6 +5,10 @@ import ( "github.com/hpcng/warewulf/internal/pkg/warewulfconf" ) +/* +struct which contains the variables to which are available in +the templates. +*/ type TemplateStruct struct { Id string Hostname string diff --git a/internal/pkg/overlay/overlay.go b/internal/pkg/overlay/overlay.go index 212e603f..a1e054b0 100644 --- a/internal/pkg/overlay/overlay.go +++ b/internal/pkg/overlay/overlay.go @@ -231,8 +231,8 @@ func BuildOverlayIndir(nodeInfo node.NodeInfo, overlayNames []string, outputDir tstruct.IpmiPassword = nodeInfo.IpmiPassword.Get() tstruct.IpmiInterface = nodeInfo.IpmiInterface.Get() tstruct.IpmiWrite = nodeInfo.IpmiWrite.Get() - tstruct.RuntimeOverlay = nodeInfo.RuntimeOverlay.Get() - tstruct.SystemOverlay = nodeInfo.SystemOverlay.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)