6.3 KiB
Phase 18.2: minimal Fruix-managed installer environment on FreeBSD
Date: 2026-04-04
Goal
Phase 18.2 builds on the Phase 18.1 host-driven install primitive.
The goal here is not a polished live installer. The goal is a small Fruix-managed environment that can:
- boot as its own Fruix system,
- carry a selected target Fruix system closure and rootfs payload,
- install that target system onto a second disk from inside the booted environment,
- and leave the installed target bootable.
Implementation
New installer-environment API
Added in modules/fruix/system/freebsd.scm:
installer-operating-systemoperating-system-installer-image-specmaterialize-installer-image
The installer environment is derived from the selected target operating system, but with installer-specific behavior:
- host name defaults to:
<target-host-name>-installer
- init mode is kept on the currently most stable installer path:
freebsd-init+rc.d-shepherd
- the installer image root label is distinct:
fruix-installer-root
sshdis enabled for operator/debug access- installer accounts needed for SSH/DHCP are ensured if absent:
sshd_dhcp
Bootable installer image contents
materialize-installer-image now produces a bootable image that contains:
- the installer system closure and its runtime store closure
- the selected target system closure
- the selected target system's referenced store items
- a prebuilt target rootfs tree staged under:
/var/lib/fruix/installer/target-rootfs
- installer plan/state files under:
/var/lib/fruix/installer
- installer helper scripts:
/usr/local/libexec/fruix-installer-run/usr/local/etc/rc.d/fruix-installer
The booted installer environment runs a background rc.d job that:
- partitions the selected target disk
- creates EFI + UFS filesystems
- copies the staged target rootfs onto the target
- copies only the target system's required store items into the target
/frx/store - installs the target's
loader.efi - writes
/var/lib/fruix/install.scmon the target - records installer state in:
/var/lib/fruix/installer/state
- logs to:
/var/log/fruix-installer.log
New CLI action
Added in scripts/fruix.scm:
fruix system installer
Added option:
--install-target-device DEVICE
This action materializes a bootable installer image in /frx/store and emits metadata for:
- installer image paths
- installer closure path
- target closure path
- target install device
- installer state/log paths
- declared/materialized FreeBSD source metadata
- target/native/runtime store metadata
FreeBSD virtio target-device detail
A practical detail surfaced during validation:
- the correct FreeBSD virtio block device node for the second QEMU disk is:
/dev/vtbd1
The earlier Linux-flavored guess:
/dev/vtblk1
was wrong for the actual FreeBSD device node namespace in this environment.
The installer defaults were updated accordingly.
Small image-builder correctness fix
While doing this work I also fixed materialize-bhyve-image so its generated UFS filesystem label respects the requested:
root-partition-label
instead of always hardcoding:
fruix-root
This matters for the installer image because it needs a distinct root label while the target disk still uses the normal target label.
Validation
Added validation artifacts:
tests/system/phase18-installer-target-operating-system.scm.intests/system/run-phase18-installer-environment.sh
Passing validations:
PASS phase18-installer-environment- regression re-check:
PASS phase18-system-install
- regression re-check:
PASS phase17-source-revisions-qemu
Validated installer-environment result:
installer_image_store_path=/frx/store/fb038dbf5dac2ad1bb767a264d3a268915f489b936dc5dd32425645102d3da48-fruix-installer-image-fruix-freebsd-installer
installer_disk_image=/frx/store/fb038dbf5dac2ad1bb767a264d3a268915f489b936dc5dd32425645102d3da48-fruix-installer-image-fruix-freebsd-installer/disk.img
installer_disk_capacity=16g
installer_root_size=14g
target_disk_capacity=12g
install_target_device=/dev/vtbd1
installer_closure_path=/frx/store/ea821f20b579684877fdc86a2a1e80485cf2b12d9d32f74f42e368d738c2ad4d-fruix-system-fruix-freebsd-installer
target_closure_path=/frx/store/7ee225db532b6973e385f8507d2d61aec3cd3aeb0864f983c2ae4b6e149ef3b0-fruix-system-fruix-freebsd
freebsd_source_kind=git
freebsd_source_ref=stable/15
freebsd_source_commit=332708a606f6bf0841c1d4a74c0d067f5640fe89
materialized_source_store=/frx/store/7563df2714ae7fa9bd40b83c74512ffe2cb2ad91b297915591b55c76edbb2fcb-freebsd-source-stable15-installer-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_environment_boot=ok
installer_environment_install=ok
installed_target_boot=ok
The harness verified all of the following:
fruix system installerproduces a bootable installer image in/frx/store- validation boots a workdir copy of that installer disk image so the store artifact itself is not mutated during the boot/install run
- the installer environment boots successfully under QEMU/UEFI/TCG
- the installer environment becomes reachable over SSH
/run/current-systeminside the installer environment points at the installer closure- the installer rc.d job reaches:
state=done
- the installer log records:
fruix-installer:done
- the target raw disk is transformed into a valid GPT-installed Fruix target with:
- EFI filesystem:
msdosfs - root filesystem:
ufs EFI/BOOT/BOOTX64.EFIpresent/var/lib/fruix/install.scmpresent
- EFI filesystem:
- 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/usr/local/etc/rc.d/fruix-shepherd onestatusreports runningsshdis running- activation completed successfully
Result
Phase 18.2 is complete.
Fruix now has a real installer substrate on FreeBSD:
- a bootable Fruix-managed installer image
- a target closure bundled inside that installer environment
- in-guest non-interactive installation onto a second disk
- validated boot of the installed result
The next step is Phase 18.3:
- produce a bootable installer ISO for UEFI systems, rather than only a disk-image-style installer environment.