#!/bin/bash # Netboot image builder for diskless K3s nodes # Builds Ubuntu Noble base system with SquashFS set -e BUILD_DIR="/srv/netboot/build" IMAGE_DIR="/srv/netboot/images" HTTP_DIR="/srv/netboot/http" VERSION=$(date +%Y%m%d-%H%M) echo "Building netboot image version $VERSION" # Clean previous build - unmount any stray mounts first if [ -d "$BUILD_DIR/rootfs" ]; then echo "Cleaning up previous build mounts..." mount | grep "$BUILD_DIR/rootfs" | awk '{print $3}' | while read mount; do umount -l "$mount" 2>/dev/null || true done fi rm -rf $BUILD_DIR/rootfs mkdir -p $BUILD_DIR/rootfs # Create base Ubuntu system echo "Running debootstrap (this will take several minutes)..." debootstrap --arch=amd64 --variant=minbase --components=main,universe,multiverse \ noble $BUILD_DIR/rootfs \ http://archive.ubuntu.com/ubuntu # Chroot and configure cat << 'CHROOT_SCRIPT' > $BUILD_DIR/rootfs/setup.sh #!/bin/bash set -e # Set keyboard layout and encoding to Norwegian UTF-8 (non-interactive) export DEBIAN_FRONTEND=noninteractive export DEBCONF_NONINTERACTIVE_SEEN=true echo "keyboard-configuration keyboard-configuration/layout select Norwegian" | debconf-set-selections echo "keyboard-configuration keyboard-configuration/variant select Norwegian" | debconf-set-selections echo "locales locales/default_environment_locale select en_US.UTF-8" | debconf-set-selections echo "locales locales/locales_to_be_generated multiselect en_US.UTF-8 UTF-8, nb_NO.UTF-8 UTF-8" | debconf-set-selections # Update and upgrade apt-get update apt-get upgrade -y # Install essential packages apt-get install -y \ linux-image-generic \ linux-firmware \ cloud-initramfs-rooturl \ busybox-initramfs \ initramfs-tools \ keyboard-configuration \ systemd \ systemd-sysv \ dbus \ udev \ kmod \ iproute2 \ iputils-ping \ netplan.io \ openssh-server \ curl \ wget \ ca-certificates \ gnupg \ sudo \ locales # K3s prerequisites apt-get install -y \ apparmor \ apparmor-utils \ iptables \ nftables \ conntrack \ socat \ ethtool \ nfs-common # Container runtime prerequisites apt-get install -y \ containerd \ runc # Useful tools apt-get install -y \ htop \ iotop \ vim \ less \ rsync \ git # Clean up apt-get clean rm -rf /var/lib/apt/lists/* rm -rf /tmp/* rm -rf /var/tmp/* # Configure hostname (will be overridden by netplan) echo "k3s-node" > /etc/hostname # Configure network with netplan cat > /etc/netplan/01-netcfg.yaml <> /root/.ssh/authorized_keys <> /etc/fstab < /etc/systemd/journald.conf.d/tmpfs.conf < /etc/locale.gen locale-gen # Build initramfs will be done outside the chroot after mount cleanup echo "Initramfs build will be done after chroot cleanup" CHROOT_SCRIPT # Make script executable and run in chroot with proper mounts chmod +x $BUILD_DIR/rootfs/setup.sh # Mount required filesystems for DKMS compilation mount -t proc proc $BUILD_DIR/rootfs/proc mount -t sysfs sysfs $BUILD_DIR/rootfs/sys mount -t devtmpfs devtmpfs $BUILD_DIR/rootfs/dev mount -t devpts devpts $BUILD_DIR/rootfs/dev/pts # Run setup script in chroot chroot $BUILD_DIR/rootfs /setup.sh # Unmount filesystems umount -l $BUILD_DIR/rootfs/dev/pts umount -l $BUILD_DIR/rootfs/dev umount -l $BUILD_DIR/rootfs/sys umount -l $BUILD_DIR/rootfs/proc rm $BUILD_DIR/rootfs/setup.sh # Build initramfs with dracut using the rootfs modules echo "Building initramfs with dracut using rootfs kernel and modules..." KERNEL_VERSION=$(ls -1 $BUILD_DIR/rootfs/boot/vmlinuz-* | sed 's|.*/vmlinuz-||' | head -1) # Mount proc/sys temporarily for dracut if needed mount -t proc proc $BUILD_DIR/rootfs/proc 2>/dev/null || true dracut -f \ --add "network" \ --hostonly \ --hostonly-cmdline \ --include "/usr/share/initramfs-tools/hooks/rooturl" "/usr/share/initramfs-tools/hooks/" \ --include "/usr/share/initramfs-tools/scripts/local-top/rooturl" "/usr/share/initramfs-tools/scripts/local-top/" \ -k $KERNEL_VERSION \ -r $BUILD_DIR/rootfs \ $BUILD_DIR/rootfs/boot/initrd-netboot.img umount -l $BUILD_DIR/rootfs/proc 2>/dev/null || true echo "Initramfs build complete. Size: $(du -h $BUILD_DIR/rootfs/boot/initrd-netboot.img | cut -f1)" # Copy kernel and netboot initramfs mkdir -p $IMAGE_DIR/$VERSION cp $BUILD_DIR/rootfs/boot/vmlinuz-* $IMAGE_DIR/$VERSION/vmlinuz cp $BUILD_DIR/rootfs/boot/initrd-netboot.img $IMAGE_DIR/$VERSION/initrd-netboot.img echo "Creating squashfs image..." mksquashfs $BUILD_DIR/rootfs \ $IMAGE_DIR/$VERSION/filesystem.squashfs \ -comp xz \ -Xbcj x86 \ -b 1M \ -noappend \ -no-progress # Create version info file cat > $IMAGE_DIR/$VERSION/version.txt <