Files
fruix/docs/reports/phase18-minimal-installation-flow-freebsd.md

168 lines
4.7 KiB
Markdown

# Phase 18.1: minimal non-interactive Fruix installation flow on FreeBSD
Date: 2026-04-03
## Goal
Phase 18.1 turns Fruix's existing closure/rootfs/image machinery into a real installation workflow.
The goal is not a polished installer yet. The goal is a repeatable, non-interactive install path that can:
- take a declarative Fruix system,
- partition and format a target disk or image,
- populate it with the selected system closure,
- install boot assets,
- and leave the target bootable.
## Implementation
### New install spec and installer entry point
Added in `modules/fruix/system/freebsd.scm`:
- `operating-system-install-spec`
- `install-operating-system`
The installer currently supports:
- raw image-file targets
- `/dev/...` block-device targets
For raw image-file targets, Fruix now:
- creates/truncates the target image
- attaches it with `mdconfig`
- creates a GPT layout
- adds:
- an EFI partition
- a FreeBSD UFS root partition
- formats them with:
- `newfs_msdos`
- `newfs`
- mounts them
- stages the declarative Fruix rootfs
- copies the closure and referenced `/frx/store` items into the installed root
- installs `loader.efi` to `EFI/BOOT/BOOTX64.EFI`
- writes install metadata to:
- `/var/lib/fruix/install.scm`
### Rootfs staging was factored for reuse
Added internal helper:
- `populate-rootfs-from-closure`
This lets image generation and installation reuse the same rootfs staging logic while differing in how the final target is created.
### New CLI action
Added user-facing command support in `scripts/fruix.scm`:
- `fruix system install`
New system option:
- `--target PATH`
Install metadata now emits machine-readable fields including:
- `target`
- `target_kind`
- `target_device`
- `esp_device`
- `root_device`
- `install_metadata_path`
- `disk_capacity`
- `root_size`
- declared/materialized FreeBSD source metadata
- closure/native/runtime store metadata
### Validation harnesses
Added:
- `tests/system/phase18-install-operating-system.scm.in`
- `tests/system/run-phase18-system-install.sh`
The Phase 18 install validation uses the already-validated boot mode:
- `freebsd-init+rc.d-shepherd`
This keeps the install-flow validation focused on installation mechanics rather than on the separate Shepherd-as-PID-1 boot path.
## Validation
Passing validation:
- `PASS phase18-system-install`
- regression re-check:
- `PASS phase17-source-revisions-qemu`
Validated install result:
```text
target_image=/tmp/fruix-phase18-install.CyrgKc/installed.img
target_kind=raw-file
disk_capacity=12g
root_size=10g
closure_path=/frx/store/ee486985797103aa5d3eeeef7f2cf066bcbd6839cd81083dbe626a594e71a703-fruix-system-fruix-freebsd
freebsd_source_kind=git
freebsd_source_ref=stable/15
freebsd_source_commit=332708a606f6bf0841c1d4a74c0d067f5640fe89
materialized_source_store=/frx/store/a892afb425235de71c9da38884e2ebdba5dafd3a1993f432fe7c446f5af2151f-freebsd-source-stable15-install-source
native_base_store_count=3
install_metadata_path=/var/lib/fruix/install.scm
esp_fstype=msdosfs
root_fstype=ufs
shepherd_status=running
sshd_status=running
install_flow=non_interactive
init_mode=freebsd-init+rc.d-shepherd
install_target_boot=ok
```
The harness verified all of the following:
- GPT partitioning is created on the target image
- the installed ESP is a valid `msdosfs` filesystem
- the installed root partition is `ufs`
- `EFI/BOOT/BOOTX64.EFI` exists on the target
- `/run/current-system` points at the installed closure in `/frx/store`
- the installed closure exists under the target's `/frx/store`
- `/var/lib/fruix/install.scm` exists and records:
- closure path
- store items
- install spec
- materialized source provenance via the referenced closure/store items
- the installed system boots under local QEMU/UEFI/TCG
- after boot:
- `sshd` is running
- `/usr/local/etc/rc.d/fruix-shepherd onestatus` reports running
- activation completed successfully
## QEMU SMP note
I tested the idea of defaulting local QEMU validation to 8 vCPUs.
Result:
- for local `qemu-system-x86_64` under **TCG**, higher SMP did not help this validation path and in practice regressed boot responsiveness
- the harnesses therefore keep `QEMU_SMP` configurable but retain a conservative default of `2` for TCG-based local validation
This keeps the validated path reliable while still allowing manual override when useful.
## Result
Phase 18.1 is complete.
Fruix now has a real, repeatable, non-interactive installation workflow for FreeBSD systems:
- declarative system input
- native/source-driven closure output
- partition/format/install to a target image or disk
- bootable installed result
The next step is Phase 18.2:
- a minimal Fruix-managed installer environment that can boot into an install context and run this workflow from within that environment.