diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e4effd5..95c7369f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Add examples for building overlays in parallel to documentation - 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 ### Changed diff --git a/Makefile b/Makefile index 3d8cf23a..8a8eaed7 100644 --- a/Makefile +++ b/Makefile @@ -138,6 +138,8 @@ install: build docs install -m 0644 etc/bash_completion.d/wwctl $(DESTDIR)$(BASHCOMPDIR)/wwctl for f in docs/man/man1/*.1.gz; do install -m 0644 $$f $(DESTDIR)$(MANDIR)/man1/; done for f in docs/man/man5/*.5.gz; do install -m 0644 $$f $(DESTDIR)$(MANDIR)/man5/; done + install -pd -m 0755 $(DESTDIR)$(DRACUTMODDIR)/90wwinit + install -m 0644 dracut/modules.d/90wwinit/*.sh $(DESTDIR)$(DRACUTMODDIR)/90wwinit .PHONY: installapi installapi: diff --git a/Variables.mk b/Variables.mk index b6d17784..b23f6a11 100644 --- a/Variables.mk +++ b/Variables.mk @@ -44,10 +44,11 @@ else endif # OS-Specific Service Locations -VARLIST += TFTPDIR FIREWALLDDIR SYSTEMDDIR BASHCOMPDIR +VARLIST += TFTPDIR FIREWALLDDIR SYSTEMDDIR BASHCOMPDIR DRACUTMODDIR SYSTEMDDIR ?= /usr/lib/systemd/system BASHCOMPDIR ?= /etc/bash_completion.d FIREWALLDDIR ?= /usr/lib/firewalld/services +DRACUTMODDIR ?= /usr/lib/dracut/modules.d ifeq ($(OS),suse) TFTPDIR ?= /srv/tftpboot endif diff --git a/dracut/modules.d/90wwinit/load-wwinit.sh b/dracut/modules.d/90wwinit/load-wwinit.sh new file mode 100755 index 00000000..3086207d --- /dev/null +++ b/dracut/modules.d/90wwinit/load-wwinit.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +info "Mounting tmpfs at $NEWROOT" +mount -t tmpfs ${wwinit_tmpfs_size_option} tmpfs "$NEWROOT" + +for archive in "${wwinit_container}" "${wwinit_kmods}" "${wwinit_system}" "${wwinit_runtime}" +do + if [ -n "${archive}" ] + then + info "Loading ${archive}" + (curl --silent -L "${archive}" | gzip -d | cpio -im --directory="${NEWROOT}") || die "Unable to load ${archive}" + fi +done diff --git a/dracut/modules.d/90wwinit/module-setup.sh b/dracut/modules.d/90wwinit/module-setup.sh new file mode 100755 index 00000000..454562ad --- /dev/null +++ b/dracut/modules.d/90wwinit/module-setup.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +check() { + # Don't include in hostonly mode + [[ $hostonly ]] && return 1 + + # Don't include by default + return 255 +} + +depends() { + echo network + return 0 +} + +install() { + inst_multiple cpio curl + inst_hook cmdline 30 "$moddir/parse-wwinit.sh" + inst_hook pre-mount 30 "$moddir/load-wwinit.sh" +} diff --git a/dracut/modules.d/90wwinit/parse-wwinit.sh b/dracut/modules.d/90wwinit/parse-wwinit.sh new file mode 100755 index 00000000..45875024 --- /dev/null +++ b/dracut/modules.d/90wwinit/parse-wwinit.sh @@ -0,0 +1,28 @@ +#!/bin/sh +# root=wwinit + +[ -z "$root" ] && root=$(getarg root=) + +if [ "${root}" = "wwinit" ] +then + info "root=${root}" + export wwinit_container=$(getarg wwinit.container=); info "wwinit.container=${wwinit_container}" + export wwinit_system=$(getarg wwinit.system=); info "wwinit.system=${wwinit_system}" + export wwinit_runtime=$(getarg wwinit.runtime=); info "wwinit.runtime=${wwinit_runtime}" + export wwinit_kmods=$(getarg wwinit.kmods=); info "wwinit.kmods=${wwinit_kmods}" + + wwinit_tmpfs_size=$(getarg wwinit.tmpfs.size=) + if [ -n "$wwinit_tmpfs_size" ] + then + info "wwinit.tmpfs.size=${wwinit_tmpfs_size}" + export wwinit_tmpfs_size_option="-o size=${wwinit_tmpfs_size}" + fi + + if [ -n "${wwinit_container}" ] + then + info "Found root=${root} and a Warewulf container image. Will boot from Warewulf." + rootok=1 + else + die "Found root=${root} but no container image. Cannot boot from Warewulf." + fi +fi diff --git a/warewulf.spec.in b/warewulf.spec.in index 71e6bbf2..63a1fddb 100644 --- a/warewulf.spec.in +++ b/warewulf.spec.in @@ -82,6 +82,23 @@ BuildRequires: libassuan-devel gpgme-devel Warewulf is a stateless and diskless container operating system provisioning system for large clusters of bare metal and/or virtual systems. +%package dracut +Summary: dracut module for loading a Warewulf container image +BuildArch: noarch + +Requires: dracut +%if 0%{?suse_version} +%else +Requires: dracut-network +%endif + +%description dracut +Warewulf is a stateless and diskless container operating system provisioning +system for large clusters of bare metal and/or virtual systems. + +This subpackage contains a dracut module that can be used to generate +an initramfs that can fetch and boot a Warewulf container image from a +Warewulf server. %prep %setup -q -n %{name}-%{version} -b0 %if %{?with_offline:-a2} @@ -105,7 +122,8 @@ make defaults \ BASHCOMPDIR=/etc/bash_completion.d/ \ FIREWALLDDIR=/usr/lib/firewalld/services \ WWCLIENTDIR=/warewulf \ - IPXESOURCE=/usr/share/ipxe + IPXESOURCE=/usr/share/ipxe \ + DRACUTMODDIR=/usr/lib/dracut/modules.d make %if %{api} make api @@ -185,7 +203,16 @@ getent group %{wwgroup} >/dev/null || groupadd -r %{wwgroup} %endif +%files dracut +%defattr(-, root, root) +%dir %{_prefix}/lib/dracut/modules.d/90wwinit +%{_prefix}/lib/dracut/modules.d/90wwinit/*.sh + + %changelog +* Thu Apr 18 2024 Jonathon Anderson +- New warewulf-dracut subpackage + * Wed Apr 17 2024 Jonathon Anderson - Don't build the API on EL7