168 lines
4.7 KiB
Markdown
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.
|