7.0 KiB
Phase 18.3: bootable Fruix installer ISO on FreeBSD
Date: 2026-04-04
Goal
Phase 18.3 extends the Phase 18.2 installer-environment work from a disk-image-style installer into a UEFI-bootable ISO artifact.
The intended first ISO is deliberately narrow:
- UEFI only
- serial-console-friendly
- non-interactive install flow reused from Phase 18.1/18.2
- target disk installation still performed by the same Fruix-managed in-guest installer logic
Implementation
New API
Added in modules/fruix/system/freebsd.scm:
operating-system-installer-iso-specmaterialize-installer-iso
The system module split done immediately before this phase was also exercised during this work.
New CLI action
Added in scripts/fruix.scm:
fruix system installer-iso
This action emits metadata for:
- ISO store path
- ISO image path
- EFI boot image path
- installer root image path
- installer and target closure paths
- installer state/log paths
- declared/materialized FreeBSD source metadata
- store closure counts
ISO boot model
The ISO does not try to run the Fruix installer directly from a read-only cd9660 root.
Instead it uses a small UEFI El Torito boot image plus an in-memory installer root image:
- a small FAT EFI boot image contains
EFI/BOOT/BOOTX64.EFI - the ISO root contains real boot assets under
/boot - the ISO root also contains
/boot/root.img loader.confon the ISO is augmented with:mdroot_load="YES"mdroot_type="mfs_root"mdroot_name="/boot/root.img"vfs.root.mountfrom="ufs:/dev/md0"vfs.root.mountfrom.options="rw"
A practical loader detail surfaced during validation:
- setting
rootdevorcurrdevtomd0:in the ISO loader path is wrong for this loader configuration and caused an early EFI-loader crash before kernel handoff - the reliable ISO path is to let loader keep its current device on the CD media, preload
/boot/root.img, and pass onlyvfs.root.mountfrom=ufs:/dev/md0
This preserves the existing Fruix installer environment semantics while avoiding the need to make the whole installer operate directly from a read-only ISO root.
Installer root image contents
materialize-installer-iso stages the same installer payload model already validated in Phase 18.2:
- installer closure
- target closure
- target runtime store closure needed for installation/boot
- staged target rootfs under
/var/lib/fruix/installer/target-rootfs - installer plan and state files under
/var/lib/fruix/installer - installer helper scripts:
/usr/local/libexec/fruix-installer-run/usr/local/etc/rc.d/fruix-installer
The ISO root image is then built as a UFS image and embedded as /boot/root.img.
Split-regression fixes found during this work
While exercising the refactored split modules, two issues surfaced and were fixed:
string-hashname-clash warnings- the old helper name collided with Guile/SRFI bindings
- it was renamed to
sha256-string
- missing
prefix-materializer-version- this constant was accidentally omitted when
modules/fruix/system/freebsd.scmwas split - the missing definition was restored in
modules/fruix/system/freebsd/build.scm
- this constant was accidentally omitted when
Validation
Completed smoke validation
A host-side smoke build was completed successfully for the new ISO builder using a host-staged operating-system definition:
- command pattern:
fruix system installer-iso ...
- result:
- successful ISO materialization in a temporary store
- artifact checks performed:
etdumpreports an EFI El Torito boot entry- the ISO contains:
boot/kernel/kernelboot/kernel/linker.hintsboot/loader.confboot/loader.efiboot/root.img
boot/loader.confinside the ISO contains the expectedmdroot_*andvfs.root.mountfromentries
Example smoke-build metadata:
action=installer-iso
iso_volume_label=FRUIX_INSTALLER
iso_store_path=/tmp/...-fruix-installer-iso-fruix-freebsd-installer
iso_image=/tmp/...-fruix-installer-iso-fruix-freebsd-installer/installer.iso
boot_efi_image=/tmp/...-fruix-installer-iso-fruix-freebsd-installer/efiboot.img
root_image=/tmp/...-fruix-installer-iso-fruix-freebsd-installer/root.img
installer_closure_path=/tmp/...-fruix-system-fruix-freebsd-installer
target_closure_path=/tmp/...-fruix-system-fruix-freebsd
End-to-end harness validation
Added:
tests/system/run-phase18-installer-iso.sh
This harness validates the full Phase 18.3 flow:
- build installer ISO
- boot it under QEMU/UEFI/TCG
- install onto a target disk from inside the booted ISO environment
- boot the installed target
Passing validation:
PASS phase18-installer-iso
Validated result summary:
installer_iso_store_path=/frx/store/...-fruix-installer-iso-fruix-freebsd-installer
installer_iso_image=/frx/store/...-fruix-installer-iso-fruix-freebsd-installer/installer.iso
installer_boot_efi_image=/frx/store/...-fruix-installer-iso-fruix-freebsd-installer/efiboot.img
installer_root_image=/frx/store/...-fruix-installer-iso-fruix-freebsd-installer/root.img
install_target_device=/dev/vtbd0
freebsd_source_kind=git
freebsd_source_ref=stable/15
freebsd_source_commit=332708a606f6bf0841c1d4a74c0d067f5640fe89
materialized_source_store=/frx/store/459499e0eb29f4c73ad455060dd2502d21fb56f205c0a676831cf723b3a0c378-freebsd-source-stable15-installer-iso-target-source
installer_state=done
installer_sshd_status=running
target_esp_fstype=msdosfs
target_root_fstype=ufs
target_shepherd_status=running
target_sshd_status=running
installer_iso_boot=ok
installer_iso_install=ok
installed_target_boot=ok
Notable ISO-specific validation detail:
- unlike the disk-image-style installer environment from Phase 18.2, the ISO boots from
cd0, so the target virtio disk appears as:/dev/vtbd0
- the earlier installer-environment default:
/dev/vtbd1remains correct for the disk-image installer, but not for the ISO path
The harness verified all of the following:
fruix system installer-isoproduces a bootable ISO artifact in/frx/store- the ISO boots successfully under QEMU/UEFI/TCG
- the booted installer ISO environment becomes reachable over SSH
/run/current-systeminside the installer ISO points at the installer closure- the installer rc.d job reaches:
state=done
- the installer log records:
fruix-installer:done
- the installed target disk contains:
- GPT partitioning
- EFI filesystem:
msdosfs - root filesystem:
ufs EFI/BOOT/BOOTX64.EFI/var/lib/fruix/install.scm
- the installed target then boots successfully as its own Fruix system under QEMU/UEFI/TCG
- after target boot:
/run/current-systempoints at the target closure- shepherd is running
sshdis running- activation completed successfully
Result
Phase 18.3 is complete.
Fruix now has a validated bootable UEFI installer ISO on FreeBSD that can:
- boot into a Fruix-managed installer environment from ISO media
- perform the non-interactive installation flow onto a target disk
- and boot the installed target successfully