5.4 KiB
Fruix FreeBSD Progress Summary
What we have achieved so far
Fruix now has a working end-to-end prototype of a Guix-inspired system on FreeBSD, while preserving the Fruix product boundary (fruix, /frx) and the core model: declarative builds, content-addressed store paths, daemon-mediated privilege separation, garbage-collection roots, derivations, and reproducible system artifacts.
Completed milestones include:
- Core runtime/build foundation: validated Guile on FreeBSD, diagnosed the packaged-Guile subprocess crash, and established a working local Guile path with the upstream FreeBSD fix.
- Store and daemon path: built the first Fruix daemon/store workflow on FreeBSD, including jail/build-user isolation, store population under
/frx/store, derivation generation, and minimal RPC integration. - Real package builds: adapted enough of the GNU build/package path to build real package outputs into
/frx/storeand install a minimal profile. - System model: introduced a declarative FreeBSD
operating-systemmodel, reproducible system closures, rootfs generation, and raw image generation as first-class system artifacts. - Bootable VM images: built FreeBSD images that boot reproducibly and stage the full
/frx/storeinto the guest image. - Real VM validation on XCP-ng: proved the system boots on the real target VM, gets DHCP, starts SSH, and exposes a usable guest for validation.
- User-facing CLI: added
bin/fruixwithfruix system build|rootfs|image, making system artifact generation a real Fruix workflow instead of a phase-specific prototype. - Boot architecture progress: validated both boot modes on the real XCP-ng VM:
freebsd-init+rc.d-shepherdshepherd-pid1
- Native runtime cleanup: removed the guest runtime’s dependence on
/tmp/*-validate-installcompatibility-prefix symlinks for Guile, guile-extra, and Shepherd. The guest now boots and runs Guile/Shepherd from the store-backed runtime layout without those temporary aliases. - Native FreeBSD base artifacts: replaced the validated host-copy boot/runtime path with native
/usr/src-built artifacts in/frx/storefor:freebsd-native-kernelfreebsd-native-bootloaderfreebsd-native-runtime
- Declarative FreeBSD base model: the FreeBSD base is now an explicit system input via
freebsd-base, not just an ambient property of the builder host. - Base upgrade story: Fruix can now keep distinct declared base versions side by side in
/frx/storeand roll forward / back between them through the normal system deployment flow.
Major pain points now behind us
- Guile subprocess instability on FreeBSD: root-caused and bypassed with the validated local Guile build.
- “Prototype only” store/build flow: replaced with real derivations, store outputs, and system artifacts under
/frx/store. - Non-booting early images: fixed rootfs/image composition, GPT sizing issues for XCP-ng, and early rc/fstab problems.
- No practical VM validation path: when local bhyve proved impossible under Xen, validation successfully pivoted to the real XCP-ng VM and existing VDI.
- Guest runtime crashes from locale/prefix issues: fixed enough locale/runtime staging and later removed dependence on guest-side compatibility-prefix shims.
- Shepherd only as a bridged service: Fruix has now proven Shepherd can run as PID 1 on FreeBSD, not just behind FreeBSD
init+rc.d.
Major pain points still ahead
- True store-native runtime artifacts: some historical build/install prefixes are still embedded in binaries and metadata. They are no longer required at runtime, but the local Guile/guile-extra/Shepherd build/install flow should still be moved to a genuinely store-native prefix from the start.
- Source reproducibility for the FreeBSD base: the next major boundary is no longer host-copy boot/runtime assets; it is making source-tree selection/acquisition more reproducible and less tied to a single ambient
/usr/src. - Boot-path simplification: Fruix now supports both the legacy
freebsd-init+rc.d-shepherdpath and the more Guix-likeshepherd-pid1path. We still need to decide whether Shepherd PID 1 becomes the preferred/default architecture. - Reduce transitional FreeBSD glue: more of the current bootstrap/activation/runtime setup should become cleaner and less prototype-specific over time.
- Tooling and platform constraints: local bhyve remains blocked by missing nested virtualization under Xen, and XO permissions still prevent creating/importing new VDIs; current validation must keep reusing the approved VM/VDI path.
- Remaining ecosystem gaps: some deeper Guix-like features are still immature on FreeBSD, especially around native package-management ergonomics and fully polished runtime/deployment behavior.
Bottom line
Fruix has crossed the most important threshold: it is no longer just a collection of isolated FreeBSD experiments. It can now build declarative FreeBSD system artifacts, boot them on the real target VM, reach the network, serve SSH, run Shepherd as PID 1, operate from /frx without depending on temporary runtime-prefix shims, build native FreeBSD base artifacts into /frx/store, and roll forward / back between declared base versions. The biggest remaining work is no longer “can this boot?” but “how reproducible and source-declarative can we make the native FreeBSD base path from here?”