Merge pull request #2077 from anderbubble/1981-fix-ignition-running-twice

fix ignition running twice
This commit is contained in:
Christian Goll
2026-01-07 21:00:30 +01:00
committed by GitHub
12 changed files with 122 additions and 81 deletions

View File

@@ -33,6 +33,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Added Ipv6 support to `/etc/hosts` on host and nodes.
- Added IPv6 support to wwclient
- `sfdisk` overlay creates a GPT label when wiping disks. #2025
- Renamed systemd templates in the `ignition` overlay for clarity.
### Removed
@@ -46,6 +47,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Fix warewulf-dracut to not run the wwinit module if root is not set to `root=wwclient*`
- Fix `wwctl image import --update` #2066
- Fix filesystem overwrite/force behavior in mkfs overlay. #2028
- Prevent ignition from running twice in a provision-to-disk configuration. #1981
### Dependencies

View File

@@ -46,3 +46,11 @@ info "warewulf: mounting ${wwinit_root_device} at ${NEWROOT}"
for stage in "image" "system" "runtime"; do
get_stage "${stage}"
done
# Copy /warewulf/run from initramfs to NEWROOT
# This preserves state files created by wwinit.d scripts (e.g., ignition marker)
if [ -d /tmp/wwinit/warewulf/run ]; then
info "warewulf: preserving /warewulf/run to mounted root"
mkdir -p "${NEWROOT}/warewulf"
cp -a /tmp/wwinit/warewulf/run "${NEWROOT}/warewulf/"
fi

View File

@@ -17,8 +17,8 @@ func Test_ignitionOverlay(t *testing.T) {
output string
isJson bool
}{
"ignition:ww4-disks.target": {
args: []string{"--quiet", "--render", "node1", "ignition", "etc/systemd/system/ww4-disks.target.ww"},
"ignition:ww-ignition-disks.target": {
args: []string{"--quiet", "--render", "node1", "ignition", "etc/systemd/system/ww-ignition-disks.target.ww"},
nodesConf: `
nodes:
node1:
@@ -44,17 +44,17 @@ nodes:
[Unit]
Description=mount ww4 disks
# make sure that the disks are available
Requires=ignition-ww4-disks.service
After=ignition-ww4-disks.service
Requisite=ignition-ww4-disks.service
Requires=ww-ignition.service
After=ww-ignition.service
Requisite=ww-ignition.service
# Get the mounts
Wants=scratch.mount
Wants=dev-disk-by\x2dpartlabel-swap.swap
`,
isJson: false,
},
"ignition:ww4-disks.target (resources)": {
args: []string{"--quiet", "--render", "node1", "ignition", "etc/systemd/system/ww4-disks.target.ww"},
"ignition:ww-ignition-disks.target (resources)": {
args: []string{"--quiet", "--render", "node1", "ignition", "etc/systemd/system/ww-ignition-disks.target.ww"},
nodesConf: `
nodes:
node1:
@@ -83,17 +83,17 @@ nodes:
[Unit]
Description=mount ww4 disks
# make sure that the disks are available
Requires=ignition-ww4-disks.service
After=ignition-ww4-disks.service
Requisite=ignition-ww4-disks.service
Requires=ww-ignition.service
After=ww-ignition.service
Requisite=ww-ignition.service
# Get the mounts
Wants=scratch.mount
Wants=dev-disk-by\x2dpartlabel-swap.swap
`,
isJson: false,
},
"ignition:ww4-mounts": {
args: []string{"--quiet=false", "--render", "node1", "ignition", "etc/systemd/system/ww4-mounts.ww"},
"ignition:ignition.mount": {
args: []string{"--quiet=false", "--render", "node1", "ignition", "etc/systemd/system/ignition.mount.ww"},
nodesConf: `
nodes:
node1:
@@ -124,8 +124,8 @@ Filename: scratch.mount
[Unit]
ConditionPathExists=/warewulf/ignition.json
Before=local-fs.target
Requires=ignition-ww4-disks.service
After=ignition-ww4-disks.service
Requires=ww-ignition.service
After=ww-ignition.service
[Mount]
Where=/scratch
What=/dev/disk/by-partlabel/scratch
@@ -133,25 +133,11 @@ Type=btrfs
Options=nondefault
[Install]
RequiredBy=local-fs.target
backupFile: true
writeFile: true
Filename: dev-disk-by\x2dpartlabel-swap.swap
# This file is autogenerated by warewulf
[Unit]
ConditionPathExists=/warewulf/ignition.json
Requires=ignition-ww4-disks.service
After=ignition-ww4-disks.service
Before=swap.target
[Swap]
What=/dev/disk/by-partlabel/swap
[Install]
RequiredBy=swap.target
`,
isJson: false,
},
"ignition:ww4-mounts (resources)": {
args: []string{"--quiet=false", "--render", "node1", "ignition", "etc/systemd/system/ww4-mounts.ww"},
"ignition:ignition.mount (resources)": {
args: []string{"--quiet=false", "--render", "node1", "ignition", "etc/systemd/system/ignition.mount.ww"},
nodesConf: `
nodes:
node1:
@@ -184,23 +170,52 @@ Filename: scratch.mount
[Unit]
ConditionPathExists=/warewulf/ignition.json
Before=local-fs.target
Requires=ignition-ww4-disks.service
After=ignition-ww4-disks.service
Requires=ww-ignition.service
After=ww-ignition.service
[Mount]
Where=/scratch
What=/dev/disk/by-partlabel/scratch
Type=btrfs
[Install]
RequiredBy=local-fs.target
backupFile: true
`,
isJson: false,
},
"ignition:ignition.swap (resources)": {
args: []string{"--quiet=false", "--render", "node1", "ignition", "etc/systemd/system/ignition.swap.ww"},
nodesConf: `
nodes:
node1:
resources:
ignition:
storage:
disks:
- device: /dev/vda
wipeTable: true
partitions:
scratch:
shouldExist: true
swap:
number: 1
sizeMiB: 1024
filesystems:
- device: /dev/disk/by-partlabel/scratch
format: btrfs
path: /scratch
wipeFilesystem: true
- device: /dev/disk/by-partlabel/swap
format: swap
path: swap`,
output: `backupFile: true
writeFile: true
Filename: dev-disk-by\x2dpartlabel-swap.swap
# This file is autogenerated by warewulf
[Unit]
ConditionPathExists=/warewulf/ignition.json
Requires=ignition-ww4-disks.service
After=ignition-ww4-disks.service
Requires=ww-ignition.service
After=ww-ignition.service
Before=swap.target
[Swap]
What=/dev/disk/by-partlabel/swap
@@ -325,8 +340,9 @@ nodes:
t.Run(name, func(t *testing.T) {
env := testenv.New(t)
defer env.RemoveAll()
env.ImportFile("var/lib/warewulf/overlays/ignition/rootfs/etc/systemd/system/ww4-disks.target.ww", "../rootfs/etc/systemd/system/ww4-disks.target.ww")
env.ImportFile("var/lib/warewulf/overlays/ignition/rootfs/etc/systemd/system/ww4-mounts.ww", "../rootfs/etc/systemd/system/ww4-mounts.ww")
env.ImportFile("var/lib/warewulf/overlays/ignition/rootfs/etc/systemd/system/ww-ignition-disks.target.ww", "../rootfs/etc/systemd/system/ww-ignition-disks.target.ww")
env.ImportFile("var/lib/warewulf/overlays/ignition/rootfs/etc/systemd/system/ignition.mount.ww", "../rootfs/etc/systemd/system/ignition.mount.ww")
env.ImportFile("var/lib/warewulf/overlays/ignition/rootfs/etc/systemd/system/ignition.swap.ww", "../rootfs/etc/systemd/system/ignition.swap.ww")
env.ImportFile("var/lib/warewulf/overlays/ignition/rootfs/warewulf/ignition.json.ww", "../rootfs/warewulf/ignition.json.ww")
env.WriteFile("etc/warewulf/nodes.conf", tt.nodesConf)
cmd := show.GetCommand()

View File

@@ -1,27 +1,15 @@
{{- if .FileSystems }}
{{- range $fsdevice, $fs := .FileSystems }}
{{- if eq $fs.Format "swap" }}
{{ file (print ($fsdevice | SystemdEscapePath) ".swap") }}
# This file is autogenerated by warewulf
[Unit]
ConditionPathExists=/warewulf/ignition.json
Requires=ignition-ww4-disks.service
After=ignition-ww4-disks.service
Before=swap.target
[Swap]
What={{ $fsdevice }}
[Install]
RequiredBy=swap.target
{{- else if ne $fs.Path "" }}
{{- if ne $fs.Format "swap" }}
{{- if ne $fs.Path "" }}
{{ file (print ($fs.Path | SystemdEscapePath) ".mount") }}
# This file is autogenerated by warewulf
[Unit]
ConditionPathExists=/warewulf/ignition.json
Before=local-fs.target
Requires=ignition-ww4-disks.service
After=ignition-ww4-disks.service
Requires=ww-ignition.service
After=ww-ignition.service
[Mount]
Where={{ $fs.Path }}
What={{ $fsdevice }}
@@ -31,34 +19,21 @@ Options={{ $fs.MountOptions }}
{{- end }}
[Install]
RequiredBy=local-fs.target
{{- else }}
{{- continue }}
{{- end }}
{{- end }}
{{- end }}
{{- else if .Resources.ignition.storage.filesystems }}
{{- range $fs := .Resources.ignition.storage.filesystems }}
{{- if eq $fs.format "swap" }}
{{ file (print ($fs.device | SystemdEscapePath) ".swap") }}
# This file is autogenerated by warewulf
[Unit]
ConditionPathExists=/warewulf/ignition.json
Requires=ignition-ww4-disks.service
After=ignition-ww4-disks.service
Before=swap.target
[Swap]
What={{ $fs.device }}
[Install]
RequiredBy=swap.target
{{- else if ne $fs.path "" }}
{{- if ne $fs.format "swap" }}
{{- if ne $fs.path "" }}
{{ file (print ($fs.path | SystemdEscapePath) ".mount") }}
# This file is autogenerated by warewulf
[Unit]
ConditionPathExists=/warewulf/ignition.json
Before=local-fs.target
Requires=ignition-ww4-disks.service
After=ignition-ww4-disks.service
Requires=ww-ignition.service
After=ww-ignition.service
[Mount]
Where={{ $fs.path }}
What={{ $fs.device }}
@@ -68,8 +43,7 @@ Options={{ $fs.mountOptions | join "." }}
{{- end }}
[Install]
RequiredBy=local-fs.target
{{- else }}
{{- continue }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,35 @@
{{- if .FileSystems }}
{{- range $fsdevice, $fs := .FileSystems }}
{{- if eq $fs.Format "swap" }}
{{ file (print ($fsdevice | SystemdEscapePath) ".swap") }}
# This file is autogenerated by warewulf
[Unit]
ConditionPathExists=/warewulf/ignition.json
Requires=ww-ignition.service
After=ww-ignition.service
Before=swap.target
[Swap]
What={{ $fsdevice }}
[Install]
RequiredBy=swap.target
{{- end }}
{{- end }}
{{- else if .Resources.ignition.storage.filesystems }}
{{- range $fs := .Resources.ignition.storage.filesystems }}
{{- if eq $fs.format "swap" }}
{{ file (print ($fs.device | SystemdEscapePath) ".swap") }}
# This file is autogenerated by warewulf
[Unit]
ConditionPathExists=/warewulf/ignition.json
Requires=ww-ignition.service
After=ww-ignition.service
Before=swap.target
[Swap]
What={{ $fs.device }}
[Install]
RequiredBy=swap.target
{{- end }}
{{- end }}
{{- end }}

View File

@@ -1 +0,0 @@
/etc/systemd/system/ignition-ww4-disks.service

View File

@@ -0,0 +1 @@
../ww-ignition-disks.target

View File

@@ -0,0 +1 @@
../ww-ignition.service

View File

@@ -1 +0,0 @@
/etc/systemd/system/ww4-disks.target

View File

@@ -3,9 +3,9 @@
[Unit]
Description=mount ww4 disks
# make sure that the disks are available
Requires=ignition-ww4-disks.service
After=ignition-ww4-disks.service
Requisite=ignition-ww4-disks.service
Requires=ww-ignition.service
After=ww-ignition.service
Requisite=ww-ignition.service
# Get the mounts
{{- if .FileSystems }}
{{- range $fsdevice, $fs := .FileSystems }}

View File

@@ -3,10 +3,9 @@ Description=Ignition warewulf (disks)
Documentation=https://warewulf.org/
ConditionPathExists=/warewulf/ignition.json
ConditionPathExists=/usr/lib/dracut/modules.d/30ignition/ignition
ConditionPathExists=!/warewulf/run/.ignition-done
DefaultDependencies=false
Before=ignition-ww4-mount.service
# This stage runs between `basic.target` and `initrd-root-device.target`,
# see https://www.freedesktop.org/software/systemd/man/bootup.html
# Make sure to run before the file system checks, as sgdisk will trigger

View File

@@ -17,7 +17,14 @@ fi
if command -v ignition >/dev/null; then :
info "warewulf: ignition: partition and format disks"
ignition --config-cache="${PREFIX}/warewulf/ignition.json" --platform=metal --stage=disks || die "warewulf: ignition: failed to partition/format disk"
if ignition --config-cache="${PREFIX}/warewulf/ignition.json" --platform=metal --stage=disks; then
# Create marker file to signal successful completion
# This prevents the systemd service from running ignition again after switch_root
mkdir -p "${PREFIX}/warewulf/run"
echo "ignition run by 10-ignition.sh" >"${PREFIX}/warewulf/run/.ignition-done"
else
die "warewulf: ignition: failed to partition/format disk"
fi
else
info "warewulf: ignition not found"
fi