diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index bf5f0bb7..70c68abb 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -1,6 +1,6 @@ name: "\U0001F41E Bug report" +type: Bug description: Report a bug in Warewulf (command not working as expected, etc.) -labels: [bug] body: - type: textarea id: reproduce diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index d41274ba..9c8a2873 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -1,6 +1,6 @@ name: "\U0001F38A Feature request" +type: Feature description: Suggest adding a feature -labels: [enhancement] body: - type: textarea id: summary diff --git a/CHANGELOG.md b/CHANGELOG.md index a0f496de..95939dcb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Don't mount /run during wwinit. #1566 - Simpler permissions in official RPM packages. #1696 - Only calculate image chroot size when requested. #1504 +- Create temporary files in overlay directory during `wwctl overlay edit`. #1473 ### Fixed @@ -34,6 +35,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Specify init=/init when booting with Grub+dracut. #1573 - Fix a warewulfd panic when no kernel fields are specified. #1689 - Create site overlay directory. #1690 +- Urlencode asset keys during dracut boot. #1610 +- Set execute permissions for intermediate directories during `wwctl overlay import --parents`. #1655 +- Fix log output formatting during overlay build. +- Prevent merging of zero-value net.IP fields. #1710 ## v4.6.0rc1, 2025-01-29 diff --git a/dracut/modules.d/90wwinit/load-wwinit.sh b/dracut/modules.d/90wwinit/load-wwinit.sh index b434dacd..2def30f0 100755 --- a/dracut/modules.d/90wwinit/load-wwinit.sh +++ b/dracut/modules.d/90wwinit/load-wwinit.sh @@ -3,18 +3,25 @@ info "Mounting tmpfs at $NEWROOT" mount -t tmpfs -o mpol=interleave ${wwinit_tmpfs_size_option} tmpfs "$NEWROOT" -for archive in "${wwinit_image}" "${wwinit_system}" "${wwinit_runtime}" +for stage in "image" "system" "runtime" do - if [ -n "${archive}" ] + info "Loading stage: ${stage}" + # Load runtime overlay from a static privledged port. + # Others use default settings. + localport="" + if [[ "${stage}" == "runtime" ]] then - info "Loading ${archive}" - # Load runtime overlay from a static privledged port. - # Others use default settings. - localport="" - if [[ "${archive}" == "${wwinit_runtime}" ]] - then - localport="--local-port 1-1023" - fi - (curl --retry 60 --retry-delay 1 --silent ${localport} -L "${archive}" | gzip -d | cpio -im --directory="${NEWROOT}") || die "Unable to load ${archive}" + localport="--local-port 1-1023" fi + ( + curl --location --silent --get ${localport} \ + --retry 60 --retry-delay 1 \ + --data-urlencode "assetkey=${wwinit_assetkey}" \ + --data-urlencode "uuid=${wwinit_uuid}" \ + --data-urlencode "stage=${stage}" \ + --data-urlencode "compress=gz" \ + "${wwinit_uri}" \ + | gzip -d \ + | cpio -im --directory="${NEWROOT}" + ) || die "Unable to load stage: ${stage}" done diff --git a/dracut/modules.d/90wwinit/parse-wwinit.sh b/dracut/modules.d/90wwinit/parse-wwinit.sh index b9e7446f..65bc6349 100755 --- a/dracut/modules.d/90wwinit/parse-wwinit.sh +++ b/dracut/modules.d/90wwinit/parse-wwinit.sh @@ -6,12 +6,9 @@ if [ "${root}" = "wwinit" ] then info "root=${root}" - uuid=$(dmidecode -s system-uuid) - assetkey=$(dmidecode -s chassis-asset-tag | sed -E -e 's/(^ +| +$)//g' -e 's/^(Unknown|Not Specified)$//g' -e 's/ /_/g') - wwinit_uri="$(getarg wwinit.uri)?assetkey=${assetkey}&uuid=${uuid}" - export wwinit_image="${wwinit_uri}&stage=image&compress=gz"; info "wwinit_image=${wwinit_image}" - export wwinit_system="${wwinit_uri}&stage=system&compress=gz"; info "wwinit_system=${wwinit_system}" - export wwinit_runtime="${wwinit_uri}&stage=runtime&compress=gz"; info "wwinit_runtime=${wwinit_runtime}" + export wwinit_uuid=$(dmidecode -s system-uuid) + export wwinit_assetkey=$(dmidecode -s chassis-asset-tag) + export wwinit_uri="$(getarg wwinit.uri)" wwinit_tmpfs_size=$(getarg wwinit.tmpfs.size=) if [ -n "$wwinit_tmpfs_size" ] @@ -20,11 +17,11 @@ then export wwinit_tmpfs_size_option="-o size=${wwinit_tmpfs_size}" fi - if [ -n "${wwinit_image}" ] + if [ -n "${wwinit_uri}" ] then - info "Found root=${root} and a Warewulf image. Will boot from Warewulf." + info "Found root=${root} and a Warewulf server uri. Will boot from Warewulf." rootok=1 else - die "Found root=${root} but no image. Cannot boot from Warewulf." + die "Found root=${root} but no Warewulf server uri. Cannot boot from Warewulf." fi fi diff --git a/internal/app/wwctl/overlay/edit/main.go b/internal/app/wwctl/overlay/edit/main.go index bb54d563..65c930ca 100644 --- a/internal/app/wwctl/overlay/edit/main.go +++ b/internal/app/wwctl/overlay/edit/main.go @@ -48,7 +48,7 @@ func CobraRunE(cmd *cobra.Command, args []string) (err error) { return fmt.Errorf("%s does not exist. Use '--parents' option to create automatically", overlayFileDir) } - tempFile, tempFileErr := os.CreateTemp("", "ww-overlay-edit-") + tempFile, tempFileErr := os.CreateTemp(overlay_.Path(), "ww-overlay-edit-") if tempFileErr != nil { return fmt.Errorf("unable to create temporary file for editing: %s", tempFileErr) } diff --git a/internal/app/wwctl/overlay/imprt/main.go b/internal/app/wwctl/overlay/imprt/main.go index f53144f8..890950bc 100644 --- a/internal/app/wwctl/overlay/imprt/main.go +++ b/internal/app/wwctl/overlay/imprt/main.go @@ -51,11 +51,13 @@ func CobraRunE(cmd *cobra.Command, args []string) (err error) { wwlog.Debug("Create dir: %s", parent) srcInfo, err := os.Stat(source) if err != nil { - return fmt.Errorf("could not retrieve the stat for file: %s", err) + return fmt.Errorf("could not retrieve the stat for file: %w", err) } - err = os.MkdirAll(parent, srcInfo.Mode()) + mode := srcInfo.Mode() + mode |= ((mode & 0444) >> 2) // add execute permission wherever srcInfo has read + err = os.MkdirAll(parent, mode) if err != nil { - return fmt.Errorf("could not create parent dif: %s: %v", parent, err) + return fmt.Errorf("could not create parent dir: %s: %w", parent, err) } } } diff --git a/internal/pkg/node/mergo.go b/internal/pkg/node/mergo.go index 7f0b3cce..cb92c5e9 100644 --- a/internal/pkg/node/mergo.go +++ b/internal/pkg/node/mergo.go @@ -71,7 +71,7 @@ type Transformer struct{} func (t Transformer) Transformer(typ reflect.Type) func(dst, src reflect.Value) error { if typ == reflect.TypeOf(net.IP{}) { return func(dst, src reflect.Value) error { - if !src.IsValid() || !src.CanSet() { + if !src.IsValid() || src.IsZero() { return nil } dst.Set(src) diff --git a/internal/pkg/node/mergo_test.go b/internal/pkg/node/mergo_test.go index 9b507d39..ac569a82 100644 --- a/internal/pkg/node/mergo_test.go +++ b/internal/pkg/node/mergo_test.go @@ -935,11 +935,14 @@ nodeprofiles: nodes: n1: profiles: - - p1`, - node: "n1", - field: "NetDevs[default].Netmask", - source: "p1", - value: "255.255.255.0", + - p1 + network devices: + default: + ipaddr: 192.168.1.1`, + nodes: []string{"n1", "n1"}, + fields: []string{"NetDevs[default].Netmask", "NetDevs[default].Ipaddr"}, + sources: []string{"p1", ""}, + values: []string{"255.255.255.0", "192.168.1.1"}, }, } diff --git a/internal/pkg/overlay/overlay.go b/internal/pkg/overlay/overlay.go index fa80ee36..3f3995f7 100644 --- a/internal/pkg/overlay/overlay.go +++ b/internal/pkg/overlay/overlay.go @@ -146,7 +146,7 @@ func BuildSpecificOverlays(nodes []node.Node, allNodes []node.Node, overlayNames var wg sync.WaitGroup worker := func() { for n := range nodeChan { - wwlog.Info("Building overlay for %s: %v", n, overlayNames) + wwlog.Info("Building overlay for %s: %v", n.Id(), overlayNames) for _, overlayName := range overlayNames { err := BuildOverlay(n, allNodes, "", []string{overlayName}) if err != nil { diff --git a/internal/pkg/warewulfd/provision.go b/internal/pkg/warewulfd/provision.go index 5a9e408a..ab1d16da 100644 --- a/internal/pkg/warewulfd/provision.go +++ b/internal/pkg/warewulfd/provision.go @@ -83,7 +83,7 @@ func ProvisionSend(w http.ResponseWriter, req *http.Request) { if remoteNode.AssetKey != "" && remoteNode.AssetKey != rinfo.assetkey { w.WriteHeader(http.StatusUnauthorized) - wwlog.Denied("Incorrect asset key for node: %s", remoteNode.Id()) + wwlog.Denied("incorrect asset key: node %s: %s", remoteNode.Id(), rinfo.assetkey) updateStatus(remoteNode.Id(), status_stage, "BAD_ASSET", rinfo.ipaddr) return }