Files
warewulf/overlays/ignition/internal/ignition_test.go
Jonathon Anderson b98eae4b01 Refactor ignition support during dracut
- Control root device using the node/profile root field
- Add support for `/warewulf/wwinit.d` to run scripts during first stage
- Move first-stage ignition support to `/warewulf/wwinit.d/`
- Add `wwctl <node|profile> set --parttype`
- Add overlay template functions `SystemdEscape` and `SystemdEscapePath`
- Support configuring ignition with resources

Signed-off-by: Jonathon Anderson <janderson@ciq.com>
2025-06-30 23:19:31 -06:00

354 lines
8.6 KiB
Go

package ignition
import (
"bytes"
"testing"
"github.com/stretchr/testify/assert"
"github.com/warewulf/warewulf/internal/app/wwctl/overlay/show"
"github.com/warewulf/warewulf/internal/pkg/testenv"
"github.com/warewulf/warewulf/internal/pkg/wwlog"
)
func Test_ignitionOverlay(t *testing.T) {
tests := map[string]struct {
args []string
nodesConf string
output string
isJson bool
}{
"ignition:ww4-disks.target": {
args: []string{"--quiet", "--render", "node1", "ignition", "etc/systemd/system/ww4-disks.target.ww"},
nodesConf: `
nodes:
node1:
disks:
/dev/vda:
wipe_table: true
partitions:
scratch:
should_exist: true
swap:
number: "1"
size_mib: "1024"
filesystems:
/dev/disk/by-partlabel/scratch:
format: btrfs
path: /scratch
wipe_filesystem: true
/dev/disk/by-partlabel/swap:
format: swap
path: swap`,
output: `# This file is autogenerated by warewulf
[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
# 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"},
nodesConf: `
nodes:
node1:
resources:
ignition:
storage:
disks:
- device: /dev/vda
wipeTable: true
partitions:
- label: scratch
shouldExist: true
- label: 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: `# This file is autogenerated by warewulf
[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
# 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"},
nodesConf: `
nodes:
node1:
disks:
/dev/vda:
wipe_table: true
partitions:
scratch:
should_exist: true
swap:
number: "1"
size_mib: "1024"
filesystems:
/dev/disk/by-partlabel/scratch:
format: btrfs
path: /scratch
wipe_filesystem: true
/dev/disk/by-partlabel/swap:
format: swap
path: swap`,
output: `backupFile: true
writeFile: true
Filename: scratch.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
[Mount]
Where=/scratch
What=/dev/disk/by-partlabel/scratch
Type=btrfs
[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"},
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: scratch.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
[Mount]
Where=/scratch
What=/dev/disk/by-partlabel/scratch
Type=btrfs
[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:ignition.json": {
args: []string{"--quiet", "--render", "node1", "ignition", "warewulf/ignition.json.ww"},
nodesConf: `
nodes:
node1:
disks:
/dev/vda:
wipe_table: true
partitions:
scratch:
should_exist: true
swap:
number: "1"
size_mib: "1024"
filesystems:
/dev/disk/by-partlabel/scratch:
format: btrfs
path: /scratch
wipe_filesystem: true
/dev/disk/by-partlabel/swap:
format: swap
path: swap`,
output: `{
"ignition": {
"version": "3.1.0"
},
"storage": {
"disks": [
{
"device": "/dev/vda",
"partitions": [
{
"label": "scratch",
"shouldExist": true,
"wipePartitionEntry": false
},
{
"label": "swap",
"number": 1,
"shouldExist": false,
"sizeMiB": 1024,
"wipePartitionEntry": false
}
],
"wipeTable": true
}
],
"filesystems": [
{
"device": "/dev/disk/by-partlabel/scratch",
"format": "btrfs",
"path": "/scratch",
"wipeFilesystem": true
},
{
"device": "/dev/disk/by-partlabel/swap",
"format": "swap",
"path": "swap",
"wipeFilesystem": false
}
]
}
}`,
isJson: true,
},
"ignition:ignition.json (resources)": {
args: []string{"--quiet", "--render", "node1", "ignition", "warewulf/ignition.json.ww"},
nodesConf: `
nodes:
node1:
resources:
ignition:
storage:
disks:
- device: /dev/vda
partitions:
- label: rootfs
number: 1
shouldExist: true
wipePartitionEntry: false
wipeTable: true
filesystems:
- device: /dev/disk/by-partlabel/rootfs
format: ext4
path: /
wipeFilesystem: false`,
output: `{
"storage": {
"disks": [
{
"device": "/dev/vda",
"partitions": [
{
"label": "rootfs",
"number": 1,
"shouldExist": true,
"wipePartitionEntry": false
}
],
"wipeTable": true
}
],
"filesystems": [
{
"device": "/dev/disk/by-partlabel/rootfs",
"format": "ext4",
"path": "/",
"wipeFilesystem": false
}
]
}
}`,
isJson: true,
},
}
for name, tt := range tests {
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/warewulf/ignition.json.ww", "../rootfs/warewulf/ignition.json.ww")
env.WriteFile("etc/warewulf/nodes.conf", tt.nodesConf)
cmd := show.GetCommand()
cmd.SetArgs(tt.args)
stdout := bytes.NewBufferString("")
stderr := bytes.NewBufferString("")
logbuf := bytes.NewBufferString("")
cmd.SetOut(stdout)
cmd.SetErr(stderr)
wwlog.SetLogWriter(logbuf)
err := cmd.Execute()
assert.NoError(t, err)
assert.Empty(t, stdout.String())
assert.Empty(t, stderr.String())
if tt.isJson {
assert.JSONEq(t, tt.output, logbuf.String())
} else {
assert.Equal(t, tt.output, logbuf.String())
}
})
}
}