diff --git a/.github/workflows/nightly-release.yml b/.github/workflows/nightly-release.yml index 989908e2..f413c29c 100644 --- a/.github/workflows/nightly-release.yml +++ b/.github/workflows/nightly-release.yml @@ -51,6 +51,9 @@ jobs: permissions: write-all steps: + - name: Install git + run: | + dnf install -y git - name: Checkout Code uses: actions/checkout@v4 with: diff --git a/CHANGELOG.md b/CHANGELOG.md index d6bdd20a..c06cafc3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,23 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Bump golang.org/x/net from 0.30.0 to 0.33.0 #1774 - Bump github.com/go-jose/go-jose/v4 from 4.0.2 to 4.0.5 #1773 - Bump github.com/golang/glog from 1.2.3 to 1.2.4 #1771 +### Added + +- Support Ubuntu-style dracut initrd images. + +### Changed + +- Match default kernel arguments from `wwctl upgrade nodes` with the distributed `nodes.conf`. + +### Fixed + +- Fix nightly builds. +- Better handling for missing NetDev.Device. #1777 +- Remove dracut NetworkManager connections between boot phases. #1780 + +### Changed + +- User `wwctl overlay --workers=0` to indicate `runtime.NumCPU()`. #1782 ## v4.6.0rc3, 2025-02-23 diff --git a/Tools.mk b/Tools.mk index 9bc49836..924bb2f2 100644 --- a/Tools.mk +++ b/Tools.mk @@ -59,7 +59,7 @@ $(GOLANG_LICENSES): GOBIN="$(PWD)/$(TOOLS_BIN)" go install github.com/google/go-licenses@v1.6.0 $(GOLANG_STATICCHECK): - GOBIN="$(PWD)/$(TOOLS_BIN)" go install honnef.co/go/tools/cmd/staticcheck@latest + GOBIN="$(PWD)/$(TOOLS_BIN)" go install honnef.co/go/tools/cmd/staticcheck@v0.5.1 .PHONY: cleantools cleantools: diff --git a/internal/app/wwctl/overlay/build/main.go b/internal/app/wwctl/overlay/build/main.go index fd10342c..22e4b9f8 100644 --- a/internal/app/wwctl/overlay/build/main.go +++ b/internal/app/wwctl/overlay/build/main.go @@ -3,6 +3,7 @@ package build import ( "errors" "fmt" + "runtime" "strings" "syscall" @@ -67,10 +68,15 @@ func CobraRunE(cmd *cobra.Command, args []string) error { oldMask := syscall.Umask(000) defer syscall.Umask(oldMask) + workers := Workers + if workers <= 0 { + workers = runtime.NumCPU() + } + if len(OverlayNames) > 0 { - err = overlay.BuildSpecificOverlays(filteredNodes, allNodes, OverlayNames, Workers) + err = overlay.BuildSpecificOverlays(filteredNodes, allNodes, OverlayNames, workers) } else { - err = overlay.BuildAllOverlays(filteredNodes, allNodes, Workers) + err = overlay.BuildAllOverlays(filteredNodes, allNodes, workers) } if err != nil { diff --git a/internal/app/wwctl/overlay/build/root.go b/internal/app/wwctl/overlay/build/root.go index ba1fe163..2c4fac86 100644 --- a/internal/app/wwctl/overlay/build/root.go +++ b/internal/app/wwctl/overlay/build/root.go @@ -1,8 +1,6 @@ package build import ( - "runtime" - "github.com/spf13/cobra" "github.com/warewulf/warewulf/internal/app/wwctl/completions" ) @@ -29,7 +27,7 @@ func init() { } baseCmd.PersistentFlags().StringVarP(&OverlayDir, "output", "o", "", `Do not create an overlay image for distribution but write to the given directory. An overlay must also be ge given to use this option.`) - baseCmd.PersistentFlags().IntVar(&Workers, "workers", runtime.NumCPU(), "The number of parallel workers building overlays") + baseCmd.PersistentFlags().IntVar(&Workers, "workers", 0, "The number of parallel workers building overlays (<=0 indicates 1 worker per CPU)") } // GetRootCommand returns the root cobra.Command for the application. diff --git a/internal/app/wwctl/overlay/imprt/main.go b/internal/app/wwctl/overlay/imprt/main.go index 890950bc..335ab673 100644 --- a/internal/app/wwctl/overlay/imprt/main.go +++ b/internal/app/wwctl/overlay/imprt/main.go @@ -5,6 +5,7 @@ import ( "os" "path" "path/filepath" + "runtime" "github.com/spf13/cobra" "github.com/warewulf/warewulf/internal/pkg/node" @@ -88,7 +89,11 @@ func CobraRunE(cmd *cobra.Command, args []string) (err error) { } } - return overlay.BuildSpecificOverlays(updateNodes, nodes, []string{overlayName}, Workers) + workers := Workers + if workers <= 0 { + workers = runtime.NumCPU() + } + return overlay.BuildSpecificOverlays(updateNodes, nodes, []string{overlayName}, workers) } return nil diff --git a/internal/app/wwctl/overlay/imprt/root.go b/internal/app/wwctl/overlay/imprt/root.go index 0c1f6b49..8d54521e 100644 --- a/internal/app/wwctl/overlay/imprt/root.go +++ b/internal/app/wwctl/overlay/imprt/root.go @@ -1,8 +1,6 @@ package imprt import ( - "runtime" - "github.com/spf13/cobra" "github.com/warewulf/warewulf/internal/app/wwctl/completions" ) @@ -34,7 +32,7 @@ var ( func init() { baseCmd.PersistentFlags().BoolVarP(&NoOverlayUpdate, "noupdate", "n", false, "Don't update overlays") baseCmd.PersistentFlags().BoolVarP(&CreateDirs, "parents", "p", false, "Create any necessary parent directories") - baseCmd.PersistentFlags().IntVar(&Workers, "workers", runtime.NumCPU(), "The number of parallel workers building overlays") + baseCmd.PersistentFlags().IntVar(&Workers, "workers", 0, "The number of parallel workers building overlays (<=0 indicates 1 worker per CPU)") } // GetRootCommand returns the root cobra.Command for the application. diff --git a/internal/pkg/image/initramfs.go b/internal/pkg/image/initramfs.go index 85a69010..0a7b7777 100644 --- a/internal/pkg/image/initramfs.go +++ b/internal/pkg/image/initramfs.go @@ -14,6 +14,7 @@ var ( initramfsSearchPaths = []string{ "/boot/initramfs-*", "/boot/initrd-*", + "/boot/initrd.img-*", } versionPattern *regexp.Regexp diff --git a/internal/pkg/image/initramfs_test.go b/internal/pkg/image/initramfs_test.go index ce81c98f..0f4f680d 100644 --- a/internal/pkg/image/initramfs_test.go +++ b/internal/pkg/image/initramfs_test.go @@ -20,7 +20,6 @@ func TestFindInitramfs(t *testing.T) { assert.NoError(t, os.MkdirAll(filepath.Join(RootFsDir("image"), "boot"), 0700)) tests := map[string]struct { - name string initramfs []string ver string path string @@ -45,6 +44,11 @@ func TestFindInitramfs(t *testing.T) { ver: "1.1.1", path: "/boot/initrd-1.1.1.aarch64.img", }, + "ok case 5 (ubuntu)": { + initramfs: []string{"/boot/initrd.img-6.11.0-18-generic"}, + ver: "6.11.0-18", + path: "/boot/initrd.img-6.11.0-18-generic", + }, "prefix match": { initramfs: []string{"/boot/initrd-1.1.1.aarch64.img"}, ver: "1.1", diff --git a/internal/pkg/upgrade/node.go b/internal/pkg/upgrade/node.go index 46cf5d63..3e8fa26f 100644 --- a/internal/pkg/upgrade/node.go +++ b/internal/pkg/upgrade/node.go @@ -123,7 +123,7 @@ func (legacy *NodesYaml) Upgrade(addDefaults bool, replaceOverlays bool, warewul defaultProfile.RuntimeOverlay, genericSplitOverlays...) } if len(defaultProfile.Kernel.Args) < 1 { - defaultProfile.Kernel.Args = []string{"quiet", "crashkernel=no", "vga=791", "net.naming-scheme=v238"} + defaultProfile.Kernel.Args = []string{"quiet", "crashkernel=no"} } if defaultProfile.Init == "" { defaultProfile.Init = "/sbin/init" diff --git a/internal/pkg/upgrade/node_test.go b/internal/pkg/upgrade/node_test.go index fa04fea5..132b109b 100644 --- a/internal/pkg/upgrade/node_test.go +++ b/internal/pkg/upgrade/node_test.go @@ -576,8 +576,6 @@ nodeprofiles: args: - quiet - crashkernel=no - - vga=791 - - net.naming-scheme=v238 init: /sbin/init root: initramfs resources: @@ -656,8 +654,6 @@ nodeprofiles: args: - quiet - crashkernel=no - - vga=791 - - net.naming-scheme=v238 init: /sbin/init root: initramfs resources: @@ -919,8 +915,6 @@ nodeprofiles: args: - quiet - crashkernel=no - - vga=791 - - net.naming-scheme=v238 init: /sbin/init root: initramfs resources: diff --git a/overlays/NetworkManager/internal/networkmanager_test.go b/overlays/NetworkManager/internal/networkmanager_test.go index 3d106194..f9db63e0 100644 --- a/overlays/NetworkManager/internal/networkmanager_test.go +++ b/overlays/NetworkManager/internal/networkmanager_test.go @@ -50,7 +50,7 @@ Filename: warewulf-unmanaged.conf plugins=keyfile [keyfile] -unmanaged-devices=except:mac:e6:92:39:49:7b:03,except:interface-name:wwnet0,except:mac:9a:77:29:73:14:f1,except:interface-name:wwnet1, +unmanaged-devices=except:mac:e6:92:39:49:7b:03,except:interface-name:wwnet0,except:mac:9a:77:29:73:14:f1,except:interface-name:wwnet1 `, }, "NetworkManager:ww4-managed.ww": { @@ -119,6 +119,74 @@ gateway=192.168.3.1 dns=8.8.8.8;8.8.4.4; dns-search=example.com;example.net; +[ipv6] +addr-gen-mode=stable-privacy +method=ignore +never-default=true +`, + }, + "NetworkManager:ww4-managed.ww without device": { + nodes_conf: ` +nodes: + node1: + network devices: + default: + onboot: true + hwaddr: e6:92:39:49:7b:03 + ipaddr: 192.168.3.21 + netmask: 255.255.255.0 + gateway: 192.168.3.1 + secondary: + onboot: true + hwaddr: 9a:77:29:73:14:f1 + ipaddr: 192.168.3.22 + netmask: 255.255.255.0 + gateway: 192.168.3.1 + tags: + DNS1: 8.8.8.8 + DNS2: 8.8.4.4 + DNSSEARCH: "example.com;example.net;" +`, + args: []string{"--render", "node1", "NetworkManager", "etc/NetworkManager/system-connections/ww4-managed.ww"}, + log: `backupFile: true +writeFile: true +Filename: warewulf-default.conf + +# This file is autogenerated by warewulf + +[connection] +id=default +type=ethernet +autoconnect=true +[ethernet] +mac-address=e6:92:39:49:7b:03 +[ipv4] +method=manual +address=192.168.3.21/24 +gateway=192.168.3.1 + +[ipv6] +addr-gen-mode=stable-privacy +method=ignore +never-default=true +backupFile: true +writeFile: true +Filename: warewulf-secondary.conf +# This file is autogenerated by warewulf + +[connection] +id=secondary +type=ethernet +autoconnect=true +[ethernet] +mac-address=9a:77:29:73:14:f1 +[ipv4] +method=manual +address=192.168.3.22/24 +gateway=192.168.3.1 +dns=8.8.8.8;8.8.4.4; +dns-search=example.com;example.net; + [ipv6] addr-gen-mode=stable-privacy method=ignore @@ -158,7 +226,7 @@ Filename: warewulf-unmanaged.conf plugins=keyfile [keyfile] -unmanaged-devices=except:interface-name:wwnet0,except:mac:9a:77:29:73:14:f1,except:interface-name:wwnet1, +unmanaged-devices=except:interface-name:wwnet0,except:mac:9a:77:29:73:14:f1,except:interface-name:wwnet1 `, }, "NetworkManager:ww4-managed.ww with vlan": { diff --git a/overlays/NetworkManager/rootfs/etc/NetworkManager/conf.d/ww4-unmanaged.ww b/overlays/NetworkManager/rootfs/etc/NetworkManager/conf.d/ww4-unmanaged.ww index 1afa9491..4b66b892 100644 --- a/overlays/NetworkManager/rootfs/etc/NetworkManager/conf.d/ww4-unmanaged.ww +++ b/overlays/NetworkManager/rootfs/etc/NetworkManager/conf.d/ww4-unmanaged.ww @@ -5,4 +5,15 @@ plugins=keyfile [keyfile] -unmanaged-devices={{ range $connection_id, $netdev := .NetDevs }}{{ if $netdev.Hwaddr }}except:mac:{{ $netdev.Hwaddr }},{{ end }}{{ if $netdev.Device }}except:interface-name:{{ $netdev.Device }},{{ end }}{{ end }} +{{- $unmanaged := list }} +{{- range $_, $netdev := .NetDevs }} +{{- if $netdev.Hwaddr }} +{{- $unmanaged = append $unmanaged (printf "except:mac:%s" $netdev.Hwaddr) }} +{{- end }} +{{- if $netdev.Device }} +{{- $unmanaged = append $unmanaged (printf "except:interface-name:%s" $netdev.Device) }} +{{- end }} +{{- end }} +{{- if $unmanaged }} +unmanaged-devices={{ join "," $unmanaged }} +{{- end }} diff --git a/overlays/NetworkManager/rootfs/etc/NetworkManager/system-connections/ww4-managed.ww b/overlays/NetworkManager/rootfs/etc/NetworkManager/system-connections/ww4-managed.ww index ae70f38b..2586837b 100644 --- a/overlays/NetworkManager/rootfs/etc/NetworkManager/system-connections/ww4-managed.ww +++ b/overlays/NetworkManager/rootfs/etc/NetworkManager/system-connections/ww4-managed.ww @@ -4,7 +4,9 @@ [connection] id={{ $devname }} +{{- if $netdev.Device }} interface-name={{ $netdev.Device }} +{{- end }} type={{ default "ethernet" (lower $netdev.Type) }} {{- if $netdev.Tags.master }} master={{ $netdev.Tags.master }} @@ -78,7 +80,9 @@ ipaddr="{{ $netdev.Ipaddr6 }}" {{- if eq $netdev.Type "vlan" }} [vlan] +{{- if $netdev.Device }} interface-name={{ $netdev.Device }} +{{- end }} parent={{ $netdev.Tags.parent_device }} id={{ $netdev.Tags.vlan_id }} {{- end }} diff --git a/overlays/NetworkManager/rootfs/warewulf/init.d/20-NetworkManager b/overlays/NetworkManager/rootfs/warewulf/init.d/20-NetworkManager new file mode 100644 index 00000000..45481033 --- /dev/null +++ b/overlays/NetworkManager/rootfs/warewulf/init.d/20-NetworkManager @@ -0,0 +1,6 @@ +#!/bin/sh + +echo "Warewulf prescript: NetworkManager" +echo +echo "Removing NetworkManager state from any prior boot stage..." +rm -rf /run/NetworkManager diff --git a/overlays/ifcfg/internal/ifcfg_test.go b/overlays/ifcfg/internal/ifcfg_test.go index 654ec2d4..164349d9 100644 --- a/overlays/ifcfg/internal/ifcfg_test.go +++ b/overlays/ifcfg/internal/ifcfg_test.go @@ -86,6 +86,74 @@ IPV6_FAILURE_FATAL=no DNS1=8.8.8.8 DNS2=8.8.4.4 DOMAIN="example.net example.com" +`, + }, + "ifcfg:ifcfg.ww without device": { + nodes_conf: ` +nodes: + node1: + network devices: + default: + hwaddr: e6:92:39:49:7b:03 + ipaddr: 192.168.3.21 + netmask: 255.255.255.0 + gateway: 192.168.3.1 + tags: + DNS1: 1.1.1.1 + DNS2: 1.0.0.1 + DNSSEARCH: "example.com example.net" + secondary: + hwaddr: 9a:77:29:73:14:f1 + ipaddr: 192.168.3.22 + netmask: 255.255.255.0 + gateway: 192.168.3.1 + tags: + DNS1: 8.8.8.8 + DNS2: 8.8.4.4 + DNSSEARCH: "example.net;example.com;" +`, + args: []string{"--render", "node1", "ifcfg", "etc/sysconfig/network-scripts/ifcfg.ww"}, + log: `backupFile: true +writeFile: true +Filename: ifcfg-default.conf + +# This file is autogenerated by warewulf +TYPE=Ethernet +NAME=default +BOOTPROTO=static +DEVTIMEOUT=10 +IPADDR=192.168.3.21 +NETMASK=255.255.255.0 +GATEWAY=192.168.3.1 +HWADDR=e6:92:39:49:7b:03 +ONBOOT=true +IPV6INIT=yes +IPV6_AUTOCONF=yes +IPV6_DEFROUTE=yes +IPV6_FAILURE_FATAL=no +DNS1=1.1.1.1 +DNS2=1.0.0.1 +DOMAIN="example.com example.net" +backupFile: true +writeFile: true +Filename: ifcfg-secondary.conf +# This file is autogenerated by warewulf +TYPE=Ethernet +NAME=secondary +BOOTPROTO=static +DEVTIMEOUT=10 +IPADDR=192.168.3.22 +NETMASK=255.255.255.0 +GATEWAY=192.168.3.1 +HWADDR=9a:77:29:73:14:f1 +ONBOOT=true +IPV6INIT=yes +IPV6_AUTOCONF=yes +IPV6_DEFROUTE=yes +IPV6_FAILURE_FATAL=no +DNS1=8.8.8.8 +DNS2=8.8.4.4 +DOMAIN="example.net example.com" `, }, "ifcfg:network.ww": { diff --git a/overlays/ifcfg/rootfs/etc/sysconfig/network-scripts/ifcfg.ww b/overlays/ifcfg/rootfs/etc/sysconfig/network-scripts/ifcfg.ww index 7086ff5e..f29a7bd0 100644 --- a/overlays/ifcfg/rootfs/etc/sysconfig/network-scripts/ifcfg.ww +++ b/overlays/ifcfg/rootfs/etc/sysconfig/network-scripts/ifcfg.ww @@ -9,7 +9,9 @@ TYPE={{ default "Ethernet" $netdev.Type }} {{- if $netdev.Tags.master }} MASTER={{ $netdev.Tags.master }} {{- end }} +{{- if $netdev.Device }} DEVICE={{ $netdev.Device }} +{{- end }} NAME={{ $devname }} {{- if $netdev.MTU }} MTU={{ $netdev.MTU }}