diff --git a/.gitignore b/.gitignore index 894fa86d..7859c0c0 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/internal/app/wwctl/configure/dhcp/main.go b/internal/app/wwctl/configure/dhcp/main.go index 38ff6f97..a98561d9 100644 --- a/internal/app/wwctl/configure/dhcp/main.go +++ b/internal/app/wwctl/configure/dhcp/main.go @@ -6,5 +6,5 @@ import ( ) func CobraRunE(cmd *cobra.Command, args []string) error { - return configure.Dhcp() + return configure.DHCP() } diff --git a/internal/app/wwctl/configure/main.go b/internal/app/wwctl/configure/main.go index 3512d2fc..798c1d03 100644 --- a/internal/app/wwctl/configure/main.go +++ b/internal/app/wwctl/configure/main.go @@ -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) diff --git a/internal/pkg/config/buildconfig.go.in b/internal/pkg/config/buildconfig.go.in index 5316e518..57ef0fba 100644 --- a/internal/pkg/config/buildconfig.go.in +++ b/internal/pkg/config/buildconfig.go.in @@ -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@"` diff --git a/internal/pkg/config/datastructure.go b/internal/pkg/config/datastructure.go deleted file mode 100644 index 4d5cefd1..00000000 --- a/internal/pkg/config/datastructure.go +++ /dev/null @@ -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 -} diff --git a/internal/pkg/config/dhcp.go b/internal/pkg/config/dhcp.go new file mode 100644 index 00000000..3dbcd241 --- /dev/null +++ b/internal/pkg/config/dhcp.go @@ -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"` +} diff --git a/internal/pkg/config/mounts.go b/internal/pkg/config/mounts.go new file mode 100644 index 00000000..daf38c0a --- /dev/null +++ b/internal/pkg/config/mounts.go @@ -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 +} diff --git a/internal/pkg/config/nfs.go b/internal/pkg/config/nfs.go new file mode 100644 index 00000000..03726379 --- /dev/null +++ b/internal/pkg/config/nfs.go @@ -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 +} diff --git a/internal/pkg/config/root.go b/internal/pkg/config/root.go index 822df5c0..9ffd667a 100644 --- a/internal/pkg/config/root.go +++ b/internal/pkg/config/root.go @@ -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 diff --git a/internal/pkg/config/tftp.go b/internal/pkg/config/tftp.go new file mode 100644 index 00000000..6681df55 --- /dev/null +++ b/internal/pkg/config/tftp.go @@ -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\"}"` +} diff --git a/internal/pkg/config/warewulf.go b/internal/pkg/config/warewulf.go new file mode 100644 index 00000000..75d6b6ba --- /dev/null +++ b/internal/pkg/config/warewulf.go @@ -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"` +} diff --git a/internal/pkg/configure/dhcp.go b/internal/pkg/configure/dhcp.go index d7ef2e69..02613f05 100644 --- a/internal/pkg/configure/dhcp.go +++ b/internal/pkg/configure/dhcp.go @@ -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") } diff --git a/internal/pkg/configure/nfs.go b/internal/pkg/configure/nfs.go index 343d59c8..82f70e84 100644 --- a/internal/pkg/configure/nfs.go +++ b/internal/pkg/configure/nfs.go @@ -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") } diff --git a/internal/pkg/configure/tftp.go b/internal/pkg/configure/tftp.go index 16a28bbb..333a7961 100644 --- a/internal/pkg/configure/tftp.go +++ b/internal/pkg/configure/tftp.go @@ -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 diff --git a/internal/pkg/overlay/datastructure.go b/internal/pkg/overlay/datastructure.go index 760d3f42..6af7adb2 100644 --- a/internal/pkg/overlay/datastructure.go +++ b/internal/pkg/overlay/datastructure.go @@ -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