Last updated:

stub — Multi-Distribution Installer and kexec Boot Loader for VMs

GitHub: genpack-artifacts/stub

Overview

stub is one of the artifacts built with the genpack toolchain. It serves as a disposable boot environment for installing other Linux distributions on QEMU/KVM virtual machines.

While it operates as a genpack image, its ultimate purpose is to bring up an OS other than genpack. It is a two-stage provisioning tool that acts as an installer on first boot and as a boot loader using kexec on subsequent boots.

Usage

Used in combination with the vm command.

# 1. Create a virtual disk for data (8GiB)
vm allocate debian12.img 8

# 2. Start a VM with stub as the system image and debian12.img as the data disk
vm run -d debian12.img stub-$(uname -m).squashfs

# 3. After auto-login inside the VM, run the script for the desired distribution
./debian12.sh

# 4. After installation completes, reboot — from then on, Debian 12 boots directly

How It Works

Supported Distributions

Debian / Ubuntu (using debootstrap)

ScriptDistribution
debian12.shDebian 12 (Bookworm)
debian13.shDebian 13 (Trixie)
ubuntu2004.shUbuntu 20.04 (Focal)
ubuntu2204.shUbuntu 22.04 (Jammy)
ubuntu2404.shUbuntu 24.04 (Noble)
ubuntu2604.shUbuntu 26.04 (Resolute)

RHEL / RPM-based (using rpmbootstrap)

ScriptDistribution
centos6.shCentOS 6
centos7.shCentOS 7
centos8stream.shCentOS Stream 8
centos9stream.shCentOS Stream 9
centos10stream.shCentOS Stream 10
almalinux9.shAlmaLinux 9
rocky8.shRocky Linux 8
miraclelinux8.shMIRACLE LINUX 8
fedora42.shFedora 42

Other

ScriptDistribution
gentoo.shGentoo Linux (built from a stage3 tarball)

Key Components

kexec Boot Plugin (files/usr/lib/genpack-init/00kexec.py)

A Python script that runs as a genpack-init plugin on every boot. It checks whether an installed OS kernel and initramfs exist on the data disk (/dev/vdb) or on virtiofs. If found, it loads and transitions to that kernel using kexec.

This allows stub to function as a transparent boot loader after the initial installation, making the VM boot flow look like:

QEMU start stub kernel genpack-init kexec installed OS kernel OS boot

Distribution Install Scripts (files/root/*.sh)

Each script follows a common pattern:

  1. Wait for network connectivity with systemd-networkd-wait-online
  2. Create a filesystem on the data disk (XFS / Btrfs)
  3. Bootstrap the base system with debootstrap or rpmbootstrap
  4. Configure hostname, networking, SSH, and timezone
  5. Deploy SSH public keys, LLMNRD (Link-Local Name Resolution), and the QEMU guest agent
  6. Generate initramfs with dracut (including virtiofs / encryption support)
  7. Reboot

The system is ready for remote management via SSH immediately after installation.

Auto-Login (files/build.d/autologin.sh)

Sets up root auto-login on both hvc0 (virtio console) and ttyS0 (serial console). When connecting via vm console, a shell is available immediately without a login prompt.

LLMNRD (files/build.d/build-llmnrd.sh)

Statically builds the Link-Local Multicast Name Resolution Daemon from source. It is deployed to the installed OS, enabling hostname resolution without a DNS server.

Included Packages

PackagePurpose
genpack/paravirtParavirtualized kernel and base system
sys-kernel/gentoo-kernelMinimal kernel built from source
sys-apps/kexec-toolsUsed to transition to the OS kernel
dev-util/debootstrapBootstrapping Debian / Ubuntu systems
dev-util/rpmbootstrapBootstrapping RPM-based systems
sys-fs/cryptsetupDisk encryption support
sys-devel/binutilsBinary utilities

Kernel Minimization

Since stub is a disposable boot environment that does not require broad hardware support, 1,757 kernel options are disabled in kernel/config.d/unset.config.

Major features disabled include:

Supported Architectures

ArchitectureKernel ConfigurationOutput File
x86_64unset.config onlystub-x86_64.squashfs
aarch64savedconfig + unset.configstub-aarch64.squashfs
riscv64savedconfig + unset.configstub-riscv64.squashfs

Design Rationale

stub is a unique entity within the genpack ecosystem. Although it is built and booted as a genpack image, its purpose is to bring up an OS other than genpack. By leveraging genpack-init's plugin mechanism (pybind11 + Python) and the vm command's virtual disk management, it provides a unified environment for provisioning many different distribution VMs using a common procedure in QEMU/KVM environments.

Source References

This document was written based on the following repository snapshots:

Update History