system: validate development environment overlay

This commit is contained in:
2026-04-05 11:56:06 +02:00
parent 4975084baa
commit 9e9a0b59fc
10 changed files with 612 additions and 36 deletions

View File

@@ -1,6 +1,6 @@
# Fruix differences for Guix sysadmins
Date: 2026-04-04
Date: 2026-04-05
This document is aimed at operators who already know Guix well and want a quick map of where Fruix behaves similarly and where it intentionally differs.
@@ -242,6 +242,24 @@ For Guix-familiar operators, the practical takeaway is:
- do **not** assume Fruix store prefixes are byte-for-byte comparable to Guix/Nix ones
- expect Fruix to prefer a simpler, centralized naming policy unless exact Guix/Nix behavior becomes necessary later
## 8. Fruix can expose a separate in-system development profile overlay
For the validated Phase 20.1 path, Fruix can now expose development tooling separately from the main runtime profile.
On those systems, Fruix exposes:
- `/run/current-system/development-profile`
- `/run/current-development`
- `/usr/local/bin/fruix-development-environment`
The intent is:
- keep the main runtime profile lean
- expose headers, `usr/share/mk`, and selected toolchain commands explicitly
- avoid treating a development-heavy system image as the default runtime shape
Compared with Guix, this is conceptually similar to keeping development-oriented state separate from the main runtime identity, but Fruix currently expresses it as a system-attached development overlay rather than through Guix's broader profile/tooling model.
## Where Fruix is intentionally trying to improve on Guix's representation
Fruix is not trying to improve on Guix's core semantics. Guix already got those right.

View File

@@ -34,6 +34,10 @@ Fruix currently has:
- `fruix system status`
- `fruix system switch`
- `fruix system rollback`
- a validated separate in-system development environment overlay via:
- `/run/current-system/development-profile`
- `/run/current-development`
- `/usr/local/bin/fruix-development-environment`
Validated boot modes still are:
@@ -46,44 +50,37 @@ The validated Phase 18 installation work currently uses:
## Latest completed achievement
### 2026-04-04 — Phase 19.3 completed
### 2026-04-05 — Phase 20.1 completed
Fruix now has a validated installed-system operator workflow for switching to a staged candidate generation and rolling back to the recorded previous generation.
Fruix now has a validated real-VM path where a booted Fruix-managed FreeBSD system exposes a separate development environment for native base work without collapsing the runtime/development split.
Highlights:
- installed systems now ship an in-guest Fruix deployment helper at:
- `/usr/local/bin/fruix`
- validated in-guest command surface:
- `fruix system status`
- `fruix system switch /frx/store/...-fruix-system-...`
- `fruix system rollback`
- switching now records explicit rollback state under:
- `/var/lib/fruix/system/rollback`
- `/var/lib/fruix/system/rollback-generation`
- switching now records explicit rollback GC roots under:
- `/frx/var/fruix/gcroots/rollback-system`
- the validated installed-system workflow now supports:
- stage candidate closure in `/frx/store`
- switch to generation 2
- reboot into the candidate
- rollback to generation 1
- reboot into the restored current system
- operating-system declarations now support:
- `#:development-packages`
- system closures can now carry a separate development profile at:
- `/run/current-system/development-profile`
- `/run/current-development`
- opt-in systems now ship an in-guest helper at:
- `/usr/local/bin/fruix-development-environment`
- the validated Phase 20.1 guest path exposes:
- native headers
- `usr/share/mk` for `bsd.*.mk`
- Clang toolchain commands such as `cc`, `c++`, `ar`, `ranlib`, and `nm`
- the validated guest workflow now supports:
- `eval "$(/usr/local/bin/fruix-development-environment)"`
- direct compilation with the Fruix-provided toolchain
- a simple `bsd.prog.mk` build on the running Fruix guest
Validation:
- `PASS phase19-installed-system-rollback-qemu`
- regression re-checks:
- `PASS phase19-generation-layout-qemu`
- `PASS phase18-installer-iso`
- `PASS phase20-development-environment-xcpng`
Reports:
- `docs/system-deployment-workflow.md`
- `docs/GUIX_DIFFERENCES.md`
- `docs/reports/phase19-deployment-workflow-freebsd.md`
- `docs/reports/phase19-generation-layout-freebsd.md`
- `docs/reports/phase19-installed-system-rollback-freebsd.md`
- `docs/reports/phase20-development-environment-freebsd.md`
## Recent major milestones
@@ -109,6 +106,6 @@ Reports:
Per `docs/PLAN_4.md`, the next planned step is:
- **Phase 20.1** — validate a Fruix-managed development environment for native FreeBSD base work
- **Phase 20.2** — run host-initiated native base builds inside a Fruix-managed environment
Phase 19.3 is now complete: Fruix validates installed-system generation switching and rollback through the intended operator-facing workflow.
Phase 20.1 is now complete: Fruix validates a separate in-system development environment for native FreeBSD base work on the approved real XCP-ng path.

View File

@@ -0,0 +1,160 @@
# Phase 20.1: Fruix-managed development environment for native FreeBSD base work
Date: 2026-04-05
## Goal
Validate that a booted Fruix-managed FreeBSD system can expose a usable development environment for deeper native base work without collapsing the runtime/development boundary back into one broad profile.
This step explicitly builds on the Phase 14 split between:
- native runtime/boot artifacts for the running system
- separate development-facing artifacts such as headers and toolchain pieces
The goal is **not** full self-hosting yet.
It is to prove that a running Fruix system can expose the tools and paths needed for native FreeBSD build work in a controlled way.
## Implementation
### New operating-system field
`modules/fruix/system/freebsd/model.scm` now supports:
- `#:development-packages`
- `operating-system-development-packages`
The default remains empty, so existing systems do not change unless they opt in.
### Separate development profile inside the system closure
`modules/fruix/system/freebsd/media.scm` now materializes an additional profile tree when `development-packages` is non-empty:
- `/frx/store/...-fruix-system-.../development-profile`
The main runtime tree remains:
- `/frx/store/...-fruix-system-.../profile`
This preserves the runtime/development split:
- runtime stays under `profile`
- development tooling stays under `development-profile`
The development stores are also now part of the closure references and recorded in `metadata/store-layout.scm`.
### In-guest development environment helper
Opt-in systems with development packages now ship:
- `/usr/local/bin/fruix-development-environment`
and expose a stable runtime link:
- `/run/current-development -> /run/current-system/development-profile`
The helper emits shell exports for the active development profile, including at least:
- `FRUIX_DEVELOPMENT_PROFILE`
- `FRUIX_DEVELOPMENT_INCLUDE`
- `FRUIX_DEVELOPMENT_SHARE_MK`
- `FRUIX_CC`
- `FRUIX_CXX`
- `FRUIX_AR`
- `FRUIX_RANLIB`
- `FRUIX_NM`
- `FRUIX_BMAKE`
- `CPPFLAGS`
- `MAKEFLAGS`
- `PATH`
Intended use:
```sh
eval "$(/usr/local/bin/fruix-development-environment)"
```
### Chosen development overlay for this phase
For the validated Phase 20.1 guest path, the development overlay is intentionally narrow:
- `freebsd-native-headers`
- `freebsd-clang-toolchain`
This was chosen deliberately.
The earlier standalone Phase 14 development-profile package set was designed for broad profile composition, but for a running Fruix system it unnecessarily duplicated runtime pieces already present in the system profile.
For native base work, the important additions here are:
- `usr/include`
- `usr/share/mk`
- Clang/binutils-style frontend tools
while the running system already supplies:
- base runtime
- `/usr/bin/make`
- system libraries and boot/runtime state
That keeps the Phase 20.1 environment focused on native base development rather than reintroducing a broad mixed profile.
## New files
Added:
- `tests/system/phase20-development-operating-system.scm.in`
- `tests/system/run-phase20-development-environment-xcpng.sh`
## Validation
Passing run:
- `PASS phase20-development-environment-xcpng`
- workdir: `/tmp/fruix-phase20-development-xcpng`
Validated on the approved real XCP-ng path:
- VM `90490f2e-e8fc-4b7a-388e-5c26f0157289`
- VDI `0f1f90d3-48ca-4fa2-91d8-fc6339b95743`
Representative result:
```text
closure_path=/frx/store/c0ad43d7ef72323d4270a4f1e96ca1f5cc99566c-fruix-system-fruix-freebsd
development_profile_path=/frx/store/c0ad43d7ef72323d4270a4f1e96ca1f5cc99566c-fruix-system-fruix-freebsd/development-profile
development_profile_guest=/run/current-system/development-profile
cc_version=FreeBSD clang version 19.1.7 (https://github.com/llvm/llvm-project.git llvmorg-19.1.7-0-gcd708029e0b2)
hello_direct=hello-from-direct-dev-env
hello_make=hello-from-make-dev-env
development_environment=ok
```
The harness verified all of the following on the real booted Fruix guest:
- runtime boot/regression still succeeds on XCP-ng
- the closure contains a separate `development-profile`
- runtime `profile` does **not** regain headers or `usr/share/mk`
- `/usr/local/bin/fruix-development-environment` exists and emits the expected exports
- `/run/current-development` points at `/run/current-system/development-profile`
- direct compilation works with the exported Clang toolchain and headers
- a simple native FreeBSD `make` build using `.include <bsd.prog.mk>` also succeeds
## Result
Phase 20.1 is complete.
Fruix now validates a real booted FreeBSD system path where:
- the running system remains lean and runtime-focused
- native development artifacts are exposed separately and explicitly
- the guest can compile code directly with the Fruix-provided toolchain
- the guest can also drive a simple `bsd.prog.mk` build using the exported development environment
This is enough to say that Fruix can host a controlled native FreeBSD base-development environment, without yet claiming full self-hosting.
## Next step
Per `docs/PLAN_4.md`, the next planned step is:
- **Phase 20.2** — run host-initiated native base builds inside a Fruix-managed environment

View File

@@ -1,6 +1,6 @@
# Fruix system deployment workflow
Date: 2026-04-04
Date: 2026-04-05
## Purpose
@@ -197,6 +197,32 @@ Important current limitation:
- `fruix system switch` does **not** yet fetch or copy the candidate closure onto the target for you
- it assumes the selected closure is already present in the installed system's `/frx/store`
### In-guest development environment
Opt-in systems can also expose a separate development overlay under:
- `/run/current-system/development-profile`
- `/run/current-development`
Those systems now ship a helper at:
- `/usr/local/bin/fruix-development-environment`
Intended use:
```sh
eval "$(/usr/local/bin/fruix-development-environment)"
```
That helper exports a development-oriented environment while keeping the main runtime profile separate. The validated Phase 20.1 path currently uses this to expose at least:
- native headers under `usr/include`
- FreeBSD `share/mk` files for `bsd.*.mk`
- Clang toolchain commands such as `cc`, `c++`, `ar`, `ranlib`, and `nm`
- `MAKEFLAGS` pointing at the development profile's `usr/share/mk`
This is the current Fruix-native way to make a running system suitable for controlled native base-development work without merging development content back into the main runtime profile.
## Deployment patterns
### 1. Build-first workflow