Refactor and document config/datastructure

Also adjusted case for initialisms (e.g., DHCP, TFTP, NFS).

Signed-off-by: Jonathon Anderson <janderson@ciq.co>
This commit is contained in:
Jonathon Anderson
2023-04-14 19:21:29 -06:00
parent cfdf179e16
commit 8321193645
15 changed files with 122 additions and 100 deletions

3
.gitignore vendored
View File

@@ -28,8 +28,7 @@ internal/pkg/buildconfig/setconfigs.go
internal/pkg/config/buildconfig.go
include/systemd/warewulfd.service
_dist/
config
!internal/pkg/config
/config
warewulf-*.tar.gz
Defaults.mk
/etc/wwapid.config

View File

@@ -6,5 +6,5 @@ import (
)
func CobraRunE(cmd *cobra.Command, args []string) error {
return configure.Dhcp()
return configure.DHCP()
}

View File

@@ -11,7 +11,7 @@ import (
func CobraRunE(cmd *cobra.Command, args []string) error {
var err error
if allFunctions {
err = configure.Dhcp()
err = configure.DHCP()
if err != nil {
wwlog.Error("%s", err)
os.Exit(1)

View File

@@ -8,7 +8,7 @@ type BuildConfig struct {
Datadir string `default:"@DATADIR@"`
Localstatedir string `default:"@LOCALSTATEDIR@"`
Srvdir string `default:"@SRVDIR@"`
Tftpdir string `default:"@TFTPDIR@"`
TFTPdir string `default:"@TFTPDIR@"`
Firewallddir string `default:"@FIREWALLDDIR@"`
Systemddir string `default:"@SYSTEMDDIR@"`
WWOverlaydir string `default:"@WWOVERLAYDIR@"`

View File

@@ -1,61 +0,0 @@
package config
import (
"github.com/creasty/defaults"
)
type WarewulfConf struct {
Port int `yaml:"port" default:"9983"`
Secure bool `yaml:"secure" default:"true"`
UpdateInterval int `yaml:"update interval" default:"60"`
AutobuildOverlays bool `yaml:"autobuild overlays" default:"true"`
EnableHostOverlay bool `yaml:"host overlay" default:"true"`
Syslog bool `yaml:"syslog" default:"false"`
DataStore string `yaml:"datastore" default:"/var/lib/warewulf"`
}
type DhcpConf struct {
Enabled bool `yaml:"enabled" default:"true"`
Template string `yaml:"template" default:"default"`
RangeStart string `yaml:"range start,omitempty"`
RangeEnd string `yaml:"range end,omitempty"`
SystemdName string `yaml:"systemd name" default:"dhcpd"`
}
type TftpConf struct {
Enabled bool `yaml:"enabled" default:"true"`
TftpRoot string `yaml:"tftproot" default:"/var/lib/tftpboot"`
SystemdName string `yaml:"systemd name" default:"tftp"`
// Path is relative to buildconfig.DATADIR()
IpxeBinaries map[string]string `yaml:"ipxe" default:"{\"00:09\": \"x86_64.efi\",\"00:00\": \"x86_64.kpxe\",\"00:0B\": \"arm64.efi\",\"00:07\": \"x86_64.efi\"}"`
}
type NfsConf struct {
Enabled bool `yaml:"enabled" default:"true"`
ExportsExtended []*NfsExportConf `yaml:"export paths" default:"[]"`
SystemdName string `yaml:"systemd name" default:"nfsd"`
}
type NfsExportConf struct {
Path string `yaml:"path" default:"/dev/null"`
ExportOptions string `default:"rw,sync,no_subtree_check" yaml:"export options"`
MountOptions string `default:"defaults" yaml:"mount options"`
Mount bool `default:"true" yaml:"mount"`
}
/*
Describe a mount point for a container exec
*/
type MountEntry struct {
Source string `yaml:"source" default:"/etc/resolv.conf"`
Dest string `yaml:"dest,omitempty" default:"/etc/resolv.conf"`
ReadOnly bool `yaml:"readonly,omitempty" default:"false"`
Options string `yaml:"options,omitempty"` // ignored at the moment
}
func (s *NfsConf) Unmarshal(unmarshal func(interface{}) error) error {
if err := defaults.Set(s); err != nil {
return err
}
return nil
}

View File

@@ -0,0 +1,12 @@
package config
// DHCPConf represents the configuration for the DHCP service that
// Warewulf will configure.
type DHCPConf struct {
Enabled bool `yaml:"enabled" default:"true"`
Template string `yaml:"template" default:"default"`
RangeStart string `yaml:"range start,omitempty"`
RangeEnd string `yaml:"range end,omitempty"`
SystemdName string `yaml:"systemd name" default:"dhcpd"`
}

View File

@@ -0,0 +1,10 @@
package config
// A MountEntry represents a bind mount that is applied to a container
// during exec and shell.
type MountEntry struct {
Source string `yaml:"source" default:"/etc/resolv.conf"`
Dest string `yaml:"dest,omitempty" default:"/etc/resolv.conf"`
ReadOnly bool `yaml:"readonly,omitempty" default:"false"`
Options string `yaml:"options,omitempty"` // ignored at the moment
}

View File

@@ -0,0 +1,35 @@
package config
import (
"github.com/creasty/defaults"
)
// NFSConf represents the NFS configuration that will be used by
// Warewulf to generate exports on the server and mounts on compute
// nodes.
type NFSConf struct {
Enabled bool `yaml:"enabled" default:"true"`
ExportsExtended []*NFSExportConf `yaml:"export paths" default:"[]"`
SystemdName string `yaml:"systemd name" default:"nfsd"`
}
// An NFSExportConf reprents a single NFS export / mount.
type NFSExportConf struct {
Path string `yaml:"path" default:"/dev/null"`
ExportOptions string `default:"rw,sync,no_subtree_check" yaml:"export options"`
MountOptions string `default:"defaults" yaml:"mount options"`
Mount bool `default:"true" yaml:"mount"`
}
// Implements the Unmarshal interface for NFSConf to set default
// values.
func (conf *NFSConf) Unmarshal(unmarshal func(interface{}) error) error {
if err := defaults.Set(conf); err != nil {
return err
}
return nil
}

View File

@@ -26,7 +26,7 @@ var cachedConf RootConf
// RootConf is the main Warewulf configuration structure. It stores
// some information about the Warewulf server locally, and has
// [WarewulfConf], [DhcpConf], [TftpConf], and [NfsConf] sub-sections.
// [WarewulfConf], [DHCPConf], [TFTPConf], and [NFSConf] sub-sections.
type RootConf struct {
WWInternal int `yaml:"WW_INTERNAL"`
Comment string `yaml:"comment,omitempty"`
@@ -37,9 +37,9 @@ type RootConf struct {
Ipv6net string `yaml:"ipv6net,omitempty"`
Fqdn string `yaml:"fqdn,omitempty"`
Warewulf *WarewulfConf `yaml:"warewulf"`
Dhcp *DhcpConf `yaml:"dhcp"`
Tftp *TftpConf `yaml:"tftp"`
Nfs *NfsConf `yaml:"nfs"`
DHCP *DHCPConf `yaml:"dhcp"`
TFTP *TFTPConf `yaml:"tftp"`
NFS *NFSConf `yaml:"nfs"`
MountsContainer []*MountEntry `yaml:"container mounts" default:"[{\"source\": \"/etc/resolv.conf\", \"dest\": \"/etc/resolv.conf\"}]"`
Paths *BuildConfig `yaml:"paths"`
@@ -53,9 +53,9 @@ func New() (*RootConf) {
cachedConf = RootConf{}
cachedConf.fromFile = false
cachedConf.Warewulf = new(WarewulfConf)
cachedConf.Dhcp = new(DhcpConf)
cachedConf.Tftp = new(TftpConf)
cachedConf.Nfs = new(NfsConf)
cachedConf.DHCP = new(DHCPConf)
cachedConf.TFTP = new(TFTPConf)
cachedConf.NFS = new(NFSConf)
cachedConf.Paths = new(BuildConfig)
if err := defaults.Set(&cachedConf); err != nil {
panic(err)
@@ -95,15 +95,15 @@ func (conf *RootConf) Read(confFileName string) (error) {
func (conf *RootConf) Parse(data []byte) (error) {
// ipxe binaries are merged not overwritten, store defaults separate
defIpxe := make(map[string]string)
for k, v := range conf.Tftp.IpxeBinaries {
for k, v := range conf.TFTP.IPXEBinaries {
defIpxe[k] = v
delete(conf.Tftp.IpxeBinaries, k)
delete(conf.TFTP.IPXEBinaries, k)
}
if err := yaml.Unmarshal(data, &conf); err != nil {
return err
}
if len(conf.Tftp.IpxeBinaries) == 0 {
conf.Tftp.IpxeBinaries = defIpxe
if len(conf.TFTP.IPXEBinaries) == 0 {
conf.TFTP.IPXEBinaries = defIpxe
}
return nil
}
@@ -141,14 +141,14 @@ func (conf *RootConf) SetDynamicDefaults() (err error) {
wwlog.Verbose("Network is not configured in warewulf.conf, using %s", conf.Network)
}
}
if conf.Dhcp.RangeStart == "" && conf.Dhcp.RangeEnd == "" {
if conf.DHCP.RangeStart == "" && conf.DHCP.RangeEnd == "" {
start := net.ParseIP(conf.Network).To4()
start[3] += 1
if start.Equal(net.ParseIP(conf.Ipaddr)) {
start[3] += 1
}
conf.Dhcp.RangeStart = start.String()
wwlog.Verbose("dhpd start is not configured in warewulf.conf, using %s", conf.Dhcp.RangeStart)
conf.DHCP.RangeStart = start.String()
wwlog.Verbose("dhpd start is not configured in warewulf.conf, using %s", conf.DHCP.RangeStart)
sz, _ := net.IPMask(net.ParseIP(conf.Netmask).To4()).Size()
range_end := (1 << (32 - sz)) / 8
if range_end > 127 {
@@ -156,8 +156,8 @@ func (conf *RootConf) SetDynamicDefaults() (err error) {
}
end := net.ParseIP(conf.Network).To4()
end[3] += byte(range_end)
conf.Dhcp.RangeEnd = end.String()
wwlog.Verbose("dhpd end is not configured in warewulf.conf, using %s", conf.Dhcp.RangeEnd)
conf.DHCP.RangeEnd = end.String()
wwlog.Verbose("dhpd end is not configured in warewulf.conf, using %s", conf.DHCP.RangeEnd)
}
// check validity of ipv6 net

View File

@@ -0,0 +1,13 @@
package config
// TFTPConf represents that configuration for the TFTP service that
// Warewulf will configure.
type TFTPConf struct {
Enabled bool `yaml:"enabled" default:"true"`
TFTPRoot string `yaml:"tftproot" default:"/var/lib/tftpboot"`
SystemdName string `yaml:"systemd name" default:"tftp"`
// Path is relative to buildconfig.DATADIR()
IPXEBinaries map[string]string `yaml:"ipxe" default:"{\"00:09\": \"x86_64.efi\",\"00:00\": \"x86_64.kpxe\",\"00:0B\": \"arm64.efi\",\"00:07\": \"x86_64.efi\"}"`
}

View File

@@ -0,0 +1,14 @@
package config
// WarewulfConf adds additional Warewulf-specific configuration to
// BaseConf.
type WarewulfConf struct {
Port int `yaml:"port" default:"9983"`
Secure bool `yaml:"secure" default:"true"`
UpdateInterval int `yaml:"update interval" default:"60"`
AutobuildOverlays bool `yaml:"autobuild overlays" default:"true"`
EnableHostOverlay bool `yaml:"host overlay" default:"true"`
Syslog bool `yaml:"syslog" default:"false"`
DataStore string `yaml:"datastore" default:"/var/lib/warewulf"`
}

View File

@@ -15,21 +15,21 @@ import (
Configures the dhcpd server, when show is set to false, else the
dhcp configuration is checked.
*/
func Dhcp() (err error) {
func DHCP() (err error) {
controller := warewulfconf.Get()
if !controller.Dhcp.Enabled {
if !controller.DHCP.Enabled {
wwlog.Info("This system is not configured as a Warewulf DHCP controller")
os.Exit(1)
}
if controller.Dhcp.RangeStart == "" {
if controller.DHCP.RangeStart == "" {
wwlog.Error("Configuration is not defined: `dhcpd range start`")
os.Exit(1)
}
if controller.Dhcp.RangeEnd == "" {
if controller.DHCP.RangeEnd == "" {
wwlog.Error("Configuration is not defined: `dhcpd range end`")
os.Exit(1)
}
@@ -42,7 +42,7 @@ func Dhcp() (err error) {
wwlog.Info("host overlays are disabled, did not modify/create dhcpd configuration")
}
fmt.Printf("Enabling and restarting the DHCP services\n")
err = util.SystemdStart(controller.Dhcp.SystemdName)
err = util.SystemdStart(controller.DHCP.SystemdName)
if err != nil {
return errors.Wrap(err, "failed to start")
}

View File

@@ -18,7 +18,7 @@ func NFS() error {
controller := warewulfconf.Get()
if controller.Nfs.Enabled {
if controller.NFS.Enabled {
if controller.Warewulf.EnableHostOverlay {
err := overlay.BuildHostOverlay()
if err != nil {
@@ -28,13 +28,13 @@ func NFS() error {
wwlog.Info("host overlays are disabled, did not modify exports")
}
fmt.Printf("Enabling and restarting the NFS services\n")
if controller.Nfs.SystemdName == "" {
if controller.NFS.SystemdName == "" {
err := util.SystemdStart("nfs-server")
if err != nil {
return errors.Wrap(err, "failed to start nfs-server")
}
} else {
err := util.SystemdStart(controller.Nfs.SystemdName)
err := util.SystemdStart(controller.NFS.SystemdName)
if err != nil {
return errors.Wrap(err, "failed to start")
}

View File

@@ -12,7 +12,7 @@ import (
func TFTP() error {
controller := warewulfconf.Get()
var tftpdir string = path.Join(controller.Paths.Tftpdir, "warewulf")
var tftpdir string = path.Join(controller.Paths.TFTPdir, "warewulf")
err := os.MkdirAll(tftpdir, 0755)
if err != nil {
@@ -22,7 +22,7 @@ func TFTP() error {
fmt.Printf("Writing PXE files to: %s\n", tftpdir)
copyCheck := make(map[string]bool)
for _, f := range controller.Tftp.IpxeBinaries {
for _, f := range controller.TFTP.IPXEBinaries {
if copyCheck[f] {
continue
}
@@ -33,13 +33,13 @@ func TFTP() error {
}
}
if !controller.Tftp.Enabled {
if !controller.TFTP.Enabled {
wwlog.Info("Warewulf does not auto start TFTP services due to disable by warewulf.conf")
os.Exit(0)
}
fmt.Printf("Enabling and restarting the TFTP services\n")
err = util.SystemdStart(controller.Tftp.SystemdName)
err = util.SystemdStart(controller.TFTP.SystemdName)
if err != nil {
wwlog.Error("%s", err)
return err

View File

@@ -28,10 +28,10 @@ type TemplateStruct struct {
Network string
NetworkCIDR string
Ipv6 bool
Dhcp warewulfconf.DhcpConf
Nfs warewulfconf.NfsConf
Dhcp warewulfconf.DHCPConf
Nfs warewulfconf.NFSConf
Warewulf warewulfconf.WarewulfConf
Tftp warewulfconf.TftpConf
Tftp warewulfconf.TFTPConf
Paths warewulfconf.BuildConfig
AllNodes []node.NodeInfo
node.NodeConf
@@ -60,9 +60,9 @@ func InitStruct(nodeInfo node.NodeInfo) TemplateStruct {
tstruct.Hostname = nodeInfo.Id.Get()
// Backwards compatibility for templates using "Keys"
tstruct.AllNodes = allNodes
tstruct.Nfs = *controller.Nfs
tstruct.Dhcp = *controller.Dhcp
tstruct.Tftp = *controller.Tftp
tstruct.Nfs = *controller.NFS
tstruct.Dhcp = *controller.DHCP
tstruct.Tftp = *controller.TFTP
tstruct.Warewulf = *controller.Warewulf
tstruct.Ipaddr = controller.Ipaddr
tstruct.Ipaddr6 = controller.Ipaddr6