Skip to content

Commit

Permalink
Support dracut booting with GRUB
Browse files Browse the repository at this point in the history
Signed-off-by: Jonathon Anderson <[email protected]>
  • Loading branch information
anderbubble committed Jun 6, 2024
1 parent 9500487 commit 05b951d
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 6 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Add `stage=initramfs` to warewulfd provision to serve initramfs from container image. #1115
- Add `warewulf-dracut` package to support building Warewulf-compatible initramfs images with dracut. #1115
- Add iPXE template `dracut.ipxe` to boot a dracut initramfs. #1115
- Add `.NetDevs` variable to iPXE templates, similar to overlay templates. #1115
- Add dracut menuentry to `grub.cfg.ww` to boot a dracut initramfs. #1115
- Add `.NetDevs` variable to iPXE and GRUB templates, similar to overlay templates. #1115
- Add `.Tags` variable to iPXE and GRUB templates, similar to overlay templates. #1115

### Changed

Expand Down
42 changes: 41 additions & 1 deletion etc/grub/grub.cfg.ww
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@ echo "Warewulf Controller: {{.Ipaddr}}"
echo
sleep 1
smbios --type1 --get-string 8 --set assetkey

uri="(http,{{.Ipaddr}}:{{.Port}})/provision/${net_default_mac}?assetkey=${assetkey}"
kernel="${uri}&stage=kernel"
container="${uri}&stage=container&compress=gz"
system="${uri}&stage=system&compress=gz"
runtime="${uri}&stage=runtime&compress=gz"
set default=ww4

set default={{ or .Tags.GrubMenuEntry "ww4" }}
set timeout=5

menuentry "Network boot node: {{.Id}}" --id ww4 {
{{if .KernelOverride }}
echo "Kernel: {{.KernelOverride}}"
Expand All @@ -34,17 +37,54 @@ menuentry "Network boot node: {{.Id}}" --id ww4 {
reboot
fi
}

menuentry "Network boot node with dracut: {{.Id}}" --id dracut {
initramfs="${uri}&stage=initramfs"

uri="http://{{.Ipaddr}}:{{.Port}}/provision/${net_default_mac}?assetkey=${assetkey}"
container="${uri}&stage=container&compress=gz"
system="${uri}&stage=system&compress=gz"
runtime="${uri}&stage=runtime&compress=gz"

{{if .KernelOverride }}
echo "Kernel: {{.KernelOverride}}"
{{else}}
echo "Kernel: {{.ContainerName}} (container default)"
{{end}}
echo "KernelArgs: {{.KernelArgs}}"

net_args="rd.neednet=1 {{range $devname, $netdev := .NetDevs}}{{if and $netdev.Hwaddr $netdev.Device}} ifname={{$netdev.Device}}:{{$netdev.Hwaddr}} {{end}}{{end}}"
wwinit_args="root=wwinit wwinit.container=${container} wwinit.system=${system} wwinit.runtime=${runtime} init=/init"
linux $kernel wwid=${net_default_mac} {{.KernelArgs}} $net_args $wwinit_args

if [ x$? = x0 ] ; then
echo "Loading Container: {{.ContainerName}}"
initrd $initramfs
boot
else
echo "MESSAGE: This node seems to be unconfigured. Please have your system administrator add a"
echo " configuration for this node with HW address: ${net_default_mac}"
echo ""
echo "Rebooting in 1 minute..."
sleep 60
reboot
fi
}

menuentry "Chainload specific configfile" {
conf="(http,{{.Ipaddr}}:{{.Port}})/efiboot/grub.cfg"
configfile $conf
}

menuentry "UEFI Firmware Settings" --id "uefi-firmware" {
fwsetup
}

menuentry "System restart" {
echo "System rebooting..."
reboot
}

menuentry "System shutdown" {
echo "System shutting down..."
halt
Expand Down
9 changes: 7 additions & 2 deletions internal/pkg/warewulfd/provision.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ type templateVars struct {
Port string
KernelArgs string
KernelOverride string
Tags map[string]string
NetDevs map[string]*node.NetDevs
}

Expand Down Expand Up @@ -108,7 +109,8 @@ func ProvisionSend(w http.ResponseWriter, req *http.Request) {
ContainerName: node.ContainerName.Get(),
KernelArgs: node.Kernel.Args.Get(),
KernelOverride: node.Kernel.Override.Get(),
NetDevs: tstruct.NetDevs}
NetDevs: tstruct.NetDevs,
Tags: tstruct.Tags}
} else if rinfo.stage == "kernel" {
if node.Kernel.Override.Defined() {
stage_file = kernel.KernelImage(node.Kernel.Override.Get())
Expand Down Expand Up @@ -180,6 +182,7 @@ func ProvisionSend(w http.ResponseWriter, req *http.Request) {
}
case "grub.cfg":
stage_file = path.Join(conf.Paths.Sysconfdir, "warewulf/grub/grub.cfg.ww")
tstruct := overlay.InitStruct(&node)
tmpl_data = templateVars{
Id: node.Id.Get(),
Cluster: node.ClusterName.Get(),
Expand All @@ -190,7 +193,9 @@ func ProvisionSend(w http.ResponseWriter, req *http.Request) {
Hwaddr: rinfo.hwaddr,
ContainerName: node.ContainerName.Get(),
KernelArgs: node.Kernel.Args.Get(),
KernelOverride: node.Kernel.Override.Get()}
KernelOverride: node.Kernel.Override.Get(),
NetDevs: tstruct.NetDevs,
Tags: tstruct.Tags}
if stage_file == "" {
wwlog.ErrorExc(fmt.Errorf("could't find grub.cfg template"), containerName)
w.WriteHeader(http.StatusNotFound)
Expand Down
21 changes: 19 additions & 2 deletions userdocs/contents/boot-management.rst
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,27 @@ booting the node image directly.

The iPXE template may be set at the node or profile level.

Alternatively, to direct GRUB to fetch the node's initramfs image and boot with
dracut semantics, set a ``GrubMenuEntry`` tag for the node.

.. note::

Warewulf configures GRUB with a template located at
``/etc/warewulf/grub/grub.cfg.ww``. Inspect the template to learn more about
the dracut booting process.

.. code-block:: shell
wwctl node set wwnode1 --tagadd GrubMenuEntry=dracut
.. note::

The ``GrubMenuEntry`` variable may be set at the node or profile level.

During boot, ``warewulfd`` will detect and dynamically serve an
initramfs from a node's container image in much the same way that it
can serve a kernel from a container image. This image is loaded by
iPXE, and iPXE directs dracut to fetch the node's container image
iPXE (or GRUB) which directs dracut to fetch the node's container image
during boot.

The wwinit module provisions to tmpfs. By default, tmpfs is permitted
Expand All @@ -88,7 +105,7 @@ more details.)

.. warning::

Kernel overrides are not currently supported during dracut initramfs boot.
Kernel overrides are not currently fully supported during dracut initramfs boot.

Booting with GRUB
=================
Expand Down

0 comments on commit 05b951d

Please sign in to comment.