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:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -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
|
||||
|
||||
@@ -6,5 +6,5 @@ import (
|
||||
)
|
||||
|
||||
func CobraRunE(cmd *cobra.Command, args []string) error {
|
||||
return configure.Dhcp()
|
||||
return configure.DHCP()
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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@"`
|
||||
|
||||
@@ -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
|
||||
}
|
||||
12
internal/pkg/config/dhcp.go
Normal file
12
internal/pkg/config/dhcp.go
Normal 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"`
|
||||
}
|
||||
10
internal/pkg/config/mounts.go
Normal file
10
internal/pkg/config/mounts.go
Normal 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
|
||||
}
|
||||
35
internal/pkg/config/nfs.go
Normal file
35
internal/pkg/config/nfs.go
Normal 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
|
||||
}
|
||||
@@ -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
|
||||
|
||||
13
internal/pkg/config/tftp.go
Normal file
13
internal/pkg/config/tftp.go
Normal 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\"}"`
|
||||
}
|
||||
14
internal/pkg/config/warewulf.go
Normal file
14
internal/pkg/config/warewulf.go
Normal 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"`
|
||||
}
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user