317 lines
14 KiB
Markdown
317 lines
14 KiB
Markdown
# Fruix on FreeBSD, Path C: Short Hardening Pass, Then Native FreeBSD Base Builds
|
|
|
|
This document extends `docs/PLAN_2.md` after the completion of Phases 1 through 10 and the post-Phase-10 Shepherd/PID-1 and runtime-prefix cleanup work.
|
|
|
|
The project has already crossed the main feasibility threshold:
|
|
|
|
- Fruix can build declarative FreeBSD system artifacts
|
|
- those artifacts boot on the real XCP-ng VM
|
|
- the guest reaches DHCP and SSH
|
|
- both `freebsd-init+rc.d-shepherd` and `shepherd-pid1` have been validated
|
|
- the guest no longer depends on `/tmp/*-validate-install` runtime-compatibility shims
|
|
|
|
The next architectural question is about the **FreeBSD base itself**.
|
|
|
|
Today, Fruix still assembles the kernel, bootloader, libraries, rc assets, and userland largely by **copying curated artifacts from the build host** into `/frx/store`. That was the right bootstrap move, but it is now the largest remaining non-native part of the system.
|
|
|
|
Long-term, the desired direction is clear:
|
|
|
|
- build FreeBSD kernel/world as Fruix-managed artifacts
|
|
- keep them in `/frx/store`
|
|
- make system upgrades a declarative rebuild/redeploy story instead of a host-copy refresh
|
|
|
|
However, this plan does **not** recommend jumping directly into full self-hosted FreeBSD base builds inside the guest. Instead, it takes a narrower and safer sequence:
|
|
|
|
1. do a **short hardening pass** on the current working system
|
|
2. then begin **Option B** immediately as the next major architecture phase
|
|
3. start Option B on the **builder side** from `/usr/src`, not with guest self-hosting
|
|
|
|
This keeps momentum while avoiding two failure modes:
|
|
|
|
- over-polishing the current host-copy pipeline as if it were the end state
|
|
- mixing base-system build mechanics, runtime polish, boot debugging, and self-hosting into one oversized step
|
|
|
|
Throughout this plan, the canonical Fruix roots remain:
|
|
|
|
- `/frx/store`
|
|
- `/frx/var`
|
|
- `/frx/etc`
|
|
|
|
The user-facing system remains **Fruix**, with CLI `fruix`, while internal upstream-derived names continue to be renamed selectively rather than mechanically.
|
|
|
|
---
|
|
|
|
## Current State at the Start of Plan 3
|
|
|
|
Fruix on FreeBSD already has:
|
|
|
|
- a functioning content-addressed store and derivation path
|
|
- daemon-mediated builds with FreeBSD-aware isolation prototypes
|
|
- real package outputs in `/frx/store`
|
|
- a declarative FreeBSD operating-system model
|
|
- rootfs and image generation driven by `fruix system ...`
|
|
- real XCP-ng validation using the approved VM/VDI path
|
|
- a working FreeBSD guest with DHCP, SSH, activation, Shepherd, and ready markers
|
|
- validated `shepherd-pid1` boot on both local QEMU/TCG and the real XCP-ng VM
|
|
- removal of the guest runtime's dependence on `/tmp` compatibility-prefix symlinks
|
|
|
|
The main remaining architectural compromise is that the FreeBSD base layer is still defined mostly as a set of curated host copies:
|
|
|
|
- kernel from `/boot/kernel`
|
|
- bootloader and boot assets from `/boot`
|
|
- userland/runtime pieces from `/bin`, `/sbin`, `/usr/bin`, `/usr/sbin`, `/lib`, `/usr/lib`, and `/etc`
|
|
- headers from `/usr/src`
|
|
|
|
That means Fruix can currently rebuild and redeploy a working system, but it does **not** yet have a truly native upgrade story for the FreeBSD base itself.
|
|
|
|
---
|
|
|
|
## Guiding Decision for the Next Milestone
|
|
|
|
The next milestone should be:
|
|
|
|
- **just enough hardening** to make the current system a reliable platform for deeper work,
|
|
- followed immediately by the first **host-built FreeBSD base artifacts** in `/frx/store`.
|
|
|
|
This means the next work should optimize for:
|
|
|
|
- debuggability
|
|
- provenance
|
|
- repeatable deployment/validation
|
|
- clean separation between host-staged base artifacts and Fruix-built artifacts
|
|
- incremental replacement of the copy-based base layer
|
|
|
|
It should **not** optimize for:
|
|
|
|
- turning the current host-copy path into a heavily polished long-term abstraction
|
|
- immediate self-hosted `buildworld`/`buildkernel` inside the Fruix guest
|
|
- solving every usability concern before starting native base work
|
|
|
|
---
|
|
|
|
## Phase 12: Short Hardening Pass on the Existing Working Pipeline
|
|
|
|
The purpose of this phase is not to beautify the bootstrap path. It is to make the existing validated system reliable enough that FreeBSD base-build work can proceed without avoidable confusion.
|
|
|
|
### Intermediate Goal 12.1: Improve Deployment Provenance and Failure Diagnosis
|
|
|
|
**Verification Goal 12.1:** Make the current pipeline record exactly what FreeBSD base inputs and deployment artifacts were used for each generated system/image.
|
|
|
|
This should include at least:
|
|
|
|
- host `freebsd-version` / `uname` provenance
|
|
- `/usr/src` revision or identifying metadata when available
|
|
- the exact staged base-package store paths used in the system closure
|
|
- image metadata that clearly distinguishes:
|
|
- host-copied FreeBSD base artifacts
|
|
- Fruix-built Guile/Shepherd/system artifacts
|
|
- better collection of boot/runtime logs where possible from the existing QEMU and XCP-ng harnesses
|
|
|
|
**Success Criteria:** a generated Fruix system/image can be traced back to its host-side FreeBSD base inputs and runtime validation logs without ad hoc investigation.
|
|
|
|
### Intermediate Goal 12.2: Tighten Basic Runtime Completeness and Operator Diagnostics
|
|
|
|
**Verification Goal 12.2:** Close the most important remaining “prototype rough edges” in the current guest so it remains a dependable validation target while Option B begins.
|
|
|
|
This should focus on small, high-value improvements such as:
|
|
|
|
- clearer boot/service logs
|
|
- fewer known noisy runtime warnings where reasonably fixable
|
|
- more explicit validation of essential services and files
|
|
- better failure surfacing from activation and service startup
|
|
|
|
This phase should avoid broad feature creep. The target is not a polished distribution; it is a sharper debugging and validation baseline.
|
|
|
|
**Success Criteria:** the current FreeBSD guest remains reproducibly bootable and easier to debug, with fewer ambiguous failures during rebuild/redeploy cycles.
|
|
|
|
### Intermediate Goal 12.3: Make the Host-Staged FreeBSD Base Boundary Explicit
|
|
|
|
**Verification Goal 12.3:** Refine the current package/model layer so the “host-staged FreeBSD base” is treated as an explicit transitional boundary rather than an implicit permanent design.
|
|
|
|
This should include:
|
|
|
|
- clearer grouping or manifesting of host-staged base packages
|
|
- documentation of which components are currently copied from the host
|
|
- explicit notes on which ones are planned to be replaced first by native base builds
|
|
|
|
**Success Criteria:** the repo documents and code clearly separate transitional host-copy FreeBSD base handling from genuine Fruix-built artifacts.
|
|
|
|
---
|
|
|
|
## Phase 13: Option B Begins — Host-Built FreeBSD Kernel and World Artifacts in `/frx/store`
|
|
|
|
This is the real architectural pivot.
|
|
|
|
The goal is **not** yet to self-host FreeBSD base builds inside a Fruix guest. The goal is to teach Fruix to produce FreeBSD base artifacts as build outputs under `/frx/store`, using the builder host and `/usr/src` as the source of truth.
|
|
|
|
### Intermediate Goal 13.1: Model FreeBSD World and Kernel as Fruix Build Artifacts
|
|
|
|
**Verification Goal 13.1:** Introduce Fruix build descriptions for the FreeBSD base that can represent at least:
|
|
|
|
- a `freebsd-world` artifact
|
|
- a `freebsd-kernel` artifact
|
|
- required boot assets associated with the selected kernel/world build
|
|
|
|
The first version may still be specialized and FreeBSD-specific rather than fully generalized.
|
|
|
|
This step should determine and document:
|
|
|
|
- how `/usr/src` is treated as an input
|
|
- what build parameters affect output identity
|
|
- how kernel/world configuration is hashed into the output model
|
|
- how these outputs are split or grouped in `/frx/store`
|
|
|
|
**Success Criteria:** Fruix can describe native FreeBSD world/kernel build outputs as real store artifacts rather than only host-copy packages.
|
|
|
|
### Intermediate Goal 13.2: Build and Stage Minimal FreeBSD World/Kernel Outputs From `/usr/src`
|
|
|
|
**Verification Goal 13.2:** Produce the first concrete world/kernel build outputs from `/usr/src` and stage them into `/frx/store`.
|
|
|
|
The first target should be intentionally narrow:
|
|
|
|
- build a kernel matching the validated VM target
|
|
- build a minimal world sufficient for the current Fruix guest to boot
|
|
- stage install trees under content-addressed store paths
|
|
|
|
This phase should prefer correctness and repeatability over completeness. A minimal successful output split is acceptable if it is documented.
|
|
|
|
**Success Criteria:** `/frx/store` contains native Fruix-managed FreeBSD world/kernel outputs built from `/usr/src`, and their contents can be inspected as build results rather than copied host snapshots.
|
|
|
|
### Intermediate Goal 13.3: Boot a Fruix System Using Store-Built FreeBSD Base Artifacts
|
|
|
|
**Verification Goal 13.3:** Wire the operating-system/image pipeline so a generated system can boot using the newly built world/kernel outputs instead of the corresponding host-copy packages.
|
|
|
|
This should preserve the existing validation strategy:
|
|
|
|
- local QEMU/TCG + UEFI where useful
|
|
- real XCP-ng validation on the approved VM and existing VDI
|
|
|
|
The first boot target may still leave some secondary base components on the older copy path if necessary, as long as the transition boundary is explicit.
|
|
|
|
**Success Criteria:** a Fruix system/image boots successfully using native store-built FreeBSD base artifacts for at least the kernel and core world runtime.
|
|
|
|
---
|
|
|
|
## Phase 14: Incrementally Replace the Host-Copy FreeBSD Base Layer
|
|
|
|
Once a minimal native world/kernel path works, the rest of the host-copy base layer should be retired incrementally rather than in one giant switch.
|
|
|
|
### Intermediate Goal 14.1: Replace Kernel and Boot Assets First
|
|
|
|
**Verification Goal 14.1:** Move the system closure and image generator to prefer native store-built kernel and boot assets over host-copied `/boot/...` material.
|
|
|
|
This should include:
|
|
|
|
- kernel
|
|
- loader/boot assets as appropriate
|
|
- any required linker or boot metadata
|
|
|
|
**Success Criteria:** the image no longer relies on host-copied kernel/boot components for the validated boot path.
|
|
|
|
### Intermediate Goal 14.2: Replace the Core Runtime World Slice
|
|
|
|
**Verification Goal 14.2:** Move the essential userland/runtime components to the native world outputs, including the files required for:
|
|
|
|
- boot
|
|
- activation
|
|
- networking
|
|
- SSH
|
|
- service startup
|
|
- basic operator access
|
|
|
|
**Success Criteria:** the booted Fruix system reaches ready state using a native store-built core FreeBSD runtime rather than a hand-curated host copy set.
|
|
|
|
### Intermediate Goal 14.3: Revisit Headers, Toolchain, and Development Splits
|
|
|
|
**Verification Goal 14.3:** Define cleaner boundaries between:
|
|
|
|
- runtime world outputs
|
|
- development headers
|
|
- toolchain artifacts
|
|
- optional build/developer profiles
|
|
|
|
This step should reduce accidental coupling between “what the guest needs to boot” and “what the host needs to build software”.
|
|
|
|
**Success Criteria:** Fruix has a clearer and more maintainable model for FreeBSD runtime vs. development artifacts in `/frx/store`.
|
|
|
|
---
|
|
|
|
## Phase 15: Establish a Real Fruix Upgrade Story for the FreeBSD Base
|
|
|
|
After native base artifacts exist and are used by the system closure, Fruix can move from “rebuild from current host copies” toward a more honest upgrade story.
|
|
|
|
### Intermediate Goal 15.1: Make the FreeBSD Base Version a Declarative Input
|
|
|
|
**Verification Goal 15.1:** Define how a Fruix system declares which FreeBSD base/kernel source version it targets.
|
|
|
|
This may initially remain tied to locally available `/usr/src`, but it should move the model toward a declarative notion of:
|
|
|
|
- target FreeBSD branch/release
|
|
- kernel configuration
|
|
- world configuration
|
|
- boot/runtime variant
|
|
|
|
**Success Criteria:** FreeBSD base versioning becomes an explicit part of the Fruix system model rather than an implicit property of the builder host.
|
|
|
|
### Intermediate Goal 15.2: Support Rebuild/Redeploy/Rollback Across Base Versions
|
|
|
|
**Verification Goal 15.2:** Demonstrate that at least two distinct FreeBSD base builds can coexist in `/frx/store` and that the generated system can switch between them through the normal rebuild/redeploy flow.
|
|
|
|
This should preserve the Guix-inspired strengths:
|
|
|
|
- content-addressed outputs
|
|
- side-by-side versions
|
|
- rollback-friendly system closures
|
|
|
|
**Success Criteria:** Fruix can rebuild and redeploy a system against a newer FreeBSD base without mutating the old one in place.
|
|
|
|
### Intermediate Goal 15.3: Decide When to Pursue Self-Hosted Base Builds
|
|
|
|
**Verification Goal 15.3:** Reassess whether the next step should be:
|
|
|
|
- building FreeBSD base artifacts inside a Fruix-managed environment, or
|
|
- continuing to use the host builder while improving reproducibility and source acquisition
|
|
|
|
This decision should be made only after native world/kernel artifacts are already working in `/frx/store`.
|
|
|
|
**Success Criteria:** the project has a documented, evidence-based decision on whether and when to pursue self-hosted FreeBSD base builds.
|
|
|
|
---
|
|
|
|
## Strategic Notes
|
|
|
|
### Why this order?
|
|
|
|
This sequence is intended to preserve momentum and architectural clarity.
|
|
|
|
The short hardening pass prevents the next phase from being undermined by avoidable debugging ambiguity. But the hardening phase is intentionally short so the project does not over-invest in the transitional host-copy design.
|
|
|
|
Then Option B begins immediately in a way that is ambitious but still controlled:
|
|
|
|
- build FreeBSD base artifacts on the host
|
|
- store them in `/frx/store`
|
|
- boot from them
|
|
- replace the host-copy model incrementally
|
|
|
|
### What this plan does **not** require yet
|
|
|
|
This plan does **not** require, in its first native-base stages:
|
|
|
|
- guest self-hosting
|
|
- in-place `freebsd-update` integration
|
|
- complete replacement of every base file in one step
|
|
- abandoning the validated XCP-ng/QEMU test harnesses
|
|
- immediate adoption of `shepherd-pid1` as the only supported boot path
|
|
|
|
### What success will mean
|
|
|
|
Success under this plan means the project moves from:
|
|
|
|
- “Fruix assembles a FreeBSD system by copying a curated slice of the host”
|
|
|
|
into:
|
|
|
|
- “Fruix builds and stores FreeBSD base artifacts itself, then assembles and deploys systems from those declared outputs.”
|
|
|
|
That is the real bridge from the current prototype to a more genuinely native Fruix system on FreeBSD.
|