226 lines
7.6 KiB
Markdown
226 lines
7.6 KiB
Markdown
# Fruix differences for Guix sysadmins
|
|
|
|
Date: 2026-04-04
|
|
|
|
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.
|
|
|
|
The short version is:
|
|
|
|
- Fruix is strongly **Guix-inspired**
|
|
- it tries to preserve the important semantic properties
|
|
- but it does **not** copy Guix mechanically where FreeBSD or Fruix-specific concerns make a different representation clearer
|
|
|
|
## Big picture
|
|
|
|
Fruix keeps the core Guix ideas you would expect:
|
|
|
|
- declarative inputs
|
|
- content-addressed store paths
|
|
- immutable build outputs
|
|
- rollback-friendly deployment identity
|
|
- provenance tied to the deployed closure rather than mutable in-place state
|
|
|
|
But Fruix differs in at least four major ways today:
|
|
|
|
1. it targets **FreeBSD**, not GNU/Linux
|
|
2. its system frontend is currently smaller:
|
|
- `fruix system build|rootfs|image|install|installer|installer-iso`
|
|
3. it treats **FreeBSD source provenance** as an explicit deployment concern
|
|
4. its installed-system generation model is still earlier-stage than Guix's mature system-generation workflow
|
|
|
|
## Similarities to Guix
|
|
|
|
If you know Guix System, these Fruix properties should feel familiar.
|
|
|
|
### Immutable deployment identity
|
|
|
|
A deployed Fruix system is identified primarily by its closure path in `/frx/store`, not by mutable files under `/etc` or `/usr/local`.
|
|
|
|
### `/run/current-system`
|
|
|
|
Fruix keeps the Guix-like runtime convention:
|
|
|
|
- `/run/current-system`
|
|
|
|
That path remains the active runtime boundary used by activation and service wiring.
|
|
|
|
### Rollback-friendly semantics
|
|
|
|
Fruix avoids in-place mutation of an older deployed closure.
|
|
|
|
The validated rollback story today is:
|
|
|
|
- keep the earlier declaration
|
|
- rebuild or rematerialize it
|
|
- boot or redeploy that earlier closure again
|
|
|
|
That is Guix-like in spirit even though Fruix does not yet expose the same installed-system rollback command surface.
|
|
|
|
### Generation-style metadata and roots
|
|
|
|
Fruix now records explicit installed-system generation state under:
|
|
|
|
- `/var/lib/fruix/system`
|
|
|
|
and explicit retention roots under:
|
|
|
|
- `/frx/var/fruix/gcroots`
|
|
|
|
This preserves the basic Guix idea that deployment state and reachability should be represented explicitly rather than inferred from whatever happens to be on disk.
|
|
|
|
## Important differences from Guix
|
|
|
|
## 1. Fruix does not mirror Guix's on-disk generation layout 1:1
|
|
|
|
This is intentional.
|
|
|
|
Guix heavily reuses its profile-generation model and represents a lot of meaning through symlink structure such as profile links and system generation links.
|
|
|
|
Fruix keeps the **semantics** but uses a more explicit metadata-oriented layout for installed systems.
|
|
|
|
Current Fruix layout:
|
|
|
|
```text
|
|
/var/lib/fruix/system/
|
|
current -> generations/1
|
|
current-generation
|
|
generations/
|
|
1/
|
|
closure -> /frx/store/...-fruix-system-...
|
|
metadata.scm
|
|
provenance.scm
|
|
install.scm
|
|
```
|
|
|
|
Why Fruix does this:
|
|
|
|
- it makes deployment state easier to inspect directly
|
|
- it gives FreeBSD-specific install and provenance details a clearer home
|
|
- it keeps room for richer operator tooling later without losing the Guix properties
|
|
|
|
So the rule of thumb is:
|
|
|
|
- **same semantics as Guix where practical**
|
|
- **not necessarily the same directory names or symlink vocabulary**
|
|
|
|
## 2. Fruix currently keeps `/run/current-system` simple
|
|
|
|
Even though Fruix now records explicit generation metadata under `/var/lib/fruix/system`, it still keeps:
|
|
|
|
- `/run/current-system -> /frx/store/...`
|
|
|
|
rather than making `/run/current-system` point through a generation directory first.
|
|
|
|
This was chosen to preserve compatibility with the already-validated activation and runtime model while adding explicit generation metadata separately.
|
|
|
|
## 3. Fruix treats source provenance more explicitly
|
|
|
|
Guix sysadmins are used to derivation/store provenance. Fruix adds an extra emphasis because its current FreeBSD story depends on explicit source selection and materialization.
|
|
|
|
Fruix routinely records:
|
|
|
|
- declared FreeBSD source object metadata
|
|
- materialized source store paths
|
|
- source materialization metadata files
|
|
- closure-level store layout metadata
|
|
- install metadata on the target system
|
|
|
|
This is more prominent in Fruix than most Guix system docs because FreeBSD base/source identity has been an active design concern for this project.
|
|
|
|
## 4. Fruix has installer-media workflows as first-class system actions
|
|
|
|
Guix has installation media and image workflows, but Fruix's current system frontend makes these especially explicit because they are still part of the active architectural bring-up story.
|
|
|
|
Current Fruix actions include:
|
|
|
|
- `fruix system install`
|
|
- `fruix system installer`
|
|
- `fruix system installer-iso`
|
|
|
|
That is a little more deployment-medium-oriented than the mental model many Guix users start with.
|
|
|
|
## 5. Device naming is more environment-sensitive than Guix users may expect
|
|
|
|
Because Fruix is on FreeBSD, the install target device naming is not the same as on Linux.
|
|
|
|
Validated examples:
|
|
|
|
- installer disk-image path under QEMU:
|
|
- `/dev/vtbd1`
|
|
- installer ISO path under QEMU:
|
|
- `/dev/vtbd0`
|
|
- installer ISO path under XCP-ng:
|
|
- `/dev/ada0`
|
|
|
|
So compared with Guix-on-Linux intuition, Fruix operators should be more explicit about target-device selection during installation and installer-media validation.
|
|
|
|
## 6. Fruix does not yet have Guix-equivalent installed-system generation commands
|
|
|
|
This is the biggest current operational gap.
|
|
|
|
Fruix does **not** yet provide a mature equivalent of the familiar Guix System operator flow around in-place generation switching and rollback commands.
|
|
|
|
Today, Fruix rollback is mostly:
|
|
|
|
- declaration-driven
|
|
- rebuild/redeploy based
|
|
|
|
rather than:
|
|
|
|
- switch current system generation in place through a dedicated command
|
|
|
|
So if you come from Guix, assume that Fruix currently has:
|
|
|
|
- strong closure/store semantics
|
|
- explicit install artifacts
|
|
- explicit generation metadata roots
|
|
- but a less mature installed-system generation UX
|
|
|
|
## 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.
|
|
|
|
Where Fruix is intentionally experimenting is mostly the **representation layer**:
|
|
|
|
- make generation state more legible to operators
|
|
- make provenance more visible without needing to reconstruct it mentally from symlink layout alone
|
|
- separate:
|
|
- runtime entry point (`/run/current-system`)
|
|
- installed deployment state (`/var/lib/fruix/system`)
|
|
- retention roots (`/frx/var/fruix/gcroots`)
|
|
|
|
That is why Fruix currently prefers a small per-generation metadata directory instead of only a bare generation link.
|
|
|
|
## Practical operator advice for Guix users
|
|
|
|
If you are already comfortable with Guix, the safest Fruix mental model today is:
|
|
|
|
1. think in terms of immutable closures and declarations first
|
|
2. use `fruix system build` as the canonical starting point
|
|
3. treat image/install/installer/installer-iso as deployment materializers built from the same declaration
|
|
4. identify a deployment by:
|
|
- closure path
|
|
- source provenance metadata
|
|
- install metadata
|
|
5. think of rollback today as:
|
|
- “redeploy the earlier declaration again”
|
|
rather than:
|
|
- “switch to an already-managed previous generation in place”
|
|
|
|
## Status summary
|
|
|
|
Today Fruix is closest to Guix in:
|
|
|
|
- store and closure semantics
|
|
- declarative deployment identity
|
|
- rollback-friendly immutability
|
|
- `/run/current-system` runtime model
|
|
|
|
It differs most from Guix in:
|
|
|
|
- FreeBSD platform details
|
|
- source-provenance emphasis
|
|
- installer-medium-oriented workflows
|
|
- generation-layout representation
|
|
- and the still-maturing installed-system generation command surface
|