{ config, lib, pkgs, ... }: { virtualisation.oci-containers.containers.fedora-dracut = { pull = "newer"; autoStart = false; entrypoint = "bash"; image = "docker.io/fedora:latest"; cmd = [ "/data/workdir/entry.sh" ]; volumes = [ "/srv/nfs/arch/lower:/data/arch:ro" "/var/lib/podman-dracut:/data/workdir" "/srv/nfs/fedora/lower:/data/fedora:ro" ]; }; services = { nfs.server = { enable = true; exports = let clients."10.2.0.0/16" = [ "mp" "rw" "no_root_squash" ]; in { "/srv/nfs/arch/root" = clients; "/srv/nfs/fedora/root" = clients; }; }; dnsmasq = { enable = true; settings = { enable-ra = true; no-resolv = true; cache-size = 4096; bogus-priv = true; enable-tftp = true; interface = "enp1s0"; domain-needed = true; tftp-root = "/srv/tftp"; dhcp-boot = "grubx64.efi"; server = [ "1.1.1.2" "2606:4700:4700::1112" "1.0.0.2" "2606:4700:4700::1002" ]; dhcp-range = [ "10.2.0.2,10.2.255.254,12h" "fc02::2,fc02::ffff:ffff:ffff:ffff,12h" ]; }; }; }; systemd = { tmpfiles.rules = [ "d /srv/tftp" ]; services.pxeboot = { before = [ "nfs-server.service" ]; requiredBy = [ "nfs-server.service" ]; path = with pkgs; [ xz curl e2fsprogs grub2_efi util-linux ]; serviceConfig = { Type = "oneshot"; RemainAfterExit = true; ExecStop = pkgs.writeShellScript "stop.sh" '' set -e for distro in arch fedora; do cd /srv/nfs/$distro mountpoint -q root && umount root mountpoint -q lower && umount lower mountpoint -q loop && umount loop done ''; }; script = let resolv = pkgs.writeText "resolv.conf" '' nameserver fc02::1 nameserver 10.2.0.1 options edns0 trust-ad ''; archIso = { rootfs = "arch/x86_64/airootfs.sfs"; hash = "684ded26c63240ff4a41e8c25ee84ea6da233f557364821f13d12c2b0a9059a5"; url = "https://fastly.mirror.pkgbuild.com/iso/2026.10.01/archlinux-x86_64.iso"; }; fedoraIso = { rootfs = "LiveOS/squashfs.img"; hash = "1620295f6a00c27c3208f0c00b8ece4eab1ec69b9002152d97488bf26a426ddf"; url = "https://download.fedoraproject.org/pub/fedora/linux/releases/" + "44/Workstation/x86_64/iso/Fedora-Workstation-Live-44-1.7.x86_64.iso"; }; grubCfg = pkgs.writeText "grub.cfg" '' function load { set p=$cmdpath/boot/$1 linux $p/vmlinuz $2 rw ip=dhcp root=nfs4:$net_default_server:/srv/nfs/$1/root initrd $p/boot/$1/initramfs } menuentry Arch { load arch } menuentry Fedora { load fedora selinux=0 } ''; entryScript = pkgs.writeShellScript "entry.sh" '' set -e dnf install -y nfs-utils dracut-network cd /data/workdir for target in $(ls .. | grep -v workdir); do mkdir $target modsDir=../$target/usr/lib/modules/* cp $modsDir/vmlinuz $target dracut -Nm "network-manager nfs" --zstd -k $modsDir \ --kver $(basename $modsDir) $target/initramfs done ''; in '' for distro in arch fedora; do case $distro in arch) url=${archIso.url} rootfs=${archIso.rootfs} hash=${archIso.hash};; fedora) url=${fedoraIso.url} rootfs=${fedoraIso.rootfs} hash=${fedoraIso.hash};; esac mkdir -p /srv/nfs/$distro cd /srv/nfs/$distro if [ ! -e $distro.iso ]; then curl -C - "$url" -Lo $distro.iso.tmp mv $distro.iso{.tmp,} sha256sum $distro.iso | grep $hash fi mkdir -p loop root work lower upper mountpoint -q loop || mount $distro.iso loop mountpoint -q lower || mount loop/$rootfs lower mountpoint -q root || mount -t overlay overlay root -o \ workdir=work,nfs_export=on,lowerdir=lower,upperdir=upper if [ ! -e upper/etc/resolv.conf ]; then cd root/etc rm -f resolv.conf cp ${resolv} resolv.conf chattr +i resolv.conf fi done cd /srv/tftp if [ ! -e grubx64.efi ]; then grub-mkstandalone -O x86_64-efi --compress=xz -o \ grubx64.efi --modules=efinet /boot/grub/grub.cfg=${grubCfg} fi if [ ! -e boot ]; then workdir=/var/lib/podman-dracut rm -rf $workdir mkdir boot $workdir cp ${entryScript} $workdir/entry.sh systemctl --wait start podman-fedora-dracut.service mv $workdir/*/ boot chmod -R 644 boot chmod +x $(find boot -type d) fi ''; }; }; }