Compare commits
10 Commits
1108153277
...
d89225fe11
| Author | SHA1 | Date | |
|---|---|---|---|
| d89225fe11 | |||
| 390bfb248f | |||
| 03fbd9bf08 | |||
| 72f89c51b5 | |||
| 3b95ced578 | |||
| f163a63b1f | |||
| 04b6ade095 | |||
| 94e498f57d | |||
| 4def04a357 | |||
| 6021a57c38 |
406
docs/PLAN_4.md
Normal file
406
docs/PLAN_4.md
Normal file
@@ -0,0 +1,406 @@
|
||||
# Fruix on FreeBSD, Path D: Declarative Source Acquisition, Installation Artifacts, and the Road to Self-Hosting
|
||||
|
||||
This document extends `docs/PLAN_3.md` after the completion of Phases 1 through 15.
|
||||
|
||||
The project has now crossed another important threshold:
|
||||
|
||||
- Fruix builds native FreeBSD base artifacts from `/usr/src` into `/frx/store`
|
||||
- the validated boot/runtime path is host-base-free at the deployed system layer
|
||||
- the FreeBSD base is now an explicit declarative Fruix input
|
||||
- side-by-side base versions can coexist in `/frx/store`
|
||||
- Fruix can rebuild, redeploy, and roll back between declared base versions
|
||||
|
||||
That means the next question is no longer whether Fruix can assemble and boot a native FreeBSD system. It can.
|
||||
|
||||
The next question is how to make that native base path **more reproducible, more source-declarative, and more installable**.
|
||||
|
||||
The biggest remaining impurity is now clear:
|
||||
|
||||
- the native base build path still relies on the builder host's ambient `/usr/src`
|
||||
|
||||
That was the right bridge through Phases 13 to 15, but it should not be the long-term source story.
|
||||
|
||||
Accordingly, Plan 4 focuses on three connected goals:
|
||||
|
||||
1. make FreeBSD source acquisition and source identity more declarative
|
||||
2. turn the current image-generation path into a real installation story
|
||||
3. only then move carefully toward self-hosted base builds
|
||||
|
||||
This preserves the Guix-inspired core while continuing to embrace FreeBSD semantics rather than trying to imitate Linux-specific workflows.
|
||||
|
||||
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.
|
||||
|
||||
The current real-VM validation constraints still apply unless explicitly relaxed later:
|
||||
|
||||
- approved VM: `90490f2e-e8fc-4b7a-388e-5c26f0157289`
|
||||
- approved A/B VDIs:
|
||||
- `0f1f90d3-48ca-4fa2-91d8-fc6339b95743`
|
||||
- `7061d761-3639-4bec-87f7-2ba1af924eaa`
|
||||
|
||||
---
|
||||
|
||||
## Current State at the Start of Plan 4
|
||||
|
||||
Fruix on FreeBSD already has:
|
||||
|
||||
- a functioning content-addressed store and derivation path under `/frx/store`
|
||||
- daemon-mediated builds with validated FreeBSD isolation concepts
|
||||
- a working declarative FreeBSD operating-system model
|
||||
- validated system closure, rootfs, and image generation through `fruix system ...`
|
||||
- real QEMU and XCP-ng boot validation
|
||||
- a host-base-free native boot/runtime composition built from:
|
||||
- `freebsd-native-kernel`
|
||||
- `freebsd-native-bootloader`
|
||||
- `freebsd-native-runtime`
|
||||
- a declarative `freebsd-base` model that records:
|
||||
- base identity
|
||||
- version label
|
||||
- branch
|
||||
- source root
|
||||
- target and kernel configuration
|
||||
- side-by-side native base versions in `/frx/store`
|
||||
- rollback-friendly redeploy across those declared base versions
|
||||
- a documented decision to continue using host-built native base artifacts for now rather than jumping immediately to guest self-hosting
|
||||
|
||||
The main remaining architectural compromise is now not the runtime/boot artifact split, but the **source boundary**:
|
||||
|
||||
- native FreeBSD base builds still use ambient `/usr/src`
|
||||
- source acquisition is not yet a first-class Fruix-managed input
|
||||
- therefore reproducibility and provenance still stop short of a fully declared source story
|
||||
|
||||
At the same time, Fruix still lacks a real installation workflow beyond image generation and validation harnesses.
|
||||
|
||||
---
|
||||
|
||||
## Guiding Decision for the Next Milestone
|
||||
|
||||
The next major milestone should be:
|
||||
|
||||
- **declarative FreeBSD source acquisition and source pinning first**,
|
||||
- then **native base builds from fetched or materialized source inputs**,
|
||||
- then a **real installation story**,
|
||||
- and only after that, a controlled re-evaluation of self-hosted base builds.
|
||||
|
||||
This means the next work should optimize for:
|
||||
|
||||
- explicit source identity
|
||||
- stronger provenance
|
||||
- side-by-side source revisions
|
||||
- repeatable rebuilds from fetched or materialized source trees
|
||||
- installation artifacts that are operator-usable beyond current validation harnesses
|
||||
|
||||
It should **not** optimize for:
|
||||
|
||||
- jumping straight into guest self-hosting while source identity is still weak
|
||||
- building a large interactive installer before the installation primitives are clear
|
||||
- replacing the current validated host-built native-base path prematurely
|
||||
|
||||
---
|
||||
|
||||
## Phase 16: Make FreeBSD Source Acquisition Declarative
|
||||
|
||||
This is the next architectural pivot after the native base/runtime split.
|
||||
|
||||
The goal is to move from:
|
||||
|
||||
- “build from whatever `/usr/src` is on the host”
|
||||
|
||||
into:
|
||||
|
||||
- “build from a declared FreeBSD source input with explicit provenance.”
|
||||
|
||||
### Intermediate Goal 16.1: Model FreeBSD Source Inputs Explicitly
|
||||
|
||||
**Verification Goal 16.1:** Introduce a first-class Fruix model for FreeBSD source inputs.
|
||||
|
||||
This can be a new `freebsd-source` record, an extension of `freebsd-base`, or another explicit source object, but it should represent at least:
|
||||
|
||||
- source kind:
|
||||
- local checkout snapshot
|
||||
- fetched Git checkout
|
||||
- fetched `src.txz` archive
|
||||
- source URL or local path
|
||||
- branch or release line
|
||||
- commit, tag, or revision when applicable
|
||||
- expected tree or archive hash
|
||||
- any intended patch queue or source transformation layer
|
||||
|
||||
This step should also document how that source object relates to:
|
||||
|
||||
- `freebsd-base`
|
||||
- native kernel/world/runtime/bootloader/headers builds
|
||||
- output identity in `/frx/store`
|
||||
|
||||
**Success Criteria:** Fruix can describe FreeBSD source inputs as explicit declared objects rather than only relying on ambient `/usr/src`.
|
||||
|
||||
### Intermediate Goal 16.2: Fetch or Materialize Source Trees Under Fruix Control
|
||||
|
||||
**Verification Goal 16.2:** Materialize a clean FreeBSD source tree from a declared source input using Fruix-managed fetch/materialization logic.
|
||||
|
||||
The first implementation may be intentionally modest, such as:
|
||||
|
||||
- fetching a Git checkout at a pinned revision from `https://git.FreeBSD.org/src.git`
|
||||
- or downloading a `src.txz` archive and verifying its hash
|
||||
- for example from `https://download.freebsd.org/releases/amd64/15.0-RELEASE/src.txz`
|
||||
- or from snapshot paths such as `https://download.freebsd.org/snapshots/amd64/15.0-STABLE/src.txz`
|
||||
- or snapshotting a local source tree into a content-addressed source artifact with explicit metadata
|
||||
|
||||
This phase should also define where downloaded or temporary source material lives, for example under:
|
||||
|
||||
- `/frx/var/cache/fruix/freebsd-source`
|
||||
|
||||
The important point is that the eventual build input should no longer be “the current mutable host tree” but a **materialized source snapshot with recorded identity**.
|
||||
|
||||
**Success Criteria:** Fruix can fetch or materialize a pinned FreeBSD source tree with recorded provenance and a stable identity suitable for native base builds.
|
||||
|
||||
### Intermediate Goal 16.3: Build Native Base Artifacts From the Declared Source Input
|
||||
|
||||
**Verification Goal 16.3:** Teach the native FreeBSD base build path to consume the declared source artifact rather than ambient `/usr/src`.
|
||||
|
||||
This should preserve the validated Plan-3/Plan-4 deployment story:
|
||||
|
||||
- native kernel
|
||||
- native bootloader slice
|
||||
- native runtime slice
|
||||
- host-base-free validated path
|
||||
|
||||
The goal is not yet to change the successful boot/runtime model, only the **source input boundary**.
|
||||
|
||||
**Success Criteria:** Fruix builds native FreeBSD base artifacts from a declared source input, and the resulting store artifacts record that source identity explicitly.
|
||||
|
||||
---
|
||||
|
||||
## Phase 17: Support Multiple FreeBSD Source Revisions Side by Side
|
||||
|
||||
Once source acquisition is explicit, Fruix should prove that it can treat source revisions the way it already treats declared base versions: as side-by-side inputs rather than in-place mutations.
|
||||
|
||||
### Intermediate Goal 17.1: Support Side-by-Side FreeBSD Source Revisions in `/frx/store`
|
||||
|
||||
**Verification Goal 17.1:** Demonstrate that at least two distinct declared FreeBSD source inputs can coexist and produce distinct native base artifacts in `/frx/store`.
|
||||
|
||||
These can differ by:
|
||||
|
||||
- Git revision
|
||||
- source archive hash
|
||||
- local source snapshot hash
|
||||
- or another explicit source identity boundary
|
||||
|
||||
The goal is to prove that the source declaration, not ambient host state, now drives the base build outputs.
|
||||
|
||||
**Success Criteria:** Fruix can hold at least two distinct FreeBSD source revisions side by side as meaningful native base inputs and outputs.
|
||||
|
||||
### Intermediate Goal 17.2: Rebuild and Boot From Two Distinct Source Revisions
|
||||
|
||||
**Verification Goal 17.2:** Build and boot systems from at least two distinct declared source revisions using the validated native base path.
|
||||
|
||||
This should preserve the current validation strategy:
|
||||
|
||||
- local QEMU/UEFI/TCG where useful
|
||||
- real XCP-ng validation on the approved VM and approved A/B VDI path
|
||||
|
||||
The booted systems do not necessarily need to differ in obvious runtime behavior; the important point is that their source identity and native base outputs differ and are tracked correctly.
|
||||
|
||||
**Success Criteria:** Fruix boots systems built from two distinct declared FreeBSD source revisions and records those revisions in system metadata.
|
||||
|
||||
### Intermediate Goal 17.3: Clarify Source Provenance, Caching, and Update Policy
|
||||
|
||||
**Verification Goal 17.3:** Document and encode the intended policy for:
|
||||
|
||||
- source caching
|
||||
- source refresh/invalidation
|
||||
- patch application if any
|
||||
- tree hashing rules
|
||||
- when a new source identity should or should not invalidate native base outputs
|
||||
|
||||
This step should reduce ambiguity before installation artifacts and later self-hosting experiments depend on these source objects.
|
||||
|
||||
**Success Criteria:** the repo clearly explains how FreeBSD source objects are fetched, cached, identified, invalidated, and consumed by native base builds.
|
||||
|
||||
---
|
||||
|
||||
## Phase 18: Turn System Images Into a Real Installation Story
|
||||
|
||||
Fruix can already produce bootable images. The next step is to make installation itself a first-class Fruix story rather than a manual consequence of image generation.
|
||||
|
||||
### Intermediate Goal 18.1: Define a Minimal Non-Interactive Installation Flow
|
||||
|
||||
**Verification Goal 18.1:** Introduce a minimal installation workflow that can take a Fruix system artifact and install it to a target disk or image in a repeatable way.
|
||||
|
||||
The first version should prefer clarity and automation over interactivity. For example, it may:
|
||||
|
||||
- partition a target disk
|
||||
- create required filesystems
|
||||
- copy or materialize the selected system closure
|
||||
- install boot assets
|
||||
- stage activation/runtime metadata
|
||||
- configure root SSH key or basic operator access
|
||||
|
||||
This first step should be VM-friendly and serial-console-friendly.
|
||||
|
||||
**Success Criteria:** Fruix can perform a repeatable installation of a declarative system onto a target disk or image without relying on ad hoc manual assembly.
|
||||
|
||||
### Intermediate Goal 18.2: Produce a Minimal Installer Environment
|
||||
|
||||
**Verification Goal 18.2:** Produce a small installer environment that can boot into a Fruix-managed install context and perform the installation workflow.
|
||||
|
||||
This environment may initially be one of:
|
||||
|
||||
- a special-purpose disk image
|
||||
- a minimal recovery/install rootfs
|
||||
- a proto-installer medium with only the tools needed for partitioning, filesystem creation, and deployment
|
||||
|
||||
The target here is not a polished live environment. It is a reliable installer substrate.
|
||||
|
||||
**Success Criteria:** Fruix can boot a minimal installer environment and use it to install a selected Fruix system to a target disk.
|
||||
|
||||
### Intermediate Goal 18.3: Build a Bootable Installer ISO
|
||||
|
||||
**Verification Goal 18.3:** Produce a bootable installer ISO for UEFI systems.
|
||||
|
||||
The first ISO can be intentionally narrow in scope. It should be enough to:
|
||||
|
||||
- boot under QEMU and, where practical, on the validated virtualization path
|
||||
- expose the install workflow
|
||||
- install a target Fruix system
|
||||
- leave the machine bootable into the installed system
|
||||
|
||||
A polished graphical or highly interactive installer is not required here.
|
||||
|
||||
**Success Criteria:** Fruix can build a bootable installer ISO that installs a declarative Fruix-on-FreeBSD system.
|
||||
|
||||
---
|
||||
|
||||
## Phase 19: Strengthen System Deployment and Generation Management
|
||||
|
||||
The current deployment model already has the important Guix-like semantic properties at the closure/store layer. This phase is about making that story more operator-facing and less harness-specific.
|
||||
|
||||
### Intermediate Goal 19.1: Define a First-Class Fruix Deployment Workflow
|
||||
|
||||
**Verification Goal 19.1:** Define and document the canonical user-facing deployment workflow for system rebuild, image generation, installation, and rollback.
|
||||
|
||||
This may introduce or refine user-facing commands such as:
|
||||
|
||||
- `fruix system build`
|
||||
- `fruix system image`
|
||||
- future deployment/install/switch subcommands if justified
|
||||
|
||||
The key goal is clarity: operators should have an obvious Fruix way to move between generations and deployments.
|
||||
|
||||
**Success Criteria:** the repo documents a coherent user-facing deployment workflow for system build, install, roll-forward, and rollback.
|
||||
|
||||
### Intermediate Goal 19.2: Model System Generations More Explicitly
|
||||
|
||||
**Verification Goal 19.2:** Make the system-generation story more explicit in metadata and deployment roots.
|
||||
|
||||
This should include deciding how Fruix wants to represent:
|
||||
|
||||
- current system generation
|
||||
- previous system generation
|
||||
- rollback target
|
||||
- GC roots associated with installed systems
|
||||
|
||||
This does not have to copy Guix System mechanically, but it should preserve the same important properties.
|
||||
|
||||
**Success Criteria:** Fruix has a clearer model for installed system generations and rollback roots rather than relying mainly on test-harness knowledge.
|
||||
|
||||
### Intermediate Goal 19.3: Validate Installed-System Rollback as an Operator Workflow
|
||||
|
||||
**Verification Goal 19.3:** Validate rollback through the intended installed-system workflow, not only through build/image test harnesses.
|
||||
|
||||
This step should prove that the installation and generation model work together coherently.
|
||||
|
||||
**Success Criteria:** an installed Fruix system can move between generations using the intended operator-facing deployment model.
|
||||
|
||||
---
|
||||
|
||||
## Phase 20: Controlled Steps Toward Self-Hosted Base Builds
|
||||
|
||||
Only after source identity and installation/deployment boundaries are stronger should Fruix seriously revisit self-hosted base builds.
|
||||
|
||||
### Intermediate Goal 20.1: Validate a Fruix-Managed Development Environment for Native Base Work
|
||||
|
||||
**Verification Goal 20.1:** Ensure that a Fruix-managed system can expose the development/runtime/toolchain environment needed for deeper FreeBSD-native build work.
|
||||
|
||||
This should build on the cleaner runtime/development split already established in Phase 14.
|
||||
|
||||
The goal is not yet full self-hosting; it is to prove that the system can host the tools and profiles needed for that work in a controlled way.
|
||||
|
||||
**Success Criteria:** a Fruix-managed system can expose a usable development environment for native FreeBSD build tasks.
|
||||
|
||||
### Intermediate Goal 20.2: Run Host-Initiated Native Base Builds Inside a Fruix-Managed Environment
|
||||
|
||||
**Verification Goal 20.2:** As an intermediate step, perform native base builds inside a Fruix-managed environment or jail while still using the host as the outer orchestrator.
|
||||
|
||||
This narrows the remaining gap without immediately demanding full guest self-hosting.
|
||||
|
||||
**Success Criteria:** Fruix can build native FreeBSD base artifacts from inside a Fruix-managed build environment, with the host still orchestrating the outer loop.
|
||||
|
||||
### Intermediate Goal 20.3: Reassess and Potentially Prototype Guest Self-Hosted Base Builds
|
||||
|
||||
**Verification Goal 20.3:** Revisit guest self-hosting only after the earlier source/install/deployment goals are complete enough to make that experiment meaningful.
|
||||
|
||||
At that point, the question should be answered with real evidence:
|
||||
|
||||
- what exactly self-hosting would improve
|
||||
- what it would cost in complexity
|
||||
- how it would fit with the source/deployment model already established
|
||||
|
||||
**Success Criteria:** the project either:
|
||||
|
||||
- validates a first controlled guest self-hosted base build, or
|
||||
- records a clear evidence-based decision to continue preferring host-orchestrated native builds.
|
||||
|
||||
---
|
||||
|
||||
## Strategic Notes
|
||||
|
||||
### Why this order?
|
||||
|
||||
This sequence is intended to preserve the most important win from Plan 3 and Phase 15:
|
||||
|
||||
- Fruix already has a native, store-based, rollback-friendly FreeBSD base path
|
||||
|
||||
The next improvement should therefore be to make the **source input** as explicit as the **deployment output** already is.
|
||||
|
||||
After that, Fruix can turn its successful image-generation path into a real installation story. Only then will self-hosting be judged in the right context.
|
||||
|
||||
### Why not jump straight to self-hosting?
|
||||
|
||||
Because at the end of Phase 15, the biggest remaining weakness is not “where the build runs”, but “how explicitly the source is declared and acquired”.
|
||||
|
||||
If self-hosting were attempted immediately, it would mix together:
|
||||
|
||||
- source acquisition problems
|
||||
- toolchain/profile maturity problems
|
||||
- build-environment questions
|
||||
- deployment/installation questions
|
||||
- and virtualization/operator constraints
|
||||
|
||||
That would make debugging and design less clear.
|
||||
|
||||
### Why add installation work before self-hosting?
|
||||
|
||||
Because Fruix should become more usable as a system even if self-hosting remains a later milestone.
|
||||
|
||||
A real installation story would:
|
||||
|
||||
- make the current system model more operator-meaningful
|
||||
- improve validation of generation/deployment semantics
|
||||
- prepare the project for broader VM and eventually hardware use
|
||||
- make later self-hosting experiments easier to stage and reproduce
|
||||
|
||||
### What success will mean
|
||||
|
||||
Success under this plan means the project moves from:
|
||||
|
||||
- “Fruix builds native FreeBSD base artifacts from the host’s current `/usr/src` and boots them successfully”
|
||||
|
||||
into:
|
||||
|
||||
- “Fruix acquires FreeBSD sources declaratively, builds native base artifacts from pinned source inputs, installs systems through a real Fruix workflow, and approaches self-hosting from a much cleaner architectural position.”
|
||||
883
docs/PROGRESS.md
883
docs/PROGRESS.md
@@ -1,5 +1,83 @@
|
||||
# Progress
|
||||
|
||||
## 2026-04-03 — Phase 16.1 completed: FreeBSD source inputs are now explicit Fruix objects
|
||||
|
||||
Completed work:
|
||||
|
||||
- added `docs/PLAN_4.md` to define the post-Phase-15 roadmap around:
|
||||
- declarative FreeBSD source acquisition
|
||||
- installation artifacts
|
||||
- the controlled path toward self-hosting
|
||||
- introduced a first-class `freebsd-source` record in `modules/fruix/packages/freebsd.scm` with:
|
||||
- supported kinds:
|
||||
- `local-tree`
|
||||
- `git`
|
||||
- `src-txz`
|
||||
- exported accessors for:
|
||||
- `name`
|
||||
- `kind`
|
||||
- `url`
|
||||
- `path`
|
||||
- `ref`
|
||||
- `commit`
|
||||
- `sha256`
|
||||
- new `%default-freebsd-source`
|
||||
- extended `freebsd-base` so it now records both:
|
||||
- transitional `source-root`
|
||||
- declarative `source`
|
||||
- added/exported:
|
||||
- `freebsd-base-source`
|
||||
- threaded declared source fields into native package plans so native build outputs can record them
|
||||
- in `modules/fruix/system/freebsd.scm`:
|
||||
- added source validation for:
|
||||
- `local-tree`
|
||||
- `git`
|
||||
- `src-txz`
|
||||
- added `freebsd-source-spec`
|
||||
- `freebsd-base-spec` now nests the declared source
|
||||
- native manifests and `.freebsd-native-build-info.scm` now include:
|
||||
- `declared-source`
|
||||
- closures now generate:
|
||||
- `metadata/freebsd-source.scm`
|
||||
- `metadata/store-layout.scm` now records:
|
||||
- `freebsd-source`
|
||||
- in `scripts/fruix.scm`, `build` and `image` metadata now emit:
|
||||
- `freebsd_source_name`
|
||||
- `freebsd_source_kind`
|
||||
- `freebsd_source_url`
|
||||
- `freebsd_source_path`
|
||||
- `freebsd_source_ref`
|
||||
- `freebsd_source_commit`
|
||||
- `freebsd_source_sha256`
|
||||
- `freebsd_source_file`
|
||||
- added validation artifacts:
|
||||
- `tests/system/phase16-declarative-source-operating-system.scm.in`
|
||||
- `tests/system/run-phase16-declarative-source-build.sh`
|
||||
- `tests/system/validate-phase16-freebsd-source.scm`
|
||||
- compared Fruix's new source model with Guix's source modeling via:
|
||||
- `~/repos/guix/guix/packages.scm`
|
||||
- `~/repos/guix/guix/git-download.scm`
|
||||
- wrote:
|
||||
- `docs/reports/phase16-declarative-source-model-freebsd.md`
|
||||
|
||||
Validation:
|
||||
|
||||
- `PASS phase16-declarative-source-build`
|
||||
- source model probe confirmed support for:
|
||||
- local-tree `/usr/src`
|
||||
- Git refs such as `stable/15` at `https://git.FreeBSD.org/src.git`
|
||||
- canonical `src.txz` URLs such as:
|
||||
- `https://download.freebsd.org/releases/amd64/15.0-RELEASE/src.txz`
|
||||
- `https://download.freebsd.org/snapshots/amd64/15.0-STABLE/src.txz`
|
||||
- closure/native metadata now records the declared source explicitly while preserving the current validated `/usr/src` build path
|
||||
|
||||
Current assessment:
|
||||
|
||||
- Phase 16.1 is complete
|
||||
- Fruix can now describe FreeBSD source inputs explicitly, but it does not fetch/materialize them yet
|
||||
- the next step is Phase 16.2:
|
||||
- fetch or materialize declared FreeBSD source inputs under Fruix control and use their stable identity as the next reproducibility boundary
|
||||
|
||||
## 2026-04-01 — Phase 1.1 started: Guile verified on FreeBSD amd64
|
||||
|
||||
Completed work:
|
||||
@@ -2874,3 +2952,808 @@ Next recommended step:
|
||||
1. begin Phase 13.1 by modeling FreeBSD `world` and `kernel` as Fruix-managed build artifacts rather than host-copy packages
|
||||
2. use `/usr/src` as the initial source of truth on the builder side
|
||||
3. target the first bootable replacement for the current host-staged kernel and core runtime path
|
||||
|
||||
## 2026-04-02 — Phase 13.1: modeled native FreeBSD world/kernel artifacts
|
||||
|
||||
Completed work:
|
||||
|
||||
- wrote the Phase 13.1 report:
|
||||
- `docs/reports/phase13-native-base-model-freebsd.md`
|
||||
- added native FreeBSD base package objects in `modules/fruix/packages/freebsd.scm`:
|
||||
- `freebsd-native-kernel`
|
||||
- `freebsd-native-world`
|
||||
- added and exported:
|
||||
- `freebsd-native-build-package?`
|
||||
- encoded the first native build parameters directly in those package definitions, including:
|
||||
- `source-root=/usr/src`
|
||||
- `target=amd64`
|
||||
- `target-arch=amd64`
|
||||
- `kernconf=GENERIC`
|
||||
- make flags:
|
||||
- `__MAKE_CONF=/dev/null`
|
||||
- `SRCCONF=/dev/null`
|
||||
- `SRC_ENV_CONF=/dev/null`
|
||||
- `MK_DEBUG_FILES=no`
|
||||
- `MK_TESTS=no`
|
||||
- the first native world artifact now also carries an explicit runtime-oriented prune list:
|
||||
- `usr/share/doc`
|
||||
- `usr/share/examples`
|
||||
- `usr/share/info`
|
||||
- `usr/share/man`
|
||||
- `usr/tests`
|
||||
- extended `modules/fruix/system/freebsd.scm` so `materialize-freebsd-package` now understands:
|
||||
- `copy-build-system`
|
||||
- `freebsd-world-build-system`
|
||||
- `freebsd-kernel-build-system`
|
||||
- added native-build identity/materialization helpers for:
|
||||
- `/usr/src` source-tree identity
|
||||
- `KERNCONF` path hashing
|
||||
- build-root identity
|
||||
- buildworld/buildkernel stamp handling
|
||||
- staged installworld/installkernel materialization
|
||||
- native build metadata files in store outputs
|
||||
- chose an `mtree`-based `/usr/src` identity for the first native output model using:
|
||||
- `type`
|
||||
- `link`
|
||||
- `size`
|
||||
- `mode`
|
||||
- `sha256digest`
|
||||
- updated closure/image metadata modeling so the system can now distinguish:
|
||||
- `host_base_stores`
|
||||
- `native_base_stores`
|
||||
- `fruix_runtime_stores`
|
||||
- updated profile/tree merging to skip private dotfile metadata from store outputs so native-build metadata does not leak into the merged runtime tree
|
||||
|
||||
Validation:
|
||||
|
||||
- confirmed the updated package/system modules still load after the native build-model additions
|
||||
- confirmed the new native package objects are present and classified as expected:
|
||||
- `freebsd-native-kernel` reports build-system `freebsd-kernel-build-system`
|
||||
- `freebsd-native-build-package? freebsd-native-world` returns `#t`
|
||||
- re-ran the existing host-copy regression check successfully:
|
||||
- `tests/system/run-phase7-system-closure.sh`
|
||||
- workdir: `/tmp/phase13-1-closure-1775164392`
|
||||
- result: `PASS phase7-system-closure`
|
||||
|
||||
Important findings:
|
||||
|
||||
- Fruix now has a real model for FreeBSD base artifacts built from `/usr/src`; the project is no longer limited to describing the FreeBSD base only as host-copy packages
|
||||
- the first native identity story is explicit:
|
||||
- `/usr/src` contributes through an `mtree`-based tree digest
|
||||
- `KERNCONF` contributes through its resolved path hash
|
||||
- selected make/build parameters are part of the manifest too
|
||||
- the repo can now describe a mixed system more honestly by separating:
|
||||
- transitional host-staged base stores
|
||||
- native base stores
|
||||
- Fruix runtime stores
|
||||
|
||||
Current assessment:
|
||||
|
||||
- Phase 13.1 is complete
|
||||
- the next step is no longer architectural guesswork; it is concrete execution of the newly added native package/materialization path
|
||||
|
||||
Next recommended step:
|
||||
|
||||
1. build the first concrete `freebsd-native-kernel` and `freebsd-native-world` outputs from `/usr/src`
|
||||
2. inspect/document their staged contents in `/frx/store`
|
||||
3. then wire a bootable system closure/image around those native outputs
|
||||
|
||||
## 2026-04-03 — Phase 13.2: first native FreeBSD world/kernel outputs built from `/usr/src`
|
||||
|
||||
Completed work:
|
||||
|
||||
- wrote the Phase 13.2 report:
|
||||
- `docs/reports/phase13-native-world-kernel-build-freebsd.md`
|
||||
- exercised the new native build path for real and produced the first concrete store outputs from `/usr/src`:
|
||||
- native kernel output under `/frx/store`
|
||||
- native world output under `/frx/store`
|
||||
- added a dedicated Phase 13.2 template/harness:
|
||||
- `tests/system/phase13-native-base-pid1-operating-system.scm.in`
|
||||
- `tests/system/run-phase13-native-base-build.sh`
|
||||
- fixed the first real native-build failure:
|
||||
- `MAKEOBJDIRPREFIX` cannot be passed as a make command-line variable for this FreeBSD build path
|
||||
- changed the native builder to invoke make as:
|
||||
- `env MAKEOBJDIRPREFIX=... make ...`
|
||||
- fixed a subtle output-identity bug in the first `/usr/src` hash implementation:
|
||||
- the initial `mtree`-based source hash accidentally included unstable header comments such as date/user/machine lines
|
||||
- now strips `# ...` header lines before hashing
|
||||
- this stabilized the source-tree identity and stopped the native output/build-root identity from drifting on each run
|
||||
- verified that native world and kernel now share the same:
|
||||
- `source-tree-sha256`
|
||||
- `build-root`
|
||||
- the first native world split remains intentionally runtime-oriented and prunes at least:
|
||||
- `usr/share/doc`
|
||||
- `usr/share/examples`
|
||||
- `usr/share/info`
|
||||
- `usr/share/man`
|
||||
- `usr/tests`
|
||||
|
||||
Concrete validated outputs:
|
||||
|
||||
- native kernel store path:
|
||||
- `/frx/store/93f35ddcb9a03f63f83c9e8ae29788685d339789da664f881822b4a1914f5ff6-freebsd-native-kernel-15.0-STABLE`
|
||||
- native world store path:
|
||||
- `/frx/store/3f6f7f8c06ed8dad4cae21a1e8ac8ba4823bdb7cf54328c9bbcccaeb858beb77-freebsd-native-world-15.0-STABLE`
|
||||
- shared native build root:
|
||||
- `/var/tmp/fruix-freebsd-native-build-c59b1b8128b305d9bad9cf3d654771c941c4e8b6a2732f6bc959df96d1d32f58`
|
||||
|
||||
Validated native-world contents include at least:
|
||||
|
||||
- `/bin/sh`
|
||||
- `/sbin/init`
|
||||
- `/etc/rc`
|
||||
- `/usr/sbin/sshd`
|
||||
- `/sbin/dhclient`
|
||||
- `/usr/bin/cap_mkdb`
|
||||
- `/usr/sbin/pwd_mkdb`
|
||||
- `/usr/share/locale/C.UTF-8/LC_CTYPE`
|
||||
|
||||
Validated pruned paths are absent from the world output:
|
||||
|
||||
- `/usr/share/man`
|
||||
- `/usr/tests`
|
||||
|
||||
Validation:
|
||||
|
||||
- real native-base `fruix system build` succeeded with an operating-system using:
|
||||
- `freebsd-native-kernel`
|
||||
- `freebsd-native-world`
|
||||
- host-staged `freebsd-bootloader`
|
||||
- `shepherd-pid1`
|
||||
- `tests/system/run-phase13-native-base-build.sh` passes:
|
||||
- workdir: `/tmp/phase13-2-build-1775173551`
|
||||
- result: `PASS phase13-native-base-build`
|
||||
- the harness confirmed:
|
||||
- closure rebuild path reproducibility
|
||||
- native kernel/world store paths exist
|
||||
- native build info files exist
|
||||
- world/kernel source-tree hashes match
|
||||
- world/kernel build roots match
|
||||
- native build logs exist
|
||||
- `native-base-stores` is present in closure metadata
|
||||
- host/native store boundary now looks as expected for this mixed system:
|
||||
- `host_base_store_count=1`
|
||||
- `native_base_store_count=2`
|
||||
|
||||
Important findings:
|
||||
|
||||
- the native build path is now real, not just modeled
|
||||
- the first mixed Phase-13 system boundary is explicit and sensible:
|
||||
- host-staged bootloader only
|
||||
- native kernel + native world
|
||||
- Fruix runtime stores unchanged
|
||||
- the `mtree` preamble bug would have made native output identity drift across runs; fixing it was essential before treating these as reproducible store artifacts
|
||||
- the shared build-root result is important: the kernel/world pair now reuses the same `/usr/src` build state instead of acting like two unrelated builds
|
||||
|
||||
Current assessment:
|
||||
|
||||
- Phase 13.2 is complete
|
||||
- Fruix can now build and stage native FreeBSD base artifacts from `/usr/src` in `/frx/store`
|
||||
- the next step is to boot a system using those native outputs rather than stopping at build-time inspection
|
||||
|
||||
Next recommended step:
|
||||
|
||||
1. wire the image/boot path to use the native kernel/world outputs end-to-end
|
||||
2. validate locally with QEMU/UEFI
|
||||
3. validate on the approved XCP-ng VM and VDI path
|
||||
|
||||
## 2026-04-03 — Phase 13.3: booted Fruix from native FreeBSD kernel/world outputs
|
||||
|
||||
Completed work:
|
||||
|
||||
- wrote the Phase 13.3 report:
|
||||
- `docs/reports/phase13-native-base-boot-freebsd.md`
|
||||
- completed the first end-to-end boot path using native `/usr/src`-built FreeBSD base artifacts in `/frx/store`
|
||||
- fixed the first native-image sizing problem:
|
||||
- the old fixed `root-size=256m` was too small once the image carried a native world
|
||||
- added explicit root filesystem sizing support to the CLI/image path:
|
||||
- `scripts/fruix.scm` now accepts `--root-size SIZE`
|
||||
- image metadata now records `root_size`
|
||||
- `tests/system/run-phase8-system-image.sh` now accepts:
|
||||
- `ROOT_SIZE`
|
||||
and records:
|
||||
- `root_size`
|
||||
- `native_base_store_count`
|
||||
- `native_base_stores`
|
||||
- fixed a follow-up image metadata bug:
|
||||
- `materialize-bhyve-image` now returns:
|
||||
- `native-base-stores`
|
||||
- this removed the `length #f` failure in the native image path
|
||||
- generalized the local PID1 QEMU harness a bit further:
|
||||
- `tests/system/run-phase11-shepherd-pid1-qemu.sh` now accepts `OS_TEMPLATE`
|
||||
- added dedicated Phase 13.3 native-base boot wrappers:
|
||||
- `tests/system/run-phase13-native-base-qemu.sh`
|
||||
- `tests/system/run-phase13-native-base-xcpng.sh`
|
||||
- these wrappers reuse the validated PID1 boot path but additionally require the image metadata to prove the booted system is really using the intended Phase-13 base split:
|
||||
- native kernel present
|
||||
- native world present
|
||||
- host base reduced to bootloader only
|
||||
|
||||
Working native-base boot configuration:
|
||||
|
||||
- local QEMU:
|
||||
- `ROOT_SIZE=6g`
|
||||
- `DISK_CAPACITY=8g`
|
||||
- real XCP-ng:
|
||||
- `ROOT_SIZE=6g`
|
||||
- disk capacity kept matched to the fixed 30 GiB VDI as before
|
||||
|
||||
Validation:
|
||||
|
||||
- local QEMU/UEFI/TCG boot passes through the new wrapper:
|
||||
- `tests/system/run-phase13-native-base-qemu.sh`
|
||||
- workdir: `/tmp/phase13-3-qemu3-1775174863`
|
||||
- result: `PASS phase13-native-base-qemu`
|
||||
- confirmed:
|
||||
- `disk_capacity=8g`
|
||||
- `root_size=6g`
|
||||
- `native_base_store_count=2`
|
||||
- `host_base_store_count=1`
|
||||
- `shepherd_pid=1`
|
||||
- `sshd_status=running`
|
||||
- `native_base_boot=ok`
|
||||
- real XCP-ng boot passes through the new wrapper:
|
||||
- `tests/system/run-phase13-native-base-xcpng.sh`
|
||||
- workdir: `/tmp/phase13-3-xcpng-1775175086`
|
||||
- result: `PASS phase13-native-base-xcpng`
|
||||
- confirmed:
|
||||
- `vm_id=90490f2e-e8fc-4b7a-388e-5c26f0157289`
|
||||
- `vdi_id=0f1f90d3-48ca-4fa2-91d8-fc6339b95743`
|
||||
- `guest_ip=192.168.213.62`
|
||||
- `root_size=6g`
|
||||
- `native_base_store_count=2`
|
||||
- `host_base_store_count=1`
|
||||
- `shepherd_pid=1`
|
||||
- `sshd_status=running`
|
||||
- `compat_prefix_shims=absent`
|
||||
- `guile_module_smoke=ok`
|
||||
- `native_base_boot=ok`
|
||||
- validated native-base closure/image composition now boots with:
|
||||
- native kernel store:
|
||||
- `/frx/store/93f35ddcb9a03f63f83c9e8ae29788685d339789da664f881822b4a1914f5ff6-freebsd-native-kernel-15.0-STABLE`
|
||||
- native world store:
|
||||
- `/frx/store/3f6f7f8c06ed8dad4cae21a1e8ac8ba4823bdb7cf54328c9bbcccaeb858beb77-freebsd-native-world-15.0-STABLE`
|
||||
- remaining host base store:
|
||||
- `/frx/store/8ffcfe0356fea815726b610514a1280a11266851c2acb870047d559795569f0e-freebsd-bootloader-15.0-STABLE`
|
||||
|
||||
Important findings:
|
||||
|
||||
- the native world is large enough that the older 256 MiB rootfs assumption is no longer realistic; explicit image sizing is now part of the practical Phase-13 path
|
||||
- after the native-base transition, the remaining transitional boundary is now much narrower and explicit:
|
||||
- host-staged bootloader/boot assets
|
||||
- native kernel
|
||||
- native core world runtime
|
||||
- the real XCP-ng upload path still works with the larger native-world image, but the dynamic VHD is naturally much bigger now (~4.42 GiB)
|
||||
|
||||
Current assessment:
|
||||
|
||||
- Phase 13 is complete
|
||||
- Fruix now builds FreeBSD kernel/world artifacts from `/usr/src` into `/frx/store` and successfully boots a declarative system from those native outputs
|
||||
- this is the main architectural pivot Plan 3 called for before Phase 14
|
||||
|
||||
Next recommended step:
|
||||
|
||||
1. begin Phase 14 by replacing the remaining host-copy boot assets first
|
||||
2. keep shrinking the host-staged base boundary around the now-working native world/kernel path
|
||||
3. revisit cleaner runtime vs. development splits after the boot asset transition
|
||||
|
||||
## 2026-04-03 — Phase 14.1: removed host-copied boot assets from the validated native boot path
|
||||
|
||||
Completed work:
|
||||
|
||||
- wrote the Phase 14.1 report:
|
||||
- `docs/reports/phase14-native-boot-assets-freebsd.md`
|
||||
- added a dedicated Phase 14.1 native-boot PID1 template:
|
||||
- `tests/system/phase14-native-boot-pid1-operating-system.scm.in`
|
||||
- added dedicated Phase 14.1 validation wrappers:
|
||||
- `tests/system/run-phase14-native-boot-qemu.sh`
|
||||
- `tests/system/run-phase14-native-boot-xcpng.sh`
|
||||
- validated a cleaner native boot path by sourcing boot assets from the existing native world output instead of the host-staged `freebsd-bootloader` package:
|
||||
- `#:kernel freebsd-native-kernel`
|
||||
- `#:bootloader freebsd-native-world`
|
||||
- `#:base-packages (list freebsd-native-world)`
|
||||
- hardened the reusable local PID1 QEMU harness so it no longer boots the raw store image directly read/write from `/frx/store`:
|
||||
- `tests/system/run-phase11-shepherd-pid1-qemu.sh` now copies the generated raw image to:
|
||||
- `boot-disk.img`
|
||||
in the workdir before launching QEMU
|
||||
- this prevents repeated local boots from mutating the supposed store artifact and causing dirty-filesystem follow-up failures
|
||||
|
||||
Validation:
|
||||
|
||||
- local QEMU/UEFI/TCG native-boot wrapper passes:
|
||||
- `tests/system/run-phase14-native-boot-qemu.sh`
|
||||
- workdir: `/tmp/phase14-1-qemu2-1775188371`
|
||||
- result: `PASS phase14-native-boot-qemu`
|
||||
- confirmed:
|
||||
- `native_base_store_count=2`
|
||||
- `host_base_store_count=0`
|
||||
- `shepherd_pid=1`
|
||||
- `sshd_status=running`
|
||||
- `native_boot_assets=freebsd-native-world`
|
||||
- `native_base_boot=ok`
|
||||
- real XCP-ng native-boot wrapper passes:
|
||||
- `tests/system/run-phase14-native-boot-xcpng.sh`
|
||||
- workdir: `/tmp/phase14-1-xcpng-1775188701`
|
||||
- result: `PASS phase14-native-boot-xcpng`
|
||||
- confirmed:
|
||||
- `vm_id=90490f2e-e8fc-4b7a-388e-5c26f0157289`
|
||||
- `vdi_id=0f1f90d3-48ca-4fa2-91d8-fc6339b95743`
|
||||
- `guest_ip=192.168.213.62`
|
||||
- `native_base_store_count=2`
|
||||
- `host_base_store_count=0`
|
||||
- `shepherd_pid=1`
|
||||
- `sshd_status=running`
|
||||
- `compat_prefix_shims=absent`
|
||||
- `guile_module_smoke=ok`
|
||||
- `native_boot_assets=freebsd-native-world`
|
||||
- `native_base_boot=ok`
|
||||
|
||||
Current assessment:
|
||||
|
||||
- Phase 14.1 is complete
|
||||
- the validated native boot path no longer depends on host-copied `/boot/...` material
|
||||
- the current Phase-14.1 native boundary is now fully host-base-free for the validated path:
|
||||
- native kernel
|
||||
- native world supplying boot assets
|
||||
- native world supplying runtime
|
||||
|
||||
Next recommended step:
|
||||
|
||||
1. introduce a clearer native runtime slice so runtime is no longer modeled by reusing the broader native world output for both boot and runtime
|
||||
2. validate that explicit native runtime slice on QEMU and XCP-ng
|
||||
3. then revisit headers/toolchain/development package boundaries
|
||||
|
||||
## 2026-04-03 — Phase 14.2: validated an explicit native FreeBSD runtime slice
|
||||
|
||||
Completed work:
|
||||
|
||||
- wrote the Phase 14.2 report:
|
||||
- `docs/reports/phase14-native-runtime-freebsd.md`
|
||||
- added a new native package in `modules/fruix/packages/freebsd.scm`:
|
||||
- `freebsd-native-runtime`
|
||||
- this runtime slice is built from `/usr/src` through the native world path and now prunes at least:
|
||||
- `boot`
|
||||
- `usr/include`
|
||||
- `usr/share/doc`
|
||||
- `usr/share/examples`
|
||||
- `usr/share/info`
|
||||
- `usr/share/man`
|
||||
- `usr/share/mk`
|
||||
- `usr/tests`
|
||||
- added a dedicated Phase 14.2 operating-system template:
|
||||
- `tests/system/phase14-native-runtime-pid1-operating-system.scm.in`
|
||||
- added dedicated validation wrappers:
|
||||
- `tests/system/run-phase14-native-runtime-qemu.sh`
|
||||
- `tests/system/run-phase14-native-runtime-xcpng.sh`
|
||||
- the validated Phase 14.2 model now uses:
|
||||
- `#:kernel freebsd-native-kernel`
|
||||
- `#:bootloader freebsd-native-world`
|
||||
- `#:base-packages (list freebsd-native-runtime)`
|
||||
- this makes the system composition more explicit:
|
||||
- native world provides boot assets
|
||||
- native runtime provides the guest runtime slice
|
||||
- host base stores remain absent from the validated path
|
||||
|
||||
Important finding:
|
||||
|
||||
- this Phase 14.2 layout still duplicates some content because boot assets still come from the broader native world output while runtime comes from the separate native runtime slice
|
||||
- that made the earlier Phase 13 image sizes too small
|
||||
- the working values are now:
|
||||
- local QEMU:
|
||||
- `DISK_CAPACITY=12g`
|
||||
- `ROOT_SIZE=10g`
|
||||
- real XCP-ng:
|
||||
- `ROOT_SIZE=10g`
|
||||
- disk capacity still matched to the fixed 30 GiB VDI
|
||||
- the new Phase 14.2 wrappers now use those larger defaults
|
||||
|
||||
Validation:
|
||||
|
||||
- local QEMU/UEFI/TCG runtime wrapper passes:
|
||||
- `tests/system/run-phase14-native-runtime-qemu.sh`
|
||||
- workdir: `/tmp/phase14-2-qemu2-1775189802`
|
||||
- result: `PASS phase14-native-runtime-qemu`
|
||||
- confirmed:
|
||||
- `disk_capacity=12g`
|
||||
- `root_size=10g`
|
||||
- `runtime_store=/frx/store/684a82aeed2c9a353e3a09d2cbf5358274d758005e0bfa9b1025d101bc166f79-freebsd-native-runtime-15.0-STABLE`
|
||||
- `native_base_store_count=3`
|
||||
- `host_base_store_count=0`
|
||||
- `shepherd_pid=1`
|
||||
- `sshd_status=running`
|
||||
- `native_runtime_ready=ok`
|
||||
- real XCP-ng runtime wrapper passes:
|
||||
- `tests/system/run-phase14-native-runtime-xcpng.sh`
|
||||
- workdir: `/tmp/phase14-2-xcpng-1775190184`
|
||||
- result: `PASS phase14-native-runtime-xcpng`
|
||||
- confirmed:
|
||||
- `vm_id=90490f2e-e8fc-4b7a-388e-5c26f0157289`
|
||||
- `vdi_id=0f1f90d3-48ca-4fa2-91d8-fc6339b95743`
|
||||
- `guest_ip=192.168.213.62`
|
||||
- `root_size=10g`
|
||||
- `runtime_store=/frx/store/684a82aeed2c9a353e3a09d2cbf5358274d758005e0bfa9b1025d101bc166f79-freebsd-native-runtime-15.0-STABLE`
|
||||
- `native_base_store_count=3`
|
||||
- `host_base_store_count=0`
|
||||
- `shepherd_pid=1`
|
||||
- `sshd_status=running`
|
||||
- `compat_prefix_shims=absent`
|
||||
- `guile_module_smoke=ok`
|
||||
- `native_runtime_ready=ok`
|
||||
- the wrappers also assert the runtime-split boundary directly:
|
||||
- runtime store contains required boot-to-ready files such as:
|
||||
- `/bin/sh`
|
||||
- `/sbin/init`
|
||||
- `/etc/rc`
|
||||
- `/usr/sbin/sshd`
|
||||
- `/sbin/dhclient`
|
||||
- `/usr/bin/ssh-keygen`
|
||||
- `/usr/share/locale/C.UTF-8/LC_CTYPE`
|
||||
- runtime store no longer contains:
|
||||
- `/boot`
|
||||
- `/usr/include`
|
||||
|
||||
Current assessment:
|
||||
|
||||
- Phase 14.2 is complete
|
||||
- the validated Fruix guest now reaches ready state using an explicit native runtime artifact rather than reusing the broad native world output for both boot and runtime roles
|
||||
- the validated path remains host-base-free:
|
||||
- native kernel
|
||||
- native world as the temporary boot-source artifact
|
||||
- native runtime as the guest runtime artifact
|
||||
|
||||
Next recommended step:
|
||||
|
||||
1. define cleaner runtime vs. development boundaries in code/package sets
|
||||
2. introduce a narrower native boot asset package so the broader native world output is no longer needed as the temporary boot-source store
|
||||
3. revalidate the full host-base-free path after that split
|
||||
|
||||
## 2026-04-03 — Phase 14.3: split native FreeBSD boot, runtime, and development artifacts
|
||||
|
||||
Completed work:
|
||||
|
||||
- wrote the Phase 14.3 report:
|
||||
- `docs/reports/phase14-native-splits-freebsd.md`
|
||||
- added new native packages in `modules/fruix/packages/freebsd.scm`:
|
||||
- `freebsd-native-bootloader`
|
||||
- `freebsd-native-headers`
|
||||
- refined `freebsd-native-runtime` into a narrower runtime slice by pruning more obviously non-runtime content, including at least:
|
||||
- `boot`
|
||||
- `rescue`
|
||||
- `usr/include`
|
||||
- `usr/lib/debug`
|
||||
- `usr/lib32`
|
||||
- `usr/obj`
|
||||
- `usr/src`
|
||||
- `usr/share/doc`
|
||||
- `usr/share/examples`
|
||||
- `usr/share/info`
|
||||
- `usr/share/man`
|
||||
- `usr/share/mk`
|
||||
- `usr/tests`
|
||||
- extended the native world-derived build path in `modules/fruix/system/freebsd.scm` with support for:
|
||||
- `keep-paths`
|
||||
- native build manifests/output metadata now record both:
|
||||
- `keep-paths`
|
||||
- `prune-paths`
|
||||
- added explicit native package-set boundaries:
|
||||
- `%freebsd-native-system-packages`
|
||||
- `%freebsd-native-development-profile-packages`
|
||||
- the final validated Phase 14 system template now uses:
|
||||
- `#:kernel freebsd-native-kernel`
|
||||
- `#:bootloader freebsd-native-bootloader`
|
||||
- `#:base-packages %freebsd-native-system-packages`
|
||||
- this removes the need for the broad `freebsd-native-world` artifact from the final validated system closure
|
||||
|
||||
New validation files:
|
||||
|
||||
- `tests/system/phase14-native-split-pid1-operating-system.scm.in`
|
||||
- `tests/system/run-phase14-native-split-qemu.sh`
|
||||
- `tests/system/run-phase14-native-split-xcpng.sh`
|
||||
- `tests/system/run-phase14-native-development-split.sh`
|
||||
|
||||
Validation:
|
||||
|
||||
- development/runtime split harness passes:
|
||||
- `tests/system/run-phase14-native-development-split.sh`
|
||||
- workdir: `/tmp/phase14-3-dev5-1775191195`
|
||||
- result: `PASS phase14-native-development-split`
|
||||
- confirmed:
|
||||
- `bootloader_store=/frx/store/71aa3ba5dd9a02f7d2710bfc3624cbf5e3cd18f1fbff0744c82df36901b10ec0-freebsd-native-bootloader-15.0-STABLE`
|
||||
- `headers_store=/frx/store/aab09122d37962e6d479c17172ce4b8ea85e5ff33c98aa76424ada2fa1a82617-freebsd-native-headers-15.0-STABLE`
|
||||
- `native_system_packages=freebsd-native-runtime`
|
||||
- `native_development_packages=freebsd-native-runtime,freebsd-native-headers,freebsd-clang-toolchain,freebsd-gmake,freebsd-autotools,freebsd-openssl,freebsd-zlib,freebsd-sh,freebsd-bash`
|
||||
- `runtime_vs_development_split=ok`
|
||||
- the harness also confirmed:
|
||||
- bootloader slice contains the expected boot assets only
|
||||
- headers slice contains headers/mk files
|
||||
- headers slice does not contain `/boot` or runtime binaries
|
||||
- final split-system local QEMU validation passes:
|
||||
- `tests/system/run-phase14-native-split-qemu.sh`
|
||||
- workdir: `/tmp/phase14-3-qemu-1775191337`
|
||||
- result: `PASS phase14-native-split-qemu`
|
||||
- confirmed:
|
||||
- `disk_capacity=8g`
|
||||
- `root_size=6g`
|
||||
- `bootloader_store=/frx/store/71aa3ba5dd9a02f7d2710bfc3624cbf5e3cd18f1fbff0744c82df36901b10ec0-freebsd-native-bootloader-15.0-STABLE`
|
||||
- `runtime_store=/frx/store/1b4b8774d0df36df2635fe1c35367a2c5fa7790e303f0aaa26eabfe3cce667f2-freebsd-native-runtime-15.0-STABLE`
|
||||
- `native_base_store_count=3`
|
||||
- `host_base_store_count=0`
|
||||
- `shepherd_pid=1`
|
||||
- `sshd_status=running`
|
||||
- `native_split_boot=ok`
|
||||
- final split-system real XCP-ng validation passes:
|
||||
- `tests/system/run-phase14-native-split-xcpng.sh`
|
||||
- workdir: `/tmp/phase14-3-xcpng-1775191743`
|
||||
- result: `PASS phase14-native-split-xcpng`
|
||||
- confirmed:
|
||||
- `vm_id=90490f2e-e8fc-4b7a-388e-5c26f0157289`
|
||||
- `vdi_id=0f1f90d3-48ca-4fa2-91d8-fc6339b95743`
|
||||
- `guest_ip=192.168.213.62`
|
||||
- `root_size=6g`
|
||||
- `bootloader_store=/frx/store/71aa3ba5dd9a02f7d2710bfc3624cbf5e3cd18f1fbff0744c82df36901b10ec0-freebsd-native-bootloader-15.0-STABLE`
|
||||
- `runtime_store=/frx/store/1b4b8774d0df36df2635fe1c35367a2c5fa7790e303f0aaa26eabfe3cce667f2-freebsd-native-runtime-15.0-STABLE`
|
||||
- `native_base_store_count=3`
|
||||
- `host_base_store_count=0`
|
||||
- `shepherd_pid=1`
|
||||
- `sshd_status=running`
|
||||
- `compat_prefix_shims=absent`
|
||||
- `guile_module_smoke=ok`
|
||||
- `native_split_boot=ok`
|
||||
|
||||
Important findings:
|
||||
|
||||
- after replacing the temporary broad-world boot source with the narrower native bootloader slice and tightening the runtime slice, the validated image became much smaller again
|
||||
- the real XCP-ng dynamic VHD upload for the final split path was:
|
||||
- `1560725504` bytes (~1.45 GiB)
|
||||
- that is far better than the temporary broad-world + runtime duplication in Phase 14.2
|
||||
- the final validated Phase 14 closure no longer needs the broad `freebsd-native-world` artifact in its native base store set
|
||||
|
||||
Current assessment:
|
||||
|
||||
- Phase 14 is complete
|
||||
- Fruix now has a validated, host-base-free FreeBSD system path composed from native artifacts in `/frx/store`:
|
||||
- `freebsd-native-kernel`
|
||||
- `freebsd-native-bootloader`
|
||||
- `freebsd-native-runtime`
|
||||
- the runtime vs. development boundary is also clearer now through:
|
||||
- `freebsd-native-headers`
|
||||
- `%freebsd-native-development-profile-packages`
|
||||
- this completes the Plan-3 Phase-14 goal of incrementally replacing the host-copy FreeBSD base layer for the validated boot/runtime path
|
||||
|
||||
Next recommended step:
|
||||
|
||||
1. begin Phase 15 by making the FreeBSD base version a declarative Fruix input
|
||||
2. demonstrate side-by-side native base versions in `/frx/store`
|
||||
3. validate rebuild/redeploy/rollback across those base versions
|
||||
|
||||
## 2026-04-03 — Phase 15.1: made the FreeBSD base a declarative Fruix input
|
||||
|
||||
Completed work:
|
||||
|
||||
- wrote the Phase 15.1 report:
|
||||
- `docs/reports/phase15-declarative-base-freebsd.md`
|
||||
- added a new declarative base record in `modules/fruix/packages/freebsd.scm`:
|
||||
- `freebsd-base`
|
||||
- `freebsd-base?`
|
||||
- `%default-freebsd-base`
|
||||
- the declarative base now records at least:
|
||||
- `name`
|
||||
- `version-label`
|
||||
- `release`
|
||||
- `branch`
|
||||
- `source-root`
|
||||
- `target`
|
||||
- `target-arch`
|
||||
- `kernconf`
|
||||
- `make-flags`
|
||||
- native FreeBSD package constructors are now parameterized by a declared base:
|
||||
- `freebsd-native-kernel-for`
|
||||
- `freebsd-native-world-for`
|
||||
- `freebsd-native-runtime-for`
|
||||
- `freebsd-native-bootloader-for`
|
||||
- `freebsd-native-headers-for`
|
||||
- `freebsd-native-system-packages-for`
|
||||
- `freebsd-native-development-profile-packages-for`
|
||||
- existing exported native package variables remain available as the `%default-freebsd-base` instances:
|
||||
- `freebsd-native-kernel`
|
||||
- `freebsd-native-world`
|
||||
- `freebsd-native-runtime`
|
||||
- `freebsd-native-bootloader`
|
||||
- `freebsd-native-headers`
|
||||
- added a new operating-system field in `modules/fruix/system/freebsd.scm`:
|
||||
- `#:freebsd-base`
|
||||
- exported accessor: `operating-system-freebsd-base`
|
||||
- the declared base is now recorded in system/image metadata through:
|
||||
- `operating-system-closure-spec`
|
||||
- `operating-system-image-spec`
|
||||
- `metadata/freebsd-base.scm`
|
||||
- `metadata/store-layout.scm`
|
||||
- native build manifests and `.freebsd-native-build-info.scm` now record:
|
||||
- `declared-base`
|
||||
- `scripts/fruix.scm` now emits declared base metadata for `build` and `image`:
|
||||
- `freebsd_base_name`
|
||||
- `freebsd_base_version_label`
|
||||
- `freebsd_base_release`
|
||||
- `freebsd_base_branch`
|
||||
- `freebsd_base_source_root`
|
||||
- `freebsd_base_target`
|
||||
- `freebsd_base_target_arch`
|
||||
- `freebsd_base_kernconf`
|
||||
- `freebsd_base_file`
|
||||
|
||||
New validation files:
|
||||
|
||||
- `tests/system/phase15-declarative-base-pid1-operating-system.scm.in`
|
||||
- `tests/system/run-phase15-declarative-base-build.sh`
|
||||
|
||||
Validation:
|
||||
|
||||
- declarative-base build harness passes:
|
||||
- `tests/system/run-phase15-declarative-base-build.sh`
|
||||
- workdir: `/tmp/phase15-1-build-1775202535`
|
||||
- result: `PASS phase15-declarative-base-build`
|
||||
- confirmed:
|
||||
- `kernel_store=/frx/store/8fcef04c7e507e86ea5e92f251fe3c6ac1aa3bcf4809fa77ddd8b92854bfcde0-freebsd-native-kernel-15.0-STABLE-declarative`
|
||||
- `bootloader_store=/frx/store/7a0ba431e487dc35a8f6318108da16a37c8426c43e77e7a7f91404ba1d980eef-freebsd-native-bootloader-15.0-STABLE-declarative`
|
||||
- `runtime_store=/frx/store/17c24ad20ddcb136c39352b68e758deae0b480258ba0128a5546f696a7eba0a6-freebsd-native-runtime-15.0-STABLE-declarative`
|
||||
- `native_base_store_count=3`
|
||||
- `host_base_store_count=0`
|
||||
- `freebsd_base_name=stable-default`
|
||||
- `freebsd_base_version_label=15.0-STABLE-declarative`
|
||||
- `freebsd_base_release=15.0-STABLE`
|
||||
- `freebsd_base_branch=stable/15`
|
||||
- `freebsd_base_source_root=/usr/src`
|
||||
- `freebsd_base_kernconf=GENERIC`
|
||||
- `declarative_base_input=ok`
|
||||
- the harness also confirmed:
|
||||
- `metadata/freebsd-base.scm` exists
|
||||
- `parameters.scm` records the declared base
|
||||
- `metadata/store-layout.scm` records the declared base
|
||||
- native build info files record the declared base version/branch
|
||||
|
||||
Current assessment:
|
||||
|
||||
- Phase 15.1 is complete
|
||||
- Fruix now models the FreeBSD base as an explicit declarative system input instead of leaving it implicit in the builder host alone
|
||||
- the next step is to use that new declaration to prove side-by-side base versions and rollback-friendly rebuild/redeploy behavior
|
||||
|
||||
## 2026-04-03 — Phase 15.2: validated side-by-side base versions and rollback-friendly redeploy
|
||||
|
||||
Completed work:
|
||||
|
||||
- wrote the Phase 15.2 report:
|
||||
- `docs/reports/phase15-base-upgrades-freebsd.md`
|
||||
- added validation harnesses:
|
||||
- `tests/system/run-phase15-base-coexistence.sh`
|
||||
- `tests/system/run-phase15-base-rollback-qemu.sh`
|
||||
- `tests/system/run-phase15-base-rollback-xcpng.sh`
|
||||
- used two explicit declarative base identities against the current validated native Phase 14 package split:
|
||||
- current base:
|
||||
- `name=stable-default`
|
||||
- `version-label=15.0-STABLE`
|
||||
- `release=15.0-STABLE`
|
||||
- `branch=stable/15`
|
||||
- candidate base:
|
||||
- `name=stable-canary`
|
||||
- `version-label=15.0-STABLE-p1`
|
||||
- `release=15.0-STABLE`
|
||||
- `branch=stable/15`
|
||||
- both declarations still use the same local `/usr/src`, but now produce distinct declared base/store/deployment identities
|
||||
|
||||
Validation:
|
||||
|
||||
- side-by-side base-coexistence harness passes:
|
||||
- `tests/system/run-phase15-base-coexistence.sh`
|
||||
- workdir: `/tmp/phase15-2-coexist-1775202833`
|
||||
- result: `PASS phase15-base-coexistence`
|
||||
- confirmed:
|
||||
- `current_closure=/frx/store/9f57ecc6481e271811ceb53ac21a3b2aef4ef329f82b7d4788622315db1f0e43-fruix-system-fruix-freebsd`
|
||||
- `candidate_closure=/frx/store/dc40b1b7a76084e140d0457f3b7f6c5d4acc185f0d6cee0b161c9775d5fb3bec-fruix-system-fruix-freebsd`
|
||||
- `current_base_version_label=15.0-STABLE`
|
||||
- `candidate_base_version_label=15.0-STABLE-p1`
|
||||
- `side_by_side_base_versions=ok`
|
||||
- `rollback_rebuild_path=ok`
|
||||
- this also confirmed that:
|
||||
- both closures exist side by side in `/frx/store`
|
||||
- rebuilding the current declaration returns the exact original current closure path
|
||||
- current native base stores remain separate from candidate native base stores
|
||||
- local QEMU rollback harness passes:
|
||||
- `tests/system/run-phase15-base-rollback-qemu.sh`
|
||||
- workdir: `/tmp/phase15-2-qemu2-1775204321`
|
||||
- result: `PASS phase15-base-rollback-qemu`
|
||||
- validation sequence:
|
||||
1. boot current base
|
||||
2. boot candidate base
|
||||
3. boot current base again
|
||||
- confirmed:
|
||||
- `current_first_closure=/frx/store/9f57ecc6481e271811ceb53ac21a3b2aef4ef329f82b7d4788622315db1f0e43-fruix-system-fruix-freebsd`
|
||||
- `candidate_closure=/frx/store/dc40b1b7a76084e140d0457f3b7f6c5d4acc185f0d6cee0b161c9775d5fb3bec-fruix-system-fruix-freebsd`
|
||||
- `rollback_closure=/frx/store/9f57ecc6481e271811ceb53ac21a3b2aef4ef329f82b7d4788622315db1f0e43-fruix-system-fruix-freebsd`
|
||||
- `current_base_version_label=15.0-STABLE`
|
||||
- `candidate_base_version_label=15.0-STABLE-p1`
|
||||
- `rollback_base_version_label=15.0-STABLE`
|
||||
- `base_rollforward_and_rollback=ok`
|
||||
- real XCP-ng rollback harness passes:
|
||||
- `tests/system/run-phase15-base-rollback-xcpng.sh`
|
||||
- workdir: `/tmp/phase15-2-xcpng-1775204839`
|
||||
- result: `PASS phase15-base-rollback-xcpng`
|
||||
- validation sequence:
|
||||
1. boot candidate base on the approved VM/VDI
|
||||
2. boot current base again on the same approved VM/VDI
|
||||
- confirmed:
|
||||
- `candidate_closure=/frx/store/dc40b1b7a76084e140d0457f3b7f6c5d4acc185f0d6cee0b161c9775d5fb3bec-fruix-system-fruix-freebsd`
|
||||
- `rollback_closure=/frx/store/9f57ecc6481e271811ceb53ac21a3b2aef4ef329f82b7d4788622315db1f0e43-fruix-system-fruix-freebsd`
|
||||
- `candidate_base_version_label=15.0-STABLE-p1`
|
||||
- `rollback_base_version_label=15.0-STABLE`
|
||||
- `vm_id=90490f2e-e8fc-4b7a-388e-5c26f0157289`
|
||||
- `vdi_id=0f1f90d3-48ca-4fa2-91d8-fc6339b95743`
|
||||
- `base_rollforward_and_rollback=ok`
|
||||
- guest invariants stayed intact for both boots:
|
||||
- `shepherd_pid=1`
|
||||
- `sshd_status=running`
|
||||
- `compat_prefix_shims=absent`
|
||||
- `guile_module_smoke=ok`
|
||||
|
||||
Current assessment:
|
||||
|
||||
- Phase 15.2 is complete
|
||||
- Fruix now supports a real upgrade-style FreeBSD base workflow at the store/deployment level:
|
||||
- explicit current vs. candidate base declarations
|
||||
- side-by-side native base outputs in `/frx/store`
|
||||
- rollback to the earlier closure without mutating it in place
|
||||
- the remaining Phase 15 work is to document the evidence-based decision on whether self-hosted base builds should be the next step, or whether host-built native base artifacts should remain the near-term path while reproducibility/source acquisition improve
|
||||
|
||||
## 2026-04-03 — Phase 15.3: decided not to pursue self-hosted base builds yet
|
||||
|
||||
Completed work:
|
||||
|
||||
- wrote the Phase 15.3 report:
|
||||
- `docs/reports/phase15-self-hosting-decision-freebsd.md`
|
||||
- updated the high-level summary:
|
||||
- `docs/PROG_SUMMARY.md`
|
||||
- recorded an evidence-based decision about the next architecture step after Phases 13–15
|
||||
|
||||
Decision:
|
||||
|
||||
- do **not** pursue self-hosted FreeBSD base builds as the next immediate milestone
|
||||
- keep the near-term path on:
|
||||
1. host-built native FreeBSD base artifacts from `/usr/src`
|
||||
2. storage in `/frx/store`
|
||||
3. stronger declarative source-tree/version selection and provenance
|
||||
4. tighter reproducibility around source inputs and build parameters
|
||||
- only revisit guest self-hosting after those pieces are stronger
|
||||
|
||||
Evidence used for the decision:
|
||||
|
||||
- Fruix already builds native FreeBSD base artifacts from `/usr/src` into `/frx/store`
|
||||
- Fruix already validates a host-base-free boot/runtime path composed from:
|
||||
- `freebsd-native-kernel`
|
||||
- `freebsd-native-bootloader`
|
||||
- `freebsd-native-runtime`
|
||||
- that path already boots on:
|
||||
- local QEMU/UEFI/TCG
|
||||
- the approved real XCP-ng VM/VDI path
|
||||
- the FreeBSD base is now an explicit declarative input through `freebsd-base`
|
||||
- Fruix now supports side-by-side declared base versions and rollback-friendly redeploy
|
||||
- the most important remaining reproducibility gap is now source-tree selection/acquisition, not host-copy boot/runtime assembly
|
||||
- environment constraints still argue for caution before a self-hosting pivot:
|
||||
- local bhyve remains blocked under Xen due to missing nested VT-x exposure
|
||||
- real validation still reuses a single approved XCP-ng VM/VDI pair
|
||||
- XCP-ng storage permissions still prevent creating fresh VDIs on demand
|
||||
|
||||
Current assessment:
|
||||
|
||||
- Phase 15.3 is complete
|
||||
- Phase 15 is fully complete
|
||||
- Fruix now has:
|
||||
- a host-base-free native FreeBSD boot/runtime path in `/frx/store`
|
||||
- an explicit declarative FreeBSD base model
|
||||
- side-by-side base-version coexistence in `/frx/store`
|
||||
- rollback-friendly redeploy across declared base versions
|
||||
- a documented decision to continue with host-built native base artifacts for now rather than jumping immediately to guest self-hosting
|
||||
|
||||
Next recommended step:
|
||||
|
||||
1. focus the next phase on making FreeBSD source-tree selection/acquisition more declarative and reproducible
|
||||
2. keep improving provenance and source-input identity around the now-working native base path
|
||||
3. revisit self-hosted base builds only after the source/reproducibility boundary is substantially stronger
|
||||
|
||||
@@ -17,6 +17,12 @@ Completed milestones include:
|
||||
- `freebsd-init+rc.d-shepherd`
|
||||
- `shepherd-pid1`
|
||||
- **Native runtime cleanup**: removed the guest runtime’s dependence on `/tmp/*-validate-install` compatibility-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/store` for:
|
||||
- `freebsd-native-kernel`
|
||||
- `freebsd-native-bootloader`
|
||||
- `freebsd-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/store` and roll forward / back between them through the normal system deployment flow.
|
||||
|
||||
## Major pain points now behind us
|
||||
|
||||
@@ -30,6 +36,7 @@ Completed milestones include:
|
||||
## 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-shepherd` path and the more Guix-like `shepherd-pid1` path. 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.
|
||||
@@ -37,4 +44,4 @@ Completed milestones include:
|
||||
|
||||
## 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, and operate from `/frx` without depending on temporary runtime-prefix shims. The biggest remaining work is no longer “can this boot?” but “how cleanly and natively can we make the runtime and boot architecture from here?”
|
||||
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?”
|
||||
|
||||
191
docs/reports/phase13-native-base-boot-freebsd.md
Normal file
191
docs/reports/phase13-native-base-boot-freebsd.md
Normal file
@@ -0,0 +1,191 @@
|
||||
# Phase 13.3: booted Fruix using native store-built FreeBSD base artifacts
|
||||
|
||||
Date: 2026-04-03
|
||||
|
||||
## Goal
|
||||
|
||||
Phase 13.3 was the first end-to-end boot validation of the new native FreeBSD base path.
|
||||
|
||||
The target was a Fruix system/image that boots using:
|
||||
|
||||
- native `/usr/src`-built kernel output in `/frx/store`
|
||||
- native `/usr/src`-built world output in `/frx/store`
|
||||
- host-staged bootloader only, as the remaining explicit transitional boundary
|
||||
|
||||
Validation still followed the established strategy:
|
||||
|
||||
- local QEMU/UEFI/TCG
|
||||
- real XCP-ng on the approved VM/VDI path
|
||||
|
||||
## Issues found and fixed
|
||||
|
||||
### 1. The old fixed 256 MiB root filesystem image was too small
|
||||
|
||||
The first native-base image attempt failed during `makefs` with:
|
||||
|
||||
```text
|
||||
size of .../image-rootfs is larger than the maxsize of 268435456
|
||||
```
|
||||
|
||||
That was expected once the image started carrying a native world instead of the earlier curated host-copy runtime slice.
|
||||
|
||||
To fix this cleanly, Fruix image generation gained an explicit root filesystem size parameter:
|
||||
|
||||
- `scripts/fruix.scm` now accepts:
|
||||
- `--root-size SIZE`
|
||||
- image metadata now emits:
|
||||
- `root_size=...`
|
||||
- `tests/system/run-phase8-system-image.sh` now accepts:
|
||||
- `ROOT_SIZE`
|
||||
and records the reported root size in metadata
|
||||
|
||||
For the native-base boot validation, the working values were:
|
||||
|
||||
- local QEMU:
|
||||
- `ROOT_SIZE=6g`
|
||||
- `DISK_CAPACITY=8g`
|
||||
- real XCP-ng:
|
||||
- `ROOT_SIZE=6g`
|
||||
- disk capacity kept matched to the fixed 30 GiB VDI as before
|
||||
|
||||
### 2. `materialize-bhyve-image` needed to propagate native-base metadata
|
||||
|
||||
After adding the new `native_base_*` metadata path, the first native image run hit a Scheme error because `materialize-bhyve-image` still returned:
|
||||
|
||||
- `host-base-stores`
|
||||
- `fruix-runtime-stores`
|
||||
|
||||
but not:
|
||||
|
||||
- `native-base-stores`
|
||||
|
||||
That was corrected so image-generation results now carry the native-base store set too.
|
||||
|
||||
## Harness updates
|
||||
|
||||
### Reused/extended existing Phase 11 boot harnesses
|
||||
|
||||
- `tests/system/run-phase11-shepherd-pid1-qemu.sh`
|
||||
- now accepts `OS_TEMPLATE` like the XCP-ng PID1 harness already did
|
||||
- `tests/system/run-phase8-system-image.sh`
|
||||
- now records:
|
||||
- `native_base_store_count`
|
||||
- `native_base_stores`
|
||||
- `root_size`
|
||||
|
||||
### Added native-base boot wrappers
|
||||
|
||||
New wrappers:
|
||||
|
||||
- `tests/system/run-phase13-native-base-qemu.sh`
|
||||
- `tests/system/run-phase13-native-base-xcpng.sh`
|
||||
|
||||
These wrappers reuse the already-validated PID1 boot path but require the image metadata to confirm that the booted system really uses the intended Phase-13 base split:
|
||||
|
||||
- `native_base_store_count=2`
|
||||
- native kernel present
|
||||
- native world present
|
||||
- `host_base_store_count=1`
|
||||
- host base reduced to bootloader only
|
||||
|
||||
## Validation
|
||||
|
||||
### Local QEMU / UEFI / TCG
|
||||
|
||||
Passing run:
|
||||
|
||||
- `PASS phase13-native-base-qemu`
|
||||
- workdir: `/tmp/phase13-3-qemu3-1775174863`
|
||||
|
||||
Key metadata:
|
||||
|
||||
```text
|
||||
disk_capacity=8g
|
||||
root_size=6g
|
||||
native_base_store_count=2
|
||||
host_base_store_count=1
|
||||
shepherd_pid=1
|
||||
sshd_status=running
|
||||
native_base_boot=ok
|
||||
```
|
||||
|
||||
The wrapped underlying Phase 11 PID1 harness also confirmed the full guest runtime path:
|
||||
|
||||
- ready marker present
|
||||
- `/run/current-system` correct
|
||||
- Shepherd socket present
|
||||
- Shepherd PID is `1`
|
||||
- `sshd` running
|
||||
- activation completed successfully
|
||||
- `/etc/login.conf` regular + databases present
|
||||
|
||||
### Real XCP-ng VM
|
||||
|
||||
Passing run:
|
||||
|
||||
- `PASS phase13-native-base-xcpng`
|
||||
- workdir: `/tmp/phase13-3-xcpng-1775175086`
|
||||
|
||||
Key metadata:
|
||||
|
||||
```text
|
||||
vm_id=90490f2e-e8fc-4b7a-388e-5c26f0157289
|
||||
vdi_id=0f1f90d3-48ca-4fa2-91d8-fc6339b95743
|
||||
guest_ip=192.168.213.62
|
||||
root_size=6g
|
||||
native_base_store_count=2
|
||||
host_base_store_count=1
|
||||
shepherd_pid=1
|
||||
sshd_status=running
|
||||
compat_prefix_shims=absent
|
||||
guile_module_smoke=ok
|
||||
native_base_boot=ok
|
||||
```
|
||||
|
||||
The dynamic VHD upload remained workable even with the larger native-world image payload, though naturally much larger than the earlier minimal image path:
|
||||
|
||||
- upload size: `4740784128` bytes (~4.42 GiB)
|
||||
|
||||
## What booted
|
||||
|
||||
The validated native-base system closure used:
|
||||
|
||||
- native kernel store:
|
||||
- `/frx/store/93f35ddcb9a03f63f83c9e8ae29788685d339789da664f881822b4a1914f5ff6-freebsd-native-kernel-15.0-STABLE`
|
||||
- native world store:
|
||||
- `/frx/store/3f6f7f8c06ed8dad4cae21a1e8ac8ba4823bdb7cf54328c9bbcccaeb858beb77-freebsd-native-world-15.0-STABLE`
|
||||
- remaining host base store:
|
||||
- `/frx/store/8ffcfe0356fea815726b610514a1280a11266851c2acb870047d559795569f0e-freebsd-bootloader-15.0-STABLE`
|
||||
|
||||
That means Phase 13 has now crossed its main success boundary:
|
||||
|
||||
- the kernel is native
|
||||
- the core world runtime is native
|
||||
- the system actually boots from those outputs
|
||||
|
||||
## Assessment
|
||||
|
||||
Phase 13 is complete.
|
||||
|
||||
Fruix has now moved from:
|
||||
|
||||
- building a FreeBSD system from curated host copies
|
||||
|
||||
into:
|
||||
|
||||
- building kernel/world artifacts from `/usr/src` into `/frx/store`, then booting a declarative Fruix system from those outputs.
|
||||
|
||||
The remaining major transitional boundary is now much narrower and explicit:
|
||||
|
||||
- host-staged bootloader/boot assets remain
|
||||
- native kernel + native core world runtime are already in place
|
||||
|
||||
That is a real architectural shift, not just more documentation.
|
||||
|
||||
## Next recommended step
|
||||
|
||||
Proceed to Phase 14:
|
||||
|
||||
1. replace the remaining host-copy boot assets first
|
||||
2. then keep reducing the older host-staged FreeBSD base slice around the now-working native world/kernel path
|
||||
3. revisit cleaner runtime vs. development splits once the boot asset transition is done
|
||||
144
docs/reports/phase13-native-base-model-freebsd.md
Normal file
144
docs/reports/phase13-native-base-model-freebsd.md
Normal file
@@ -0,0 +1,144 @@
|
||||
# Phase 13.1: model FreeBSD world and kernel as native Fruix build artifacts
|
||||
|
||||
Date: 2026-04-02
|
||||
|
||||
## Goal
|
||||
|
||||
Phase 13 begins the Option B pivot from host-copy FreeBSD base packages toward builder-produced FreeBSD base artifacts in `/frx/store`.
|
||||
|
||||
This first subphase focused on the modeling and package/materialization layer:
|
||||
|
||||
- define native Fruix package objects for FreeBSD kernel and world outputs
|
||||
- make their output identity depend on `/usr/src` and explicit build parameters
|
||||
- teach the system metadata to distinguish host-staged base stores from native base stores
|
||||
|
||||
The purpose of this step was not yet to prove a full boot from those new outputs. It was to land the description and materialization model that Phase 13.2 can exercise concretely.
|
||||
|
||||
## Implementation
|
||||
|
||||
### 1. Added native package definitions in `modules/fruix/packages/freebsd.scm`
|
||||
|
||||
New package objects:
|
||||
|
||||
- `freebsd-native-kernel`
|
||||
- `freebsd-native-world`
|
||||
|
||||
New predicate:
|
||||
|
||||
- `freebsd-native-build-package?`
|
||||
|
||||
The native packages are intentionally FreeBSD-specific and currently parameterized with:
|
||||
|
||||
- `source-root` => `/usr/src`
|
||||
- `target` => `amd64`
|
||||
- `target-arch` => `amd64`
|
||||
- `kernconf` => `GENERIC`
|
||||
- `make-flags` =>
|
||||
- `__MAKE_CONF=/dev/null`
|
||||
- `SRCCONF=/dev/null`
|
||||
- `SRC_ENV_CONF=/dev/null`
|
||||
- `MK_DEBUG_FILES=no`
|
||||
- `MK_TESTS=no`
|
||||
|
||||
The first native world artifact also carries an explicit runtime-oriented prune list:
|
||||
|
||||
- `usr/share/doc`
|
||||
- `usr/share/examples`
|
||||
- `usr/share/info`
|
||||
- `usr/share/man`
|
||||
- `usr/tests`
|
||||
|
||||
That keeps the first native world target narrower and aligned with the current boot/runtime goal.
|
||||
|
||||
### 2. Added native build-system support in `modules/fruix/system/freebsd.scm`
|
||||
|
||||
`materialize-freebsd-package` now understands three classes of package build system:
|
||||
|
||||
- `copy-build-system`
|
||||
- `freebsd-world-build-system`
|
||||
- `freebsd-kernel-build-system`
|
||||
|
||||
For the native FreeBSD path, the materializer now records identity from:
|
||||
|
||||
- `/usr/src`
|
||||
- explicit build parameters
|
||||
- the selected kernel configuration
|
||||
|
||||
The `/usr/src` source identity is currently represented by an `mtree`-based tree digest using:
|
||||
|
||||
- `type`
|
||||
- `link`
|
||||
- `size`
|
||||
- `mode`
|
||||
- `sha256digest`
|
||||
|
||||
The kernel configuration is also hashed explicitly via its resolved `KERNCONF` path.
|
||||
|
||||
The code now has dedicated helpers for:
|
||||
|
||||
- native source identity
|
||||
- native build-root identity
|
||||
- buildworld/buildkernel stamp handling
|
||||
- staged installworld/installkernel materialization
|
||||
- writing native build metadata beside the resulting store outputs
|
||||
|
||||
### 3. Store-layout metadata now separates native and host-staged base stores
|
||||
|
||||
The closure metadata and CLI metadata now distinguish:
|
||||
|
||||
- `host_base_stores`
|
||||
- `native_base_stores`
|
||||
- `fruix_runtime_stores`
|
||||
|
||||
This is important for the architecture transition: a system can now say explicitly which parts of its FreeBSD base still come from transitional host-copy packages and which parts come from native `/usr/src`-driven artifacts.
|
||||
|
||||
### 4. Merged output trees now skip private dotfile metadata
|
||||
|
||||
The profile/tree merge logic now ignores private dotfile metadata in store outputs. This keeps internal build metadata files from leaking into the merged runtime tree when native base outputs start being consumed by real system closures.
|
||||
|
||||
## Validation
|
||||
|
||||
### Package/model load
|
||||
|
||||
Verified that the package/system modules still load after the native build-model additions, and that the new native package objects are present.
|
||||
|
||||
Observed output included:
|
||||
|
||||
```text
|
||||
freebsd-kernel-build-system
|
||||
#t
|
||||
```
|
||||
|
||||
for:
|
||||
|
||||
- `freebsd-native-kernel` build-system lookup
|
||||
- `freebsd-native-build-package? freebsd-native-world`
|
||||
|
||||
### Existing closure path regression check
|
||||
|
||||
To make sure the modeling work did not break the already validated host-copy path, re-ran:
|
||||
|
||||
- `tests/system/run-phase7-system-closure.sh`
|
||||
|
||||
Passing run:
|
||||
|
||||
- `PASS phase7-system-closure`
|
||||
- workdir: `/tmp/phase13-1-closure-1775164392`
|
||||
|
||||
This confirmed that the existing FreeBSD system closure path still works while the new native base model is being introduced.
|
||||
|
||||
## Assessment
|
||||
|
||||
Phase 13.1 is complete.
|
||||
|
||||
Fruix now has a real representation for native FreeBSD base artifacts in its package/materialization model rather than only the older host-copy package set. Just as importantly, the output identity story is no longer purely implicit: `/usr/src`, `KERNCONF`, and the selected build parameters are now part of the native artifact definition.
|
||||
|
||||
This is the necessary bridge into Phase 13.2, where those new package definitions need to be exercised to produce concrete kernel/world outputs in `/frx/store`.
|
||||
|
||||
## Next recommended step
|
||||
|
||||
Proceed to Phase 13.2:
|
||||
|
||||
- build the first concrete `freebsd-native-kernel` and `freebsd-native-world` outputs from `/usr/src`
|
||||
- inspect their staged contents in `/frx/store`
|
||||
- document the exact split that the first native runtime target provides
|
||||
176
docs/reports/phase13-native-world-kernel-build-freebsd.md
Normal file
176
docs/reports/phase13-native-world-kernel-build-freebsd.md
Normal file
@@ -0,0 +1,176 @@
|
||||
# Phase 13.2: built the first native FreeBSD world and kernel artifacts from `/usr/src`
|
||||
|
||||
Date: 2026-04-03
|
||||
|
||||
## Goal
|
||||
|
||||
After Phase 13.1 introduced native Fruix package/materialization support for FreeBSD base artifacts, the next step was to exercise that path for real:
|
||||
|
||||
- build a kernel from `/usr/src`
|
||||
- build and stage a minimal runtime-oriented world from `/usr/src`
|
||||
- place both outputs under `/frx/store`
|
||||
- document the exact split of this first native base target
|
||||
|
||||
## Implementation
|
||||
|
||||
### 1. Fixed two important builder issues found during the first real run
|
||||
|
||||
#### `MAKEOBJDIRPREFIX` had to move to the environment
|
||||
|
||||
The first real `buildworld` attempt failed with:
|
||||
|
||||
```text
|
||||
MAKEOBJDIRPREFIX can only be set in environment or src-env.conf(5)
|
||||
```
|
||||
|
||||
The native build path originally passed `MAKEOBJDIRPREFIX=...` as a make command-line variable. That was corrected so the generated build command now uses:
|
||||
|
||||
- `env MAKEOBJDIRPREFIX=... make ...`
|
||||
|
||||
instead.
|
||||
|
||||
#### The initial `/usr/src` tree hash was accidentally unstable
|
||||
|
||||
The first source-tree hashing attempt hashed the raw `mtree -c` output. That was subtly wrong because `mtree` includes header comments such as:
|
||||
|
||||
- date
|
||||
- user
|
||||
- machine
|
||||
- tree path banner
|
||||
|
||||
As a result, successive hash computations differed even when `/usr/src` had not changed.
|
||||
|
||||
This was corrected by stripping the leading `# ...` comment lines before hashing the `mtree` content. After that fix:
|
||||
|
||||
- native world and native kernel reported the same `source-tree-sha256`
|
||||
- both reused the same native build root
|
||||
- output identity stopped drifting on each run
|
||||
|
||||
## First concrete native outputs
|
||||
|
||||
A native Fruix system definition using:
|
||||
|
||||
- `freebsd-native-kernel`
|
||||
- `freebsd-native-world`
|
||||
- host-staged `freebsd-bootloader`
|
||||
- `shepherd-pid1`
|
||||
|
||||
was built successfully.
|
||||
|
||||
Resulting store outputs:
|
||||
|
||||
- kernel:
|
||||
- `/frx/store/93f35ddcb9a03f63f83c9e8ae29788685d339789da664f881822b4a1914f5ff6-freebsd-native-kernel-15.0-STABLE`
|
||||
- world:
|
||||
- `/frx/store/3f6f7f8c06ed8dad4cae21a1e8ac8ba4823bdb7cf54328c9bbcccaeb858beb77-freebsd-native-world-15.0-STABLE`
|
||||
|
||||
Native build metadata records for both outputs show:
|
||||
|
||||
- `source-root=/usr/src`
|
||||
- the same `source-tree-sha256`
|
||||
- `kernconf=GENERIC`
|
||||
- the same shared `build-root`
|
||||
|
||||
Shared build root:
|
||||
|
||||
- `/var/tmp/fruix-freebsd-native-build-c59b1b8128b305d9bad9cf3d654771c941c4e8b6a2732f6bc959df96d1d32f58`
|
||||
|
||||
Key log files recorded in the output metadata:
|
||||
|
||||
- `buildworld.log`
|
||||
- `buildkernel-GENERIC.log`
|
||||
- `install-freebsd-native-world.log`
|
||||
- `install-freebsd-native-kernel.log`
|
||||
|
||||
## First native world split
|
||||
|
||||
The first `freebsd-native-world` output is intentionally runtime-oriented. Validation confirmed that it contains the core pieces needed by the existing Fruix guest model, including:
|
||||
|
||||
- `/bin/sh`
|
||||
- `/sbin/init`
|
||||
- `/etc/rc`
|
||||
- `/usr/sbin/sshd`
|
||||
- `/sbin/dhclient`
|
||||
- `/usr/bin/cap_mkdb`
|
||||
- `/usr/sbin/pwd_mkdb`
|
||||
- `/usr/share/locale/C.UTF-8/LC_CTYPE`
|
||||
|
||||
The first prune list is also active. Validation confirmed the world output does **not** contain:
|
||||
|
||||
- `/usr/share/man`
|
||||
- `/usr/tests`
|
||||
|
||||
This keeps the first native world output closer to the current boot/runtime target instead of a fully unpruned base install tree.
|
||||
|
||||
## Store-boundary result
|
||||
|
||||
The generated closure metadata now shows the intended transitional boundary clearly:
|
||||
|
||||
- `host_base_store_count=1`
|
||||
- `host_base_stores=` bootloader only
|
||||
- `native_base_store_count=2`
|
||||
- `native_base_stores=` native kernel + native world
|
||||
|
||||
That means Fruix now has a mixed but explicit Phase-13 system boundary:
|
||||
|
||||
- bootloader still comes from the old host-staged path
|
||||
- kernel and core runtime world now come from native `/usr/src`-built store outputs
|
||||
|
||||
## Validation
|
||||
|
||||
### Direct build through `fruix system build`
|
||||
|
||||
A real native-base system build succeeded and produced:
|
||||
|
||||
- native kernel store output
|
||||
- native world store output
|
||||
- a system closure referencing those outputs
|
||||
|
||||
### Dedicated Phase 13.2 harness
|
||||
|
||||
Added:
|
||||
|
||||
- `tests/system/phase13-native-base-pid1-operating-system.scm.in`
|
||||
- `tests/system/run-phase13-native-base-build.sh`
|
||||
|
||||
Passing run:
|
||||
|
||||
- `PASS phase13-native-base-build`
|
||||
- workdir: `/tmp/phase13-2-build-1775173551`
|
||||
|
||||
Key metadata from that run:
|
||||
|
||||
```text
|
||||
kernel_store=/frx/store/93f35ddcb9a03f63f83c9e8ae29788685d339789da664f881822b4a1914f5ff6-freebsd-native-kernel-15.0-STABLE
|
||||
world_store=/frx/store/3f6f7f8c06ed8dad4cae21a1e8ac8ba4823bdb7cf54328c9bbcccaeb858beb77-freebsd-native-world-15.0-STABLE
|
||||
host_base_store_count=1
|
||||
native_base_store_count=2
|
||||
world_source_tree_sha256=72a451e2ea47c4c4777035f797dc35f8d905eaabb2a717bc1fd71019f3021f72
|
||||
kernel_source_tree_sha256=72a451e2ea47c4c4777035f797dc35f8d905eaabb2a717bc1fd71019f3021f72
|
||||
world_build_root=/var/tmp/fruix-freebsd-native-build-c59b1b8128b305d9bad9cf3d654771c941c4e8b6a2732f6bc959df96d1d32f58
|
||||
kernel_build_root=/var/tmp/fruix-freebsd-native-build-c59b1b8128b305d9bad9cf3d654771c941c4e8b6a2732f6bc959df96d1d32f58
|
||||
```
|
||||
|
||||
The harness also verified:
|
||||
|
||||
- closure rebuild path reproducibility
|
||||
- existence of required kernel/world runtime files
|
||||
- absence of the pruned world paths
|
||||
- presence of native build metadata and logs
|
||||
- presence of `native-base-stores` in closure store-layout metadata
|
||||
|
||||
## Assessment
|
||||
|
||||
Phase 13.2 is complete.
|
||||
|
||||
Fruix now does more than describe native FreeBSD base artifacts: it actually builds them from `/usr/src`, stores them under `/frx/store`, and records enough metadata to inspect how they were produced.
|
||||
|
||||
This is the first point where Fruix can honestly say that part of the FreeBSD base is no longer just a curated copy of the builder host.
|
||||
|
||||
## Next recommended step
|
||||
|
||||
Proceed to Phase 13.3:
|
||||
|
||||
- wire the operating-system/image path to boot using these native kernel/world outputs
|
||||
- validate locally with QEMU/UEFI
|
||||
- validate on the approved XCP-ng VM/VDI path
|
||||
126
docs/reports/phase14-native-boot-assets-freebsd.md
Normal file
126
docs/reports/phase14-native-boot-assets-freebsd.md
Normal file
@@ -0,0 +1,126 @@
|
||||
# Phase 14.1: validated native FreeBSD boot assets without host-copied `/boot`
|
||||
|
||||
Date: 2026-04-03
|
||||
|
||||
## Goal
|
||||
|
||||
The goal of Phase 14.1 was to stop relying on the host-staged `freebsd-bootloader` package for the validated boot path.
|
||||
|
||||
Phase 13 had already proved that Fruix could boot with:
|
||||
|
||||
- native kernel
|
||||
- native world
|
||||
- host-staged bootloader only
|
||||
|
||||
Phase 14.1 moved the remaining boot assets onto the native side as well.
|
||||
|
||||
## Approach
|
||||
|
||||
Before introducing a cleaner package split, Fruix first reused the already-built native world output as the source of boot assets.
|
||||
|
||||
The Phase 14.1 operating-system template now uses:
|
||||
|
||||
- `#:kernel freebsd-native-kernel`
|
||||
- `#:bootloader freebsd-native-world`
|
||||
- `#:base-packages (list freebsd-native-world)`
|
||||
|
||||
That means the validated image now gets both:
|
||||
|
||||
- runtime files
|
||||
- loader/boot assets
|
||||
|
||||
from the native `/usr/src`-built world output already staged in `/frx/store`.
|
||||
|
||||
This is slightly redundant at the model layer, but it is a clean way to prove the architectural point first:
|
||||
|
||||
- the boot path no longer needs host-copied `/boot/...` material
|
||||
|
||||
## Additional QEMU harness fix
|
||||
|
||||
During repeated local validation, the existing QEMU PID1 harness was found to boot the raw store image directly from `/frx/store`.
|
||||
|
||||
That meant each local boot mutated the supposedly immutable image artifact and could leave the filesystem dirty for later runs.
|
||||
|
||||
To avoid that, `tests/system/run-phase11-shepherd-pid1-qemu.sh` now copies the built raw image to a temporary writable workdir file before launching QEMU:
|
||||
|
||||
- source image remains in `/frx/store`
|
||||
- QEMU now writes to `boot-disk.img` in the workdir
|
||||
|
||||
This keeps the store image stable across repeated local boots.
|
||||
|
||||
## New files
|
||||
|
||||
Added:
|
||||
|
||||
- `tests/system/phase14-native-boot-pid1-operating-system.scm.in`
|
||||
- `tests/system/run-phase14-native-boot-qemu.sh`
|
||||
- `tests/system/run-phase14-native-boot-xcpng.sh`
|
||||
|
||||
These wrappers reuse the proven PID1 boot harnesses and assert the new boundary:
|
||||
|
||||
- `host_base_store_count=0`
|
||||
- native kernel present
|
||||
- native world present
|
||||
- boot assets come from native world
|
||||
|
||||
## Validation
|
||||
|
||||
### Local QEMU / UEFI / TCG
|
||||
|
||||
Passing run:
|
||||
|
||||
- `PASS phase14-native-boot-qemu`
|
||||
- workdir: `/tmp/phase14-1-qemu2-1775188371`
|
||||
|
||||
Confirmed:
|
||||
|
||||
```text
|
||||
native_base_store_count=2
|
||||
host_base_store_count=0
|
||||
shepherd_pid=1
|
||||
sshd_status=running
|
||||
native_boot_assets=freebsd-native-world
|
||||
native_base_boot=ok
|
||||
```
|
||||
|
||||
### Real XCP-ng VM
|
||||
|
||||
Passing run:
|
||||
|
||||
- `PASS phase14-native-boot-xcpng`
|
||||
- workdir: `/tmp/phase14-1-xcpng-1775188701`
|
||||
|
||||
Confirmed:
|
||||
|
||||
```text
|
||||
vm_id=90490f2e-e8fc-4b7a-388e-5c26f0157289
|
||||
vdi_id=0f1f90d3-48ca-4fa2-91d8-fc6339b95743
|
||||
guest_ip=192.168.213.62
|
||||
native_base_store_count=2
|
||||
host_base_store_count=0
|
||||
shepherd_pid=1
|
||||
sshd_status=running
|
||||
compat_prefix_shims=absent
|
||||
guile_module_smoke=ok
|
||||
native_boot_assets=freebsd-native-world
|
||||
native_base_boot=ok
|
||||
```
|
||||
|
||||
## Result
|
||||
|
||||
Phase 14.1 is complete.
|
||||
|
||||
For the validated boot path, Fruix no longer depends on a host-copied `freebsd-bootloader` store item.
|
||||
|
||||
The currently validated native boot boundary is now:
|
||||
|
||||
- native kernel
|
||||
- native world providing boot assets
|
||||
- native world providing runtime
|
||||
- Fruix runtime stores for Guile/Shepherd
|
||||
|
||||
That is already enough to say the image no longer relies on host-copied kernel/boot material.
|
||||
|
||||
## Next step
|
||||
|
||||
Phase 14.2 should remove the remaining model redundancy by introducing a clearer native runtime slice, so the booted guest reaches ready state using an explicit native runtime output rather than reusing the broader native world output for both boot and runtime roles.
|
||||
139
docs/reports/phase14-native-runtime-freebsd.md
Normal file
139
docs/reports/phase14-native-runtime-freebsd.md
Normal file
@@ -0,0 +1,139 @@
|
||||
# Phase 14.2: validated an explicit native FreeBSD runtime slice
|
||||
|
||||
Date: 2026-04-03
|
||||
|
||||
## Goal
|
||||
|
||||
Phase 14.1 proved that Fruix could boot without host-copied `/boot` material by sourcing boot assets from the existing native world output.
|
||||
|
||||
Phase 14.2 removed the remaining model ambiguity on the runtime side:
|
||||
|
||||
- the guest should now boot and reach ready state using an explicit native runtime output
|
||||
- not by reusing the broader native world artifact for both boot and runtime roles
|
||||
|
||||
## Changes
|
||||
|
||||
Added a new native package:
|
||||
|
||||
- `freebsd-native-runtime`
|
||||
|
||||
This package is built from `/usr/src` via the existing native world build path and prunes at least:
|
||||
|
||||
- `boot`
|
||||
- `usr/include`
|
||||
- `usr/share/doc`
|
||||
- `usr/share/examples`
|
||||
- `usr/share/info`
|
||||
- `usr/share/man`
|
||||
- `usr/share/mk`
|
||||
- `usr/tests`
|
||||
|
||||
The validated Phase 14.2 operating-system template now uses:
|
||||
|
||||
- `#:kernel freebsd-native-kernel`
|
||||
- `#:bootloader freebsd-native-world`
|
||||
- `#:base-packages (list freebsd-native-runtime)`
|
||||
|
||||
That means the model is now explicit:
|
||||
|
||||
- native world provides boot assets
|
||||
- native runtime provides the guest runtime slice
|
||||
- host base stores are no longer part of the validated path
|
||||
|
||||
## Practical sizing finding
|
||||
|
||||
This Phase 14.2 layout still duplicates some native world/runtime content in the closure because the boot assets still come from the broader native world output.
|
||||
|
||||
As a result, the Phase 13 image sizes were no longer large enough.
|
||||
|
||||
Working values were:
|
||||
|
||||
- local QEMU:
|
||||
- `DISK_CAPACITY=12g`
|
||||
- `ROOT_SIZE=10g`
|
||||
- real XCP-ng:
|
||||
- `ROOT_SIZE=10g`
|
||||
- disk capacity still matched to the fixed 30 GiB VDI
|
||||
|
||||
The wrappers were updated to use those larger defaults.
|
||||
|
||||
This is acceptable for Phase 14.2 because the next subphase is specifically about cleaning up the runtime/development/boot boundary further.
|
||||
|
||||
## New files
|
||||
|
||||
Added:
|
||||
|
||||
- `tests/system/phase14-native-runtime-pid1-operating-system.scm.in`
|
||||
- `tests/system/run-phase14-native-runtime-qemu.sh`
|
||||
- `tests/system/run-phase14-native-runtime-xcpng.sh`
|
||||
|
||||
These wrappers assert:
|
||||
|
||||
- `host_base_store_count=0`
|
||||
- native kernel present
|
||||
- native world present as the current boot-source artifact
|
||||
- native runtime present
|
||||
- runtime store still contains the files needed for boot-to-ready
|
||||
- runtime store no longer contains `/boot`
|
||||
- runtime store no longer contains `/usr/include`
|
||||
|
||||
## Validation
|
||||
|
||||
### Local QEMU / UEFI / TCG
|
||||
|
||||
Passing run:
|
||||
|
||||
- `PASS phase14-native-runtime-qemu`
|
||||
- workdir: `/tmp/phase14-2-qemu2-1775189802`
|
||||
|
||||
Confirmed:
|
||||
|
||||
```text
|
||||
disk_capacity=12g
|
||||
root_size=10g
|
||||
runtime_store=/frx/store/684a82aeed2c9a353e3a09d2cbf5358274d758005e0bfa9b1025d101bc166f79-freebsd-native-runtime-15.0-STABLE
|
||||
native_base_store_count=3
|
||||
host_base_store_count=0
|
||||
shepherd_pid=1
|
||||
sshd_status=running
|
||||
native_runtime_ready=ok
|
||||
```
|
||||
|
||||
### Real XCP-ng VM
|
||||
|
||||
Passing run:
|
||||
|
||||
- `PASS phase14-native-runtime-xcpng`
|
||||
- workdir: `/tmp/phase14-2-xcpng-1775190184`
|
||||
|
||||
Confirmed:
|
||||
|
||||
```text
|
||||
vm_id=90490f2e-e8fc-4b7a-388e-5c26f0157289
|
||||
vdi_id=0f1f90d3-48ca-4fa2-91d8-fc6339b95743
|
||||
guest_ip=192.168.213.62
|
||||
root_size=10g
|
||||
runtime_store=/frx/store/684a82aeed2c9a353e3a09d2cbf5358274d758005e0bfa9b1025d101bc166f79-freebsd-native-runtime-15.0-STABLE
|
||||
native_base_store_count=3
|
||||
host_base_store_count=0
|
||||
shepherd_pid=1
|
||||
sshd_status=running
|
||||
compat_prefix_shims=absent
|
||||
guile_module_smoke=ok
|
||||
native_runtime_ready=ok
|
||||
```
|
||||
|
||||
## Result
|
||||
|
||||
Phase 14.2 is complete.
|
||||
|
||||
The validated Fruix guest now reaches ready state using an explicit native runtime artifact:
|
||||
|
||||
- native kernel
|
||||
- native world for boot assets
|
||||
- native runtime for the guest runtime slice
|
||||
- no host-staged FreeBSD base stores in the validated path
|
||||
|
||||
## Next step
|
||||
|
||||
Phase 14.3 should clean up the remaining redundancy by defining clearer runtime vs. development boundaries and, ideally, replacing the temporary use of the broad native world artifact as the boot-source package with a narrower native boot asset package.
|
||||
225
docs/reports/phase14-native-splits-freebsd.md
Normal file
225
docs/reports/phase14-native-splits-freebsd.md
Normal file
@@ -0,0 +1,225 @@
|
||||
# Phase 14.3: split native FreeBSD boot, runtime, and development artifacts
|
||||
|
||||
Date: 2026-04-03
|
||||
|
||||
## Goal
|
||||
|
||||
Phase 14.3 finished the Phase 14 cleanup work by replacing the temporary broad-world reuse with narrower native artifacts and by making the runtime/development boundary explicit in code.
|
||||
|
||||
The target was:
|
||||
|
||||
- no host-staged FreeBSD base stores in the validated path
|
||||
- no need to keep the broad `freebsd-native-world` artifact in the final validated system closure
|
||||
- explicit native boot and runtime slices
|
||||
- clearer development-profile boundaries
|
||||
|
||||
## Implementation
|
||||
|
||||
### New native packages
|
||||
|
||||
Added in `modules/fruix/packages/freebsd.scm`:
|
||||
|
||||
- `freebsd-native-bootloader`
|
||||
- `freebsd-native-headers`
|
||||
|
||||
Also refined:
|
||||
|
||||
- `freebsd-native-runtime`
|
||||
|
||||
### Narrower native runtime slice
|
||||
|
||||
`freebsd-native-runtime` now prunes more obviously non-runtime content, including at least:
|
||||
|
||||
- `boot`
|
||||
- `rescue`
|
||||
- `usr/include`
|
||||
- `usr/lib/debug`
|
||||
- `usr/lib32`
|
||||
- `usr/obj`
|
||||
- `usr/src`
|
||||
- `usr/share/doc`
|
||||
- `usr/share/examples`
|
||||
- `usr/share/info`
|
||||
- `usr/share/man`
|
||||
- `usr/share/mk`
|
||||
- `usr/tests`
|
||||
|
||||
This shrank the runtime output substantially and made the runtime/development distinction much cleaner.
|
||||
|
||||
### Native bootloader slice
|
||||
|
||||
`freebsd-native-bootloader` is now a native world-derived slice that keeps only the validated boot assets Fruix currently needs:
|
||||
|
||||
- `boot/loader`
|
||||
- `boot/loader.efi`
|
||||
- `boot/device.hints`
|
||||
- `boot/defaults`
|
||||
- `boot/lua`
|
||||
|
||||
### Native headers slice
|
||||
|
||||
`freebsd-native-headers` now captures the development-facing header/mk boundary explicitly:
|
||||
|
||||
- `usr/include`
|
||||
- `usr/share/mk`
|
||||
|
||||
### Build-system support for sliced native outputs
|
||||
|
||||
`modules/fruix/system/freebsd.scm` gained support for `keep-paths` on native world-derived packages.
|
||||
|
||||
That means a native package can now:
|
||||
|
||||
- install full world/distribution into a staging tree
|
||||
- keep only selected subtrees/files for its final store output
|
||||
- still participate in the same `/usr/src`-based identity/build-root story
|
||||
|
||||
Native output metadata now records both:
|
||||
|
||||
- `keep-paths`
|
||||
- `prune-paths`
|
||||
|
||||
## New package-set boundaries
|
||||
|
||||
Added explicit package sets:
|
||||
|
||||
- `%freebsd-native-system-packages`
|
||||
- currently centered on `freebsd-native-runtime`
|
||||
- `%freebsd-native-development-profile-packages`
|
||||
- `freebsd-native-runtime`
|
||||
- `freebsd-native-headers`
|
||||
- explicit toolchain/dev helpers that remain separate artifacts
|
||||
|
||||
This makes the boundary clearer:
|
||||
|
||||
- runtime world output
|
||||
- headers artifact
|
||||
- toolchain artifact(s)
|
||||
- optional development profile composition
|
||||
|
||||
## Final validated Phase 14 system model
|
||||
|
||||
The final Phase 14 PID1 system template now uses:
|
||||
|
||||
- `#:kernel freebsd-native-kernel`
|
||||
- `#:bootloader freebsd-native-bootloader`
|
||||
- `#:base-packages %freebsd-native-system-packages`
|
||||
|
||||
That means the validated system closure now contains:
|
||||
|
||||
- native kernel
|
||||
- native bootloader slice
|
||||
- native runtime slice
|
||||
- Fruix runtime stores
|
||||
|
||||
and no longer needs the broad `freebsd-native-world` artifact in the final system closure.
|
||||
|
||||
## New files
|
||||
|
||||
Added:
|
||||
|
||||
- `tests/system/phase14-native-split-pid1-operating-system.scm.in`
|
||||
- `tests/system/run-phase14-native-split-qemu.sh`
|
||||
- `tests/system/run-phase14-native-split-xcpng.sh`
|
||||
- `tests/system/run-phase14-native-development-split.sh`
|
||||
|
||||
## Validation
|
||||
|
||||
### Development split validation
|
||||
|
||||
Passing run:
|
||||
|
||||
- `PASS phase14-native-development-split`
|
||||
- workdir: `/tmp/phase14-3-dev5-1775191195`
|
||||
|
||||
Confirmed:
|
||||
|
||||
```text
|
||||
bootloader_store=/frx/store/71aa3ba5dd9a02f7d2710bfc3624cbf5e3cd18f1fbff0744c82df36901b10ec0-freebsd-native-bootloader-15.0-STABLE
|
||||
headers_store=/frx/store/aab09122d37962e6d479c17172ce4b8ea85e5ff33c98aa76424ada2fa1a82617-freebsd-native-headers-15.0-STABLE
|
||||
native_system_packages=freebsd-native-runtime
|
||||
native_development_packages=freebsd-native-runtime,freebsd-native-headers,freebsd-clang-toolchain,freebsd-gmake,freebsd-autotools,freebsd-openssl,freebsd-zlib,freebsd-sh,freebsd-bash
|
||||
runtime_vs_development_split=ok
|
||||
```
|
||||
|
||||
The harness also confirmed:
|
||||
|
||||
- native bootloader slice contains only expected boot assets
|
||||
- native headers slice contains headers/mk files
|
||||
- native headers slice does not contain `/boot` or runtime binaries
|
||||
|
||||
### Local QEMU / UEFI / TCG
|
||||
|
||||
Passing run:
|
||||
|
||||
- `PASS phase14-native-split-qemu`
|
||||
- workdir: `/tmp/phase14-3-qemu-1775191337`
|
||||
|
||||
Confirmed:
|
||||
|
||||
```text
|
||||
disk_capacity=8g
|
||||
root_size=6g
|
||||
bootloader_store=/frx/store/71aa3ba5dd9a02f7d2710bfc3624cbf5e3cd18f1fbff0744c82df36901b10ec0-freebsd-native-bootloader-15.0-STABLE
|
||||
runtime_store=/frx/store/1b4b8774d0df36df2635fe1c35367a2c5fa7790e303f0aaa26eabfe3cce667f2-freebsd-native-runtime-15.0-STABLE
|
||||
native_base_store_count=3
|
||||
host_base_store_count=0
|
||||
shepherd_pid=1
|
||||
sshd_status=running
|
||||
native_split_boot=ok
|
||||
```
|
||||
|
||||
### Real XCP-ng VM
|
||||
|
||||
Passing run:
|
||||
|
||||
- `PASS phase14-native-split-xcpng`
|
||||
- workdir: `/tmp/phase14-3-xcpng-1775191743`
|
||||
|
||||
Confirmed:
|
||||
|
||||
```text
|
||||
vm_id=90490f2e-e8fc-4b7a-388e-5c26f0157289
|
||||
vdi_id=0f1f90d3-48ca-4fa2-91d8-fc6339b95743
|
||||
guest_ip=192.168.213.62
|
||||
root_size=6g
|
||||
bootloader_store=/frx/store/71aa3ba5dd9a02f7d2710bfc3624cbf5e3cd18f1fbff0744c82df36901b10ec0-freebsd-native-bootloader-15.0-STABLE
|
||||
runtime_store=/frx/store/1b4b8774d0df36df2635fe1c35367a2c5fa7790e303f0aaa26eabfe3cce667f2-freebsd-native-runtime-15.0-STABLE
|
||||
native_base_store_count=3
|
||||
host_base_store_count=0
|
||||
shepherd_pid=1
|
||||
sshd_status=running
|
||||
compat_prefix_shims=absent
|
||||
guile_module_smoke=ok
|
||||
native_split_boot=ok
|
||||
```
|
||||
|
||||
Notably, after the narrower native split, the XCP-ng upload size dropped back down dramatically:
|
||||
|
||||
- dynamic VHD upload: `1560725504` bytes (~1.45 GiB)
|
||||
|
||||
That is much better than the temporary broad-world + runtime duplication in Phase 14.2.
|
||||
|
||||
## Result
|
||||
|
||||
Phase 14 is complete.
|
||||
|
||||
Fruix now has a validated, host-base-free FreeBSD system path built from native artifacts in `/frx/store`:
|
||||
|
||||
- `freebsd-native-kernel`
|
||||
- `freebsd-native-bootloader`
|
||||
- `freebsd-native-runtime`
|
||||
|
||||
with a clearer development boundary via:
|
||||
|
||||
- `freebsd-native-headers`
|
||||
- `%freebsd-native-development-profile-packages`
|
||||
|
||||
This completes the Phase 14 objective of incrementally replacing the host-copy FreeBSD base layer for the validated boot/runtime path.
|
||||
|
||||
## Next step
|
||||
|
||||
Proceed to Phase 15:
|
||||
|
||||
1. make the FreeBSD base version a declarative input
|
||||
2. demonstrate side-by-side base versions in `/frx/store`
|
||||
3. establish rebuild/redeploy/rollback across those base versions
|
||||
179
docs/reports/phase15-base-upgrades-freebsd.md
Normal file
179
docs/reports/phase15-base-upgrades-freebsd.md
Normal file
@@ -0,0 +1,179 @@
|
||||
# Phase 15.2: side-by-side native base versions and rollback-friendly redeploy
|
||||
|
||||
Date: 2026-04-03
|
||||
|
||||
## Goal
|
||||
|
||||
Phase 15.2 demonstrated that Fruix can keep at least two distinct declarative FreeBSD base builds in `/frx/store` at the same time and switch between them through the normal system rebuild/image/boot flow.
|
||||
|
||||
For this first upgrade-story validation, both declared bases still point at the same local `/usr/src`, but they carry distinct declarative version labels:
|
||||
|
||||
- current base: `15.0-STABLE`
|
||||
- candidate base: `15.0-STABLE-p1`
|
||||
|
||||
That is enough to prove the Fruix properties needed here:
|
||||
|
||||
- distinct content-addressed outputs
|
||||
- side-by-side coexistence
|
||||
- no in-place mutation of the older base closure
|
||||
- rollback to the earlier closure using the normal deployment path
|
||||
|
||||
## New files
|
||||
|
||||
Added:
|
||||
|
||||
- `tests/system/run-phase15-base-coexistence.sh`
|
||||
- `tests/system/run-phase15-base-rollback-qemu.sh`
|
||||
- `tests/system/run-phase15-base-rollback-xcpng.sh`
|
||||
|
||||
## Validation model
|
||||
|
||||
### Current base declaration
|
||||
|
||||
```scheme
|
||||
(freebsd-base
|
||||
#:name "stable-default"
|
||||
#:version-label "15.0-STABLE"
|
||||
#:release "15.0-STABLE"
|
||||
#:branch "stable/15"
|
||||
...)
|
||||
```
|
||||
|
||||
### Candidate base declaration
|
||||
|
||||
```scheme
|
||||
(freebsd-base
|
||||
#:name "stable-canary"
|
||||
#:version-label "15.0-STABLE-p1"
|
||||
#:release "15.0-STABLE"
|
||||
#:branch "stable/15"
|
||||
...)
|
||||
```
|
||||
|
||||
Both declarations use the same validated native Phase 14 package composition:
|
||||
|
||||
- kernel from `freebsd-native-kernel-for`
|
||||
- bootloader from `freebsd-native-bootloader-for`
|
||||
- runtime from `freebsd-native-system-packages-for`
|
||||
- `shepherd-pid1`
|
||||
|
||||
## Side-by-side build validation
|
||||
|
||||
Passing run:
|
||||
|
||||
- `PASS phase15-base-coexistence`
|
||||
- workdir: `/tmp/phase15-2-coexist-1775202833`
|
||||
|
||||
Confirmed:
|
||||
|
||||
```text
|
||||
current_closure=/frx/store/9f57ecc6481e271811ceb53ac21a3b2aef4ef329f82b7d4788622315db1f0e43-fruix-system-fruix-freebsd
|
||||
candidate_closure=/frx/store/dc40b1b7a76084e140d0457f3b7f6c5d4acc185f0d6cee0b161c9775d5fb3bec-fruix-system-fruix-freebsd
|
||||
current_base_version_label=15.0-STABLE
|
||||
candidate_base_version_label=15.0-STABLE-p1
|
||||
side_by_side_base_versions=ok
|
||||
rollback_rebuild_path=ok
|
||||
```
|
||||
|
||||
Current native base stores:
|
||||
|
||||
```text
|
||||
/frx/store/d9785661ea4829d51fbf545c2607a5691af2cc33c8ef3cd44de7ad5626685098-freebsd-native-kernel-15.0-STABLE
|
||||
/frx/store/b448c822302ccdfb2f06da811fb224a044c51a9935bbfcd77a71a25d02f228f1-freebsd-native-bootloader-15.0-STABLE
|
||||
/frx/store/ac3ba684020e70d3c76e593fd687cef8ab5e148958baabb477b7ef3d2647c5cd-freebsd-native-runtime-15.0-STABLE
|
||||
```
|
||||
|
||||
Candidate native base stores:
|
||||
|
||||
```text
|
||||
/frx/store/05bee8ffbe8c43242ffd97da4dc305f2921612a660cbcb48c3a3536bfac07079-freebsd-native-kernel-15.0-STABLE-p1
|
||||
/frx/store/8955f1bfe89321e6e1e628c59376f2092547523f48a773974cc259963adac184-freebsd-native-bootloader-15.0-STABLE-p1
|
||||
/frx/store/30314f17fd8ff4a1a3eff31c8c5048f15f67c46d1132d5b8c45fd9768742665e-freebsd-native-runtime-15.0-STABLE-p1
|
||||
```
|
||||
|
||||
Important result:
|
||||
|
||||
- the older current closure stayed in `/frx/store`
|
||||
- the candidate closure appeared beside it
|
||||
- rebuilding the current declaration returned the exact original current closure path again
|
||||
|
||||
## Local QEMU rollback validation
|
||||
|
||||
Passing run:
|
||||
|
||||
- `PASS phase15-base-rollback-qemu`
|
||||
- workdir: `/tmp/phase15-2-qemu2-1775204321`
|
||||
|
||||
Validation sequence:
|
||||
|
||||
1. boot current base
|
||||
2. boot candidate base
|
||||
3. boot current base again
|
||||
|
||||
Confirmed:
|
||||
|
||||
```text
|
||||
current_first_closure=/frx/store/9f57ecc6481e271811ceb53ac21a3b2aef4ef329f82b7d4788622315db1f0e43-fruix-system-fruix-freebsd
|
||||
candidate_closure=/frx/store/dc40b1b7a76084e140d0457f3b7f6c5d4acc185f0d6cee0b161c9775d5fb3bec-fruix-system-fruix-freebsd
|
||||
rollback_closure=/frx/store/9f57ecc6481e271811ceb53ac21a3b2aef4ef329f82b7d4788622315db1f0e43-fruix-system-fruix-freebsd
|
||||
current_base_version_label=15.0-STABLE
|
||||
candidate_base_version_label=15.0-STABLE-p1
|
||||
rollback_base_version_label=15.0-STABLE
|
||||
base_rollforward_and_rollback=ok
|
||||
```
|
||||
|
||||
This showed that the booted system could move forward to the candidate base and then return to the earlier closure without mutating it in place.
|
||||
|
||||
## Real XCP-ng rollback validation
|
||||
|
||||
Passing run:
|
||||
|
||||
- `PASS phase15-base-rollback-xcpng`
|
||||
- workdir: `/tmp/phase15-2-xcpng-1775204839`
|
||||
|
||||
Validation sequence:
|
||||
|
||||
1. boot candidate base on the approved VM/VDI
|
||||
2. boot current base again on the same approved VM/VDI
|
||||
|
||||
Confirmed:
|
||||
|
||||
```text
|
||||
candidate_closure=/frx/store/dc40b1b7a76084e140d0457f3b7f6c5d4acc185f0d6cee0b161c9775d5fb3bec-fruix-system-fruix-freebsd
|
||||
rollback_closure=/frx/store/9f57ecc6481e271811ceb53ac21a3b2aef4ef329f82b7d4788622315db1f0e43-fruix-system-fruix-freebsd
|
||||
candidate_base_version_label=15.0-STABLE-p1
|
||||
rollback_base_version_label=15.0-STABLE
|
||||
vm_id=90490f2e-e8fc-4b7a-388e-5c26f0157289
|
||||
vdi_id=0f1f90d3-48ca-4fa2-91d8-fc6339b95743
|
||||
base_rollforward_and_rollback=ok
|
||||
```
|
||||
|
||||
Both boots also preserved the already-hardened guest properties:
|
||||
|
||||
- `shepherd_pid=1`
|
||||
- `sshd_status=running`
|
||||
- `compat_prefix_shims=absent`
|
||||
- `guile_module_smoke=ok`
|
||||
|
||||
## Result
|
||||
|
||||
Phase 15.2 is complete.
|
||||
|
||||
Fruix now has a real declarative rebuild/redeploy/rollback story for the FreeBSD base at the store/model layer:
|
||||
|
||||
- two declared base versions can coexist side by side in `/frx/store`
|
||||
- the candidate deployment does not overwrite the current one in place
|
||||
- rebuilding the earlier declaration returns to the earlier closure path
|
||||
- the same story works both locally under QEMU and on the approved XCP-ng VM/VDI path
|
||||
|
||||
## Scope note
|
||||
|
||||
This first upgrade-story validation still uses the same local `/usr/src` as the underlying source tree for both declarations. What changed is the declared base identity and therefore the store/model/deployment identity.
|
||||
|
||||
That is sufficient for this phase because the requirement was to establish the upgrade semantics:
|
||||
|
||||
- explicit base declaration
|
||||
- side-by-side outputs
|
||||
- rollback-friendly closures
|
||||
|
||||
The next improvement beyond Phase 15 would be to make acquiring or selecting distinct source trees/releases more reproducible and less tied to a single host checkout.
|
||||
141
docs/reports/phase15-declarative-base-freebsd.md
Normal file
141
docs/reports/phase15-declarative-base-freebsd.md
Normal file
@@ -0,0 +1,141 @@
|
||||
# Phase 15.1: make the FreeBSD base version a declarative Fruix input
|
||||
|
||||
Date: 2026-04-03
|
||||
|
||||
## Goal
|
||||
|
||||
Phase 15.1 made the FreeBSD base an explicit declarative part of the Fruix system model instead of leaving it as an implicit property of whatever `/usr/src` happened to be present on the builder host.
|
||||
|
||||
## Implementation
|
||||
|
||||
### New declarative base record
|
||||
|
||||
Added in `modules/fruix/packages/freebsd.scm`:
|
||||
|
||||
- `freebsd-base`
|
||||
- `freebsd-base?`
|
||||
- accessors for:
|
||||
- `name`
|
||||
- `version-label`
|
||||
- `release`
|
||||
- `branch`
|
||||
- `source-root`
|
||||
- `target`
|
||||
- `target-arch`
|
||||
- `kernconf`
|
||||
- `make-flags`
|
||||
- `%default-freebsd-base`
|
||||
|
||||
This gives Fruix an explicit model for the base input used by native FreeBSD artifacts.
|
||||
|
||||
### Native package constructors now accept a declared base
|
||||
|
||||
Added package constructors:
|
||||
|
||||
- `freebsd-native-kernel-for`
|
||||
- `freebsd-native-world-for`
|
||||
- `freebsd-native-runtime-for`
|
||||
- `freebsd-native-bootloader-for`
|
||||
- `freebsd-native-headers-for`
|
||||
- `freebsd-native-system-packages-for`
|
||||
- `freebsd-native-development-profile-packages-for`
|
||||
|
||||
The existing exported package variables remain as the `%default-freebsd-base` instances:
|
||||
|
||||
- `freebsd-native-kernel`
|
||||
- `freebsd-native-world`
|
||||
- `freebsd-native-runtime`
|
||||
- `freebsd-native-bootloader`
|
||||
- `freebsd-native-headers`
|
||||
|
||||
That preserves the validated Phase 14 path while making alternative declared bases possible.
|
||||
|
||||
### Operating-system model now records the declared base
|
||||
|
||||
Added to `modules/fruix/system/freebsd.scm`:
|
||||
|
||||
- `operating-system-freebsd-base`
|
||||
- new `#:freebsd-base` field on `operating-system`
|
||||
|
||||
The declared base is now recorded in:
|
||||
|
||||
- `operating-system-closure-spec`
|
||||
- `operating-system-image-spec`
|
||||
- `metadata/freebsd-base.scm`
|
||||
- `metadata/store-layout.scm`
|
||||
|
||||
### CLI metadata now exposes the declared base
|
||||
|
||||
`scripts/fruix.scm` now emits, for `fruix system build` and `image`:
|
||||
|
||||
- `freebsd_base_name`
|
||||
- `freebsd_base_version_label`
|
||||
- `freebsd_base_release`
|
||||
- `freebsd_base_branch`
|
||||
- `freebsd_base_source_root`
|
||||
- `freebsd_base_target`
|
||||
- `freebsd_base_target_arch`
|
||||
- `freebsd_base_kernconf`
|
||||
- `freebsd_base_file`
|
||||
|
||||
### Native build metadata now records the declared base
|
||||
|
||||
Native build manifests and `.freebsd-native-build-info.scm` now carry a `declared-base` block so the native artifacts themselves record the declarative base choice.
|
||||
|
||||
## New files
|
||||
|
||||
Added:
|
||||
|
||||
- `tests/system/phase15-declarative-base-pid1-operating-system.scm.in`
|
||||
- `tests/system/run-phase15-declarative-base-build.sh`
|
||||
|
||||
## Validation
|
||||
|
||||
Passing run:
|
||||
|
||||
- `PASS phase15-declarative-base-build`
|
||||
- workdir: `/tmp/phase15-1-build-1775202535`
|
||||
|
||||
The harness used an explicit declared base:
|
||||
|
||||
```scheme
|
||||
(freebsd-base
|
||||
#:name "stable-default"
|
||||
#:version-label "15.0-STABLE-declarative"
|
||||
#:release "15.0-STABLE"
|
||||
#:branch "stable/15"
|
||||
#:source-root "/usr/src"
|
||||
#:target "amd64"
|
||||
#:target-arch "amd64"
|
||||
#:kernconf "GENERIC")
|
||||
```
|
||||
|
||||
Confirmed:
|
||||
|
||||
```text
|
||||
kernel_store=/frx/store/8fcef04c7e507e86ea5e92f251fe3c6ac1aa3bcf4809fa77ddd8b92854bfcde0-freebsd-native-kernel-15.0-STABLE-declarative
|
||||
bootloader_store=/frx/store/7a0ba431e487dc35a8f6318108da16a37c8426c43e77e7a7f91404ba1d980eef-freebsd-native-bootloader-15.0-STABLE-declarative
|
||||
runtime_store=/frx/store/17c24ad20ddcb136c39352b68e758deae0b480258ba0128a5546f696a7eba0a6-freebsd-native-runtime-15.0-STABLE-declarative
|
||||
native_base_store_count=3
|
||||
host_base_store_count=0
|
||||
freebsd_base_name=stable-default
|
||||
freebsd_base_version_label=15.0-STABLE-declarative
|
||||
freebsd_base_release=15.0-STABLE
|
||||
freebsd_base_branch=stable/15
|
||||
freebsd_base_source_root=/usr/src
|
||||
freebsd_base_kernconf=GENERIC
|
||||
declarative_base_input=ok
|
||||
```
|
||||
|
||||
The harness also confirmed:
|
||||
|
||||
- `metadata/freebsd-base.scm` exists
|
||||
- `parameters.scm` records the declared base
|
||||
- `metadata/store-layout.scm` records the declared base
|
||||
- native build info files record the declared base version/branch
|
||||
|
||||
## Result
|
||||
|
||||
Phase 15.1 is complete.
|
||||
|
||||
Fruix now has an explicit declarative FreeBSD base input in the system model, while still allowing the current validated `/usr/src`-based path to work unchanged by default.
|
||||
120
docs/reports/phase15-self-hosting-decision-freebsd.md
Normal file
120
docs/reports/phase15-self-hosting-decision-freebsd.md
Normal file
@@ -0,0 +1,120 @@
|
||||
# Phase 15.3: decision on self-hosted FreeBSD base builds
|
||||
|
||||
Date: 2026-04-03
|
||||
|
||||
## Question
|
||||
|
||||
After Phases 13 through 15, should Fruix immediately pursue self-hosted FreeBSD base builds inside a Fruix-managed guest, or should it continue using the host builder while tightening source/reproducibility boundaries?
|
||||
|
||||
## Current evidence
|
||||
|
||||
What is now already true:
|
||||
|
||||
- Fruix builds native FreeBSD base artifacts from `/usr/src` into `/frx/store`
|
||||
- Fruix has validated a host-base-free boot/runtime path composed from:
|
||||
- `freebsd-native-kernel`
|
||||
- `freebsd-native-bootloader`
|
||||
- `freebsd-native-runtime`
|
||||
- that path boots locally under QEMU/UEFI and on the approved real XCP-ng VM/VDI
|
||||
- the FreeBSD base is now an explicit declarative system input through `freebsd-base`
|
||||
- Fruix can keep distinct declared base versions side by side in `/frx/store`
|
||||
- Fruix can roll forward to a candidate base declaration and roll back to the earlier closure without mutating it in place
|
||||
|
||||
So the main Guix-inspired value proposition is already present at the system-deployment layer:
|
||||
|
||||
- declarative system descriptions
|
||||
- content-addressed outputs
|
||||
- side-by-side versions
|
||||
- rollback-friendly closures
|
||||
|
||||
## What is still not strong enough for self-hosting to be the best next step
|
||||
|
||||
### 1. Source acquisition is still too host-local
|
||||
|
||||
The native base path still depends on the host's local `/usr/src` tree as the source of truth.
|
||||
|
||||
That means the next reproducibility win is not "build inside the guest" first; it is "make the source tree selection/acquisition more explicit and reproducible" first.
|
||||
|
||||
### 2. The host-built path is already validated and useful
|
||||
|
||||
The current host-built native base flow is not hypothetical anymore. It has already proven:
|
||||
|
||||
- native artifacts in `/frx/store`
|
||||
- host-base-free boot/runtime composition
|
||||
- side-by-side closures
|
||||
- rollback behavior
|
||||
|
||||
That makes it the productive path to continue refining.
|
||||
|
||||
### 3. Self-hosting would currently mix several problems at once
|
||||
|
||||
Jumping to guest self-hosting now would combine:
|
||||
|
||||
- source acquisition/reproducibility questions
|
||||
- toolchain/profile maturity questions
|
||||
- build-environment modeling questions
|
||||
- large build-resource/runtime questions inside the guest
|
||||
- deployment/debugging questions
|
||||
|
||||
That would make failure analysis worse just after the project finally obtained a clean validated deployment path.
|
||||
|
||||
### 4. Platform constraints still argue for caution
|
||||
|
||||
Current operator/environment constraints still matter:
|
||||
|
||||
- local bhyve remains blocked under Xen due to missing nested VT-x exposure
|
||||
- real VM validation still reuses a single approved XCP-ng VM/VDI pair
|
||||
- XCP-ng storage permissions still prevent creating fresh VDIs on demand
|
||||
|
||||
Those constraints do not block the current host-built native-base path, but they do make an early self-hosting pivot less attractive.
|
||||
|
||||
## Decision
|
||||
|
||||
**Decision:** do **not** pursue self-hosted FreeBSD base builds as the next immediate milestone.
|
||||
|
||||
The near-term direction should remain:
|
||||
|
||||
1. continue building native FreeBSD base artifacts on the host
|
||||
2. keep storing them in `/frx/store`
|
||||
3. improve declarative source-tree/version selection and provenance
|
||||
4. tighten reproducibility around source inputs and build parameters
|
||||
5. only revisit self-hosting after those pieces are stronger
|
||||
|
||||
## Why this is the right decision now
|
||||
|
||||
This preserves the important architectural win already achieved:
|
||||
|
||||
- Fruix, not ad hoc host copying, now defines the deployed FreeBSD base through declared store artifacts
|
||||
|
||||
It also follows the same spirit as Guix generation/rollback semantics: the crucial user-facing property is not where the build happened first, but that the result is declarative, content-addressed, side-by-side, and rollback-friendly.
|
||||
|
||||
At this point Fruix already has those properties for the FreeBSD base path.
|
||||
|
||||
## Conditions for revisiting self-hosting later
|
||||
|
||||
Self-hosted base builds should be reconsidered only after at least most of the following are true:
|
||||
|
||||
- Fruix can select or acquire distinct FreeBSD source trees more reproducibly than a single ambient `/usr/src`
|
||||
- the native development/toolchain side is modeled cleanly enough for a Fruix-managed build environment
|
||||
- operator/deployment tooling can handle larger iterative validation loops without excessive friction
|
||||
- there is a concrete benefit to guest-side base builds beyond what host-built store artifacts already provide
|
||||
|
||||
## Recommended next focus after Phase 15
|
||||
|
||||
The next work should likely focus on improving the declared source/reproducibility boundary around the now-working native base path, rather than on guest self-hosting.
|
||||
|
||||
A good next phase would be centered on things like:
|
||||
|
||||
- declarative source-tree selection/acquisition for the FreeBSD base
|
||||
- stronger provenance for declared source inputs
|
||||
- cleaner rebuilds across multiple source trees or revisions
|
||||
- continued refinement of deployment/generation management around the existing store-based base artifacts
|
||||
|
||||
## Result
|
||||
|
||||
Phase 15.3 is complete.
|
||||
|
||||
The project now has an evidence-based decision:
|
||||
|
||||
- **near-term path:** host-built native FreeBSD base artifacts in `/frx/store`
|
||||
- **not yet:** self-hosted FreeBSD base builds inside the Fruix guest
|
||||
202
docs/reports/phase16-declarative-source-model-freebsd.md
Normal file
202
docs/reports/phase16-declarative-source-model-freebsd.md
Normal file
@@ -0,0 +1,202 @@
|
||||
# Phase 16.1: model FreeBSD source inputs explicitly
|
||||
|
||||
Date: 2026-04-03
|
||||
|
||||
## Goal
|
||||
|
||||
Phase 16.1 introduces a first-class Fruix model for FreeBSD source inputs so the native base path is no longer described only as "whatever `/usr/src` is on the host".
|
||||
|
||||
This step does **not** yet fetch or materialize remote source trees. It makes the source declaration explicit and records it through the package, system, and CLI metadata layers so later phases can replace ambient `/usr/src` with fetched or materialized inputs cleanly.
|
||||
|
||||
## Implementation
|
||||
|
||||
### New declarative FreeBSD source record
|
||||
|
||||
Added in `modules/fruix/packages/freebsd.scm`:
|
||||
|
||||
- `freebsd-source`
|
||||
- `freebsd-source?`
|
||||
- accessors for:
|
||||
- `name`
|
||||
- `kind`
|
||||
- `url`
|
||||
- `path`
|
||||
- `ref`
|
||||
- `commit`
|
||||
- `sha256`
|
||||
- `%default-freebsd-source`
|
||||
|
||||
Supported source kinds are now modeled explicitly as:
|
||||
|
||||
- `local-tree`
|
||||
- `git`
|
||||
- `src-txz`
|
||||
|
||||
The default source remains a local-tree declaration for:
|
||||
|
||||
- `/usr/src`
|
||||
|
||||
### FreeBSD bases now carry a declared source object
|
||||
|
||||
Extended `freebsd-base` so it now records:
|
||||
|
||||
- the transitional `source-root` still used by the current native build path
|
||||
- a new `source` record describing the declared FreeBSD source input
|
||||
|
||||
Added/exported:
|
||||
|
||||
- `freebsd-base-source`
|
||||
|
||||
This keeps the validated `/usr/src` path working while giving the base a source object that can later point at fetched Git or `src.txz` materializations.
|
||||
|
||||
### Native package plans and metadata now record the declared source
|
||||
|
||||
`modules/fruix/packages/freebsd.scm` now threads source fields into native package install plans.
|
||||
|
||||
`modules/fruix/system/freebsd.scm` now records a `declared-source` block in:
|
||||
|
||||
- native package manifests
|
||||
- `.freebsd-native-build-info.scm`
|
||||
|
||||
This means native kernel, bootloader, and runtime outputs now remember both:
|
||||
|
||||
- the declared base
|
||||
- the declared source input
|
||||
|
||||
### Operating-system validation now checks source declarations
|
||||
|
||||
Added source validation in `modules/fruix/system/freebsd.scm`.
|
||||
|
||||
Current accepted source declarations are:
|
||||
|
||||
- `local-tree`
|
||||
- requires a path
|
||||
- `git`
|
||||
- requires a URL and at least a ref or commit
|
||||
- `src-txz`
|
||||
- requires a URL
|
||||
|
||||
This is intentionally enough for Phase 16.1 modeling without yet enforcing the later fetch/materialization policy.
|
||||
|
||||
### Closure metadata now includes a dedicated source file
|
||||
|
||||
System closures now generate:
|
||||
|
||||
- `metadata/freebsd-source.scm`
|
||||
|
||||
and embed source information in:
|
||||
|
||||
- `metadata/freebsd-base.scm`
|
||||
- `metadata/store-layout.scm`
|
||||
- `parameters.scm`
|
||||
|
||||
### CLI metadata now exposes the declared FreeBSD source
|
||||
|
||||
`scripts/fruix.scm` now emits the following for `fruix system build` and `image`:
|
||||
|
||||
- `freebsd_source_name`
|
||||
- `freebsd_source_kind`
|
||||
- `freebsd_source_url`
|
||||
- `freebsd_source_path`
|
||||
- `freebsd_source_ref`
|
||||
- `freebsd_source_commit`
|
||||
- `freebsd_source_sha256`
|
||||
- `freebsd_source_file`
|
||||
|
||||
## Guix comparison
|
||||
|
||||
This follows the same broad idea as Guix source modeling:
|
||||
|
||||
- Guix uses `origin` in `guix/packages.scm`
|
||||
- Git-backed sources are modeled with `git-reference` in `guix/git-download.scm`
|
||||
|
||||
Phase 16.1 does not copy Guix mechanically, but it adopts the same useful architectural boundary:
|
||||
|
||||
- source identity should be a declarative object
|
||||
- builds should record that source object explicitly
|
||||
|
||||
For Fruix, the source kinds are FreeBSD-oriented:
|
||||
|
||||
- local source tree snapshots for development
|
||||
- FreeBSD Git refs/commits
|
||||
- official FreeBSD `src.txz` archives
|
||||
|
||||
## Upstream source forms verified during this step
|
||||
|
||||
Verified usable upstream source forms include:
|
||||
|
||||
- Git:
|
||||
- `https://git.FreeBSD.org/src.git`
|
||||
- release archive:
|
||||
- `https://download.freebsd.org/releases/amd64/15.0-RELEASE/src.txz`
|
||||
- snapshot archive:
|
||||
- `https://download.freebsd.org/snapshots/amd64/15.0-STABLE/src.txz`
|
||||
|
||||
The shorter release URL form above is treated as the canonical example in this phase.
|
||||
|
||||
## New files
|
||||
|
||||
Added:
|
||||
|
||||
- `docs/PLAN_4.md`
|
||||
- `tests/system/phase16-declarative-source-operating-system.scm.in`
|
||||
- `tests/system/run-phase16-declarative-source-build.sh`
|
||||
- `tests/system/validate-phase16-freebsd-source.scm`
|
||||
|
||||
## Validation
|
||||
|
||||
Passing run:
|
||||
|
||||
- `PASS phase16-declarative-source-build`
|
||||
- workdir:
|
||||
- `/tmp/fruix-phase16-declarative-source.0LRvaC`
|
||||
|
||||
The source model probe confirmed:
|
||||
|
||||
```text
|
||||
local_kind=local-tree
|
||||
local_path=/usr/src
|
||||
git_kind=git
|
||||
git_url=https://git.FreeBSD.org/src.git
|
||||
git_ref=stable/15
|
||||
txz_kind=src-txz
|
||||
txz_url=https://download.freebsd.org/releases/amd64/15.0-RELEASE/src.txz
|
||||
txz_sha256=example-sha256
|
||||
base_source_accessor=ok
|
||||
```
|
||||
|
||||
The closure build confirmed:
|
||||
|
||||
```text
|
||||
closure_path=/frx/store/ac73a2a89c3c3f794462ccde0d9f0952362dc2ae32e631a7e99e07e7363e6118-fruix-system-fruix-freebsd
|
||||
kernel_store=/frx/store/c2f771a794f94cf168ae26a421ffab33e0ae4765f23882257d5bb7b2947d493d-freebsd-native-kernel-15.0-STABLE-source-model
|
||||
bootloader_store=/frx/store/a146c9c2fcacdc02454fe3bfd3afb5c5dbea54b6514242d53df0783ef4ee34fd-freebsd-native-bootloader-15.0-STABLE-source-model
|
||||
runtime_store=/frx/store/530e96440a518821a701db03f9437d7646c0447f8ea55c5df08417e9274dead1-freebsd-native-runtime-15.0-STABLE-source-model
|
||||
native_base_store_count=3
|
||||
host_base_store_count=0
|
||||
freebsd_source_name=host-usr-src
|
||||
freebsd_source_kind=local-tree
|
||||
freebsd_source_path=/usr/src
|
||||
freebsd_source_file=/frx/store/ac73a2a89c3c3f794462ccde0d9f0952362dc2ae32e631a7e99e07e7363e6118-fruix-system-fruix-freebsd/metadata/freebsd-source.scm
|
||||
declarative_source_model=ok
|
||||
```
|
||||
|
||||
The harness also verified that:
|
||||
|
||||
- `metadata/freebsd-source.scm` exists
|
||||
- `metadata/freebsd-base.scm` contains a nested source block
|
||||
- `metadata/store-layout.scm` records the declared source explicitly
|
||||
- native build info files contain a `declared-source` block with:
|
||||
- `kind . local-tree`
|
||||
- `path . "/usr/src"`
|
||||
|
||||
## Result
|
||||
|
||||
Phase 16.1 is complete.
|
||||
|
||||
Fruix now has an explicit source declaration layer for FreeBSD bases while preserving the current validated `/usr/src`-driven native build path.
|
||||
|
||||
That means Phase 16.2 can focus narrowly on the next real boundary:
|
||||
|
||||
- fetching or materializing declared FreeBSD source inputs under Fruix control
|
||||
- instead of just describing them
|
||||
@@ -1,7 +1,31 @@
|
||||
(define-module (fruix packages freebsd)
|
||||
#:use-module (srfi srfi-1)
|
||||
#:use-module (srfi srfi-9)
|
||||
#:use-module (srfi srfi-13)
|
||||
#:export (freebsd-release
|
||||
freebsd-source
|
||||
freebsd-source?
|
||||
freebsd-source-name
|
||||
freebsd-source-kind
|
||||
freebsd-source-url
|
||||
freebsd-source-path
|
||||
freebsd-source-ref
|
||||
freebsd-source-commit
|
||||
freebsd-source-sha256
|
||||
%default-freebsd-source
|
||||
freebsd-base
|
||||
freebsd-base?
|
||||
freebsd-base-name
|
||||
freebsd-base-version-label
|
||||
freebsd-base-release
|
||||
freebsd-base-branch
|
||||
freebsd-base-source-root
|
||||
freebsd-base-source
|
||||
freebsd-base-target
|
||||
freebsd-base-target-arch
|
||||
freebsd-base-kernconf
|
||||
freebsd-base-make-flags
|
||||
%default-freebsd-base
|
||||
freebsd-package?
|
||||
freebsd-package-name
|
||||
freebsd-package-version
|
||||
@@ -28,7 +52,22 @@
|
||||
freebsd-zlib
|
||||
freebsd-sh
|
||||
freebsd-bash
|
||||
freebsd-native-kernel
|
||||
freebsd-native-world
|
||||
freebsd-native-runtime
|
||||
freebsd-native-bootloader
|
||||
freebsd-native-headers
|
||||
freebsd-native-kernel-for
|
||||
freebsd-native-world-for
|
||||
freebsd-native-runtime-for
|
||||
freebsd-native-bootloader-for
|
||||
freebsd-native-headers-for
|
||||
freebsd-native-system-packages-for
|
||||
freebsd-native-development-profile-packages-for
|
||||
freebsd-native-build-package?
|
||||
freebsd-host-staged-package?
|
||||
%freebsd-native-system-packages
|
||||
%freebsd-native-development-profile-packages
|
||||
%freebsd-host-staged-all-packages
|
||||
%freebsd-host-staged-core-packages
|
||||
%freebsd-host-staged-development-profile-packages
|
||||
@@ -59,6 +98,83 @@
|
||||
|
||||
(define freebsd-release "15.0-STABLE")
|
||||
|
||||
(define-record-type <freebsd-source>
|
||||
(make-freebsd-source name kind url path ref commit sha256)
|
||||
freebsd-source?
|
||||
(name freebsd-source-name)
|
||||
(kind freebsd-source-kind)
|
||||
(url freebsd-source-url)
|
||||
(path freebsd-source-path)
|
||||
(ref freebsd-source-ref)
|
||||
(commit freebsd-source-commit)
|
||||
(sha256 freebsd-source-sha256))
|
||||
|
||||
(define* (freebsd-source #:key
|
||||
(name "default")
|
||||
(kind 'local-tree)
|
||||
(url (and (eq? kind 'git) "https://git.FreeBSD.org/src.git"))
|
||||
(path (and (eq? kind 'local-tree) "/usr/src"))
|
||||
(ref #f)
|
||||
(commit #f)
|
||||
(sha256 #f))
|
||||
(make-freebsd-source name kind url path ref commit sha256))
|
||||
|
||||
(define %default-freebsd-source
|
||||
(freebsd-source))
|
||||
|
||||
(define-record-type <freebsd-base>
|
||||
(make-freebsd-base name version-label release branch source-root source target
|
||||
target-arch kernconf make-flags)
|
||||
freebsd-base?
|
||||
(name freebsd-base-name)
|
||||
(version-label freebsd-base-version-label)
|
||||
(release freebsd-base-release)
|
||||
(branch freebsd-base-branch)
|
||||
(source-root freebsd-base-source-root)
|
||||
(source freebsd-base-source)
|
||||
(target freebsd-base-target)
|
||||
(target-arch freebsd-base-target-arch)
|
||||
(kernconf freebsd-base-kernconf)
|
||||
(make-flags freebsd-base-make-flags))
|
||||
|
||||
(define default-native-make-flags
|
||||
'("__MAKE_CONF=/dev/null"
|
||||
"SRCCONF=/dev/null"
|
||||
"SRC_ENV_CONF=/dev/null"
|
||||
"MK_DEBUG_FILES=no"
|
||||
"MK_TESTS=no"))
|
||||
|
||||
(define (default-freebsd-branch release)
|
||||
(let ((major (car (string-split release #\.))))
|
||||
(cond
|
||||
((string-contains release "STABLE")
|
||||
(string-append "stable/" major))
|
||||
((string-contains release "RELEASE")
|
||||
(string-append "releng/" major))
|
||||
(else
|
||||
"unknown"))))
|
||||
|
||||
(define* (freebsd-base #:key
|
||||
(name "default")
|
||||
(version-label freebsd-release)
|
||||
(release freebsd-release)
|
||||
(branch (default-freebsd-branch release))
|
||||
(source #f)
|
||||
(source-root #f)
|
||||
(target "amd64")
|
||||
(target-arch "amd64")
|
||||
(kernconf "GENERIC")
|
||||
(make-flags default-native-make-flags))
|
||||
(let* ((source (or source %default-freebsd-source))
|
||||
(source-root (or source-root
|
||||
(freebsd-source-path source)
|
||||
"/usr/src")))
|
||||
(make-freebsd-base name version-label release branch source-root source target
|
||||
target-arch kernconf make-flags)))
|
||||
|
||||
(define %default-freebsd-base
|
||||
(freebsd-base))
|
||||
|
||||
(define freebsd-kernel
|
||||
(freebsd-package
|
||||
#:name "freebsd-kernel"
|
||||
@@ -461,6 +577,157 @@ library for profile experiments."
|
||||
#:install-plan
|
||||
'((file "/lib/libz.so.6" "lib/libz.so.6"))))
|
||||
|
||||
(define default-native-world-prune-paths
|
||||
'("usr/share/doc"
|
||||
"usr/share/examples"
|
||||
"usr/share/info"
|
||||
"usr/share/man"
|
||||
"usr/tests"))
|
||||
|
||||
(define default-native-runtime-prune-paths
|
||||
'("boot"
|
||||
"rescue"
|
||||
"usr/include"
|
||||
"usr/lib/debug"
|
||||
"usr/lib32"
|
||||
"usr/obj"
|
||||
"usr/src"
|
||||
"usr/share/doc"
|
||||
"usr/share/examples"
|
||||
"usr/share/info"
|
||||
"usr/share/man"
|
||||
"usr/share/mk"
|
||||
"usr/tests"))
|
||||
|
||||
(define default-native-bootloader-keep-paths
|
||||
'("boot/loader"
|
||||
"boot/loader.efi"
|
||||
"boot/device.hints"
|
||||
"boot/defaults"
|
||||
"boot/lua"))
|
||||
|
||||
(define default-native-headers-keep-paths
|
||||
'("usr/include"
|
||||
"usr/share/mk"))
|
||||
|
||||
(define (freebsd-base-native-plan base)
|
||||
`((base-name . ,(freebsd-base-name base))
|
||||
(base-version-label . ,(freebsd-base-version-label base))
|
||||
(base-release . ,(freebsd-base-release base))
|
||||
(base-branch . ,(freebsd-base-branch base))
|
||||
(base-source-name . ,(freebsd-source-name (freebsd-base-source base)))
|
||||
(base-source-kind . ,(freebsd-source-kind (freebsd-base-source base)))
|
||||
(base-source-url . ,(freebsd-source-url (freebsd-base-source base)))
|
||||
(base-source-path . ,(freebsd-source-path (freebsd-base-source base)))
|
||||
(base-source-ref . ,(freebsd-source-ref (freebsd-base-source base)))
|
||||
(base-source-commit . ,(freebsd-source-commit (freebsd-base-source base)))
|
||||
(base-source-sha256 . ,(freebsd-source-sha256 (freebsd-base-source base)))
|
||||
(source-root . ,(freebsd-base-source-root base))
|
||||
(target . ,(freebsd-base-target base))
|
||||
(target-arch . ,(freebsd-base-target-arch base))
|
||||
(kernconf . ,(freebsd-base-kernconf base))
|
||||
(make-flags . ,(freebsd-base-make-flags base))))
|
||||
|
||||
(define (freebsd-native-plan base extra-fields)
|
||||
(append (freebsd-base-native-plan base) extra-fields))
|
||||
|
||||
(define (freebsd-native-kernel-for base)
|
||||
(freebsd-package
|
||||
#:name "freebsd-native-kernel"
|
||||
#:version (freebsd-base-version-label base)
|
||||
#:build-system 'freebsd-kernel-build-system
|
||||
#:home-page "https://www.freebsd.org/"
|
||||
#:synopsis "Native Fruix-managed FreeBSD kernel artifact"
|
||||
#:description
|
||||
"FreeBSD-specific package definition that builds a kernel from a declared
|
||||
FreeBSD base input and stages the resulting boot/kernel tree as a real Fruix
|
||||
store artifact."
|
||||
#:license 'bsd-2
|
||||
#:install-plan
|
||||
(freebsd-native-plan base '())))
|
||||
|
||||
(define (freebsd-native-world-for base)
|
||||
(freebsd-package
|
||||
#:name "freebsd-native-world"
|
||||
#:version (freebsd-base-version-label base)
|
||||
#:build-system 'freebsd-world-build-system
|
||||
#:home-page "https://www.freebsd.org/"
|
||||
#:synopsis "Native Fruix-managed FreeBSD world artifact"
|
||||
#:description
|
||||
"FreeBSD-specific package definition that builds and installs a broad
|
||||
native world from a declared FreeBSD base input into a real Fruix store
|
||||
artifact."
|
||||
#:license 'bsd-2
|
||||
#:install-plan
|
||||
(freebsd-native-plan base
|
||||
`((prune-paths . ,default-native-world-prune-paths)))))
|
||||
|
||||
(define (freebsd-native-runtime-for base)
|
||||
(freebsd-package
|
||||
#:name "freebsd-native-runtime"
|
||||
#:version (freebsd-base-version-label base)
|
||||
#:build-system 'freebsd-world-build-system
|
||||
#:home-page "https://www.freebsd.org/"
|
||||
#:synopsis "Native Fruix-managed FreeBSD runtime slice"
|
||||
#:description
|
||||
"FreeBSD-specific package definition that stages a runtime-focused slice of
|
||||
installworld/distribution from a declared FreeBSD base input."
|
||||
#:license 'bsd-2
|
||||
#:install-plan
|
||||
(freebsd-native-plan base
|
||||
`((prune-paths . ,default-native-runtime-prune-paths)))))
|
||||
|
||||
(define (freebsd-native-bootloader-for base)
|
||||
(freebsd-package
|
||||
#:name "freebsd-native-bootloader"
|
||||
#:version (freebsd-base-version-label base)
|
||||
#:build-system 'freebsd-world-build-system
|
||||
#:home-page "https://www.freebsd.org/"
|
||||
#:synopsis "Native Fruix-managed FreeBSD boot asset slice"
|
||||
#:description
|
||||
"FreeBSD-specific package definition that stages only the loader and boot
|
||||
support assets needed by the validated Fruix image path from a declared
|
||||
FreeBSD base input."
|
||||
#:license 'bsd-2
|
||||
#:install-plan
|
||||
(freebsd-native-plan base
|
||||
`((keep-paths . ,default-native-bootloader-keep-paths)))))
|
||||
|
||||
(define (freebsd-native-headers-for base)
|
||||
(freebsd-package
|
||||
#:name "freebsd-native-headers"
|
||||
#:version (freebsd-base-version-label base)
|
||||
#:build-system 'freebsd-world-build-system
|
||||
#:home-page "https://www.freebsd.org/"
|
||||
#:synopsis "Native Fruix-managed FreeBSD headers slice"
|
||||
#:description
|
||||
"FreeBSD-specific package definition that stages the userland header set and
|
||||
build-system support files from installworld/distribution for a declared
|
||||
FreeBSD base input."
|
||||
#:license 'bsd-2
|
||||
#:install-plan
|
||||
(freebsd-native-plan base
|
||||
`((keep-paths . ,default-native-headers-keep-paths)))))
|
||||
|
||||
(define freebsd-native-kernel
|
||||
(freebsd-native-kernel-for %default-freebsd-base))
|
||||
|
||||
(define freebsd-native-world
|
||||
(freebsd-native-world-for %default-freebsd-base))
|
||||
|
||||
(define freebsd-native-runtime
|
||||
(freebsd-native-runtime-for %default-freebsd-base))
|
||||
|
||||
(define freebsd-native-bootloader
|
||||
(freebsd-native-bootloader-for %default-freebsd-base))
|
||||
|
||||
(define freebsd-native-headers
|
||||
(freebsd-native-headers-for %default-freebsd-base))
|
||||
|
||||
(define (freebsd-native-build-package? package)
|
||||
(not (not (memq (freebsd-package-build-system package)
|
||||
'(freebsd-kernel-build-system freebsd-world-build-system)))))
|
||||
|
||||
;; Transitional boundary: the FreeBSD base layer below is still staged by
|
||||
;; copying selected artifacts from the builder host. Plan 3 keeps these
|
||||
;; package sets explicit so they can be replaced incrementally by native
|
||||
@@ -511,10 +778,11 @@ library for profile experiments."
|
||||
%freebsd-host-staged-system-packages)))
|
||||
|
||||
(define (freebsd-host-staged-package? package)
|
||||
(any (lambda (candidate)
|
||||
(string=? (freebsd-package-name candidate)
|
||||
(freebsd-package-name package)))
|
||||
%freebsd-host-staged-all-packages))
|
||||
(and (not (freebsd-native-build-package? package))
|
||||
(any (lambda (candidate)
|
||||
(string=? (freebsd-package-name candidate)
|
||||
(freebsd-package-name package)))
|
||||
%freebsd-host-staged-all-packages)))
|
||||
|
||||
(define %freebsd-host-staged-replacement-order
|
||||
'((first-wave . (freebsd-kernel freebsd-bootloader))
|
||||
@@ -523,6 +791,26 @@ library for profile experiments."
|
||||
(fourth-wave . (freebsd-kernel-headers freebsd-clang-toolchain))
|
||||
(fifth-wave . (freebsd-gmake freebsd-autotools freebsd-openssl freebsd-zlib freebsd-sh freebsd-bash))))
|
||||
|
||||
(define (freebsd-native-system-packages-for base)
|
||||
(list (freebsd-native-runtime-for base)))
|
||||
|
||||
(define (freebsd-native-development-profile-packages-for base)
|
||||
(list (freebsd-native-runtime-for base)
|
||||
(freebsd-native-headers-for base)
|
||||
freebsd-clang-toolchain
|
||||
freebsd-gmake
|
||||
freebsd-autotools
|
||||
freebsd-openssl
|
||||
freebsd-zlib
|
||||
freebsd-sh
|
||||
freebsd-bash))
|
||||
|
||||
(define %freebsd-native-system-packages
|
||||
(freebsd-native-system-packages-for %default-freebsd-base))
|
||||
|
||||
(define %freebsd-native-development-profile-packages
|
||||
(freebsd-native-development-profile-packages-for %default-freebsd-base))
|
||||
|
||||
(define %freebsd-core-packages %freebsd-host-staged-core-packages)
|
||||
(define %freebsd-development-profile-packages %freebsd-host-staged-development-profile-packages)
|
||||
(define %freebsd-system-packages %freebsd-host-staged-system-packages)
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
operating-system
|
||||
operating-system?
|
||||
operating-system-host-name
|
||||
operating-system-freebsd-base
|
||||
operating-system-kernel
|
||||
operating-system-bootloader
|
||||
operating-system-base-packages
|
||||
@@ -96,11 +97,12 @@
|
||||
(make-file-system device mount-point type options needed-for-boot?))
|
||||
|
||||
(define-record-type <operating-system>
|
||||
(make-operating-system host-name kernel bootloader base-packages users groups
|
||||
(make-operating-system host-name freebsd-base kernel bootloader base-packages users groups
|
||||
file-systems services loader-entries rc-conf-entries
|
||||
init-mode ready-marker root-authorized-keys)
|
||||
operating-system?
|
||||
(host-name operating-system-host-name)
|
||||
(freebsd-base operating-system-freebsd-base)
|
||||
(kernel operating-system-kernel)
|
||||
(bootloader operating-system-bootloader)
|
||||
(base-packages operating-system-base-packages)
|
||||
@@ -116,6 +118,7 @@
|
||||
|
||||
(define* (operating-system #:key
|
||||
(host-name "fruix-freebsd")
|
||||
(freebsd-base %default-freebsd-base)
|
||||
(kernel freebsd-kernel)
|
||||
(bootloader freebsd-bootloader)
|
||||
(base-packages %freebsd-system-packages)
|
||||
@@ -160,7 +163,7 @@
|
||||
(init-mode 'freebsd-init+rc.d-shepherd)
|
||||
(ready-marker "/var/lib/fruix/ready")
|
||||
(root-authorized-keys '()))
|
||||
(make-operating-system host-name kernel bootloader base-packages users groups
|
||||
(make-operating-system host-name freebsd-base kernel bootloader base-packages users groups
|
||||
file-systems services loader-entries rc-conf-entries
|
||||
init-mode ready-marker root-authorized-keys))
|
||||
|
||||
@@ -251,7 +254,98 @@
|
||||
(_
|
||||
(error (format #f "unsupported install plan entry: ~s" entry)))))
|
||||
|
||||
(define (package-manifest-string package input-paths)
|
||||
(define native-freebsd-build-version "1")
|
||||
|
||||
(define (freebsd-native-build-system? build-system)
|
||||
(not (not (memq build-system '(freebsd-kernel-build-system freebsd-world-build-system)))))
|
||||
|
||||
(define (build-plan-ref plan key default)
|
||||
(match (assoc key plan)
|
||||
((_ . value) value)
|
||||
(#f default)))
|
||||
|
||||
(define (make-flag->pair flag)
|
||||
(match (string-split flag #\=)
|
||||
((name value ...) (cons name (string-join value "=")))
|
||||
((name) (cons name "yes"))
|
||||
(_ (error (format #f "invalid make flag: ~a" flag)))))
|
||||
|
||||
(define (native-build-kernconf-path plan)
|
||||
(or (build-plan-ref plan 'kernconf-path #f)
|
||||
(string-append (build-plan-ref plan 'source-root "/usr/src")
|
||||
"/sys/"
|
||||
(build-plan-ref plan 'target-arch "amd64")
|
||||
"/conf/"
|
||||
(build-plan-ref plan 'kernconf "GENERIC"))))
|
||||
|
||||
(define (native-build-source-tree-sha256 source-root)
|
||||
(let* ((mtree-output (command-output "mtree" "-c" "-k" "type,link,size,mode,sha256digest" "-p" source-root))
|
||||
(stable-lines (filter (lambda (line)
|
||||
(not (string-prefix? "#" line)))
|
||||
(string-split mtree-output #\newline))))
|
||||
(string-hash (string-join stable-lines "\n"))))
|
||||
|
||||
(define (native-build-common-manifest plan)
|
||||
(let* ((source-root (build-plan-ref plan 'source-root "/usr/src"))
|
||||
(target (build-plan-ref plan 'target "amd64"))
|
||||
(target-arch (build-plan-ref plan 'target-arch "amd64"))
|
||||
(kernconf (build-plan-ref plan 'kernconf "GENERIC"))
|
||||
(make-flags (build-plan-ref plan 'make-flags '()))
|
||||
(kernconf-path (native-build-kernconf-path plan)))
|
||||
(unless (file-exists? source-root)
|
||||
(error (format #f "native FreeBSD source root does not exist: ~a" source-root)))
|
||||
(unless (file-exists? kernconf-path)
|
||||
(error (format #f "native FreeBSD kernconf does not exist: ~a" kernconf-path)))
|
||||
`((build-version . ,native-freebsd-build-version)
|
||||
(source-root . ,source-root)
|
||||
(source-tree-identity-mode . "mtree:type,link,size,mode,sha256digest")
|
||||
(source-tree-sha256 . ,(native-build-source-tree-sha256 source-root))
|
||||
(target . ,target)
|
||||
(target-arch . ,target-arch)
|
||||
(kernconf . ,kernconf)
|
||||
(kernconf-path . ,kernconf-path)
|
||||
(kernconf-sha256 . ,(file-hash kernconf-path))
|
||||
(make-flags . ,make-flags))))
|
||||
|
||||
(define (native-build-declared-base plan)
|
||||
`((name . ,(build-plan-ref plan 'base-name "default"))
|
||||
(version-label . ,(build-plan-ref plan 'base-version-label freebsd-release))
|
||||
(release . ,(build-plan-ref plan 'base-release freebsd-release))
|
||||
(branch . ,(build-plan-ref plan 'base-branch "unknown"))))
|
||||
|
||||
(define (native-build-declared-source plan)
|
||||
`((name . ,(build-plan-ref plan 'base-source-name "default"))
|
||||
(kind . ,(build-plan-ref plan 'base-source-kind 'local-tree))
|
||||
(url . ,(build-plan-ref plan 'base-source-url #f))
|
||||
(path . ,(build-plan-ref plan 'base-source-path #f))
|
||||
(ref . ,(build-plan-ref plan 'base-source-ref #f))
|
||||
(commit . ,(build-plan-ref plan 'base-source-commit #f))
|
||||
(sha256 . ,(build-plan-ref plan 'base-source-sha256 #f))))
|
||||
|
||||
(define (native-build-manifest-string package input-paths)
|
||||
(let* ((plan (freebsd-package-install-plan package))
|
||||
(common (native-build-common-manifest plan))
|
||||
(declared-base (native-build-declared-base plan))
|
||||
(declared-source (native-build-declared-source plan))
|
||||
(keep-paths (build-plan-ref plan 'keep-paths '()))
|
||||
(prune-paths (build-plan-ref plan 'prune-paths '())))
|
||||
(string-append
|
||||
"name=" (freebsd-package-name package) "\n"
|
||||
"version=" (freebsd-package-version package) "\n"
|
||||
"build-system=" (symbol->string (freebsd-package-build-system package)) "\n"
|
||||
"inputs=" (string-join input-paths ",") "\n"
|
||||
"declared-base=\n"
|
||||
(object->string declared-base)
|
||||
"\ndeclared-source=\n"
|
||||
(object->string declared-source)
|
||||
"\nnative-build-common=\n"
|
||||
(object->string common)
|
||||
"\nkeep-paths=\n"
|
||||
(object->string keep-paths)
|
||||
"\nprune-paths=\n"
|
||||
(object->string prune-paths))))
|
||||
|
||||
(define (copy-build-manifest-string package input-paths)
|
||||
(string-append
|
||||
"name=" (freebsd-package-name package) "\n"
|
||||
"version=" (freebsd-package-version package) "\n"
|
||||
@@ -262,6 +356,11 @@
|
||||
(freebsd-package-install-plan package))
|
||||
"\n")))
|
||||
|
||||
(define (package-manifest-string package input-paths)
|
||||
(if (freebsd-native-build-system? (freebsd-package-build-system package))
|
||||
(native-build-manifest-string package input-paths)
|
||||
(copy-build-manifest-string package input-paths)))
|
||||
|
||||
(define (copy-regular-file source destination)
|
||||
(let ((mode (stat:perms (stat source))))
|
||||
(copy-file source destination)
|
||||
@@ -291,6 +390,165 @@
|
||||
(_
|
||||
(error (format #f "unsupported install plan entry: ~s" entry)))))
|
||||
|
||||
(define (clear-file-flags path)
|
||||
(false-if-exception (system* "chflags" "-R" "noschg,nouchg" path)))
|
||||
|
||||
(define (delete-path-if-exists path)
|
||||
(when (or (file-exists? path) (false-if-exception (readlink path)))
|
||||
(clear-file-flags path)
|
||||
(let ((kind (stat:type (lstat path))))
|
||||
(case kind
|
||||
((directory) (delete-file-recursively path))
|
||||
(else (delete-file path))))))
|
||||
|
||||
(define (stage-tree-into-output stage-root output-path)
|
||||
(mkdir-p output-path)
|
||||
(for-each (lambda (entry)
|
||||
(copy-node (string-append stage-root "/" entry)
|
||||
(string-append output-path "/" entry)))
|
||||
(directory-entries stage-root)))
|
||||
|
||||
(define (current-build-jobs)
|
||||
(or (getenv "FRUIX_FREEBSD_BUILD_JOBS")
|
||||
(safe-command-output "sysctl" "-n" "hw.ncpu")
|
||||
"1"))
|
||||
|
||||
(define (native-build-root common)
|
||||
(string-append "/var/tmp/fruix-freebsd-native-build-"
|
||||
(string-hash (object->string common))))
|
||||
|
||||
(define (native-make-arguments common _build-root)
|
||||
(append
|
||||
(list "-C" (assoc-ref common 'source-root)
|
||||
(string-append "TARGET=" (assoc-ref common 'target))
|
||||
(string-append "TARGET_ARCH=" (assoc-ref common 'target-arch))
|
||||
(string-append "KERNCONF=" (assoc-ref common 'kernconf)))
|
||||
(assoc-ref common 'make-flags)))
|
||||
|
||||
(define* (make-command-string common build-root target #:key (parallel? #f) (destdir #f))
|
||||
(string-join
|
||||
(append
|
||||
(list "env" (string-append "MAKEOBJDIRPREFIX=" build-root "/obj") "make")
|
||||
(if parallel?
|
||||
(list (string-append "-j" (current-build-jobs)))
|
||||
'())
|
||||
(native-make-arguments common build-root)
|
||||
(if destdir
|
||||
(list (string-append "DESTDIR=" destdir))
|
||||
'())
|
||||
(list target))
|
||||
" "))
|
||||
|
||||
(define (run-command/log log-file command)
|
||||
(mkdir-p (dirname log-file))
|
||||
(let ((status (system* "sh" "-c" (string-append command " >" log-file " 2>&1"))))
|
||||
(unless (zero? status)
|
||||
(error (format #f "command failed; see ~a: ~a" log-file command)))))
|
||||
|
||||
(define (ensure-native-build-root common build-root)
|
||||
(mkdir-p build-root)
|
||||
(mkdir-p (string-append build-root "/logs"))
|
||||
(mkdir-p (string-append build-root "/stamps"))
|
||||
(write-file (string-append build-root "/build-parameters.scm")
|
||||
(object->string common)))
|
||||
|
||||
(define (ensure-native-buildworld common build-root)
|
||||
(let ((stamp (string-append build-root "/stamps/buildworld.done")))
|
||||
(ensure-native-build-root common build-root)
|
||||
(unless (file-exists? stamp)
|
||||
(run-command/log (string-append build-root "/logs/buildworld.log")
|
||||
(make-command-string common build-root "buildworld" #:parallel? #t))
|
||||
(write-file stamp "ok\n"))))
|
||||
|
||||
(define (ensure-native-buildkernel common build-root)
|
||||
(let ((stamp (string-append build-root "/stamps/buildkernel-" (assoc-ref common 'kernconf) ".done")))
|
||||
(ensure-native-buildworld common build-root)
|
||||
(unless (file-exists? stamp)
|
||||
(run-command/log (string-append build-root "/logs/buildkernel-" (assoc-ref common 'kernconf) ".log")
|
||||
(make-command-string common build-root "buildkernel" #:parallel? #t))
|
||||
(write-file stamp "ok\n"))))
|
||||
|
||||
(define (prune-stage-paths stage-root paths)
|
||||
(for-each (lambda (path)
|
||||
(delete-path-if-exists (string-append stage-root "/" path)))
|
||||
paths))
|
||||
|
||||
(define (select-stage-paths stage-root paths)
|
||||
(let ((selected-root (string-append stage-root ".selected")))
|
||||
(delete-path-if-exists selected-root)
|
||||
(mkdir-p selected-root)
|
||||
(for-each (lambda (path)
|
||||
(let ((source (string-append stage-root "/" path))
|
||||
(target (string-append selected-root "/" path)))
|
||||
(unless (or (file-exists? source)
|
||||
(false-if-exception (readlink source)))
|
||||
(error (format #f "native stage path is missing: ~a" source)))
|
||||
(copy-node source target)))
|
||||
paths)
|
||||
selected-root))
|
||||
(define (native-build-output-metadata package common build-root stage-root)
|
||||
(let ((plan (freebsd-package-install-plan package)))
|
||||
`((package . ,(freebsd-package-name package))
|
||||
(version . ,(freebsd-package-version package))
|
||||
(declared-base . ,(native-build-declared-base plan))
|
||||
(declared-source . ,(native-build-declared-source plan))
|
||||
(build-system . ,(freebsd-package-build-system package))
|
||||
(source-root . ,(assoc-ref common 'source-root))
|
||||
(source-tree-sha256 . ,(assoc-ref common 'source-tree-sha256))
|
||||
(target . ,(assoc-ref common 'target))
|
||||
(target-arch . ,(assoc-ref common 'target-arch))
|
||||
(kernconf . ,(assoc-ref common 'kernconf))
|
||||
(kernconf-path . ,(assoc-ref common 'kernconf-path))
|
||||
(kernconf-sha256 . ,(assoc-ref common 'kernconf-sha256))
|
||||
(make-flags . ,(assoc-ref common 'make-flags))
|
||||
(keep-paths . ,(build-plan-ref plan 'keep-paths '()))
|
||||
(prune-paths . ,(build-plan-ref plan 'prune-paths '()))
|
||||
(build-root . ,build-root)
|
||||
(stage-root . ,stage-root)
|
||||
(buildworld-log . ,(string-append build-root "/logs/buildworld.log"))
|
||||
(buildkernel-log . ,(string-append build-root "/logs/buildkernel-" (assoc-ref common 'kernconf) ".log"))
|
||||
(install-log . ,(string-append build-root "/logs/install-" (freebsd-package-name package) ".log")))))
|
||||
|
||||
(define (materialize-native-freebsd-package package input-paths manifest output-path)
|
||||
(let* ((plan (freebsd-package-install-plan package))
|
||||
(common (native-build-common-manifest plan))
|
||||
(build-root (native-build-root common))
|
||||
(stage-root (string-append build-root "/stage-" (freebsd-package-name package) "-" (string-hash manifest)))
|
||||
(install-log (string-append build-root "/logs/install-" (freebsd-package-name package) ".log"))
|
||||
(final-stage-root
|
||||
(case (freebsd-package-build-system package)
|
||||
((freebsd-world-build-system)
|
||||
(ensure-native-buildworld common build-root)
|
||||
(delete-path-if-exists stage-root)
|
||||
(mkdir-p stage-root)
|
||||
(run-command/log install-log
|
||||
(string-append (make-command-string common build-root "installworld" #:destdir stage-root)
|
||||
" && "
|
||||
(make-command-string common build-root "distribution" #:destdir stage-root)))
|
||||
(let* ((keep-paths (build-plan-ref plan 'keep-paths '()))
|
||||
(selected-root (if (null? keep-paths)
|
||||
stage-root
|
||||
(select-stage-paths stage-root keep-paths))))
|
||||
(prune-stage-paths selected-root (build-plan-ref plan 'prune-paths '()))
|
||||
selected-root))
|
||||
((freebsd-kernel-build-system)
|
||||
(ensure-native-buildkernel common build-root)
|
||||
(delete-path-if-exists stage-root)
|
||||
(mkdir-p stage-root)
|
||||
(run-command/log install-log
|
||||
(make-command-string common build-root "installkernel" #:destdir stage-root))
|
||||
stage-root)
|
||||
(else
|
||||
(error (format #f "unsupported native FreeBSD build system: ~a"
|
||||
(freebsd-package-build-system package)))))))
|
||||
(mkdir-p output-path)
|
||||
(stage-tree-into-output final-stage-root output-path)
|
||||
(write-file (string-append output-path "/.references")
|
||||
(string-join input-paths "\n"))
|
||||
(write-file (string-append output-path "/.fruix-package") manifest)
|
||||
(write-file (string-append output-path "/.freebsd-native-build-info.scm")
|
||||
(object->string (native-build-output-metadata package common build-root final-stage-root)))))
|
||||
|
||||
(define (package-cache-key package)
|
||||
(string-append (freebsd-package-name package) "-" (freebsd-package-version package)))
|
||||
|
||||
@@ -308,13 +566,20 @@
|
||||
"-"
|
||||
(freebsd-package-version package))))
|
||||
(unless (file-exists? output-path)
|
||||
(mkdir-p output-path)
|
||||
(for-each (lambda (entry)
|
||||
(materialize-plan-entry output-path entry))
|
||||
(freebsd-package-install-plan package))
|
||||
(write-file (string-append output-path "/.references")
|
||||
(string-join input-paths "\n"))
|
||||
(write-file (string-append output-path "/.fruix-package") manifest))
|
||||
(case (freebsd-package-build-system package)
|
||||
((copy-build-system)
|
||||
(mkdir-p output-path)
|
||||
(for-each (lambda (entry)
|
||||
(materialize-plan-entry output-path entry))
|
||||
(freebsd-package-install-plan package))
|
||||
(write-file (string-append output-path "/.references")
|
||||
(string-join input-paths "\n"))
|
||||
(write-file (string-append output-path "/.fruix-package") manifest))
|
||||
((freebsd-world-build-system freebsd-kernel-build-system)
|
||||
(materialize-native-freebsd-package package input-paths manifest output-path))
|
||||
(else
|
||||
(error (format #f "unsupported package build system: ~a"
|
||||
(freebsd-package-build-system package))))))
|
||||
(hash-set! cache (package-cache-key package) output-path)
|
||||
output-path))))
|
||||
|
||||
@@ -430,6 +695,27 @@
|
||||
(define (package-names packages)
|
||||
(map freebsd-package-name packages))
|
||||
|
||||
(define (freebsd-source-spec source)
|
||||
`((name . ,(freebsd-source-name source))
|
||||
(kind . ,(freebsd-source-kind source))
|
||||
(url . ,(freebsd-source-url source))
|
||||
(path . ,(freebsd-source-path source))
|
||||
(ref . ,(freebsd-source-ref source))
|
||||
(commit . ,(freebsd-source-commit source))
|
||||
(sha256 . ,(freebsd-source-sha256 source))))
|
||||
|
||||
(define (freebsd-base-spec base)
|
||||
`((name . ,(freebsd-base-name base))
|
||||
(version-label . ,(freebsd-base-version-label base))
|
||||
(release . ,(freebsd-base-release base))
|
||||
(branch . ,(freebsd-base-branch base))
|
||||
(source-root . ,(freebsd-base-source-root base))
|
||||
(source . ,(freebsd-source-spec (freebsd-base-source base)))
|
||||
(target . ,(freebsd-base-target base))
|
||||
(target-arch . ,(freebsd-base-target-arch base))
|
||||
(kernconf . ,(freebsd-base-kernconf base))
|
||||
(make-flags . ,(freebsd-base-make-flags base))))
|
||||
|
||||
(define (duplicate-elements values)
|
||||
(let loop ((rest values) (seen '()) (duplicates '()))
|
||||
(match rest
|
||||
@@ -439,8 +725,34 @@
|
||||
(loop tail seen (if (member head duplicates) duplicates (cons head duplicates)))
|
||||
(loop tail (cons head seen) duplicates))))))
|
||||
|
||||
(define (non-empty-string? value)
|
||||
(and (string? value)
|
||||
(not (string-null? value))))
|
||||
|
||||
(define (validate-freebsd-source source)
|
||||
(unless (freebsd-source? source)
|
||||
(error "freebsd base source must be a <freebsd-source> record"))
|
||||
(let ((kind (freebsd-source-kind source)))
|
||||
(unless (member kind '(local-tree git src-txz))
|
||||
(error "unsupported freebsd source kind" kind))
|
||||
(case kind
|
||||
((local-tree)
|
||||
(unless (non-empty-string? (freebsd-source-path source))
|
||||
(error "local-tree freebsd source must declare a path" source)))
|
||||
((git)
|
||||
(unless (non-empty-string? (freebsd-source-url source))
|
||||
(error "git freebsd source must declare a URL" source))
|
||||
(unless (or (non-empty-string? (freebsd-source-ref source))
|
||||
(non-empty-string? (freebsd-source-commit source)))
|
||||
(error "git freebsd source must declare a ref or commit" source)))
|
||||
((src-txz)
|
||||
(unless (non-empty-string? (freebsd-source-url source))
|
||||
(error "src-txz freebsd source must declare a URL" source)))))
|
||||
#t)
|
||||
|
||||
(define (validate-operating-system os)
|
||||
(let* ((host-name (operating-system-host-name os))
|
||||
(base (operating-system-freebsd-base os))
|
||||
(users (operating-system-users os))
|
||||
(groups (operating-system-groups os))
|
||||
(file-systems (operating-system-file-systems os))
|
||||
@@ -450,6 +762,9 @@
|
||||
(init-mode (operating-system-init-mode os)))
|
||||
(when (string-null? host-name)
|
||||
(error "operating-system host-name must not be empty"))
|
||||
(unless (freebsd-base? base)
|
||||
(error "operating-system freebsd-base must be a <freebsd-base> record"))
|
||||
(validate-freebsd-source (freebsd-base-source base))
|
||||
(let ((dups (duplicate-elements user-names)))
|
||||
(unless (null? dups)
|
||||
(error "duplicate user names in operating-system" dups)))
|
||||
@@ -957,6 +1272,7 @@
|
||||
"etc/shells"
|
||||
"etc/motd"
|
||||
"etc/ttys"
|
||||
"metadata/freebsd-base.scm"
|
||||
"metadata/host-base-provenance.scm"
|
||||
"metadata/store-layout.scm"
|
||||
"activate"
|
||||
@@ -1002,6 +1318,7 @@
|
||||
(define (operating-system-closure-spec os)
|
||||
(validate-operating-system os)
|
||||
`((host-name . ,(operating-system-host-name os))
|
||||
(freebsd-base . ,(freebsd-base-spec (operating-system-freebsd-base os)))
|
||||
(kernel-package . ,(freebsd-package-name (operating-system-kernel os)))
|
||||
(bootloader-package . ,(freebsd-package-name (operating-system-bootloader os)))
|
||||
(base-package-count . ,(length (operating-system-base-packages os)))
|
||||
@@ -1033,7 +1350,8 @@
|
||||
(string-append output-path "/" relative))))
|
||||
(for-each
|
||||
(lambda (entry)
|
||||
(unless (member entry '(".references" ".fruix-package"))
|
||||
(unless (or (member entry '(".references" ".fruix-package"))
|
||||
(string-prefix? "." entry))
|
||||
(let* ((entry-relative (if (string-null? relative)
|
||||
entry
|
||||
(string-append relative "/" entry)))
|
||||
@@ -1067,11 +1385,19 @@
|
||||
(shepherd-prefix "/tmp/shepherd-freebsd-validate-install"))
|
||||
(validate-operating-system os)
|
||||
(let* ((cache (make-hash-table))
|
||||
(kernel-store (materialize-freebsd-package (operating-system-kernel os) store-dir cache))
|
||||
(bootloader-store (materialize-freebsd-package (operating-system-bootloader os) store-dir cache))
|
||||
(kernel-package (operating-system-kernel os))
|
||||
(bootloader-package (operating-system-bootloader os))
|
||||
(base-packages (operating-system-base-packages os))
|
||||
(kernel-store (materialize-freebsd-package kernel-package store-dir cache))
|
||||
(bootloader-store (materialize-freebsd-package bootloader-package store-dir cache))
|
||||
(base-package-stores (map (lambda (package)
|
||||
(materialize-freebsd-package package store-dir cache))
|
||||
(operating-system-base-packages os)))
|
||||
base-packages))
|
||||
(base-package-pairs (map cons base-packages base-package-stores))
|
||||
(store-classification
|
||||
(append (list (cons kernel-package kernel-store)
|
||||
(cons bootloader-package bootloader-store))
|
||||
base-package-pairs))
|
||||
(guile-runtime-extra-files
|
||||
'(("/usr/local/lib/libgc-threaded.so.1" . "lib/libgc-threaded.so.1")
|
||||
("/usr/local/lib/libffi.so.8" . "lib/libffi.so.8")
|
||||
@@ -1093,16 +1419,34 @@
|
||||
#:extra-files (append guile-runtime-extra-files
|
||||
guile-extra-runtime-files)))
|
||||
(shepherd-store (materialize-prefix shepherd-prefix "fruix-shepherd-runtime" "1.0.9" store-dir))
|
||||
(host-base-stores (delete-duplicates (append (list kernel-store bootloader-store)
|
||||
base-package-stores)))
|
||||
(host-base-stores
|
||||
(delete-duplicates
|
||||
(map cdr
|
||||
(filter (lambda (entry)
|
||||
(freebsd-host-staged-package? (car entry)))
|
||||
store-classification))))
|
||||
(native-base-stores
|
||||
(delete-duplicates
|
||||
(map cdr
|
||||
(filter (lambda (entry)
|
||||
(freebsd-native-build-package? (car entry)))
|
||||
store-classification))))
|
||||
(fruix-runtime-stores (list guile-store guile-extra-store shepherd-store))
|
||||
(metadata-files
|
||||
`(("metadata/host-base-provenance.scm"
|
||||
`(("metadata/freebsd-base.scm"
|
||||
. ,(object->string (freebsd-base-spec (operating-system-freebsd-base os))))
|
||||
("metadata/freebsd-source.scm"
|
||||
. ,(object->string (freebsd-source-spec (freebsd-base-source (operating-system-freebsd-base os)))))
|
||||
("metadata/host-base-provenance.scm"
|
||||
. ,(object->string (host-freebsd-provenance)))
|
||||
("metadata/store-layout.scm"
|
||||
. ,(object->string
|
||||
`((host-base-store-count . ,(length host-base-stores))
|
||||
`((freebsd-base . ,(freebsd-base-spec (operating-system-freebsd-base os)))
|
||||
(freebsd-source . ,(freebsd-source-spec (freebsd-base-source (operating-system-freebsd-base os))))
|
||||
(host-base-store-count . ,(length host-base-stores))
|
||||
(host-base-stores . ,host-base-stores)
|
||||
(native-base-store-count . ,(length native-base-stores))
|
||||
(native-base-stores . ,native-base-stores)
|
||||
(fruix-runtime-store-count . ,(length fruix-runtime-stores))
|
||||
(fruix-runtime-stores . ,fruix-runtime-stores)
|
||||
(host-base-replacement-order . ,%freebsd-host-staged-replacement-order)
|
||||
@@ -1116,7 +1460,7 @@
|
||||
. ,(render-activation-rc-script))
|
||||
("usr/local/etc/rc.d/fruix-shepherd"
|
||||
. ,(render-rc-script shepherd-store guile-store guile-extra-store)))))
|
||||
(references (delete-duplicates (append host-base-stores fruix-runtime-stores)))
|
||||
(references (delete-duplicates (append host-base-stores native-base-stores fruix-runtime-stores)))
|
||||
(manifest (string-append
|
||||
"closure-spec=\n"
|
||||
(object->string (operating-system-closure-spec os))
|
||||
@@ -1171,7 +1515,10 @@
|
||||
(shepherd-store . ,shepherd-store)
|
||||
(base-package-stores . ,base-package-stores)
|
||||
(host-base-stores . ,host-base-stores)
|
||||
(native-base-stores . ,native-base-stores)
|
||||
(fruix-runtime-stores . ,fruix-runtime-stores)
|
||||
(freebsd-base-file . ,(string-append closure-path "/metadata/freebsd-base.scm"))
|
||||
(freebsd-source-file . ,(string-append closure-path "/metadata/freebsd-source.scm"))
|
||||
(host-base-provenance-file . ,(string-append closure-path "/metadata/host-base-provenance.scm"))
|
||||
(store-layout-file . ,(string-append closure-path "/metadata/store-layout.scm"))
|
||||
(generated-files . ,(map car generated-files))
|
||||
@@ -1258,6 +1605,7 @@
|
||||
(root-partition-label "fruix-root")
|
||||
(serial-console "comconsole"))
|
||||
`((host-name . ,(operating-system-host-name os))
|
||||
(freebsd-base . ,(freebsd-base-spec (operating-system-freebsd-base os)))
|
||||
(boot-mode . ,boot-mode)
|
||||
(image-format . ,image-format)
|
||||
(partition-scheme . ,partition-scheme)
|
||||
@@ -1435,7 +1783,9 @@
|
||||
(root-image . ,root-image)
|
||||
(closure-path . ,closure-path)
|
||||
(host-base-stores . ,(assoc-ref closure 'host-base-stores))
|
||||
(native-base-stores . ,(assoc-ref closure 'native-base-stores))
|
||||
(fruix-runtime-stores . ,(assoc-ref closure 'fruix-runtime-stores))
|
||||
(freebsd-base-file . ,(assoc-ref closure 'freebsd-base-file))
|
||||
(host-base-provenance-file . ,(assoc-ref closure 'host-base-provenance-file))
|
||||
(store-layout-file . ,(assoc-ref closure 'store-layout-file))
|
||||
(image-spec . ,image-spec)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
!#
|
||||
|
||||
(use-modules (fruix system freebsd)
|
||||
(fruix packages freebsd)
|
||||
(ice-9 format)
|
||||
(ice-9 match)
|
||||
(srfi srfi-1)
|
||||
@@ -20,6 +21,7 @@ Options:\n\
|
||||
--system NAME Scheme variable holding the operating-system object.\n\
|
||||
--store DIR Store directory to use (default: /frx/store).\n\
|
||||
--disk-capacity SIZE Disk capacity for 'image' (example: 30g).\n\
|
||||
--root-size SIZE Root filesystem size for 'image' (example: 6g).\n\
|
||||
--rootfs DIR Rootfs target for 'rootfs'.\n\
|
||||
--help Show this help.\n")
|
||||
(exit code))
|
||||
@@ -89,6 +91,7 @@ Options:\n\
|
||||
(system-name #f)
|
||||
(store-dir "/frx/store")
|
||||
(disk-capacity #f)
|
||||
(root-size #f)
|
||||
(rootfs #f))
|
||||
(match args
|
||||
(()
|
||||
@@ -98,29 +101,34 @@ Options:\n\
|
||||
(system-name . ,system-name)
|
||||
(store-dir . ,store-dir)
|
||||
(disk-capacity . ,disk-capacity)
|
||||
(root-size . ,root-size)
|
||||
(rootfs . ,rootfs))))
|
||||
(("--help")
|
||||
(usage 0))
|
||||
(((? (lambda (arg) (string-prefix? "--system=" arg)) arg) . tail)
|
||||
(loop tail positional (option-value arg "--system=") store-dir disk-capacity rootfs))
|
||||
(loop tail positional (option-value arg "--system=") store-dir disk-capacity root-size rootfs))
|
||||
(("--system" value . tail)
|
||||
(loop tail positional value store-dir disk-capacity rootfs))
|
||||
(loop tail positional value store-dir disk-capacity root-size rootfs))
|
||||
(((? (lambda (arg) (string-prefix? "--store=" arg)) arg) . tail)
|
||||
(loop tail positional system-name (option-value arg "--store=") disk-capacity rootfs))
|
||||
(loop tail positional system-name (option-value arg "--store=") disk-capacity root-size rootfs))
|
||||
(("--store" value . tail)
|
||||
(loop tail positional system-name value disk-capacity rootfs))
|
||||
(loop tail positional system-name value disk-capacity root-size rootfs))
|
||||
(((? (lambda (arg) (string-prefix? "--disk-capacity=" arg)) arg) . tail)
|
||||
(loop tail positional system-name store-dir (option-value arg "--disk-capacity=") rootfs))
|
||||
(loop tail positional system-name store-dir (option-value arg "--disk-capacity=") root-size rootfs))
|
||||
(("--disk-capacity" value . tail)
|
||||
(loop tail positional system-name store-dir value rootfs))
|
||||
(loop tail positional system-name store-dir value root-size rootfs))
|
||||
(((? (lambda (arg) (string-prefix? "--root-size=" arg)) arg) . tail)
|
||||
(loop tail positional system-name store-dir disk-capacity (option-value arg "--root-size=") rootfs))
|
||||
(("--root-size" value . tail)
|
||||
(loop tail positional system-name store-dir disk-capacity value rootfs))
|
||||
(((? (lambda (arg) (string-prefix? "--rootfs=" arg)) arg) . tail)
|
||||
(loop tail positional system-name store-dir disk-capacity (option-value arg "--rootfs=")))
|
||||
(loop tail positional system-name store-dir disk-capacity root-size (option-value arg "--rootfs=")))
|
||||
(("--rootfs" value . tail)
|
||||
(loop tail positional system-name store-dir disk-capacity value))
|
||||
(loop tail positional system-name store-dir disk-capacity root-size value))
|
||||
(((? (lambda (arg) (string-prefix? "--" arg)) arg) . _)
|
||||
(error "unknown option" arg))
|
||||
((arg . tail)
|
||||
(loop tail (cons arg positional) system-name store-dir disk-capacity rootfs)))))
|
||||
(loop tail (cons arg positional) system-name store-dir disk-capacity root-size rootfs)))))
|
||||
((_ . _)
|
||||
(usage 1))))
|
||||
|
||||
@@ -130,6 +138,7 @@ Options:\n\
|
||||
(positional (assoc-ref parsed 'positional))
|
||||
(store-dir (assoc-ref parsed 'store-dir))
|
||||
(disk-capacity (assoc-ref parsed 'disk-capacity))
|
||||
(root-size (assoc-ref parsed 'root-size))
|
||||
(rootfs-opt (assoc-ref parsed 'rootfs))
|
||||
(system-name (assoc-ref parsed 'system-name))
|
||||
(requested-symbol (and system-name (string->symbol system-name))))
|
||||
@@ -164,7 +173,10 @@ Options:\n\
|
||||
(references (assoc-ref result 'references))
|
||||
(base-package-stores (assoc-ref result 'base-package-stores))
|
||||
(host-base-stores (assoc-ref result 'host-base-stores))
|
||||
(native-base-stores (assoc-ref result 'native-base-stores))
|
||||
(fruix-runtime-stores (assoc-ref result 'fruix-runtime-stores))
|
||||
(base (operating-system-freebsd-base os))
|
||||
(source (freebsd-base-source base))
|
||||
(host-provenance (call-with-input-file (assoc-ref result 'host-base-provenance-file) read)))
|
||||
(emit-metadata
|
||||
`((action . "build")
|
||||
@@ -172,6 +184,23 @@ Options:\n\
|
||||
(system_variable . ,resolved-symbol)
|
||||
(store_dir . ,store-dir)
|
||||
(closure_path . ,closure-path)
|
||||
(freebsd_base_name . ,(freebsd-base-name base))
|
||||
(freebsd_base_version_label . ,(freebsd-base-version-label base))
|
||||
(freebsd_base_release . ,(freebsd-base-release base))
|
||||
(freebsd_base_branch . ,(freebsd-base-branch base))
|
||||
(freebsd_base_source_root . ,(freebsd-base-source-root base))
|
||||
(freebsd_base_target . ,(freebsd-base-target base))
|
||||
(freebsd_base_target_arch . ,(freebsd-base-target-arch base))
|
||||
(freebsd_base_kernconf . ,(freebsd-base-kernconf base))
|
||||
(freebsd_base_file . ,(assoc-ref result 'freebsd-base-file))
|
||||
(freebsd_source_name . ,(freebsd-source-name source))
|
||||
(freebsd_source_kind . ,(freebsd-source-kind source))
|
||||
(freebsd_source_url . ,(or (freebsd-source-url source) ""))
|
||||
(freebsd_source_path . ,(or (freebsd-source-path source) ""))
|
||||
(freebsd_source_ref . ,(or (freebsd-source-ref source) ""))
|
||||
(freebsd_source_commit . ,(or (freebsd-source-commit source) ""))
|
||||
(freebsd_source_sha256 . ,(or (freebsd-source-sha256 source) ""))
|
||||
(freebsd_source_file . ,(assoc-ref result 'freebsd-source-file))
|
||||
(ready_marker . ,(operating-system-ready-marker os))
|
||||
(kernel_store . ,(assoc-ref result 'kernel-store))
|
||||
(bootloader_store . ,(assoc-ref result 'bootloader-store))
|
||||
@@ -182,6 +211,8 @@ Options:\n\
|
||||
(base_package_stores . ,(string-join base-package-stores ","))
|
||||
(host_base_store_count . ,(length host-base-stores))
|
||||
(host_base_stores . ,(string-join host-base-stores ","))
|
||||
(native_base_store_count . ,(length native-base-stores))
|
||||
(native_base_stores . ,(string-join native-base-stores ","))
|
||||
(fruix_runtime_store_count . ,(length fruix-runtime-stores))
|
||||
(fruix_runtime_stores . ,(string-join fruix-runtime-stores ","))
|
||||
(host_base_provenance_file . ,(assoc-ref result 'host-base-provenance-file))
|
||||
@@ -216,18 +247,40 @@ Options:\n\
|
||||
#:guile-prefix guile-prefix
|
||||
#:guile-extra-prefix guile-extra-prefix
|
||||
#:shepherd-prefix shepherd-prefix
|
||||
#:root-size (or root-size "256m")
|
||||
#:disk-capacity disk-capacity))
|
||||
(image-spec (assoc-ref result 'image-spec))
|
||||
(store-items (assoc-ref result 'store-items))
|
||||
(host-base-stores (assoc-ref result 'host-base-stores))
|
||||
(native-base-stores (assoc-ref result 'native-base-stores))
|
||||
(fruix-runtime-stores (assoc-ref result 'fruix-runtime-stores))
|
||||
(base (operating-system-freebsd-base os))
|
||||
(source (freebsd-base-source base))
|
||||
(host-provenance (call-with-input-file (assoc-ref result 'host-base-provenance-file) read)))
|
||||
(emit-metadata
|
||||
`((action . "image")
|
||||
(os_file . ,os-file)
|
||||
(system_variable . ,resolved-symbol)
|
||||
(store_dir . ,store-dir)
|
||||
(freebsd_base_name . ,(freebsd-base-name base))
|
||||
(freebsd_base_version_label . ,(freebsd-base-version-label base))
|
||||
(freebsd_base_release . ,(freebsd-base-release base))
|
||||
(freebsd_base_branch . ,(freebsd-base-branch base))
|
||||
(freebsd_base_source_root . ,(freebsd-base-source-root base))
|
||||
(freebsd_base_target . ,(freebsd-base-target base))
|
||||
(freebsd_base_target_arch . ,(freebsd-base-target-arch base))
|
||||
(freebsd_base_kernconf . ,(freebsd-base-kernconf base))
|
||||
(freebsd_base_file . ,(assoc-ref result 'freebsd-base-file))
|
||||
(freebsd_source_name . ,(freebsd-source-name source))
|
||||
(freebsd_source_kind . ,(freebsd-source-kind source))
|
||||
(freebsd_source_url . ,(or (freebsd-source-url source) ""))
|
||||
(freebsd_source_path . ,(or (freebsd-source-path source) ""))
|
||||
(freebsd_source_ref . ,(or (freebsd-source-ref source) ""))
|
||||
(freebsd_source_commit . ,(or (freebsd-source-commit source) ""))
|
||||
(freebsd_source_sha256 . ,(or (freebsd-source-sha256 source) ""))
|
||||
(freebsd_source_file . ,(assoc-ref result 'freebsd-source-file))
|
||||
(disk_capacity . ,(assoc-ref image-spec 'disk-capacity))
|
||||
(root_size . ,(assoc-ref image-spec 'root-size))
|
||||
(image_store_path . ,(assoc-ref result 'image-store-path))
|
||||
(disk_image . ,(assoc-ref result 'disk-image))
|
||||
(esp_image . ,(assoc-ref result 'esp-image))
|
||||
@@ -235,6 +288,8 @@ Options:\n\
|
||||
(closure_path . ,(assoc-ref result 'closure-path))
|
||||
(host_base_store_count . ,(length host-base-stores))
|
||||
(host_base_stores . ,(string-join host-base-stores ","))
|
||||
(native_base_store_count . ,(length native-base-stores))
|
||||
(native_base_stores . ,(string-join native-base-stores ","))
|
||||
(fruix_runtime_store_count . ,(length fruix-runtime-stores))
|
||||
(fruix_runtime_stores . ,(string-join fruix-runtime-stores ","))
|
||||
(host_base_provenance_file . ,(assoc-ref result 'host-base-provenance-file))
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
(use-modules (fruix system freebsd)
|
||||
(fruix packages freebsd))
|
||||
|
||||
(define phase13-operating-system
|
||||
(operating-system
|
||||
#:host-name "fruix-freebsd"
|
||||
#:kernel freebsd-native-kernel
|
||||
#:bootloader freebsd-bootloader
|
||||
#:base-packages (list freebsd-native-world)
|
||||
#:groups (list (user-group #:name "wheel" #:gid 0 #:system? #t)
|
||||
(user-group #:name "sshd" #:gid 22 #:system? #t)
|
||||
(user-group #:name "_dhcp" #:gid 65 #:system? #t)
|
||||
(user-group #:name "operator" #:gid 1000 #:system? #f))
|
||||
#:users (list (user-account #:name "root"
|
||||
#:uid 0
|
||||
#:group "wheel"
|
||||
#:comment "Charlie &"
|
||||
#:home "/root"
|
||||
#:shell "/bin/sh"
|
||||
#:system? #t)
|
||||
(user-account #:name "sshd"
|
||||
#:uid 22
|
||||
#:group "sshd"
|
||||
#:comment "Secure Shell Daemon"
|
||||
#:home "/var/empty"
|
||||
#:shell "/usr/sbin/nologin"
|
||||
#:system? #t)
|
||||
(user-account #:name "_dhcp"
|
||||
#:uid 65
|
||||
#:group "_dhcp"
|
||||
#:comment "dhcp programs"
|
||||
#:home "/var/empty"
|
||||
#:shell "/usr/sbin/nologin"
|
||||
#:system? #t)
|
||||
(user-account #:name "operator"
|
||||
#:uid 1000
|
||||
#:group "operator"
|
||||
#:supplementary-groups '("wheel")
|
||||
#:comment "Fruix Operator"
|
||||
#:home "/home/operator"
|
||||
#:shell "/bin/sh"
|
||||
#:system? #f))
|
||||
#:file-systems (list (file-system #:device "/dev/gpt/fruix-root"
|
||||
#:mount-point "/"
|
||||
#:type "ufs"
|
||||
#:options "rw"
|
||||
#:needed-for-boot? #t)
|
||||
(file-system #:device "devfs"
|
||||
#:mount-point "/dev"
|
||||
#:type "devfs"
|
||||
#:options "rw"
|
||||
#:needed-for-boot? #t)
|
||||
(file-system #:device "tmpfs"
|
||||
#:mount-point "/tmp"
|
||||
#:type "tmpfs"
|
||||
#:options "rw,size=64m"))
|
||||
#:services '(shepherd ready-marker sshd)
|
||||
#:loader-entries '(("autoboot_delay" . "1")
|
||||
("boot_multicons" . "YES")
|
||||
("boot_serial" . "YES")
|
||||
("console" . "comconsole,vidconsole"))
|
||||
#:rc-conf-entries '(("clear_tmp_enable" . "NO")
|
||||
("hostid_enable" . "NO")
|
||||
("sendmail_enable" . "NONE")
|
||||
("sshd_enable" . "YES")
|
||||
("ifconfig_xn0" . "SYNCDHCP")
|
||||
("ifconfig_em0" . "SYNCDHCP")
|
||||
("ifconfig_vtnet0" . "SYNCDHCP"))
|
||||
#:init-mode 'shepherd-pid1
|
||||
#:ready-marker "/var/lib/fruix/ready"
|
||||
#:root-authorized-keys '("__ROOT_AUTHORIZED_KEY__")))
|
||||
@@ -0,0 +1,71 @@
|
||||
(use-modules (fruix system freebsd)
|
||||
(fruix packages freebsd))
|
||||
|
||||
(define phase14-operating-system
|
||||
(operating-system
|
||||
#:host-name "fruix-freebsd"
|
||||
#:kernel freebsd-native-kernel
|
||||
#:bootloader freebsd-native-world
|
||||
#:base-packages (list freebsd-native-world)
|
||||
#:groups (list (user-group #:name "wheel" #:gid 0 #:system? #t)
|
||||
(user-group #:name "sshd" #:gid 22 #:system? #t)
|
||||
(user-group #:name "_dhcp" #:gid 65 #:system? #t)
|
||||
(user-group #:name "operator" #:gid 1000 #:system? #f))
|
||||
#:users (list (user-account #:name "root"
|
||||
#:uid 0
|
||||
#:group "wheel"
|
||||
#:comment "Charlie &"
|
||||
#:home "/root"
|
||||
#:shell "/bin/sh"
|
||||
#:system? #t)
|
||||
(user-account #:name "sshd"
|
||||
#:uid 22
|
||||
#:group "sshd"
|
||||
#:comment "Secure Shell Daemon"
|
||||
#:home "/var/empty"
|
||||
#:shell "/usr/sbin/nologin"
|
||||
#:system? #t)
|
||||
(user-account #:name "_dhcp"
|
||||
#:uid 65
|
||||
#:group "_dhcp"
|
||||
#:comment "dhcp programs"
|
||||
#:home "/var/empty"
|
||||
#:shell "/usr/sbin/nologin"
|
||||
#:system? #t)
|
||||
(user-account #:name "operator"
|
||||
#:uid 1000
|
||||
#:group "operator"
|
||||
#:supplementary-groups '("wheel")
|
||||
#:comment "Fruix Operator"
|
||||
#:home "/home/operator"
|
||||
#:shell "/bin/sh"
|
||||
#:system? #f))
|
||||
#:file-systems (list (file-system #:device "/dev/gpt/fruix-root"
|
||||
#:mount-point "/"
|
||||
#:type "ufs"
|
||||
#:options "rw"
|
||||
#:needed-for-boot? #t)
|
||||
(file-system #:device "devfs"
|
||||
#:mount-point "/dev"
|
||||
#:type "devfs"
|
||||
#:options "rw"
|
||||
#:needed-for-boot? #t)
|
||||
(file-system #:device "tmpfs"
|
||||
#:mount-point "/tmp"
|
||||
#:type "tmpfs"
|
||||
#:options "rw,size=64m"))
|
||||
#:services '(shepherd ready-marker sshd)
|
||||
#:loader-entries '(("autoboot_delay" . "1")
|
||||
("boot_multicons" . "YES")
|
||||
("boot_serial" . "YES")
|
||||
("console" . "comconsole,vidconsole"))
|
||||
#:rc-conf-entries '(("clear_tmp_enable" . "NO")
|
||||
("hostid_enable" . "NO")
|
||||
("sendmail_enable" . "NONE")
|
||||
("sshd_enable" . "YES")
|
||||
("ifconfig_xn0" . "SYNCDHCP")
|
||||
("ifconfig_em0" . "SYNCDHCP")
|
||||
("ifconfig_vtnet0" . "SYNCDHCP"))
|
||||
#:init-mode 'shepherd-pid1
|
||||
#:ready-marker "/var/lib/fruix/ready"
|
||||
#:root-authorized-keys '("__ROOT_AUTHORIZED_KEY__")))
|
||||
@@ -0,0 +1,71 @@
|
||||
(use-modules (fruix system freebsd)
|
||||
(fruix packages freebsd))
|
||||
|
||||
(define phase14-operating-system
|
||||
(operating-system
|
||||
#:host-name "fruix-freebsd"
|
||||
#:kernel freebsd-native-kernel
|
||||
#:bootloader freebsd-native-world
|
||||
#:base-packages (list freebsd-native-runtime)
|
||||
#:groups (list (user-group #:name "wheel" #:gid 0 #:system? #t)
|
||||
(user-group #:name "sshd" #:gid 22 #:system? #t)
|
||||
(user-group #:name "_dhcp" #:gid 65 #:system? #t)
|
||||
(user-group #:name "operator" #:gid 1000 #:system? #f))
|
||||
#:users (list (user-account #:name "root"
|
||||
#:uid 0
|
||||
#:group "wheel"
|
||||
#:comment "Charlie &"
|
||||
#:home "/root"
|
||||
#:shell "/bin/sh"
|
||||
#:system? #t)
|
||||
(user-account #:name "sshd"
|
||||
#:uid 22
|
||||
#:group "sshd"
|
||||
#:comment "Secure Shell Daemon"
|
||||
#:home "/var/empty"
|
||||
#:shell "/usr/sbin/nologin"
|
||||
#:system? #t)
|
||||
(user-account #:name "_dhcp"
|
||||
#:uid 65
|
||||
#:group "_dhcp"
|
||||
#:comment "dhcp programs"
|
||||
#:home "/var/empty"
|
||||
#:shell "/usr/sbin/nologin"
|
||||
#:system? #t)
|
||||
(user-account #:name "operator"
|
||||
#:uid 1000
|
||||
#:group "operator"
|
||||
#:supplementary-groups '("wheel")
|
||||
#:comment "Fruix Operator"
|
||||
#:home "/home/operator"
|
||||
#:shell "/bin/sh"
|
||||
#:system? #f))
|
||||
#:file-systems (list (file-system #:device "/dev/gpt/fruix-root"
|
||||
#:mount-point "/"
|
||||
#:type "ufs"
|
||||
#:options "rw"
|
||||
#:needed-for-boot? #t)
|
||||
(file-system #:device "devfs"
|
||||
#:mount-point "/dev"
|
||||
#:type "devfs"
|
||||
#:options "rw"
|
||||
#:needed-for-boot? #t)
|
||||
(file-system #:device "tmpfs"
|
||||
#:mount-point "/tmp"
|
||||
#:type "tmpfs"
|
||||
#:options "rw,size=64m"))
|
||||
#:services '(shepherd ready-marker sshd)
|
||||
#:loader-entries '(("autoboot_delay" . "1")
|
||||
("boot_multicons" . "YES")
|
||||
("boot_serial" . "YES")
|
||||
("console" . "comconsole,vidconsole"))
|
||||
#:rc-conf-entries '(("clear_tmp_enable" . "NO")
|
||||
("hostid_enable" . "NO")
|
||||
("sendmail_enable" . "NONE")
|
||||
("sshd_enable" . "YES")
|
||||
("ifconfig_xn0" . "SYNCDHCP")
|
||||
("ifconfig_em0" . "SYNCDHCP")
|
||||
("ifconfig_vtnet0" . "SYNCDHCP"))
|
||||
#:init-mode 'shepherd-pid1
|
||||
#:ready-marker "/var/lib/fruix/ready"
|
||||
#:root-authorized-keys '("__ROOT_AUTHORIZED_KEY__")))
|
||||
@@ -0,0 +1,71 @@
|
||||
(use-modules (fruix system freebsd)
|
||||
(fruix packages freebsd))
|
||||
|
||||
(define phase14-operating-system
|
||||
(operating-system
|
||||
#:host-name "fruix-freebsd"
|
||||
#:kernel freebsd-native-kernel
|
||||
#:bootloader freebsd-native-bootloader
|
||||
#:base-packages %freebsd-native-system-packages
|
||||
#:groups (list (user-group #:name "wheel" #:gid 0 #:system? #t)
|
||||
(user-group #:name "sshd" #:gid 22 #:system? #t)
|
||||
(user-group #:name "_dhcp" #:gid 65 #:system? #t)
|
||||
(user-group #:name "operator" #:gid 1000 #:system? #f))
|
||||
#:users (list (user-account #:name "root"
|
||||
#:uid 0
|
||||
#:group "wheel"
|
||||
#:comment "Charlie &"
|
||||
#:home "/root"
|
||||
#:shell "/bin/sh"
|
||||
#:system? #t)
|
||||
(user-account #:name "sshd"
|
||||
#:uid 22
|
||||
#:group "sshd"
|
||||
#:comment "Secure Shell Daemon"
|
||||
#:home "/var/empty"
|
||||
#:shell "/usr/sbin/nologin"
|
||||
#:system? #t)
|
||||
(user-account #:name "_dhcp"
|
||||
#:uid 65
|
||||
#:group "_dhcp"
|
||||
#:comment "dhcp programs"
|
||||
#:home "/var/empty"
|
||||
#:shell "/usr/sbin/nologin"
|
||||
#:system? #t)
|
||||
(user-account #:name "operator"
|
||||
#:uid 1000
|
||||
#:group "operator"
|
||||
#:supplementary-groups '("wheel")
|
||||
#:comment "Fruix Operator"
|
||||
#:home "/home/operator"
|
||||
#:shell "/bin/sh"
|
||||
#:system? #f))
|
||||
#:file-systems (list (file-system #:device "/dev/gpt/fruix-root"
|
||||
#:mount-point "/"
|
||||
#:type "ufs"
|
||||
#:options "rw"
|
||||
#:needed-for-boot? #t)
|
||||
(file-system #:device "devfs"
|
||||
#:mount-point "/dev"
|
||||
#:type "devfs"
|
||||
#:options "rw"
|
||||
#:needed-for-boot? #t)
|
||||
(file-system #:device "tmpfs"
|
||||
#:mount-point "/tmp"
|
||||
#:type "tmpfs"
|
||||
#:options "rw,size=64m"))
|
||||
#:services '(shepherd ready-marker sshd)
|
||||
#:loader-entries '(("autoboot_delay" . "1")
|
||||
("boot_multicons" . "YES")
|
||||
("boot_serial" . "YES")
|
||||
("console" . "comconsole,vidconsole"))
|
||||
#:rc-conf-entries '(("clear_tmp_enable" . "NO")
|
||||
("hostid_enable" . "NO")
|
||||
("sendmail_enable" . "NONE")
|
||||
("sshd_enable" . "YES")
|
||||
("ifconfig_xn0" . "SYNCDHCP")
|
||||
("ifconfig_em0" . "SYNCDHCP")
|
||||
("ifconfig_vtnet0" . "SYNCDHCP"))
|
||||
#:init-mode 'shepherd-pid1
|
||||
#:ready-marker "/var/lib/fruix/ready"
|
||||
#:root-authorized-keys '("__ROOT_AUTHORIZED_KEY__")))
|
||||
@@ -0,0 +1,83 @@
|
||||
(use-modules (fruix system freebsd)
|
||||
(fruix packages freebsd))
|
||||
|
||||
(define phase15-base
|
||||
(freebsd-base
|
||||
#:name "__BASE_NAME__"
|
||||
#:version-label "__BASE_VERSION_LABEL__"
|
||||
#:release "__BASE_RELEASE__"
|
||||
#:branch "__BASE_BRANCH__"
|
||||
#:source-root "/usr/src"
|
||||
#:target "amd64"
|
||||
#:target-arch "amd64"
|
||||
#:kernconf "GENERIC"))
|
||||
|
||||
(define phase15-operating-system
|
||||
(operating-system
|
||||
#:host-name "fruix-freebsd"
|
||||
#:freebsd-base phase15-base
|
||||
#:kernel (freebsd-native-kernel-for phase15-base)
|
||||
#:bootloader (freebsd-native-bootloader-for phase15-base)
|
||||
#:base-packages (freebsd-native-system-packages-for phase15-base)
|
||||
#:groups (list (user-group #:name "wheel" #:gid 0 #:system? #t)
|
||||
(user-group #:name "sshd" #:gid 22 #:system? #t)
|
||||
(user-group #:name "_dhcp" #:gid 65 #:system? #t)
|
||||
(user-group #:name "operator" #:gid 1000 #:system? #f))
|
||||
#:users (list (user-account #:name "root"
|
||||
#:uid 0
|
||||
#:group "wheel"
|
||||
#:comment "Charlie &"
|
||||
#:home "/root"
|
||||
#:shell "/bin/sh"
|
||||
#:system? #t)
|
||||
(user-account #:name "sshd"
|
||||
#:uid 22
|
||||
#:group "sshd"
|
||||
#:comment "Secure Shell Daemon"
|
||||
#:home "/var/empty"
|
||||
#:shell "/usr/sbin/nologin"
|
||||
#:system? #t)
|
||||
(user-account #:name "_dhcp"
|
||||
#:uid 65
|
||||
#:group "_dhcp"
|
||||
#:comment "dhcp programs"
|
||||
#:home "/var/empty"
|
||||
#:shell "/usr/sbin/nologin"
|
||||
#:system? #t)
|
||||
(user-account #:name "operator"
|
||||
#:uid 1000
|
||||
#:group "operator"
|
||||
#:supplementary-groups '("wheel")
|
||||
#:comment "Fruix Operator"
|
||||
#:home "/home/operator"
|
||||
#:shell "/bin/sh"
|
||||
#:system? #f))
|
||||
#:file-systems (list (file-system #:device "/dev/gpt/fruix-root"
|
||||
#:mount-point "/"
|
||||
#:type "ufs"
|
||||
#:options "rw"
|
||||
#:needed-for-boot? #t)
|
||||
(file-system #:device "devfs"
|
||||
#:mount-point "/dev"
|
||||
#:type "devfs"
|
||||
#:options "rw"
|
||||
#:needed-for-boot? #t)
|
||||
(file-system #:device "tmpfs"
|
||||
#:mount-point "/tmp"
|
||||
#:type "tmpfs"
|
||||
#:options "rw,size=64m"))
|
||||
#:services '(shepherd ready-marker sshd)
|
||||
#:loader-entries '(("autoboot_delay" . "1")
|
||||
("boot_multicons" . "YES")
|
||||
("boot_serial" . "YES")
|
||||
("console" . "comconsole,vidconsole"))
|
||||
#:rc-conf-entries '(("clear_tmp_enable" . "NO")
|
||||
("hostid_enable" . "NO")
|
||||
("sendmail_enable" . "NONE")
|
||||
("sshd_enable" . "YES")
|
||||
("ifconfig_xn0" . "SYNCDHCP")
|
||||
("ifconfig_em0" . "SYNCDHCP")
|
||||
("ifconfig_vtnet0" . "SYNCDHCP"))
|
||||
#:init-mode 'shepherd-pid1
|
||||
#:ready-marker "/var/lib/fruix/ready"
|
||||
#:root-authorized-keys '("__ROOT_AUTHORIZED_KEY__")))
|
||||
@@ -0,0 +1,90 @@
|
||||
(use-modules (fruix system freebsd)
|
||||
(fruix packages freebsd))
|
||||
|
||||
(define phase16-source
|
||||
(freebsd-source
|
||||
#:name "__SOURCE_NAME__"
|
||||
#:kind 'local-tree
|
||||
#:path "/usr/src"))
|
||||
|
||||
(define phase16-base
|
||||
(freebsd-base
|
||||
#:name "__BASE_NAME__"
|
||||
#:version-label "__BASE_VERSION_LABEL__"
|
||||
#:release "__BASE_RELEASE__"
|
||||
#:branch "__BASE_BRANCH__"
|
||||
#:source phase16-source
|
||||
#:source-root "/usr/src"
|
||||
#:target "amd64"
|
||||
#:target-arch "amd64"
|
||||
#:kernconf "GENERIC"))
|
||||
|
||||
(define phase16-operating-system
|
||||
(operating-system
|
||||
#:host-name "fruix-freebsd"
|
||||
#:freebsd-base phase16-base
|
||||
#:kernel (freebsd-native-kernel-for phase16-base)
|
||||
#:bootloader (freebsd-native-bootloader-for phase16-base)
|
||||
#:base-packages (freebsd-native-system-packages-for phase16-base)
|
||||
#:groups (list (user-group #:name "wheel" #:gid 0 #:system? #t)
|
||||
(user-group #:name "sshd" #:gid 22 #:system? #t)
|
||||
(user-group #:name "_dhcp" #:gid 65 #:system? #t)
|
||||
(user-group #:name "operator" #:gid 1000 #:system? #f))
|
||||
#:users (list (user-account #:name "root"
|
||||
#:uid 0
|
||||
#:group "wheel"
|
||||
#:comment "Charlie &"
|
||||
#:home "/root"
|
||||
#:shell "/bin/sh"
|
||||
#:system? #t)
|
||||
(user-account #:name "sshd"
|
||||
#:uid 22
|
||||
#:group "sshd"
|
||||
#:comment "Secure Shell Daemon"
|
||||
#:home "/var/empty"
|
||||
#:shell "/usr/sbin/nologin"
|
||||
#:system? #t)
|
||||
(user-account #:name "_dhcp"
|
||||
#:uid 65
|
||||
#:group "_dhcp"
|
||||
#:comment "dhcp programs"
|
||||
#:home "/var/empty"
|
||||
#:shell "/usr/sbin/nologin"
|
||||
#:system? #t)
|
||||
(user-account #:name "operator"
|
||||
#:uid 1000
|
||||
#:group "operator"
|
||||
#:supplementary-groups '("wheel")
|
||||
#:comment "Fruix Operator"
|
||||
#:home "/home/operator"
|
||||
#:shell "/bin/sh"
|
||||
#:system? #f))
|
||||
#:file-systems (list (file-system #:device "/dev/gpt/fruix-root"
|
||||
#:mount-point "/"
|
||||
#:type "ufs"
|
||||
#:options "rw"
|
||||
#:needed-for-boot? #t)
|
||||
(file-system #:device "devfs"
|
||||
#:mount-point "/dev"
|
||||
#:type "devfs"
|
||||
#:options "rw"
|
||||
#:needed-for-boot? #t)
|
||||
(file-system #:device "tmpfs"
|
||||
#:mount-point "/tmp"
|
||||
#:type "tmpfs"
|
||||
#:options "rw,size=64m"))
|
||||
#:services '(shepherd ready-marker sshd)
|
||||
#:loader-entries '(("autoboot_delay" . "1")
|
||||
("boot_multicons" . "YES")
|
||||
("boot_serial" . "YES")
|
||||
("console" . "comconsole,vidconsole"))
|
||||
#:rc-conf-entries '(("clear_tmp_enable" . "NO")
|
||||
("hostid_enable" . "NO")
|
||||
("sendmail_enable" . "NONE")
|
||||
("sshd_enable" . "YES")
|
||||
("ifconfig_xn0" . "SYNCDHCP")
|
||||
("ifconfig_em0" . "SYNCDHCP")
|
||||
("ifconfig_vtnet0" . "SYNCDHCP"))
|
||||
#:init-mode 'shepherd-pid1
|
||||
#:ready-marker "/var/lib/fruix/ready"
|
||||
#:root-authorized-keys '("__ROOT_AUTHORIZED_KEY__")))
|
||||
@@ -2,7 +2,7 @@
|
||||
set -eu
|
||||
|
||||
repo_root=${PROJECT_ROOT:-$(pwd)}
|
||||
os_template=$repo_root/tests/system/phase11-shepherd-pid1-operating-system.scm.in
|
||||
os_template=${OS_TEMPLATE:-$repo_root/tests/system/phase11-shepherd-pid1-operating-system.scm.in}
|
||||
system_name=${SYSTEM_NAME:-phase11-operating-system}
|
||||
metadata_target=${METADATA_OUT:-}
|
||||
root_authorized_key_file=${ROOT_AUTHORIZED_KEY_FILE:-$HOME/.ssh/id_ed25519.pub}
|
||||
@@ -68,6 +68,8 @@ closure_path=$(sed -n 's/^closure_path=//p' "$phase8_metadata")
|
||||
closure_base=$(basename "$closure_path")
|
||||
raw_sha256=$(sed -n 's/^raw_sha256=//p' "$phase8_metadata")
|
||||
image_store_path=$(sed -n 's/^image_store_path=//p' "$phase8_metadata")
|
||||
boot_disk_image=$workdir/boot-disk.img
|
||||
cp "$disk_image" "$boot_disk_image"
|
||||
|
||||
sudo qemu-system-x86_64 \
|
||||
-machine q35,accel=tcg \
|
||||
@@ -81,7 +83,7 @@ sudo qemu-system-x86_64 \
|
||||
-daemonize \
|
||||
-drive if=pflash,format=raw,readonly=on,file=/usr/local/share/edk2-qemu/QEMU_UEFI_CODE-x86_64.fd \
|
||||
-drive if=pflash,format=raw,file="$uefi_vars" \
|
||||
-drive if=virtio,format=raw,file="$disk_image" \
|
||||
-drive if=virtio,format=raw,file="$boot_disk_image" \
|
||||
-netdev user,id=net0,hostfwd=tcp::${ssh_port}-:22 \
|
||||
-device virtio-net-pci,netdev=net0
|
||||
|
||||
@@ -148,6 +150,7 @@ phase8_log=$phase8_log
|
||||
phase8_metadata=$phase8_metadata
|
||||
image_store_path=$image_store_path
|
||||
disk_image=$disk_image
|
||||
boot_disk_image=$boot_disk_image
|
||||
closure_path=$closure_path
|
||||
closure_base=$closure_base
|
||||
raw_sha256=$raw_sha256
|
||||
|
||||
224
tests/system/run-phase13-native-base-build.sh
Executable file
224
tests/system/run-phase13-native-base-build.sh
Executable file
@@ -0,0 +1,224 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
project_root=${PROJECT_ROOT:-$(pwd)}
|
||||
script_dir=$(CDPATH= cd -- "$(dirname "$0")" && pwd)
|
||||
fruix_cmd=$project_root/bin/fruix
|
||||
os_template=${OS_TEMPLATE:-$script_dir/phase13-native-base-pid1-operating-system.scm.in}
|
||||
system_name=${SYSTEM_NAME:-phase13-operating-system}
|
||||
store_dir=${STORE_DIR:-/frx/store}
|
||||
metadata_target=${METADATA_OUT:-}
|
||||
root_authorized_key_file=${ROOT_AUTHORIZED_KEY_FILE:-$HOME/.ssh/id_ed25519.pub}
|
||||
|
||||
[ -x "$fruix_cmd" ] || {
|
||||
echo "fruix command is not executable: $fruix_cmd" >&2
|
||||
exit 1
|
||||
}
|
||||
[ -f "$os_template" ] || {
|
||||
echo "missing operating-system template: $os_template" >&2
|
||||
exit 1
|
||||
}
|
||||
[ -f "$root_authorized_key_file" ] || {
|
||||
echo "missing root authorized key file: $root_authorized_key_file" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
cleanup=0
|
||||
if [ -n "${WORKDIR:-}" ]; then
|
||||
workdir=$WORKDIR
|
||||
mkdir -p "$workdir"
|
||||
else
|
||||
workdir=$(mktemp -d /tmp/fruix-phase13-native-build.XXXXXX)
|
||||
cleanup=1
|
||||
fi
|
||||
if [ "${KEEP_WORKDIR:-0}" -eq 1 ]; then
|
||||
cleanup=0
|
||||
fi
|
||||
|
||||
cleanup_workdir() {
|
||||
if [ "$cleanup" -eq 1 ]; then
|
||||
rm -rf "$workdir" 2>/dev/null || sudo rm -rf "$workdir"
|
||||
fi
|
||||
}
|
||||
trap cleanup_workdir EXIT INT TERM
|
||||
|
||||
phase13_os_file=$workdir/phase13-native-base-operating-system.scm
|
||||
build_out_a=$workdir/build-a.txt
|
||||
build_out_b=$workdir/build-b.txt
|
||||
metadata_file=$workdir/phase13-native-base-build-metadata.txt
|
||||
root_authorized_key=$(tr -d '\n' < "$root_authorized_key_file")
|
||||
sed "s|__ROOT_AUTHORIZED_KEY__|$root_authorized_key|g" "$os_template" > "$phase13_os_file"
|
||||
|
||||
action_env() {
|
||||
sudo env \
|
||||
HOME="$HOME" \
|
||||
GUILE_AUTO_COMPILE=0 \
|
||||
FRUIX_FREEBSD_BUILD_JOBS="${FRUIX_FREEBSD_BUILD_JOBS:-8}" \
|
||||
GUIX_SOURCE_DIR="${GUIX_SOURCE_DIR:-$HOME/repos/guix}" \
|
||||
GUILE_BIN="${GUILE_BIN:-/tmp/guile-freebsd-validate-install/bin/guile}" \
|
||||
GUILE_EXTRA_PREFIX="${GUILE_EXTRA_PREFIX:-/tmp/guile-gnutls-freebsd-validate-install}" \
|
||||
SHEPHERD_PREFIX="${SHEPHERD_PREFIX:-/tmp/shepherd-freebsd-validate-install}" \
|
||||
"$@"
|
||||
}
|
||||
|
||||
printf 'Using fruix command: %s\n' "$fruix_cmd"
|
||||
printf 'Working directory: %s\n' "$workdir"
|
||||
printf 'Store directory: %s\n' "$store_dir"
|
||||
printf 'OS template: %s\n' "$os_template"
|
||||
|
||||
action_env "$fruix_cmd" system build "$phase13_os_file" --system "$system_name" --store "$store_dir" >"$build_out_a"
|
||||
action_env "$fruix_cmd" system build "$phase13_os_file" --system "$system_name" --store "$store_dir" >"$build_out_b"
|
||||
|
||||
closure_path=$(sed -n 's/^closure_path=//p' "$build_out_a")
|
||||
closure_rebuild_path=$(sed -n 's/^closure_path=//p' "$build_out_b")
|
||||
kernel_store=$(sed -n 's/^kernel_store=//p' "$build_out_a")
|
||||
bootloader_store=$(sed -n 's/^bootloader_store=//p' "$build_out_a")
|
||||
host_base_store_count=$(sed -n 's/^host_base_store_count=//p' "$build_out_a")
|
||||
host_base_stores=$(sed -n 's/^host_base_stores=//p' "$build_out_a")
|
||||
native_base_store_count=$(sed -n 's/^native_base_store_count=//p' "$build_out_a")
|
||||
native_base_stores=$(sed -n 's/^native_base_stores=//p' "$build_out_a")
|
||||
fruix_runtime_store_count=$(sed -n 's/^fruix_runtime_store_count=//p' "$build_out_a")
|
||||
fruix_runtime_stores=$(sed -n 's/^fruix_runtime_stores=//p' "$build_out_a")
|
||||
host_base_provenance_file=$(sed -n 's/^host_base_provenance_file=//p' "$build_out_a")
|
||||
store_layout_file=$(sed -n 's/^store_layout_file=//p' "$build_out_a")
|
||||
reference_count=$(sed -n 's/^reference_count=//p' "$build_out_a")
|
||||
generated_file_count=$(sed -n 's/^generated_file_count=//p' "$build_out_a")
|
||||
|
||||
[ -n "$closure_path" ] || { echo "missing closure path" >&2; exit 1; }
|
||||
[ "$closure_path" = "$closure_rebuild_path" ] || {
|
||||
echo "native-base closure path was not reproducible: $closure_path != $closure_rebuild_path" >&2
|
||||
exit 1
|
||||
}
|
||||
case "$kernel_store" in
|
||||
/frx/store/*-freebsd-native-kernel-15.0-STABLE) : ;;
|
||||
*) echo "unexpected native kernel store path: $kernel_store" >&2; exit 1 ;;
|
||||
esac
|
||||
case "$bootloader_store" in
|
||||
/frx/store/*-freebsd-bootloader-15.0-STABLE) : ;;
|
||||
*) echo "unexpected bootloader store path: $bootloader_store" >&2; exit 1 ;;
|
||||
esac
|
||||
[ "$host_base_store_count" = 1 ] || { echo "expected exactly one host-staged base store, got: $host_base_store_count" >&2; exit 1; }
|
||||
[ "$native_base_store_count" = 2 ] || { echo "expected exactly two native base stores, got: $native_base_store_count" >&2; exit 1; }
|
||||
[ -n "$fruix_runtime_store_count" ] || { echo "missing Fruix runtime store count" >&2; exit 1; }
|
||||
[ -n "$reference_count" ] || { echo "missing reference count" >&2; exit 1; }
|
||||
[ -n "$generated_file_count" ] || { echo "missing generated file count" >&2; exit 1; }
|
||||
|
||||
world_store=$(printf '%s\n' "$native_base_stores" | tr ',' '\n' | grep 'freebsd-native-world-15.0-STABLE$' | head -n 1)
|
||||
[ -n "$world_store" ] || { echo "failed to recover native world store from metadata" >&2; exit 1; }
|
||||
|
||||
world_build_info=$world_store/.freebsd-native-build-info.scm
|
||||
kernel_build_info=$kernel_store/.freebsd-native-build-info.scm
|
||||
[ -f "$world_build_info" ] || { echo "missing world build info: $world_build_info" >&2; exit 1; }
|
||||
[ -f "$kernel_build_info" ] || { echo "missing kernel build info: $kernel_build_info" >&2; exit 1; }
|
||||
[ -f "$host_base_provenance_file" ] || { echo "missing host base provenance file: $host_base_provenance_file" >&2; exit 1; }
|
||||
[ -f "$store_layout_file" ] || { echo "missing store layout file: $store_layout_file" >&2; exit 1; }
|
||||
|
||||
for path in \
|
||||
"$kernel_store/boot/kernel/kernel" \
|
||||
"$kernel_store/boot/kernel/linker.hints" \
|
||||
"$world_store/bin/sh" \
|
||||
"$world_store/sbin/init" \
|
||||
"$world_store/etc/rc" \
|
||||
"$world_store/usr/sbin/sshd" \
|
||||
"$world_store/sbin/dhclient" \
|
||||
"$world_store/usr/bin/cap_mkdb" \
|
||||
"$world_store/usr/sbin/pwd_mkdb" \
|
||||
"$world_store/usr/share/locale/C.UTF-8/LC_CTYPE"
|
||||
do
|
||||
[ -e "$path" ] || {
|
||||
echo "required native world/kernel path missing: $path" >&2
|
||||
exit 1
|
||||
}
|
||||
done
|
||||
|
||||
[ ! -e "$world_store/usr/share/man" ] || { echo "native world still contains pruned man pages" >&2; exit 1; }
|
||||
[ ! -e "$world_store/usr/tests" ] || { echo "native world still contains pruned tests" >&2; exit 1; }
|
||||
|
||||
grep -F 'native-base-stores' "$store_layout_file" >/dev/null || {
|
||||
echo "store layout metadata is missing native-base-stores" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
grep -F 'source-root . "/usr/src"' "$world_build_info" >/dev/null || {
|
||||
echo "world build info is missing /usr/src provenance" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
grep -F 'source-root . "/usr/src"' "$kernel_build_info" >/dev/null || {
|
||||
echo "kernel build info is missing /usr/src provenance" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
world_source_tree_sha256=$(grep -o 'source-tree-sha256 . "[^"]*"' "$world_build_info" | head -n 1 | cut -d'"' -f2)
|
||||
kernel_source_tree_sha256=$(grep -o 'source-tree-sha256 . "[^"]*"' "$kernel_build_info" | head -n 1 | cut -d'"' -f2)
|
||||
world_build_root=$(grep -o 'build-root . "[^"]*"' "$world_build_info" | head -n 1 | cut -d'"' -f2)
|
||||
kernel_build_root=$(grep -o 'build-root . "[^"]*"' "$kernel_build_info" | head -n 1 | cut -d'"' -f2)
|
||||
world_build_log=$(grep -o 'buildworld-log . "[^"]*"' "$world_build_info" | head -n 1 | cut -d'"' -f2)
|
||||
kernel_build_log=$(grep -o 'buildkernel-log . "[^"]*"' "$kernel_build_info" | head -n 1 | cut -d'"' -f2)
|
||||
world_install_log=$(grep -o 'install-log . "[^"]*"' "$world_build_info" | head -n 1 | cut -d'"' -f2)
|
||||
kernel_install_log=$(grep -o 'install-log . "[^"]*"' "$kernel_build_info" | head -n 1 | cut -d'"' -f2)
|
||||
|
||||
[ -n "$world_source_tree_sha256" ] || { echo "missing world source-tree hash" >&2; exit 1; }
|
||||
[ -n "$kernel_source_tree_sha256" ] || { echo "missing kernel source-tree hash" >&2; exit 1; }
|
||||
[ "$world_source_tree_sha256" = "$kernel_source_tree_sha256" ] || {
|
||||
echo "native world/kernel source-tree hashes differ: $world_source_tree_sha256 != $kernel_source_tree_sha256" >&2
|
||||
exit 1
|
||||
}
|
||||
[ "$world_build_root" = "$kernel_build_root" ] || {
|
||||
echo "native world/kernel build roots differ: $world_build_root != $kernel_build_root" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
for path in "$world_build_log" "$kernel_build_log" "$world_install_log" "$kernel_install_log"; do
|
||||
[ -f "$path" ] || {
|
||||
echo "expected native build log missing: $path" >&2
|
||||
exit 1
|
||||
}
|
||||
done
|
||||
|
||||
closure_base=$(basename "$closure_path")
|
||||
cat >"$metadata_file" <<EOF
|
||||
workdir=$workdir
|
||||
phase13_os_file=$phase13_os_file
|
||||
closure_path=$closure_path
|
||||
closure_rebuild_path=$closure_rebuild_path
|
||||
closure_base=$closure_base
|
||||
kernel_store=$kernel_store
|
||||
world_store=$world_store
|
||||
bootloader_store=$bootloader_store
|
||||
host_base_store_count=$host_base_store_count
|
||||
host_base_stores=$host_base_stores
|
||||
native_base_store_count=$native_base_store_count
|
||||
native_base_stores=$native_base_stores
|
||||
fruix_runtime_store_count=$fruix_runtime_store_count
|
||||
fruix_runtime_stores=$fruix_runtime_stores
|
||||
host_base_provenance_file=$host_base_provenance_file
|
||||
store_layout_file=$store_layout_file
|
||||
reference_count=$reference_count
|
||||
generated_file_count=$generated_file_count
|
||||
world_source_tree_sha256=$world_source_tree_sha256
|
||||
kernel_source_tree_sha256=$kernel_source_tree_sha256
|
||||
world_build_root=$world_build_root
|
||||
kernel_build_root=$kernel_build_root
|
||||
world_build_log=$world_build_log
|
||||
kernel_build_log=$kernel_build_log
|
||||
world_install_log=$world_install_log
|
||||
kernel_install_log=$kernel_install_log
|
||||
frontend_invocation=$fruix_cmd system build
|
||||
native_base_model=freebsd-world+freebsd-kernel-from-usr-src
|
||||
init_mode=shepherd-pid1
|
||||
EOF
|
||||
|
||||
if [ -n "$metadata_target" ]; then
|
||||
mkdir -p "$(dirname "$metadata_target")"
|
||||
cp "$metadata_file" "$metadata_target"
|
||||
fi
|
||||
|
||||
printf 'PASS phase13-native-base-build\n'
|
||||
printf 'Work directory: %s\n' "$workdir"
|
||||
printf 'Metadata file: %s\n' "$metadata_file"
|
||||
if [ -n "$metadata_target" ]; then
|
||||
printf 'Copied metadata to: %s\n' "$metadata_target"
|
||||
fi
|
||||
printf '%s\n' '--- metadata ---'
|
||||
cat "$metadata_file"
|
||||
105
tests/system/run-phase13-native-base-qemu.sh
Executable file
105
tests/system/run-phase13-native-base-qemu.sh
Executable file
@@ -0,0 +1,105 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
repo_root=${PROJECT_ROOT:-$(pwd)}
|
||||
os_template=${OS_TEMPLATE:-$repo_root/tests/system/phase13-native-base-pid1-operating-system.scm.in}
|
||||
system_name=${SYSTEM_NAME:-phase13-operating-system}
|
||||
disk_capacity=${DISK_CAPACITY:-8g}
|
||||
root_size=${ROOT_SIZE:-6g}
|
||||
metadata_target=${METADATA_OUT:-}
|
||||
cleanup=0
|
||||
|
||||
if [ -n "${WORKDIR:-}" ]; then
|
||||
workdir=$WORKDIR
|
||||
mkdir -p "$workdir"
|
||||
else
|
||||
workdir=$(mktemp -d /tmp/fruix-phase13-native-qemu.XXXXXX)
|
||||
cleanup=1
|
||||
fi
|
||||
if [ "${KEEP_WORKDIR:-0}" -eq 1 ]; then
|
||||
cleanup=0
|
||||
fi
|
||||
|
||||
inner_metadata=$workdir/phase11-native-qemu-inner-metadata.txt
|
||||
metadata_file=$workdir/phase13-native-base-qemu-metadata.txt
|
||||
|
||||
cleanup_workdir() {
|
||||
if [ "$cleanup" -eq 1 ]; then
|
||||
rm -rf "$workdir" 2>/dev/null || sudo rm -rf "$workdir"
|
||||
fi
|
||||
}
|
||||
trap cleanup_workdir EXIT INT TERM
|
||||
|
||||
KEEP_WORKDIR=1 WORKDIR="$workdir/inner" METADATA_OUT="$inner_metadata" \
|
||||
OS_TEMPLATE="$os_template" SYSTEM_NAME="$system_name" DISK_CAPACITY="$disk_capacity" ROOT_SIZE="$root_size" \
|
||||
"$repo_root/tests/system/run-phase11-shepherd-pid1-qemu.sh"
|
||||
|
||||
phase8_metadata=$(sed -n 's/^phase8_metadata=//p' "$inner_metadata")
|
||||
closure_path=$(sed -n 's/^closure_path=//p' "$inner_metadata")
|
||||
closure_base=$(sed -n 's/^closure_base=//p' "$inner_metadata")
|
||||
serial_log=$(sed -n 's/^serial_log=//p' "$inner_metadata")
|
||||
ssh_port=$(sed -n 's/^ssh_port=//p' "$inner_metadata")
|
||||
shepherd_pid=$(sed -n 's/^shepherd_pid=//p' "$inner_metadata")
|
||||
sshd_status=$(sed -n 's/^sshd_status=//p' "$inner_metadata")
|
||||
activate_log=$(sed -n 's/^activate_log=//p' "$inner_metadata")
|
||||
|
||||
native_base_store_count=$(sed -n 's/^native_base_store_count=//p' "$phase8_metadata")
|
||||
native_base_stores=$(sed -n 's/^native_base_stores=//p' "$phase8_metadata")
|
||||
host_base_store_count=$(sed -n 's/^host_base_store_count=//p' "$phase8_metadata")
|
||||
host_base_stores=$(sed -n 's/^host_base_stores=//p' "$phase8_metadata")
|
||||
|
||||
[ "$native_base_store_count" = 2 ] || { echo "expected 2 native base stores, got: $native_base_store_count" >&2; exit 1; }
|
||||
[ "$host_base_store_count" = 1 ] || { echo "expected 1 host base store, got: $host_base_store_count" >&2; exit 1; }
|
||||
printf '%s\n' "$native_base_stores" | tr ',' '\n' | grep 'freebsd-native-kernel-15.0-STABLE$' >/dev/null || {
|
||||
echo "native base stores do not include the native kernel" >&2
|
||||
exit 1
|
||||
}
|
||||
printf '%s\n' "$native_base_stores" | tr ',' '\n' | grep 'freebsd-native-world-15.0-STABLE$' >/dev/null || {
|
||||
echo "native base stores do not include the native world" >&2
|
||||
exit 1
|
||||
}
|
||||
printf '%s\n' "$host_base_stores" | tr ',' '\n' | grep 'freebsd-bootloader-15.0-STABLE$' >/dev/null || {
|
||||
echo "host base stores do not reduce to the bootloader" >&2
|
||||
exit 1
|
||||
}
|
||||
[ "$shepherd_pid" = 1 ] || { echo "shepherd was not PID 1" >&2; exit 1; }
|
||||
[ "$sshd_status" = running ] || { echo "sshd is not running" >&2; exit 1; }
|
||||
case "$activate_log" in
|
||||
*fruix-activate:done*) : ;;
|
||||
*) echo "activation log does not show success" >&2; exit 1 ;;
|
||||
esac
|
||||
|
||||
cat >"$metadata_file" <<EOF
|
||||
workdir=$workdir
|
||||
inner_metadata=$inner_metadata
|
||||
phase8_metadata=$phase8_metadata
|
||||
closure_path=$closure_path
|
||||
closure_base=$closure_base
|
||||
serial_log=$serial_log
|
||||
ssh_port=$ssh_port
|
||||
disk_capacity=$disk_capacity
|
||||
root_size=$root_size
|
||||
native_base_store_count=$native_base_store_count
|
||||
native_base_stores=$native_base_stores
|
||||
host_base_store_count=$host_base_store_count
|
||||
host_base_stores=$host_base_stores
|
||||
shepherd_pid=$shepherd_pid
|
||||
sshd_status=$sshd_status
|
||||
boot_backend=qemu-uefi-tcg
|
||||
init_mode=shepherd-pid1
|
||||
native_base_boot=ok
|
||||
EOF
|
||||
|
||||
if [ -n "$metadata_target" ]; then
|
||||
mkdir -p "$(dirname "$metadata_target")"
|
||||
cp "$metadata_file" "$metadata_target"
|
||||
fi
|
||||
|
||||
printf 'PASS phase13-native-base-qemu\n'
|
||||
printf 'Work directory: %s\n' "$workdir"
|
||||
printf 'Metadata file: %s\n' "$metadata_file"
|
||||
if [ -n "$metadata_target" ]; then
|
||||
printf 'Copied metadata to: %s\n' "$metadata_target"
|
||||
fi
|
||||
printf '%s\n' '--- metadata ---'
|
||||
cat "$metadata_file"
|
||||
111
tests/system/run-phase13-native-base-xcpng.sh
Executable file
111
tests/system/run-phase13-native-base-xcpng.sh
Executable file
@@ -0,0 +1,111 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
repo_root=${PROJECT_ROOT:-$(pwd)}
|
||||
os_template=${OS_TEMPLATE:-$repo_root/tests/system/phase13-native-base-pid1-operating-system.scm.in}
|
||||
system_name=${SYSTEM_NAME:-phase13-operating-system}
|
||||
root_size=${ROOT_SIZE:-6g}
|
||||
metadata_target=${METADATA_OUT:-}
|
||||
cleanup=0
|
||||
|
||||
if [ -n "${WORKDIR:-}" ]; then
|
||||
workdir=$WORKDIR
|
||||
mkdir -p "$workdir"
|
||||
else
|
||||
workdir=$(mktemp -d /tmp/fruix-phase13-native-xcpng.XXXXXX)
|
||||
cleanup=1
|
||||
fi
|
||||
if [ "${KEEP_WORKDIR:-0}" -eq 1 ]; then
|
||||
cleanup=0
|
||||
fi
|
||||
|
||||
inner_metadata=$workdir/phase11-native-xcpng-inner-metadata.txt
|
||||
metadata_file=$workdir/phase13-native-base-xcpng-metadata.txt
|
||||
|
||||
cleanup_workdir() {
|
||||
if [ "$cleanup" -eq 1 ]; then
|
||||
rm -rf "$workdir"
|
||||
fi
|
||||
}
|
||||
trap cleanup_workdir EXIT INT TERM
|
||||
|
||||
KEEP_WORKDIR=1 WORKDIR="$workdir/inner" METADATA_OUT="$inner_metadata" \
|
||||
OS_TEMPLATE="$os_template" SYSTEM_NAME="$system_name" ROOT_SIZE="$root_size" \
|
||||
"$repo_root/tests/system/run-phase11-shepherd-pid1-xcpng.sh"
|
||||
|
||||
phase8_metadata=$(sed -n 's/^phase8_metadata=//p' "$inner_metadata")
|
||||
closure_path=$(sed -n 's/^closure_path=//p' "$inner_metadata")
|
||||
closure_base=$(sed -n 's/^closure_base=//p' "$inner_metadata")
|
||||
guest_ip=$(sed -n 's/^guest_ip=//p' "$inner_metadata")
|
||||
vm_id=$(sed -n 's/^vm_id=//p' "$inner_metadata")
|
||||
vdi_id=$(sed -n 's/^vdi_id=//p' "$inner_metadata")
|
||||
shepherd_pid=$(sed -n 's/^shepherd_pid=//p' "$inner_metadata")
|
||||
sshd_status=$(sed -n 's/^sshd_status=//p' "$inner_metadata")
|
||||
compat_prefix_shims=$(sed -n 's/^compat_prefix_shims=//p' "$inner_metadata")
|
||||
guile_module_smoke=$(sed -n 's/^guile_module_smoke=//p' "$inner_metadata")
|
||||
activate_log=$(sed -n 's/^activate_log=//p' "$inner_metadata")
|
||||
|
||||
native_base_store_count=$(sed -n 's/^native_base_store_count=//p' "$phase8_metadata")
|
||||
native_base_stores=$(sed -n 's/^native_base_stores=//p' "$phase8_metadata")
|
||||
host_base_store_count=$(sed -n 's/^host_base_store_count=//p' "$phase8_metadata")
|
||||
host_base_stores=$(sed -n 's/^host_base_stores=//p' "$phase8_metadata")
|
||||
|
||||
[ "$native_base_store_count" = 2 ] || { echo "expected 2 native base stores, got: $native_base_store_count" >&2; exit 1; }
|
||||
[ "$host_base_store_count" = 1 ] || { echo "expected 1 host base store, got: $host_base_store_count" >&2; exit 1; }
|
||||
printf '%s\n' "$native_base_stores" | tr ',' '\n' | grep 'freebsd-native-kernel-15.0-STABLE$' >/dev/null || {
|
||||
echo "native base stores do not include the native kernel" >&2
|
||||
exit 1
|
||||
}
|
||||
printf '%s\n' "$native_base_stores" | tr ',' '\n' | grep 'freebsd-native-world-15.0-STABLE$' >/dev/null || {
|
||||
echo "native base stores do not include the native world" >&2
|
||||
exit 1
|
||||
}
|
||||
printf '%s\n' "$host_base_stores" | tr ',' '\n' | grep 'freebsd-bootloader-15.0-STABLE$' >/dev/null || {
|
||||
echo "host base stores do not reduce to the bootloader" >&2
|
||||
exit 1
|
||||
}
|
||||
[ "$shepherd_pid" = 1 ] || { echo "shepherd was not PID 1" >&2; exit 1; }
|
||||
[ "$sshd_status" = running ] || { echo "sshd is not running" >&2; exit 1; }
|
||||
[ "$compat_prefix_shims" = absent ] || { echo "compatibility prefix shims reappeared" >&2; exit 1; }
|
||||
[ "$guile_module_smoke" = ok ] || { echo "guest Guile module smoke failed" >&2; exit 1; }
|
||||
case "$activate_log" in
|
||||
*fruix-activate:done*) : ;;
|
||||
*) echo "activation log does not show success" >&2; exit 1 ;;
|
||||
esac
|
||||
|
||||
cat >"$metadata_file" <<EOF
|
||||
workdir=$workdir
|
||||
inner_metadata=$inner_metadata
|
||||
phase8_metadata=$phase8_metadata
|
||||
closure_path=$closure_path
|
||||
closure_base=$closure_base
|
||||
vm_id=$vm_id
|
||||
vdi_id=$vdi_id
|
||||
guest_ip=$guest_ip
|
||||
root_size=$root_size
|
||||
native_base_store_count=$native_base_store_count
|
||||
native_base_stores=$native_base_stores
|
||||
host_base_store_count=$host_base_store_count
|
||||
host_base_stores=$host_base_stores
|
||||
shepherd_pid=$shepherd_pid
|
||||
sshd_status=$sshd_status
|
||||
compat_prefix_shims=$compat_prefix_shims
|
||||
guile_module_smoke=$guile_module_smoke
|
||||
boot_backend=xcp-ng-xo-cli
|
||||
init_mode=shepherd-pid1
|
||||
native_base_boot=ok
|
||||
EOF
|
||||
|
||||
if [ -n "$metadata_target" ]; then
|
||||
mkdir -p "$(dirname "$metadata_target")"
|
||||
cp "$metadata_file" "$metadata_target"
|
||||
fi
|
||||
|
||||
printf 'PASS phase13-native-base-xcpng\n'
|
||||
printf 'Work directory: %s\n' "$workdir"
|
||||
printf 'Metadata file: %s\n' "$metadata_file"
|
||||
if [ -n "$metadata_target" ]; then
|
||||
printf 'Copied metadata to: %s\n' "$metadata_target"
|
||||
fi
|
||||
printf '%s\n' '--- metadata ---'
|
||||
cat "$metadata_file"
|
||||
103
tests/system/run-phase14-native-boot-qemu.sh
Executable file
103
tests/system/run-phase14-native-boot-qemu.sh
Executable file
@@ -0,0 +1,103 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
repo_root=${PROJECT_ROOT:-$(pwd)}
|
||||
os_template=${OS_TEMPLATE:-$repo_root/tests/system/phase14-native-boot-pid1-operating-system.scm.in}
|
||||
system_name=${SYSTEM_NAME:-phase14-operating-system}
|
||||
disk_capacity=${DISK_CAPACITY:-8g}
|
||||
root_size=${ROOT_SIZE:-6g}
|
||||
metadata_target=${METADATA_OUT:-}
|
||||
cleanup=0
|
||||
|
||||
if [ -n "${WORKDIR:-}" ]; then
|
||||
workdir=$WORKDIR
|
||||
mkdir -p "$workdir"
|
||||
else
|
||||
workdir=$(mktemp -d /tmp/fruix-phase14-native-boot-qemu.XXXXXX)
|
||||
cleanup=1
|
||||
fi
|
||||
if [ "${KEEP_WORKDIR:-0}" -eq 1 ]; then
|
||||
cleanup=0
|
||||
fi
|
||||
|
||||
inner_metadata=$workdir/phase14-native-boot-qemu-inner-metadata.txt
|
||||
metadata_file=$workdir/phase14-native-boot-qemu-metadata.txt
|
||||
|
||||
cleanup_workdir() {
|
||||
if [ "$cleanup" -eq 1 ]; then
|
||||
rm -rf "$workdir" 2>/dev/null || sudo rm -rf "$workdir"
|
||||
fi
|
||||
}
|
||||
trap cleanup_workdir EXIT INT TERM
|
||||
|
||||
KEEP_WORKDIR=1 WORKDIR="$workdir/inner" METADATA_OUT="$inner_metadata" \
|
||||
OS_TEMPLATE="$os_template" SYSTEM_NAME="$system_name" DISK_CAPACITY="$disk_capacity" ROOT_SIZE="$root_size" \
|
||||
"$repo_root/tests/system/run-phase11-shepherd-pid1-qemu.sh"
|
||||
|
||||
phase8_metadata=$(sed -n 's/^phase8_metadata=//p' "$inner_metadata")
|
||||
closure_path=$(sed -n 's/^closure_path=//p' "$inner_metadata")
|
||||
closure_base=$(sed -n 's/^closure_base=//p' "$inner_metadata")
|
||||
serial_log=$(sed -n 's/^serial_log=//p' "$inner_metadata")
|
||||
ssh_port=$(sed -n 's/^ssh_port=//p' "$inner_metadata")
|
||||
shepherd_pid=$(sed -n 's/^shepherd_pid=//p' "$inner_metadata")
|
||||
sshd_status=$(sed -n 's/^sshd_status=//p' "$inner_metadata")
|
||||
activate_log=$(sed -n 's/^activate_log=//p' "$inner_metadata")
|
||||
|
||||
native_base_store_count=$(sed -n 's/^native_base_store_count=//p' "$phase8_metadata")
|
||||
native_base_stores=$(sed -n 's/^native_base_stores=//p' "$phase8_metadata")
|
||||
host_base_store_count=$(sed -n 's/^host_base_store_count=//p' "$phase8_metadata")
|
||||
host_base_stores=$(sed -n 's/^host_base_stores=//p' "$phase8_metadata")
|
||||
|
||||
[ "$native_base_store_count" = 2 ] || { echo "expected 2 native base stores, got: $native_base_store_count" >&2; exit 1; }
|
||||
[ "$host_base_store_count" = 0 ] || { echo "expected 0 host base stores, got: $host_base_store_count" >&2; exit 1; }
|
||||
[ -z "$host_base_stores" ] || { echo "host base stores are not empty: $host_base_stores" >&2; exit 1; }
|
||||
printf '%s\n' "$native_base_stores" | tr ',' '\n' | grep 'freebsd-native-kernel-15.0-STABLE$' >/dev/null || {
|
||||
echo "native base stores do not include the native kernel" >&2
|
||||
exit 1
|
||||
}
|
||||
printf '%s\n' "$native_base_stores" | tr ',' '\n' | grep 'freebsd-native-world-15.0-STABLE$' >/dev/null || {
|
||||
echo "native base stores do not include the native world" >&2
|
||||
exit 1
|
||||
}
|
||||
[ "$shepherd_pid" = 1 ] || { echo "shepherd was not PID 1" >&2; exit 1; }
|
||||
[ "$sshd_status" = running ] || { echo "sshd is not running" >&2; exit 1; }
|
||||
case "$activate_log" in
|
||||
*fruix-activate:done*) : ;;
|
||||
*) echo "activation log does not show success" >&2; exit 1 ;;
|
||||
esac
|
||||
|
||||
cat >"$metadata_file" <<EOF
|
||||
workdir=$workdir
|
||||
inner_metadata=$inner_metadata
|
||||
phase8_metadata=$phase8_metadata
|
||||
closure_path=$closure_path
|
||||
closure_base=$closure_base
|
||||
serial_log=$serial_log
|
||||
ssh_port=$ssh_port
|
||||
disk_capacity=$disk_capacity
|
||||
root_size=$root_size
|
||||
native_base_store_count=$native_base_store_count
|
||||
native_base_stores=$native_base_stores
|
||||
host_base_store_count=$host_base_store_count
|
||||
host_base_stores=$host_base_stores
|
||||
shepherd_pid=$shepherd_pid
|
||||
sshd_status=$sshd_status
|
||||
boot_backend=qemu-uefi-tcg
|
||||
init_mode=shepherd-pid1
|
||||
native_boot_assets=freebsd-native-world
|
||||
native_base_boot=ok
|
||||
EOF
|
||||
|
||||
if [ -n "$metadata_target" ]; then
|
||||
mkdir -p "$(dirname "$metadata_target")"
|
||||
cp "$metadata_file" "$metadata_target"
|
||||
fi
|
||||
|
||||
printf 'PASS phase14-native-boot-qemu\n'
|
||||
printf 'Work directory: %s\n' "$workdir"
|
||||
printf 'Metadata file: %s\n' "$metadata_file"
|
||||
if [ -n "$metadata_target" ]; then
|
||||
printf 'Copied metadata to: %s\n' "$metadata_target"
|
||||
fi
|
||||
printf '%s\n' '--- metadata ---'
|
||||
cat "$metadata_file"
|
||||
109
tests/system/run-phase14-native-boot-xcpng.sh
Executable file
109
tests/system/run-phase14-native-boot-xcpng.sh
Executable file
@@ -0,0 +1,109 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
repo_root=${PROJECT_ROOT:-$(pwd)}
|
||||
os_template=${OS_TEMPLATE:-$repo_root/tests/system/phase14-native-boot-pid1-operating-system.scm.in}
|
||||
system_name=${SYSTEM_NAME:-phase14-operating-system}
|
||||
root_size=${ROOT_SIZE:-6g}
|
||||
metadata_target=${METADATA_OUT:-}
|
||||
cleanup=0
|
||||
|
||||
if [ -n "${WORKDIR:-}" ]; then
|
||||
workdir=$WORKDIR
|
||||
mkdir -p "$workdir"
|
||||
else
|
||||
workdir=$(mktemp -d /tmp/fruix-phase14-native-boot-xcpng.XXXXXX)
|
||||
cleanup=1
|
||||
fi
|
||||
if [ "${KEEP_WORKDIR:-0}" -eq 1 ]; then
|
||||
cleanup=0
|
||||
fi
|
||||
|
||||
inner_metadata=$workdir/phase14-native-boot-xcpng-inner-metadata.txt
|
||||
metadata_file=$workdir/phase14-native-boot-xcpng-metadata.txt
|
||||
|
||||
cleanup_workdir() {
|
||||
if [ "$cleanup" -eq 1 ]; then
|
||||
rm -rf "$workdir"
|
||||
fi
|
||||
}
|
||||
trap cleanup_workdir EXIT INT TERM
|
||||
|
||||
KEEP_WORKDIR=1 WORKDIR="$workdir/inner" METADATA_OUT="$inner_metadata" \
|
||||
OS_TEMPLATE="$os_template" SYSTEM_NAME="$system_name" ROOT_SIZE="$root_size" \
|
||||
"$repo_root/tests/system/run-phase11-shepherd-pid1-xcpng.sh"
|
||||
|
||||
phase8_metadata=$(sed -n 's/^phase8_metadata=//p' "$inner_metadata")
|
||||
closure_path=$(sed -n 's/^closure_path=//p' "$inner_metadata")
|
||||
closure_base=$(sed -n 's/^closure_base=//p' "$inner_metadata")
|
||||
guest_ip=$(sed -n 's/^guest_ip=//p' "$inner_metadata")
|
||||
vm_id=$(sed -n 's/^vm_id=//p' "$inner_metadata")
|
||||
vdi_id=$(sed -n 's/^vdi_id=//p' "$inner_metadata")
|
||||
shepherd_pid=$(sed -n 's/^shepherd_pid=//p' "$inner_metadata")
|
||||
sshd_status=$(sed -n 's/^sshd_status=//p' "$inner_metadata")
|
||||
compat_prefix_shims=$(sed -n 's/^compat_prefix_shims=//p' "$inner_metadata")
|
||||
guile_module_smoke=$(sed -n 's/^guile_module_smoke=//p' "$inner_metadata")
|
||||
activate_log=$(sed -n 's/^activate_log=//p' "$inner_metadata")
|
||||
|
||||
native_base_store_count=$(sed -n 's/^native_base_store_count=//p' "$phase8_metadata")
|
||||
native_base_stores=$(sed -n 's/^native_base_stores=//p' "$phase8_metadata")
|
||||
host_base_store_count=$(sed -n 's/^host_base_store_count=//p' "$phase8_metadata")
|
||||
host_base_stores=$(sed -n 's/^host_base_stores=//p' "$phase8_metadata")
|
||||
|
||||
[ "$native_base_store_count" = 2 ] || { echo "expected 2 native base stores, got: $native_base_store_count" >&2; exit 1; }
|
||||
[ "$host_base_store_count" = 0 ] || { echo "expected 0 host base stores, got: $host_base_store_count" >&2; exit 1; }
|
||||
[ -z "$host_base_stores" ] || { echo "host base stores are not empty: $host_base_stores" >&2; exit 1; }
|
||||
printf '%s\n' "$native_base_stores" | tr ',' '\n' | grep 'freebsd-native-kernel-15.0-STABLE$' >/dev/null || {
|
||||
echo "native base stores do not include the native kernel" >&2
|
||||
exit 1
|
||||
}
|
||||
printf '%s\n' "$native_base_stores" | tr ',' '\n' | grep 'freebsd-native-world-15.0-STABLE$' >/dev/null || {
|
||||
echo "native base stores do not include the native world" >&2
|
||||
exit 1
|
||||
}
|
||||
[ "$shepherd_pid" = 1 ] || { echo "shepherd was not PID 1" >&2; exit 1; }
|
||||
[ "$sshd_status" = running ] || { echo "sshd is not running" >&2; exit 1; }
|
||||
[ "$compat_prefix_shims" = absent ] || { echo "compatibility prefix shims reappeared" >&2; exit 1; }
|
||||
[ "$guile_module_smoke" = ok ] || { echo "guest Guile module smoke failed" >&2; exit 1; }
|
||||
case "$activate_log" in
|
||||
*fruix-activate:done*) : ;;
|
||||
*) echo "activation log does not show success" >&2; exit 1 ;;
|
||||
esac
|
||||
|
||||
cat >"$metadata_file" <<EOF
|
||||
workdir=$workdir
|
||||
inner_metadata=$inner_metadata
|
||||
phase8_metadata=$phase8_metadata
|
||||
closure_path=$closure_path
|
||||
closure_base=$closure_base
|
||||
vm_id=$vm_id
|
||||
vdi_id=$vdi_id
|
||||
guest_ip=$guest_ip
|
||||
root_size=$root_size
|
||||
native_base_store_count=$native_base_store_count
|
||||
native_base_stores=$native_base_stores
|
||||
host_base_store_count=$host_base_store_count
|
||||
host_base_stores=$host_base_stores
|
||||
shepherd_pid=$shepherd_pid
|
||||
sshd_status=$sshd_status
|
||||
compat_prefix_shims=$compat_prefix_shims
|
||||
guile_module_smoke=$guile_module_smoke
|
||||
boot_backend=xcp-ng-xo-cli
|
||||
init_mode=shepherd-pid1
|
||||
native_boot_assets=freebsd-native-world
|
||||
native_base_boot=ok
|
||||
EOF
|
||||
|
||||
if [ -n "$metadata_target" ]; then
|
||||
mkdir -p "$(dirname "$metadata_target")"
|
||||
cp "$metadata_file" "$metadata_target"
|
||||
fi
|
||||
|
||||
printf 'PASS phase14-native-boot-xcpng\n'
|
||||
printf 'Work directory: %s\n' "$workdir"
|
||||
printf 'Metadata file: %s\n' "$metadata_file"
|
||||
if [ -n "$metadata_target" ]; then
|
||||
printf 'Copied metadata to: %s\n' "$metadata_target"
|
||||
fi
|
||||
printf '%s\n' '--- metadata ---'
|
||||
cat "$metadata_file"
|
||||
142
tests/system/run-phase14-native-development-split.sh
Executable file
142
tests/system/run-phase14-native-development-split.sh
Executable file
@@ -0,0 +1,142 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
repo_root=${PROJECT_ROOT:-$(pwd)}
|
||||
store_dir=${STORE_DIR:-/frx/store}
|
||||
metadata_target=${METADATA_OUT:-}
|
||||
cleanup=0
|
||||
|
||||
if [ -n "${WORKDIR:-}" ]; then
|
||||
workdir=$WORKDIR
|
||||
mkdir -p "$workdir"
|
||||
else
|
||||
workdir=$(mktemp -d /tmp/fruix-phase14-native-development.XXXXXX)
|
||||
cleanup=1
|
||||
fi
|
||||
if [ "${KEEP_WORKDIR:-0}" -eq 1 ]; then
|
||||
cleanup=0
|
||||
fi
|
||||
|
||||
metadata_file=$workdir/phase14-native-development-split-metadata.txt
|
||||
|
||||
cleanup_workdir() {
|
||||
if [ "$cleanup" -eq 1 ]; then
|
||||
rm -rf "$workdir" 2>/dev/null || sudo rm -rf "$workdir"
|
||||
fi
|
||||
}
|
||||
trap cleanup_workdir EXIT INT TERM
|
||||
|
||||
action_env() {
|
||||
sudo env \
|
||||
HOME="$HOME" \
|
||||
GUILE_AUTO_COMPILE=0 \
|
||||
FRUIX_FREEBSD_BUILD_JOBS="${FRUIX_FREEBSD_BUILD_JOBS:-8}" \
|
||||
GUIX_SOURCE_DIR="${GUIX_SOURCE_DIR:-$HOME/repos/guix}" \
|
||||
GUILE_BIN="${GUILE_BIN:-/tmp/guile-freebsd-validate-install/bin/guile}" \
|
||||
GUILE_EXTRA_PREFIX="${GUILE_EXTRA_PREFIX:-/tmp/guile-gnutls-freebsd-validate-install}" \
|
||||
SHEPHERD_PREFIX="${SHEPHERD_PREFIX:-/tmp/shepherd-freebsd-validate-install}" \
|
||||
"$@"
|
||||
}
|
||||
|
||||
native_system_packages=$(GUILE_AUTO_COMPILE=0 /tmp/guile-freebsd-validate-install/bin/guile -L modules -L "$HOME/repos/guix" -c '
|
||||
(use-modules (fruix packages freebsd) (srfi srfi-13))
|
||||
(display (string-join (map freebsd-package-name %freebsd-native-system-packages) ","))
|
||||
(newline)')
|
||||
|
||||
native_development_packages=$(GUILE_AUTO_COMPILE=0 /tmp/guile-freebsd-validate-install/bin/guile -L modules -L "$HOME/repos/guix" -c '
|
||||
(use-modules (fruix packages freebsd) (srfi srfi-13))
|
||||
(display (string-join (map freebsd-package-name %freebsd-native-development-profile-packages) ","))
|
||||
(newline)')
|
||||
|
||||
materialize_native_package() {
|
||||
package_name=$1
|
||||
action_env env LD_LIBRARY_PATH="/tmp/guile-freebsd-validate-install/lib:/usr/local/lib" /tmp/guile-freebsd-validate-install/bin/guile -L modules -L "$HOME/repos/guix" -c '
|
||||
(use-modules (fruix packages freebsd) (ice-9 hash-table))
|
||||
(let* ((args (command-line))
|
||||
(store-dir (list-ref args (- (length args) 2)))
|
||||
(package-name (list-ref args (- (length args) 1)))
|
||||
(pkg (case (string->symbol package-name)
|
||||
((freebsd-native-bootloader) freebsd-native-bootloader)
|
||||
((freebsd-native-headers) freebsd-native-headers)
|
||||
(else (error "unsupported package" package-name))))
|
||||
(system-module (resolve-module (quote (fruix system freebsd))))
|
||||
(materialize (module-ref system-module (quote materialize-freebsd-package)))
|
||||
(cache (make-hash-table))
|
||||
(path (materialize pkg store-dir cache)))
|
||||
(display "STORE_PATH=")
|
||||
(display path)
|
||||
(newline))' dummy "$store_dir" "$package_name"
|
||||
}
|
||||
|
||||
bootloader_store=$(materialize_native_package freebsd-native-bootloader | sed -n 's/^STORE_PATH=//p' | tail -n 1)
|
||||
headers_store=$(materialize_native_package freebsd-native-headers | sed -n 's/^STORE_PATH=//p' | tail -n 1)
|
||||
|
||||
case "$bootloader_store" in
|
||||
/frx/store/*-freebsd-native-bootloader-15.0-STABLE) : ;;
|
||||
*) echo "unexpected native bootloader store path: $bootloader_store" >&2; exit 1 ;;
|
||||
esac
|
||||
case "$headers_store" in
|
||||
/frx/store/*-freebsd-native-headers-15.0-STABLE) : ;;
|
||||
*) echo "unexpected native headers store path: $headers_store" >&2; exit 1 ;;
|
||||
esac
|
||||
|
||||
for path in \
|
||||
"$bootloader_store/boot/loader" \
|
||||
"$bootloader_store/boot/loader.efi" \
|
||||
"$bootloader_store/boot/device.hints" \
|
||||
"$bootloader_store/boot/defaults/loader.conf" \
|
||||
"$bootloader_store/boot/lua/loader.lua" \
|
||||
"$headers_store/usr/include/stdio.h" \
|
||||
"$headers_store/usr/include/sys/param.h" \
|
||||
"$headers_store/usr/share/mk/bsd.prog.mk"
|
||||
do
|
||||
[ -e "$path" ] || {
|
||||
echo "expected native split artifact path missing: $path" >&2
|
||||
exit 1
|
||||
}
|
||||
done
|
||||
|
||||
[ ! -e "$bootloader_store/usr/include" ] || { echo "native bootloader slice unexpectedly contains headers" >&2; exit 1; }
|
||||
[ ! -e "$headers_store/boot" ] || { echo "native headers slice unexpectedly contains /boot" >&2; exit 1; }
|
||||
[ ! -e "$headers_store/bin/sh" ] || { echo "native headers slice unexpectedly contains runtime binaries" >&2; exit 1; }
|
||||
|
||||
case ",$native_system_packages," in
|
||||
*,freebsd-native-runtime,*) : ;;
|
||||
*) echo "native system package set does not include freebsd-native-runtime" >&2; exit 1 ;;
|
||||
esac
|
||||
case ",$native_development_packages," in
|
||||
*,freebsd-native-runtime,*) : ;;
|
||||
*) echo "native development package set does not include freebsd-native-runtime" >&2; exit 1 ;;
|
||||
esac
|
||||
case ",$native_development_packages," in
|
||||
*,freebsd-native-headers,*) : ;;
|
||||
*) echo "native development package set does not include freebsd-native-headers" >&2; exit 1 ;;
|
||||
esac
|
||||
case ",$native_development_packages," in
|
||||
*,freebsd-clang-toolchain,*) : ;;
|
||||
*) echo "native development package set does not retain the explicit toolchain artifact" >&2; exit 1 ;;
|
||||
esac
|
||||
|
||||
cat >"$metadata_file" <<EOF
|
||||
workdir=$workdir
|
||||
store_dir=$store_dir
|
||||
bootloader_store=$bootloader_store
|
||||
headers_store=$headers_store
|
||||
native_system_packages=$native_system_packages
|
||||
native_development_packages=$native_development_packages
|
||||
runtime_vs_development_split=ok
|
||||
EOF
|
||||
|
||||
if [ -n "$metadata_target" ]; then
|
||||
mkdir -p "$(dirname "$metadata_target")"
|
||||
cp "$metadata_file" "$metadata_target"
|
||||
fi
|
||||
|
||||
printf 'PASS phase14-native-development-split\n'
|
||||
printf 'Work directory: %s\n' "$workdir"
|
||||
printf 'Metadata file: %s\n' "$metadata_file"
|
||||
if [ -n "$metadata_target" ]; then
|
||||
printf 'Copied metadata to: %s\n' "$metadata_target"
|
||||
fi
|
||||
printf '%s\n' '--- metadata ---'
|
||||
cat "$metadata_file"
|
||||
124
tests/system/run-phase14-native-runtime-qemu.sh
Executable file
124
tests/system/run-phase14-native-runtime-qemu.sh
Executable file
@@ -0,0 +1,124 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
repo_root=${PROJECT_ROOT:-$(pwd)}
|
||||
os_template=${OS_TEMPLATE:-$repo_root/tests/system/phase14-native-runtime-pid1-operating-system.scm.in}
|
||||
system_name=${SYSTEM_NAME:-phase14-operating-system}
|
||||
disk_capacity=${DISK_CAPACITY:-12g}
|
||||
root_size=${ROOT_SIZE:-10g}
|
||||
metadata_target=${METADATA_OUT:-}
|
||||
cleanup=0
|
||||
|
||||
if [ -n "${WORKDIR:-}" ]; then
|
||||
workdir=$WORKDIR
|
||||
mkdir -p "$workdir"
|
||||
else
|
||||
workdir=$(mktemp -d /tmp/fruix-phase14-native-runtime-qemu.XXXXXX)
|
||||
cleanup=1
|
||||
fi
|
||||
if [ "${KEEP_WORKDIR:-0}" -eq 1 ]; then
|
||||
cleanup=0
|
||||
fi
|
||||
|
||||
inner_metadata=$workdir/phase14-native-runtime-qemu-inner-metadata.txt
|
||||
metadata_file=$workdir/phase14-native-runtime-qemu-metadata.txt
|
||||
|
||||
cleanup_workdir() {
|
||||
if [ "$cleanup" -eq 1 ]; then
|
||||
rm -rf "$workdir" 2>/dev/null || sudo rm -rf "$workdir"
|
||||
fi
|
||||
}
|
||||
trap cleanup_workdir EXIT INT TERM
|
||||
|
||||
KEEP_WORKDIR=1 WORKDIR="$workdir/inner" METADATA_OUT="$inner_metadata" \
|
||||
OS_TEMPLATE="$os_template" SYSTEM_NAME="$system_name" DISK_CAPACITY="$disk_capacity" ROOT_SIZE="$root_size" \
|
||||
"$repo_root/tests/system/run-phase11-shepherd-pid1-qemu.sh"
|
||||
|
||||
phase8_metadata=$(sed -n 's/^phase8_metadata=//p' "$inner_metadata")
|
||||
closure_path=$(sed -n 's/^closure_path=//p' "$inner_metadata")
|
||||
closure_base=$(sed -n 's/^closure_base=//p' "$inner_metadata")
|
||||
serial_log=$(sed -n 's/^serial_log=//p' "$inner_metadata")
|
||||
ssh_port=$(sed -n 's/^ssh_port=//p' "$inner_metadata")
|
||||
shepherd_pid=$(sed -n 's/^shepherd_pid=//p' "$inner_metadata")
|
||||
sshd_status=$(sed -n 's/^sshd_status=//p' "$inner_metadata")
|
||||
activate_log=$(sed -n 's/^activate_log=//p' "$inner_metadata")
|
||||
|
||||
native_base_store_count=$(sed -n 's/^native_base_store_count=//p' "$phase8_metadata")
|
||||
native_base_stores=$(sed -n 's/^native_base_stores=//p' "$phase8_metadata")
|
||||
host_base_store_count=$(sed -n 's/^host_base_store_count=//p' "$phase8_metadata")
|
||||
host_base_stores=$(sed -n 's/^host_base_stores=//p' "$phase8_metadata")
|
||||
|
||||
[ "$native_base_store_count" = 3 ] || { echo "expected 3 native base stores, got: $native_base_store_count" >&2; exit 1; }
|
||||
[ "$host_base_store_count" = 0 ] || { echo "expected 0 host base stores, got: $host_base_store_count" >&2; exit 1; }
|
||||
[ -z "$host_base_stores" ] || { echo "host base stores are not empty: $host_base_stores" >&2; exit 1; }
|
||||
printf '%s\n' "$native_base_stores" | tr ',' '\n' | grep 'freebsd-native-kernel-15.0-STABLE$' >/dev/null || {
|
||||
echo "native base stores do not include the native kernel" >&2
|
||||
exit 1
|
||||
}
|
||||
printf '%s\n' "$native_base_stores" | tr ',' '\n' | grep 'freebsd-native-world-15.0-STABLE$' >/dev/null || {
|
||||
echo "native base stores do not include the native boot/world source artifact" >&2
|
||||
exit 1
|
||||
}
|
||||
runtime_store=$(printf '%s\n' "$native_base_stores" | tr ',' '\n' | grep 'freebsd-native-runtime-15.0-STABLE$' | head -n 1)
|
||||
[ -n "$runtime_store" ] || {
|
||||
echo "native base stores do not include the explicit native runtime slice" >&2
|
||||
exit 1
|
||||
}
|
||||
for path in \
|
||||
"$runtime_store/bin/sh" \
|
||||
"$runtime_store/sbin/init" \
|
||||
"$runtime_store/etc/rc" \
|
||||
"$runtime_store/usr/sbin/sshd" \
|
||||
"$runtime_store/sbin/dhclient" \
|
||||
"$runtime_store/usr/bin/ssh-keygen" \
|
||||
"$runtime_store/usr/share/locale/C.UTF-8/LC_CTYPE"
|
||||
do
|
||||
[ -e "$path" ] || {
|
||||
echo "required native runtime path missing: $path" >&2
|
||||
exit 1
|
||||
}
|
||||
done
|
||||
[ ! -e "$runtime_store/boot" ] || { echo "native runtime still contains /boot" >&2; exit 1; }
|
||||
[ ! -e "$runtime_store/usr/include" ] || { echo "native runtime still contains /usr/include" >&2; exit 1; }
|
||||
[ "$shepherd_pid" = 1 ] || { echo "shepherd was not PID 1" >&2; exit 1; }
|
||||
[ "$sshd_status" = running ] || { echo "sshd is not running" >&2; exit 1; }
|
||||
case "$activate_log" in
|
||||
*fruix-activate:done*) : ;;
|
||||
*) echo "activation log does not show success" >&2; exit 1 ;;
|
||||
esac
|
||||
|
||||
cat >"$metadata_file" <<EOF
|
||||
workdir=$workdir
|
||||
inner_metadata=$inner_metadata
|
||||
phase8_metadata=$phase8_metadata
|
||||
closure_path=$closure_path
|
||||
closure_base=$closure_base
|
||||
serial_log=$serial_log
|
||||
ssh_port=$ssh_port
|
||||
disk_capacity=$disk_capacity
|
||||
root_size=$root_size
|
||||
runtime_store=$runtime_store
|
||||
native_base_store_count=$native_base_store_count
|
||||
native_base_stores=$native_base_stores
|
||||
host_base_store_count=$host_base_store_count
|
||||
host_base_stores=$host_base_stores
|
||||
shepherd_pid=$shepherd_pid
|
||||
sshd_status=$sshd_status
|
||||
boot_backend=qemu-uefi-tcg
|
||||
init_mode=shepherd-pid1
|
||||
native_runtime_ready=ok
|
||||
EOF
|
||||
|
||||
if [ -n "$metadata_target" ]; then
|
||||
mkdir -p "$(dirname "$metadata_target")"
|
||||
cp "$metadata_file" "$metadata_target"
|
||||
fi
|
||||
|
||||
printf 'PASS phase14-native-runtime-qemu\n'
|
||||
printf 'Work directory: %s\n' "$workdir"
|
||||
printf 'Metadata file: %s\n' "$metadata_file"
|
||||
if [ -n "$metadata_target" ]; then
|
||||
printf 'Copied metadata to: %s\n' "$metadata_target"
|
||||
fi
|
||||
printf '%s\n' '--- metadata ---'
|
||||
cat "$metadata_file"
|
||||
130
tests/system/run-phase14-native-runtime-xcpng.sh
Executable file
130
tests/system/run-phase14-native-runtime-xcpng.sh
Executable file
@@ -0,0 +1,130 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
repo_root=${PROJECT_ROOT:-$(pwd)}
|
||||
os_template=${OS_TEMPLATE:-$repo_root/tests/system/phase14-native-runtime-pid1-operating-system.scm.in}
|
||||
system_name=${SYSTEM_NAME:-phase14-operating-system}
|
||||
root_size=${ROOT_SIZE:-10g}
|
||||
metadata_target=${METADATA_OUT:-}
|
||||
cleanup=0
|
||||
|
||||
if [ -n "${WORKDIR:-}" ]; then
|
||||
workdir=$WORKDIR
|
||||
mkdir -p "$workdir"
|
||||
else
|
||||
workdir=$(mktemp -d /tmp/fruix-phase14-native-runtime-xcpng.XXXXXX)
|
||||
cleanup=1
|
||||
fi
|
||||
if [ "${KEEP_WORKDIR:-0}" -eq 1 ]; then
|
||||
cleanup=0
|
||||
fi
|
||||
|
||||
inner_metadata=$workdir/phase14-native-runtime-xcpng-inner-metadata.txt
|
||||
metadata_file=$workdir/phase14-native-runtime-xcpng-metadata.txt
|
||||
|
||||
cleanup_workdir() {
|
||||
if [ "$cleanup" -eq 1 ]; then
|
||||
rm -rf "$workdir"
|
||||
fi
|
||||
}
|
||||
trap cleanup_workdir EXIT INT TERM
|
||||
|
||||
KEEP_WORKDIR=1 WORKDIR="$workdir/inner" METADATA_OUT="$inner_metadata" \
|
||||
OS_TEMPLATE="$os_template" SYSTEM_NAME="$system_name" ROOT_SIZE="$root_size" \
|
||||
"$repo_root/tests/system/run-phase11-shepherd-pid1-xcpng.sh"
|
||||
|
||||
phase8_metadata=$(sed -n 's/^phase8_metadata=//p' "$inner_metadata")
|
||||
closure_path=$(sed -n 's/^closure_path=//p' "$inner_metadata")
|
||||
closure_base=$(sed -n 's/^closure_base=//p' "$inner_metadata")
|
||||
guest_ip=$(sed -n 's/^guest_ip=//p' "$inner_metadata")
|
||||
vm_id=$(sed -n 's/^vm_id=//p' "$inner_metadata")
|
||||
vdi_id=$(sed -n 's/^vdi_id=//p' "$inner_metadata")
|
||||
shepherd_pid=$(sed -n 's/^shepherd_pid=//p' "$inner_metadata")
|
||||
sshd_status=$(sed -n 's/^sshd_status=//p' "$inner_metadata")
|
||||
compat_prefix_shims=$(sed -n 's/^compat_prefix_shims=//p' "$inner_metadata")
|
||||
guile_module_smoke=$(sed -n 's/^guile_module_smoke=//p' "$inner_metadata")
|
||||
activate_log=$(sed -n 's/^activate_log=//p' "$inner_metadata")
|
||||
|
||||
native_base_store_count=$(sed -n 's/^native_base_store_count=//p' "$phase8_metadata")
|
||||
native_base_stores=$(sed -n 's/^native_base_stores=//p' "$phase8_metadata")
|
||||
host_base_store_count=$(sed -n 's/^host_base_store_count=//p' "$phase8_metadata")
|
||||
host_base_stores=$(sed -n 's/^host_base_stores=//p' "$phase8_metadata")
|
||||
|
||||
[ "$native_base_store_count" = 3 ] || { echo "expected 3 native base stores, got: $native_base_store_count" >&2; exit 1; }
|
||||
[ "$host_base_store_count" = 0 ] || { echo "expected 0 host base stores, got: $host_base_store_count" >&2; exit 1; }
|
||||
[ -z "$host_base_stores" ] || { echo "host base stores are not empty: $host_base_stores" >&2; exit 1; }
|
||||
printf '%s\n' "$native_base_stores" | tr ',' '\n' | grep 'freebsd-native-kernel-15.0-STABLE$' >/dev/null || {
|
||||
echo "native base stores do not include the native kernel" >&2
|
||||
exit 1
|
||||
}
|
||||
printf '%s\n' "$native_base_stores" | tr ',' '\n' | grep 'freebsd-native-world-15.0-STABLE$' >/dev/null || {
|
||||
echo "native base stores do not include the native boot/world source artifact" >&2
|
||||
exit 1
|
||||
}
|
||||
runtime_store=$(printf '%s\n' "$native_base_stores" | tr ',' '\n' | grep 'freebsd-native-runtime-15.0-STABLE$' | head -n 1)
|
||||
[ -n "$runtime_store" ] || {
|
||||
echo "native base stores do not include the explicit native runtime slice" >&2
|
||||
exit 1
|
||||
}
|
||||
for path in \
|
||||
"$runtime_store/bin/sh" \
|
||||
"$runtime_store/sbin/init" \
|
||||
"$runtime_store/etc/rc" \
|
||||
"$runtime_store/usr/sbin/sshd" \
|
||||
"$runtime_store/sbin/dhclient" \
|
||||
"$runtime_store/usr/bin/ssh-keygen" \
|
||||
"$runtime_store/usr/share/locale/C.UTF-8/LC_CTYPE"
|
||||
do
|
||||
[ -e "$path" ] || {
|
||||
echo "required native runtime path missing: $path" >&2
|
||||
exit 1
|
||||
}
|
||||
done
|
||||
[ ! -e "$runtime_store/boot" ] || { echo "native runtime still contains /boot" >&2; exit 1; }
|
||||
[ ! -e "$runtime_store/usr/include" ] || { echo "native runtime still contains /usr/include" >&2; exit 1; }
|
||||
[ "$shepherd_pid" = 1 ] || { echo "shepherd was not PID 1" >&2; exit 1; }
|
||||
[ "$sshd_status" = running ] || { echo "sshd is not running" >&2; exit 1; }
|
||||
[ "$compat_prefix_shims" = absent ] || { echo "compatibility prefix shims reappeared" >&2; exit 1; }
|
||||
[ "$guile_module_smoke" = ok ] || { echo "guest Guile module smoke failed" >&2; exit 1; }
|
||||
case "$activate_log" in
|
||||
*fruix-activate:done*) : ;;
|
||||
*) echo "activation log does not show success" >&2; exit 1 ;;
|
||||
esac
|
||||
|
||||
cat >"$metadata_file" <<EOF
|
||||
workdir=$workdir
|
||||
inner_metadata=$inner_metadata
|
||||
phase8_metadata=$phase8_metadata
|
||||
closure_path=$closure_path
|
||||
closure_base=$closure_base
|
||||
vm_id=$vm_id
|
||||
vdi_id=$vdi_id
|
||||
guest_ip=$guest_ip
|
||||
root_size=$root_size
|
||||
runtime_store=$runtime_store
|
||||
native_base_store_count=$native_base_store_count
|
||||
native_base_stores=$native_base_stores
|
||||
host_base_store_count=$host_base_store_count
|
||||
host_base_stores=$host_base_stores
|
||||
shepherd_pid=$shepherd_pid
|
||||
sshd_status=$sshd_status
|
||||
compat_prefix_shims=$compat_prefix_shims
|
||||
guile_module_smoke=$guile_module_smoke
|
||||
boot_backend=xcp-ng-xo-cli
|
||||
init_mode=shepherd-pid1
|
||||
native_runtime_ready=ok
|
||||
EOF
|
||||
|
||||
if [ -n "$metadata_target" ]; then
|
||||
mkdir -p "$(dirname "$metadata_target")"
|
||||
cp "$metadata_file" "$metadata_target"
|
||||
fi
|
||||
|
||||
printf 'PASS phase14-native-runtime-xcpng\n'
|
||||
printf 'Work directory: %s\n' "$workdir"
|
||||
printf 'Metadata file: %s\n' "$metadata_file"
|
||||
if [ -n "$metadata_target" ]; then
|
||||
printf 'Copied metadata to: %s\n' "$metadata_target"
|
||||
fi
|
||||
printf '%s\n' '--- metadata ---'
|
||||
cat "$metadata_file"
|
||||
129
tests/system/run-phase14-native-split-qemu.sh
Executable file
129
tests/system/run-phase14-native-split-qemu.sh
Executable file
@@ -0,0 +1,129 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
repo_root=${PROJECT_ROOT:-$(pwd)}
|
||||
os_template=${OS_TEMPLATE:-$repo_root/tests/system/phase14-native-split-pid1-operating-system.scm.in}
|
||||
system_name=${SYSTEM_NAME:-phase14-operating-system}
|
||||
disk_capacity=${DISK_CAPACITY:-8g}
|
||||
root_size=${ROOT_SIZE:-6g}
|
||||
metadata_target=${METADATA_OUT:-}
|
||||
cleanup=0
|
||||
|
||||
if [ -n "${WORKDIR:-}" ]; then
|
||||
workdir=$WORKDIR
|
||||
mkdir -p "$workdir"
|
||||
else
|
||||
workdir=$(mktemp -d /tmp/fruix-phase14-native-split-qemu.XXXXXX)
|
||||
cleanup=1
|
||||
fi
|
||||
if [ "${KEEP_WORKDIR:-0}" -eq 1 ]; then
|
||||
cleanup=0
|
||||
fi
|
||||
|
||||
inner_metadata=$workdir/phase14-native-split-qemu-inner-metadata.txt
|
||||
metadata_file=$workdir/phase14-native-split-qemu-metadata.txt
|
||||
|
||||
cleanup_workdir() {
|
||||
if [ "$cleanup" -eq 1 ]; then
|
||||
rm -rf "$workdir" 2>/dev/null || sudo rm -rf "$workdir"
|
||||
fi
|
||||
}
|
||||
trap cleanup_workdir EXIT INT TERM
|
||||
|
||||
KEEP_WORKDIR=1 WORKDIR="$workdir/inner" METADATA_OUT="$inner_metadata" \
|
||||
OS_TEMPLATE="$os_template" SYSTEM_NAME="$system_name" DISK_CAPACITY="$disk_capacity" ROOT_SIZE="$root_size" \
|
||||
"$repo_root/tests/system/run-phase11-shepherd-pid1-qemu.sh"
|
||||
|
||||
phase8_metadata=$(sed -n 's/^phase8_metadata=//p' "$inner_metadata")
|
||||
closure_path=$(sed -n 's/^closure_path=//p' "$inner_metadata")
|
||||
closure_base=$(sed -n 's/^closure_base=//p' "$inner_metadata")
|
||||
serial_log=$(sed -n 's/^serial_log=//p' "$inner_metadata")
|
||||
ssh_port=$(sed -n 's/^ssh_port=//p' "$inner_metadata")
|
||||
shepherd_pid=$(sed -n 's/^shepherd_pid=//p' "$inner_metadata")
|
||||
sshd_status=$(sed -n 's/^sshd_status=//p' "$inner_metadata")
|
||||
activate_log=$(sed -n 's/^activate_log=//p' "$inner_metadata")
|
||||
|
||||
native_base_store_count=$(sed -n 's/^native_base_store_count=//p' "$phase8_metadata")
|
||||
native_base_stores=$(sed -n 's/^native_base_stores=//p' "$phase8_metadata")
|
||||
host_base_store_count=$(sed -n 's/^host_base_store_count=//p' "$phase8_metadata")
|
||||
host_base_stores=$(sed -n 's/^host_base_stores=//p' "$phase8_metadata")
|
||||
|
||||
[ "$native_base_store_count" = 3 ] || { echo "expected 3 native base stores, got: $native_base_store_count" >&2; exit 1; }
|
||||
[ "$host_base_store_count" = 0 ] || { echo "expected 0 host base stores, got: $host_base_store_count" >&2; exit 1; }
|
||||
[ -z "$host_base_stores" ] || { echo "host base stores are not empty: $host_base_stores" >&2; exit 1; }
|
||||
printf '%s\n' "$native_base_stores" | tr ',' '\n' | grep 'freebsd-native-kernel-15.0-STABLE$' >/dev/null || {
|
||||
echo "native base stores do not include the native kernel" >&2
|
||||
exit 1
|
||||
}
|
||||
bootloader_store=$(printf '%s\n' "$native_base_stores" | tr ',' '\n' | grep 'freebsd-native-bootloader-15.0-STABLE$' | head -n 1)
|
||||
runtime_store=$(printf '%s\n' "$native_base_stores" | tr ',' '\n' | grep 'freebsd-native-runtime-15.0-STABLE$' | head -n 1)
|
||||
[ -n "$bootloader_store" ] || { echo "native base stores do not include the native bootloader slice" >&2; exit 1; }
|
||||
[ -n "$runtime_store" ] || { echo "native base stores do not include the native runtime slice" >&2; exit 1; }
|
||||
printf '%s\n' "$native_base_stores" | tr ',' '\n' | grep 'freebsd-native-world-15.0-STABLE$' >/dev/null && {
|
||||
echo "broad native world artifact should no longer be part of the validated split-system closure" >&2
|
||||
exit 1
|
||||
}
|
||||
for path in \
|
||||
"$bootloader_store/boot/loader" \
|
||||
"$bootloader_store/boot/loader.efi" \
|
||||
"$bootloader_store/boot/device.hints" \
|
||||
"$bootloader_store/boot/defaults/loader.conf" \
|
||||
"$bootloader_store/boot/lua/loader.lua" \
|
||||
"$runtime_store/bin/sh" \
|
||||
"$runtime_store/sbin/init" \
|
||||
"$runtime_store/etc/rc" \
|
||||
"$runtime_store/usr/sbin/sshd" \
|
||||
"$runtime_store/sbin/dhclient" \
|
||||
"$runtime_store/usr/bin/ssh-keygen" \
|
||||
"$runtime_store/usr/share/locale/C.UTF-8/LC_CTYPE"
|
||||
do
|
||||
[ -e "$path" ] || {
|
||||
echo "required native split path missing: $path" >&2
|
||||
exit 1
|
||||
}
|
||||
done
|
||||
[ ! -e "$runtime_store/boot" ] || { echo "native runtime still contains /boot" >&2; exit 1; }
|
||||
[ ! -e "$runtime_store/usr/include" ] || { echo "native runtime still contains /usr/include" >&2; exit 1; }
|
||||
[ "$shepherd_pid" = 1 ] || { echo "shepherd was not PID 1" >&2; exit 1; }
|
||||
[ "$sshd_status" = running ] || { echo "sshd is not running" >&2; exit 1; }
|
||||
case "$activate_log" in
|
||||
*fruix-activate:done*) : ;;
|
||||
*) echo "activation log does not show success" >&2; exit 1 ;;
|
||||
esac
|
||||
|
||||
cat >"$metadata_file" <<EOF
|
||||
workdir=$workdir
|
||||
inner_metadata=$inner_metadata
|
||||
phase8_metadata=$phase8_metadata
|
||||
closure_path=$closure_path
|
||||
closure_base=$closure_base
|
||||
serial_log=$serial_log
|
||||
ssh_port=$ssh_port
|
||||
disk_capacity=$disk_capacity
|
||||
root_size=$root_size
|
||||
bootloader_store=$bootloader_store
|
||||
runtime_store=$runtime_store
|
||||
native_base_store_count=$native_base_store_count
|
||||
native_base_stores=$native_base_stores
|
||||
host_base_store_count=$host_base_store_count
|
||||
host_base_stores=$host_base_stores
|
||||
shepherd_pid=$shepherd_pid
|
||||
sshd_status=$sshd_status
|
||||
boot_backend=qemu-uefi-tcg
|
||||
init_mode=shepherd-pid1
|
||||
native_split_boot=ok
|
||||
EOF
|
||||
|
||||
if [ -n "$metadata_target" ]; then
|
||||
mkdir -p "$(dirname "$metadata_target")"
|
||||
cp "$metadata_file" "$metadata_target"
|
||||
fi
|
||||
|
||||
printf 'PASS phase14-native-split-qemu\n'
|
||||
printf 'Work directory: %s\n' "$workdir"
|
||||
printf 'Metadata file: %s\n' "$metadata_file"
|
||||
if [ -n "$metadata_target" ]; then
|
||||
printf 'Copied metadata to: %s\n' "$metadata_target"
|
||||
fi
|
||||
printf '%s\n' '--- metadata ---'
|
||||
cat "$metadata_file"
|
||||
135
tests/system/run-phase14-native-split-xcpng.sh
Executable file
135
tests/system/run-phase14-native-split-xcpng.sh
Executable file
@@ -0,0 +1,135 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
repo_root=${PROJECT_ROOT:-$(pwd)}
|
||||
os_template=${OS_TEMPLATE:-$repo_root/tests/system/phase14-native-split-pid1-operating-system.scm.in}
|
||||
system_name=${SYSTEM_NAME:-phase14-operating-system}
|
||||
root_size=${ROOT_SIZE:-6g}
|
||||
metadata_target=${METADATA_OUT:-}
|
||||
cleanup=0
|
||||
|
||||
if [ -n "${WORKDIR:-}" ]; then
|
||||
workdir=$WORKDIR
|
||||
mkdir -p "$workdir"
|
||||
else
|
||||
workdir=$(mktemp -d /tmp/fruix-phase14-native-split-xcpng.XXXXXX)
|
||||
cleanup=1
|
||||
fi
|
||||
if [ "${KEEP_WORKDIR:-0}" -eq 1 ]; then
|
||||
cleanup=0
|
||||
fi
|
||||
|
||||
inner_metadata=$workdir/phase14-native-split-xcpng-inner-metadata.txt
|
||||
metadata_file=$workdir/phase14-native-split-xcpng-metadata.txt
|
||||
|
||||
cleanup_workdir() {
|
||||
if [ "$cleanup" -eq 1 ]; then
|
||||
rm -rf "$workdir"
|
||||
fi
|
||||
}
|
||||
trap cleanup_workdir EXIT INT TERM
|
||||
|
||||
KEEP_WORKDIR=1 WORKDIR="$workdir/inner" METADATA_OUT="$inner_metadata" \
|
||||
OS_TEMPLATE="$os_template" SYSTEM_NAME="$system_name" ROOT_SIZE="$root_size" \
|
||||
"$repo_root/tests/system/run-phase11-shepherd-pid1-xcpng.sh"
|
||||
|
||||
phase8_metadata=$(sed -n 's/^phase8_metadata=//p' "$inner_metadata")
|
||||
closure_path=$(sed -n 's/^closure_path=//p' "$inner_metadata")
|
||||
closure_base=$(sed -n 's/^closure_base=//p' "$inner_metadata")
|
||||
guest_ip=$(sed -n 's/^guest_ip=//p' "$inner_metadata")
|
||||
vm_id=$(sed -n 's/^vm_id=//p' "$inner_metadata")
|
||||
vdi_id=$(sed -n 's/^vdi_id=//p' "$inner_metadata")
|
||||
shepherd_pid=$(sed -n 's/^shepherd_pid=//p' "$inner_metadata")
|
||||
sshd_status=$(sed -n 's/^sshd_status=//p' "$inner_metadata")
|
||||
compat_prefix_shims=$(sed -n 's/^compat_prefix_shims=//p' "$inner_metadata")
|
||||
guile_module_smoke=$(sed -n 's/^guile_module_smoke=//p' "$inner_metadata")
|
||||
activate_log=$(sed -n 's/^activate_log=//p' "$inner_metadata")
|
||||
|
||||
native_base_store_count=$(sed -n 's/^native_base_store_count=//p' "$phase8_metadata")
|
||||
native_base_stores=$(sed -n 's/^native_base_stores=//p' "$phase8_metadata")
|
||||
host_base_store_count=$(sed -n 's/^host_base_store_count=//p' "$phase8_metadata")
|
||||
host_base_stores=$(sed -n 's/^host_base_stores=//p' "$phase8_metadata")
|
||||
|
||||
[ "$native_base_store_count" = 3 ] || { echo "expected 3 native base stores, got: $native_base_store_count" >&2; exit 1; }
|
||||
[ "$host_base_store_count" = 0 ] || { echo "expected 0 host base stores, got: $host_base_store_count" >&2; exit 1; }
|
||||
[ -z "$host_base_stores" ] || { echo "host base stores are not empty: $host_base_stores" >&2; exit 1; }
|
||||
printf '%s\n' "$native_base_stores" | tr ',' '\n' | grep 'freebsd-native-kernel-15.0-STABLE$' >/dev/null || {
|
||||
echo "native base stores do not include the native kernel" >&2
|
||||
exit 1
|
||||
}
|
||||
bootloader_store=$(printf '%s\n' "$native_base_stores" | tr ',' '\n' | grep 'freebsd-native-bootloader-15.0-STABLE$' | head -n 1)
|
||||
runtime_store=$(printf '%s\n' "$native_base_stores" | tr ',' '\n' | grep 'freebsd-native-runtime-15.0-STABLE$' | head -n 1)
|
||||
[ -n "$bootloader_store" ] || { echo "native base stores do not include the native bootloader slice" >&2; exit 1; }
|
||||
[ -n "$runtime_store" ] || { echo "native base stores do not include the native runtime slice" >&2; exit 1; }
|
||||
printf '%s\n' "$native_base_stores" | tr ',' '\n' | grep 'freebsd-native-world-15.0-STABLE$' >/dev/null && {
|
||||
echo "broad native world artifact should no longer be part of the validated split-system closure" >&2
|
||||
exit 1
|
||||
}
|
||||
for path in \
|
||||
"$bootloader_store/boot/loader" \
|
||||
"$bootloader_store/boot/loader.efi" \
|
||||
"$bootloader_store/boot/device.hints" \
|
||||
"$bootloader_store/boot/defaults/loader.conf" \
|
||||
"$bootloader_store/boot/lua/loader.lua" \
|
||||
"$runtime_store/bin/sh" \
|
||||
"$runtime_store/sbin/init" \
|
||||
"$runtime_store/etc/rc" \
|
||||
"$runtime_store/usr/sbin/sshd" \
|
||||
"$runtime_store/sbin/dhclient" \
|
||||
"$runtime_store/usr/bin/ssh-keygen" \
|
||||
"$runtime_store/usr/share/locale/C.UTF-8/LC_CTYPE"
|
||||
do
|
||||
[ -e "$path" ] || {
|
||||
echo "required native split path missing: $path" >&2
|
||||
exit 1
|
||||
}
|
||||
done
|
||||
[ ! -e "$runtime_store/boot" ] || { echo "native runtime still contains /boot" >&2; exit 1; }
|
||||
[ ! -e "$runtime_store/usr/include" ] || { echo "native runtime still contains /usr/include" >&2; exit 1; }
|
||||
[ "$shepherd_pid" = 1 ] || { echo "shepherd was not PID 1" >&2; exit 1; }
|
||||
[ "$sshd_status" = running ] || { echo "sshd is not running" >&2; exit 1; }
|
||||
[ "$compat_prefix_shims" = absent ] || { echo "compatibility prefix shims reappeared" >&2; exit 1; }
|
||||
[ "$guile_module_smoke" = ok ] || { echo "guest Guile module smoke failed" >&2; exit 1; }
|
||||
case "$activate_log" in
|
||||
*fruix-activate:done*) : ;;
|
||||
*) echo "activation log does not show success" >&2; exit 1 ;;
|
||||
esac
|
||||
|
||||
cat >"$metadata_file" <<EOF
|
||||
workdir=$workdir
|
||||
inner_metadata=$inner_metadata
|
||||
phase8_metadata=$phase8_metadata
|
||||
closure_path=$closure_path
|
||||
closure_base=$closure_base
|
||||
vm_id=$vm_id
|
||||
vdi_id=$vdi_id
|
||||
guest_ip=$guest_ip
|
||||
root_size=$root_size
|
||||
bootloader_store=$bootloader_store
|
||||
runtime_store=$runtime_store
|
||||
native_base_store_count=$native_base_store_count
|
||||
native_base_stores=$native_base_stores
|
||||
host_base_store_count=$host_base_store_count
|
||||
host_base_stores=$host_base_stores
|
||||
shepherd_pid=$shepherd_pid
|
||||
sshd_status=$sshd_status
|
||||
compat_prefix_shims=$compat_prefix_shims
|
||||
guile_module_smoke=$guile_module_smoke
|
||||
boot_backend=xcp-ng-xo-cli
|
||||
init_mode=shepherd-pid1
|
||||
native_split_boot=ok
|
||||
EOF
|
||||
|
||||
if [ -n "$metadata_target" ]; then
|
||||
mkdir -p "$(dirname "$metadata_target")"
|
||||
cp "$metadata_file" "$metadata_target"
|
||||
fi
|
||||
|
||||
printf 'PASS phase14-native-split-xcpng\n'
|
||||
printf 'Work directory: %s\n' "$workdir"
|
||||
printf 'Metadata file: %s\n' "$metadata_file"
|
||||
if [ -n "$metadata_target" ]; then
|
||||
printf 'Copied metadata to: %s\n' "$metadata_target"
|
||||
fi
|
||||
printf '%s\n' '--- metadata ---'
|
||||
cat "$metadata_file"
|
||||
192
tests/system/run-phase15-base-coexistence.sh
Executable file
192
tests/system/run-phase15-base-coexistence.sh
Executable file
@@ -0,0 +1,192 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
project_root=${PROJECT_ROOT:-$(pwd)}
|
||||
script_dir=$(CDPATH= cd -- "$(dirname "$0")" && pwd)
|
||||
fruix_cmd=$project_root/bin/fruix
|
||||
os_template=${OS_TEMPLATE:-$script_dir/phase15-declarative-base-pid1-operating-system.scm.in}
|
||||
system_name=${SYSTEM_NAME:-phase15-operating-system}
|
||||
store_dir=${STORE_DIR:-/frx/store}
|
||||
current_base_name=${CURRENT_BASE_NAME:-stable-default}
|
||||
current_base_version=${CURRENT_BASE_VERSION:-15.0-STABLE}
|
||||
current_base_release=${CURRENT_BASE_RELEASE:-15.0-STABLE}
|
||||
current_base_branch=${CURRENT_BASE_BRANCH:-stable/15}
|
||||
candidate_base_name=${CANDIDATE_BASE_NAME:-stable-canary}
|
||||
candidate_base_version=${CANDIDATE_BASE_VERSION:-15.0-STABLE-p1}
|
||||
candidate_base_release=${CANDIDATE_BASE_RELEASE:-15.0-STABLE}
|
||||
candidate_base_branch=${CANDIDATE_BASE_BRANCH:-stable/15}
|
||||
metadata_target=${METADATA_OUT:-}
|
||||
root_authorized_key_file=${ROOT_AUTHORIZED_KEY_FILE:-$HOME/.ssh/id_ed25519.pub}
|
||||
|
||||
[ -x "$fruix_cmd" ] || {
|
||||
echo "fruix command is not executable: $fruix_cmd" >&2
|
||||
exit 1
|
||||
}
|
||||
[ -f "$os_template" ] || {
|
||||
echo "missing operating-system template: $os_template" >&2
|
||||
exit 1
|
||||
}
|
||||
[ -f "$root_authorized_key_file" ] || {
|
||||
echo "missing root authorized key file: $root_authorized_key_file" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
cleanup=0
|
||||
if [ -n "${WORKDIR:-}" ]; then
|
||||
workdir=$WORKDIR
|
||||
mkdir -p "$workdir"
|
||||
else
|
||||
workdir=$(mktemp -d /tmp/fruix-phase15-base-coexistence.XXXXXX)
|
||||
cleanup=1
|
||||
fi
|
||||
if [ "${KEEP_WORKDIR:-0}" -eq 1 ]; then
|
||||
cleanup=0
|
||||
fi
|
||||
|
||||
cleanup_workdir() {
|
||||
if [ "$cleanup" -eq 1 ]; then
|
||||
rm -rf "$workdir" 2>/dev/null || sudo rm -rf "$workdir"
|
||||
fi
|
||||
}
|
||||
trap cleanup_workdir EXIT INT TERM
|
||||
|
||||
render_os() {
|
||||
output=$1
|
||||
base_name=$2
|
||||
base_version=$3
|
||||
base_release=$4
|
||||
base_branch=$5
|
||||
root_authorized_key=$(tr -d '\n' < "$root_authorized_key_file")
|
||||
sed \
|
||||
-e "s|__BASE_NAME__|$base_name|g" \
|
||||
-e "s|__BASE_VERSION_LABEL__|$base_version|g" \
|
||||
-e "s|__BASE_RELEASE__|$base_release|g" \
|
||||
-e "s|__BASE_BRANCH__|$base_branch|g" \
|
||||
-e "s|__ROOT_AUTHORIZED_KEY__|$root_authorized_key|g" \
|
||||
"$os_template" > "$output"
|
||||
}
|
||||
|
||||
action_env() {
|
||||
sudo env \
|
||||
HOME="$HOME" \
|
||||
GUILE_AUTO_COMPILE=0 \
|
||||
FRUIX_FREEBSD_BUILD_JOBS="${FRUIX_FREEBSD_BUILD_JOBS:-8}" \
|
||||
GUIX_SOURCE_DIR="${GUIX_SOURCE_DIR:-$HOME/repos/guix}" \
|
||||
GUILE_BIN="${GUILE_BIN:-/tmp/guile-freebsd-validate-install/bin/guile}" \
|
||||
GUILE_EXTRA_PREFIX="${GUILE_EXTRA_PREFIX:-/tmp/guile-gnutls-freebsd-validate-install}" \
|
||||
SHEPHERD_PREFIX="${SHEPHERD_PREFIX:-/tmp/shepherd-freebsd-validate-install}" \
|
||||
"$@"
|
||||
}
|
||||
|
||||
build_os() {
|
||||
os_file=$1
|
||||
out_file=$2
|
||||
action_env "$fruix_cmd" system build "$os_file" --system "$system_name" --store "$store_dir" >"$out_file"
|
||||
}
|
||||
|
||||
current_os=$workdir/current-operating-system.scm
|
||||
candidate_os=$workdir/candidate-operating-system.scm
|
||||
current_out_a=$workdir/current-build-a.txt
|
||||
current_out_b=$workdir/current-build-b.txt
|
||||
candidate_out=$workdir/candidate-build.txt
|
||||
metadata_file=$workdir/phase15-base-coexistence-metadata.txt
|
||||
|
||||
render_os "$current_os" "$current_base_name" "$current_base_version" "$current_base_release" "$current_base_branch"
|
||||
render_os "$candidate_os" "$candidate_base_name" "$candidate_base_version" "$candidate_base_release" "$candidate_base_branch"
|
||||
|
||||
build_os "$current_os" "$current_out_a"
|
||||
build_os "$candidate_os" "$candidate_out"
|
||||
build_os "$current_os" "$current_out_b"
|
||||
|
||||
current_closure=$(sed -n 's/^closure_path=//p' "$current_out_a")
|
||||
current_closure_rebuild=$(sed -n 's/^closure_path=//p' "$current_out_b")
|
||||
candidate_closure=$(sed -n 's/^closure_path=//p' "$candidate_out")
|
||||
current_native_stores=$(sed -n 's/^native_base_stores=//p' "$current_out_a")
|
||||
candidate_native_stores=$(sed -n 's/^native_base_stores=//p' "$candidate_out")
|
||||
current_host_count=$(sed -n 's/^host_base_store_count=//p' "$current_out_a")
|
||||
candidate_host_count=$(sed -n 's/^host_base_store_count=//p' "$candidate_out")
|
||||
current_base_version_out=$(sed -n 's/^freebsd_base_version_label=//p' "$current_out_a")
|
||||
candidate_base_version_out=$(sed -n 's/^freebsd_base_version_label=//p' "$candidate_out")
|
||||
current_base_file=$(sed -n 's/^freebsd_base_file=//p' "$current_out_a")
|
||||
candidate_base_file=$(sed -n 's/^freebsd_base_file=//p' "$candidate_out")
|
||||
|
||||
[ -n "$current_closure" ] || { echo "missing current closure" >&2; exit 1; }
|
||||
[ -n "$candidate_closure" ] || { echo "missing candidate closure" >&2; exit 1; }
|
||||
[ "$current_closure" = "$current_closure_rebuild" ] || {
|
||||
echo "current closure path was not reproducible: $current_closure != $current_closure_rebuild" >&2
|
||||
exit 1
|
||||
}
|
||||
[ "$current_closure" != "$candidate_closure" ] || {
|
||||
echo "current and candidate closures unexpectedly match" >&2
|
||||
exit 1
|
||||
}
|
||||
[ "$current_host_count" = 0 ] || { echo "current build has host base stores" >&2; exit 1; }
|
||||
[ "$candidate_host_count" = 0 ] || { echo "candidate build has host base stores" >&2; exit 1; }
|
||||
[ "$current_base_version_out" = "$current_base_version" ] || { echo "unexpected current base version label" >&2; exit 1; }
|
||||
[ "$candidate_base_version_out" = "$candidate_base_version" ] || { echo "unexpected candidate base version label" >&2; exit 1; }
|
||||
[ -f "$current_base_file" ] || { echo "missing current base file" >&2; exit 1; }
|
||||
[ -f "$candidate_base_file" ] || { echo "missing candidate base file" >&2; exit 1; }
|
||||
|
||||
for path in "$current_closure" "$candidate_closure"; do
|
||||
[ -d "$path" ] || {
|
||||
echo "expected closure directory missing: $path" >&2
|
||||
exit 1
|
||||
}
|
||||
done
|
||||
|
||||
printf '%s\n' "$current_native_stores" | tr ',' '\n' | grep "freebsd-native-kernel-$current_base_version$" >/dev/null || {
|
||||
echo "current native stores do not contain the expected kernel version label" >&2
|
||||
exit 1
|
||||
}
|
||||
printf '%s\n' "$candidate_native_stores" | tr ',' '\n' | grep "freebsd-native-kernel-$candidate_base_version$" >/dev/null || {
|
||||
echo "candidate native stores do not contain the expected kernel version label" >&2
|
||||
exit 1
|
||||
}
|
||||
[ "$current_native_stores" != "$candidate_native_stores" ] || {
|
||||
echo "current and candidate native store sets unexpectedly match" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
grep -F "(version-label . \"$current_base_version\")" "$current_base_file" >/dev/null || {
|
||||
echo "current base file missing version label" >&2
|
||||
exit 1
|
||||
}
|
||||
grep -F "(version-label . \"$candidate_base_version\")" "$candidate_base_file" >/dev/null || {
|
||||
echo "candidate base file missing version label" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
current_closure_base=$(basename "$current_closure")
|
||||
candidate_closure_base=$(basename "$candidate_closure")
|
||||
cat >"$metadata_file" <<EOF
|
||||
workdir=$workdir
|
||||
current_os=$current_os
|
||||
candidate_os=$candidate_os
|
||||
current_closure=$current_closure
|
||||
current_closure_rebuild=$current_closure_rebuild
|
||||
current_closure_base=$current_closure_base
|
||||
candidate_closure=$candidate_closure
|
||||
candidate_closure_base=$candidate_closure_base
|
||||
current_native_stores=$current_native_stores
|
||||
candidate_native_stores=$candidate_native_stores
|
||||
current_freebsd_base_file=$current_base_file
|
||||
candidate_freebsd_base_file=$candidate_base_file
|
||||
current_base_version_label=$current_base_version_out
|
||||
candidate_base_version_label=$candidate_base_version_out
|
||||
side_by_side_base_versions=ok
|
||||
rollback_rebuild_path=ok
|
||||
EOF
|
||||
|
||||
if [ -n "$metadata_target" ]; then
|
||||
mkdir -p "$(dirname "$metadata_target")"
|
||||
cp "$metadata_file" "$metadata_target"
|
||||
fi
|
||||
|
||||
printf 'PASS phase15-base-coexistence\n'
|
||||
printf 'Work directory: %s\n' "$workdir"
|
||||
printf 'Metadata file: %s\n' "$metadata_file"
|
||||
if [ -n "$metadata_target" ]; then
|
||||
printf 'Copied metadata to: %s\n' "$metadata_target"
|
||||
fi
|
||||
printf '%s\n' '--- metadata ---'
|
||||
cat "$metadata_file"
|
||||
157
tests/system/run-phase15-base-rollback-qemu.sh
Executable file
157
tests/system/run-phase15-base-rollback-qemu.sh
Executable file
@@ -0,0 +1,157 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
repo_root=${PROJECT_ROOT:-$(pwd)}
|
||||
script_dir=$(CDPATH= cd -- "$(dirname "$0")" && pwd)
|
||||
os_template=${OS_TEMPLATE:-$script_dir/phase15-declarative-base-pid1-operating-system.scm.in}
|
||||
system_name=${SYSTEM_NAME:-phase15-operating-system}
|
||||
disk_capacity=${DISK_CAPACITY:-8g}
|
||||
root_size=${ROOT_SIZE:-6g}
|
||||
current_base_name=${CURRENT_BASE_NAME:-stable-default}
|
||||
current_base_version=${CURRENT_BASE_VERSION:-15.0-STABLE}
|
||||
current_base_release=${CURRENT_BASE_RELEASE:-15.0-STABLE}
|
||||
current_base_branch=${CURRENT_BASE_BRANCH:-stable/15}
|
||||
candidate_base_name=${CANDIDATE_BASE_NAME:-stable-canary}
|
||||
candidate_base_version=${CANDIDATE_BASE_VERSION:-15.0-STABLE-p1}
|
||||
candidate_base_release=${CANDIDATE_BASE_RELEASE:-15.0-STABLE}
|
||||
candidate_base_branch=${CANDIDATE_BASE_BRANCH:-stable/15}
|
||||
metadata_target=${METADATA_OUT:-}
|
||||
cleanup=0
|
||||
|
||||
if [ -n "${WORKDIR:-}" ]; then
|
||||
workdir=$WORKDIR
|
||||
mkdir -p "$workdir"
|
||||
else
|
||||
workdir=$(mktemp -d /tmp/fruix-phase15-base-rollback-qemu.XXXXXX)
|
||||
cleanup=1
|
||||
fi
|
||||
if [ "${KEEP_WORKDIR:-0}" -eq 1 ]; then
|
||||
cleanup=0
|
||||
fi
|
||||
|
||||
metadata_file=$workdir/phase15-base-rollback-qemu-metadata.txt
|
||||
current_template=$workdir/current-template.scm.in
|
||||
candidate_template=$workdir/candidate-template.scm.in
|
||||
|
||||
cleanup_workdir() {
|
||||
if [ "$cleanup" -eq 1 ]; then
|
||||
rm -rf "$workdir" 2>/dev/null || sudo rm -rf "$workdir"
|
||||
fi
|
||||
}
|
||||
trap cleanup_workdir EXIT INT TERM
|
||||
|
||||
render_template() {
|
||||
output=$1
|
||||
base_name=$2
|
||||
base_version=$3
|
||||
base_release=$4
|
||||
base_branch=$5
|
||||
sed \
|
||||
-e "s|__BASE_NAME__|$base_name|g" \
|
||||
-e "s|__BASE_VERSION_LABEL__|$base_version|g" \
|
||||
-e "s|__BASE_RELEASE__|$base_release|g" \
|
||||
-e "s|__BASE_BRANCH__|$base_branch|g" \
|
||||
"$os_template" > "$output"
|
||||
}
|
||||
|
||||
render_template "$current_template" "$current_base_name" "$current_base_version" "$current_base_release" "$current_base_branch"
|
||||
render_template "$candidate_template" "$candidate_base_name" "$candidate_base_version" "$candidate_base_release" "$candidate_base_branch"
|
||||
|
||||
run_boot() {
|
||||
name=$1
|
||||
template=$2
|
||||
metadata_out=$3
|
||||
KEEP_WORKDIR=1 WORKDIR="$workdir/$name" METADATA_OUT="$metadata_out" \
|
||||
OS_TEMPLATE="$template" SYSTEM_NAME="$system_name" DISK_CAPACITY="$disk_capacity" ROOT_SIZE="$root_size" \
|
||||
"$repo_root/tests/system/run-phase11-shepherd-pid1-qemu.sh" >/dev/null
|
||||
}
|
||||
|
||||
current_first_metadata=$workdir/current-first-metadata.txt
|
||||
candidate_metadata=$workdir/candidate-metadata.txt
|
||||
rollback_metadata=$workdir/rollback-metadata.txt
|
||||
|
||||
run_boot current-first "$current_template" "$current_first_metadata"
|
||||
run_boot candidate "$candidate_template" "$candidate_metadata"
|
||||
run_boot rollback "$current_template" "$rollback_metadata"
|
||||
|
||||
current_first_phase8=$(sed -n 's/^phase8_metadata=//p' "$current_first_metadata")
|
||||
candidate_phase8=$(sed -n 's/^phase8_metadata=//p' "$candidate_metadata")
|
||||
rollback_phase8=$(sed -n 's/^phase8_metadata=//p' "$rollback_metadata")
|
||||
|
||||
current_first_closure=$(sed -n 's/^closure_path=//p' "$current_first_metadata")
|
||||
candidate_closure=$(sed -n 's/^closure_path=//p' "$candidate_metadata")
|
||||
rollback_closure=$(sed -n 's/^closure_path=//p' "$rollback_metadata")
|
||||
|
||||
current_first_version=$(sed -n 's/^freebsd_base_version_label=//p' "$current_first_phase8")
|
||||
candidate_version=$(sed -n 's/^freebsd_base_version_label=//p' "$candidate_phase8")
|
||||
rollback_version=$(sed -n 's/^freebsd_base_version_label=//p' "$rollback_phase8")
|
||||
|
||||
current_first_shepherd_pid=$(sed -n 's/^shepherd_pid=//p' "$current_first_metadata")
|
||||
candidate_shepherd_pid=$(sed -n 's/^shepherd_pid=//p' "$candidate_metadata")
|
||||
rollback_shepherd_pid=$(sed -n 's/^shepherd_pid=//p' "$rollback_metadata")
|
||||
current_first_sshd=$(sed -n 's/^sshd_status=//p' "$current_first_metadata")
|
||||
candidate_sshd=$(sed -n 's/^sshd_status=//p' "$candidate_metadata")
|
||||
rollback_sshd=$(sed -n 's/^sshd_status=//p' "$rollback_metadata")
|
||||
|
||||
[ "$current_first_version" = "$current_base_version" ] || { echo "unexpected current version label" >&2; exit 1; }
|
||||
[ "$candidate_version" = "$candidate_base_version" ] || { echo "unexpected candidate version label" >&2; exit 1; }
|
||||
[ "$rollback_version" = "$current_base_version" ] || { echo "unexpected rollback version label" >&2; exit 1; }
|
||||
[ "$current_first_closure" != "$candidate_closure" ] || { echo "candidate closure matches current closure" >&2; exit 1; }
|
||||
[ "$current_first_closure" = "$rollback_closure" ] || { echo "rollback closure did not return to the original current closure" >&2; exit 1; }
|
||||
for value in "$current_first_shepherd_pid" "$candidate_shepherd_pid" "$rollback_shepherd_pid"; do
|
||||
[ "$value" = 1 ] || { echo "shepherd was not PID 1" >&2; exit 1; }
|
||||
done
|
||||
for value in "$current_first_sshd" "$candidate_sshd" "$rollback_sshd"; do
|
||||
[ "$value" = running ] || { echo "sshd is not running in one of the rollback boots" >&2; exit 1; }
|
||||
done
|
||||
|
||||
current_first_native=$(sed -n 's/^native_base_stores=//p' "$current_first_phase8")
|
||||
candidate_native=$(sed -n 's/^native_base_stores=//p' "$candidate_phase8")
|
||||
rollback_native=$(sed -n 's/^native_base_stores=//p' "$rollback_phase8")
|
||||
|
||||
printf '%s\n' "$current_first_native" | tr ',' '\n' | grep "freebsd-native-kernel-$current_base_version$" >/dev/null || {
|
||||
echo "current native store set missing expected kernel version" >&2
|
||||
exit 1
|
||||
}
|
||||
printf '%s\n' "$candidate_native" | tr ',' '\n' | grep "freebsd-native-kernel-$candidate_base_version$" >/dev/null || {
|
||||
echo "candidate native store set missing expected kernel version" >&2
|
||||
exit 1
|
||||
}
|
||||
[ "$current_first_native" = "$rollback_native" ] || {
|
||||
echo "rollback native store set did not return to the original current set" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
cat >"$metadata_file" <<EOF
|
||||
workdir=$workdir
|
||||
current_first_metadata=$current_first_metadata
|
||||
candidate_metadata=$candidate_metadata
|
||||
rollback_metadata=$rollback_metadata
|
||||
current_first_closure=$current_first_closure
|
||||
candidate_closure=$candidate_closure
|
||||
rollback_closure=$rollback_closure
|
||||
current_base_version_label=$current_first_version
|
||||
candidate_base_version_label=$candidate_version
|
||||
rollback_base_version_label=$rollback_version
|
||||
current_native_base_stores=$current_first_native
|
||||
candidate_native_base_stores=$candidate_native
|
||||
rollback_native_base_stores=$rollback_native
|
||||
disk_capacity=$disk_capacity
|
||||
root_size=$root_size
|
||||
boot_backend=qemu-uefi-tcg
|
||||
base_rollforward_and_rollback=ok
|
||||
EOF
|
||||
|
||||
if [ -n "$metadata_target" ]; then
|
||||
mkdir -p "$(dirname "$metadata_target")"
|
||||
cp "$metadata_file" "$metadata_target"
|
||||
fi
|
||||
|
||||
printf 'PASS phase15-base-rollback-qemu\n'
|
||||
printf 'Work directory: %s\n' "$workdir"
|
||||
printf 'Metadata file: %s\n' "$metadata_file"
|
||||
if [ -n "$metadata_target" ]; then
|
||||
printf 'Copied metadata to: %s\n' "$metadata_target"
|
||||
fi
|
||||
printf '%s\n' '--- metadata ---'
|
||||
cat "$metadata_file"
|
||||
152
tests/system/run-phase15-base-rollback-xcpng.sh
Executable file
152
tests/system/run-phase15-base-rollback-xcpng.sh
Executable file
@@ -0,0 +1,152 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
repo_root=${PROJECT_ROOT:-$(pwd)}
|
||||
script_dir=$(CDPATH= cd -- "$(dirname "$0")" && pwd)
|
||||
os_template=${OS_TEMPLATE:-$script_dir/phase15-declarative-base-pid1-operating-system.scm.in}
|
||||
system_name=${SYSTEM_NAME:-phase15-operating-system}
|
||||
root_size=${ROOT_SIZE:-6g}
|
||||
current_base_name=${CURRENT_BASE_NAME:-stable-default}
|
||||
current_base_version=${CURRENT_BASE_VERSION:-15.0-STABLE}
|
||||
current_base_release=${CURRENT_BASE_RELEASE:-15.0-STABLE}
|
||||
current_base_branch=${CURRENT_BASE_BRANCH:-stable/15}
|
||||
candidate_base_name=${CANDIDATE_BASE_NAME:-stable-canary}
|
||||
candidate_base_version=${CANDIDATE_BASE_VERSION:-15.0-STABLE-p1}
|
||||
candidate_base_release=${CANDIDATE_BASE_RELEASE:-15.0-STABLE}
|
||||
candidate_base_branch=${CANDIDATE_BASE_BRANCH:-stable/15}
|
||||
metadata_target=${METADATA_OUT:-}
|
||||
cleanup=0
|
||||
|
||||
if [ -n "${WORKDIR:-}" ]; then
|
||||
workdir=$WORKDIR
|
||||
mkdir -p "$workdir"
|
||||
else
|
||||
workdir=$(mktemp -d /tmp/fruix-phase15-base-rollback-xcpng.XXXXXX)
|
||||
cleanup=1
|
||||
fi
|
||||
if [ "${KEEP_WORKDIR:-0}" -eq 1 ]; then
|
||||
cleanup=0
|
||||
fi
|
||||
|
||||
metadata_file=$workdir/phase15-base-rollback-xcpng-metadata.txt
|
||||
current_template=$workdir/current-template.scm.in
|
||||
candidate_template=$workdir/candidate-template.scm.in
|
||||
|
||||
cleanup_workdir() {
|
||||
if [ "$cleanup" -eq 1 ]; then
|
||||
rm -rf "$workdir"
|
||||
fi
|
||||
}
|
||||
trap cleanup_workdir EXIT INT TERM
|
||||
|
||||
render_template() {
|
||||
output=$1
|
||||
base_name=$2
|
||||
base_version=$3
|
||||
base_release=$4
|
||||
base_branch=$5
|
||||
sed \
|
||||
-e "s|__BASE_NAME__|$base_name|g" \
|
||||
-e "s|__BASE_VERSION_LABEL__|$base_version|g" \
|
||||
-e "s|__BASE_RELEASE__|$base_release|g" \
|
||||
-e "s|__BASE_BRANCH__|$base_branch|g" \
|
||||
"$os_template" > "$output"
|
||||
}
|
||||
|
||||
render_template "$current_template" "$current_base_name" "$current_base_version" "$current_base_release" "$current_base_branch"
|
||||
render_template "$candidate_template" "$candidate_base_name" "$candidate_base_version" "$candidate_base_release" "$candidate_base_branch"
|
||||
|
||||
run_boot() {
|
||||
name=$1
|
||||
template=$2
|
||||
metadata_out=$3
|
||||
KEEP_WORKDIR=1 WORKDIR="$workdir/$name" METADATA_OUT="$metadata_out" \
|
||||
OS_TEMPLATE="$template" SYSTEM_NAME="$system_name" ROOT_SIZE="$root_size" \
|
||||
"$repo_root/tests/system/run-phase11-shepherd-pid1-xcpng.sh" >/dev/null
|
||||
}
|
||||
|
||||
candidate_metadata=$workdir/candidate-metadata.txt
|
||||
rollback_metadata=$workdir/rollback-metadata.txt
|
||||
|
||||
run_boot candidate "$candidate_template" "$candidate_metadata"
|
||||
run_boot rollback "$current_template" "$rollback_metadata"
|
||||
|
||||
candidate_phase8=$(sed -n 's/^phase8_metadata=//p' "$candidate_metadata")
|
||||
rollback_phase8=$(sed -n 's/^phase8_metadata=//p' "$rollback_metadata")
|
||||
|
||||
candidate_closure=$(sed -n 's/^closure_path=//p' "$candidate_metadata")
|
||||
rollback_closure=$(sed -n 's/^closure_path=//p' "$rollback_metadata")
|
||||
candidate_guest_ip=$(sed -n 's/^guest_ip=//p' "$candidate_metadata")
|
||||
rollback_guest_ip=$(sed -n 's/^guest_ip=//p' "$rollback_metadata")
|
||||
vm_id=$(sed -n 's/^vm_id=//p' "$rollback_metadata")
|
||||
vdi_id=$(sed -n 's/^vdi_id=//p' "$rollback_metadata")
|
||||
candidate_version=$(sed -n 's/^freebsd_base_version_label=//p' "$candidate_phase8")
|
||||
rollback_version=$(sed -n 's/^freebsd_base_version_label=//p' "$rollback_phase8")
|
||||
candidate_shepherd_pid=$(sed -n 's/^shepherd_pid=//p' "$candidate_metadata")
|
||||
rollback_shepherd_pid=$(sed -n 's/^shepherd_pid=//p' "$rollback_metadata")
|
||||
candidate_sshd=$(sed -n 's/^sshd_status=//p' "$candidate_metadata")
|
||||
rollback_sshd=$(sed -n 's/^sshd_status=//p' "$rollback_metadata")
|
||||
candidate_compat=$(sed -n 's/^compat_prefix_shims=//p' "$candidate_metadata")
|
||||
rollback_compat=$(sed -n 's/^compat_prefix_shims=//p' "$rollback_metadata")
|
||||
candidate_smoke=$(sed -n 's/^guile_module_smoke=//p' "$candidate_metadata")
|
||||
rollback_smoke=$(sed -n 's/^guile_module_smoke=//p' "$rollback_metadata")
|
||||
|
||||
[ "$candidate_version" = "$candidate_base_version" ] || { echo "unexpected candidate version label" >&2; exit 1; }
|
||||
[ "$rollback_version" = "$current_base_version" ] || { echo "unexpected rollback version label" >&2; exit 1; }
|
||||
[ "$candidate_closure" != "$rollback_closure" ] || { echo "candidate and rollback closures unexpectedly match" >&2; exit 1; }
|
||||
for value in "$candidate_shepherd_pid" "$rollback_shepherd_pid"; do
|
||||
[ "$value" = 1 ] || { echo "shepherd was not PID 1" >&2; exit 1; }
|
||||
done
|
||||
for value in "$candidate_sshd" "$rollback_sshd"; do
|
||||
[ "$value" = running ] || { echo "sshd is not running during XCP-ng rollback validation" >&2; exit 1; }
|
||||
done
|
||||
for value in "$candidate_compat" "$rollback_compat"; do
|
||||
[ "$value" = absent ] || { echo "compatibility prefix shims reappeared" >&2; exit 1; }
|
||||
done
|
||||
for value in "$candidate_smoke" "$rollback_smoke"; do
|
||||
[ "$value" = ok ] || { echo "guest Guile module smoke failed" >&2; exit 1; }
|
||||
done
|
||||
|
||||
candidate_native=$(sed -n 's/^native_base_stores=//p' "$candidate_phase8")
|
||||
rollback_native=$(sed -n 's/^native_base_stores=//p' "$rollback_phase8")
|
||||
printf '%s\n' "$candidate_native" | tr ',' '\n' | grep "freebsd-native-kernel-$candidate_base_version$" >/dev/null || {
|
||||
echo "candidate native store set missing expected kernel version" >&2
|
||||
exit 1
|
||||
}
|
||||
printf '%s\n' "$rollback_native" | tr ',' '\n' | grep "freebsd-native-kernel-$current_base_version$" >/dev/null || {
|
||||
echo "rollback native store set missing expected kernel version" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
cat >"$metadata_file" <<EOF
|
||||
workdir=$workdir
|
||||
candidate_metadata=$candidate_metadata
|
||||
rollback_metadata=$rollback_metadata
|
||||
candidate_closure=$candidate_closure
|
||||
rollback_closure=$rollback_closure
|
||||
candidate_base_version_label=$candidate_version
|
||||
rollback_base_version_label=$rollback_version
|
||||
candidate_native_base_stores=$candidate_native
|
||||
rollback_native_base_stores=$rollback_native
|
||||
guest_ip_candidate=$candidate_guest_ip
|
||||
guest_ip_rollback=$rollback_guest_ip
|
||||
vm_id=$vm_id
|
||||
vdi_id=$vdi_id
|
||||
root_size=$root_size
|
||||
boot_backend=xcp-ng-xo-cli
|
||||
base_rollforward_and_rollback=ok
|
||||
EOF
|
||||
|
||||
if [ -n "$metadata_target" ]; then
|
||||
mkdir -p "$(dirname "$metadata_target")"
|
||||
cp "$metadata_file" "$metadata_target"
|
||||
fi
|
||||
|
||||
printf 'PASS phase15-base-rollback-xcpng\n'
|
||||
printf 'Work directory: %s\n' "$workdir"
|
||||
printf 'Metadata file: %s\n' "$metadata_file"
|
||||
if [ -n "$metadata_target" ]; then
|
||||
printf 'Copied metadata to: %s\n' "$metadata_target"
|
||||
fi
|
||||
printf '%s\n' '--- metadata ---'
|
||||
cat "$metadata_file"
|
||||
180
tests/system/run-phase15-declarative-base-build.sh
Executable file
180
tests/system/run-phase15-declarative-base-build.sh
Executable file
@@ -0,0 +1,180 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
project_root=${PROJECT_ROOT:-$(pwd)}
|
||||
script_dir=$(CDPATH= cd -- "$(dirname "$0")" && pwd)
|
||||
fruix_cmd=$project_root/bin/fruix
|
||||
os_template=${OS_TEMPLATE:-$script_dir/phase15-declarative-base-pid1-operating-system.scm.in}
|
||||
system_name=${SYSTEM_NAME:-phase15-operating-system}
|
||||
store_dir=${STORE_DIR:-/frx/store}
|
||||
base_name=${BASE_NAME:-stable-default}
|
||||
base_version_label=${BASE_VERSION_LABEL:-15.0-STABLE-declarative}
|
||||
base_release=${BASE_RELEASE:-15.0-STABLE}
|
||||
base_branch=${BASE_BRANCH:-stable/15}
|
||||
metadata_target=${METADATA_OUT:-}
|
||||
root_authorized_key_file=${ROOT_AUTHORIZED_KEY_FILE:-$HOME/.ssh/id_ed25519.pub}
|
||||
|
||||
[ -x "$fruix_cmd" ] || {
|
||||
echo "fruix command is not executable: $fruix_cmd" >&2
|
||||
exit 1
|
||||
}
|
||||
[ -f "$os_template" ] || {
|
||||
echo "missing operating-system template: $os_template" >&2
|
||||
exit 1
|
||||
}
|
||||
[ -f "$root_authorized_key_file" ] || {
|
||||
echo "missing root authorized key file: $root_authorized_key_file" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
cleanup=0
|
||||
if [ -n "${WORKDIR:-}" ]; then
|
||||
workdir=$WORKDIR
|
||||
mkdir -p "$workdir"
|
||||
else
|
||||
workdir=$(mktemp -d /tmp/fruix-phase15-declarative-build.XXXXXX)
|
||||
cleanup=1
|
||||
fi
|
||||
if [ "${KEEP_WORKDIR:-0}" -eq 1 ]; then
|
||||
cleanup=0
|
||||
fi
|
||||
|
||||
cleanup_workdir() {
|
||||
if [ "$cleanup" -eq 1 ]; then
|
||||
rm -rf "$workdir" 2>/dev/null || sudo rm -rf "$workdir"
|
||||
fi
|
||||
}
|
||||
trap cleanup_workdir EXIT INT TERM
|
||||
|
||||
phase15_os_file=$workdir/phase15-declarative-base-operating-system.scm
|
||||
build_out=$workdir/build.txt
|
||||
metadata_file=$workdir/phase15-declarative-base-build-metadata.txt
|
||||
root_authorized_key=$(tr -d '\n' < "$root_authorized_key_file")
|
||||
sed \
|
||||
-e "s|__BASE_NAME__|$base_name|g" \
|
||||
-e "s|__BASE_VERSION_LABEL__|$base_version_label|g" \
|
||||
-e "s|__BASE_RELEASE__|$base_release|g" \
|
||||
-e "s|__BASE_BRANCH__|$base_branch|g" \
|
||||
-e "s|__ROOT_AUTHORIZED_KEY__|$root_authorized_key|g" \
|
||||
"$os_template" > "$phase15_os_file"
|
||||
|
||||
action_env() {
|
||||
sudo env \
|
||||
HOME="$HOME" \
|
||||
GUILE_AUTO_COMPILE=0 \
|
||||
FRUIX_FREEBSD_BUILD_JOBS="${FRUIX_FREEBSD_BUILD_JOBS:-8}" \
|
||||
GUIX_SOURCE_DIR="${GUIX_SOURCE_DIR:-$HOME/repos/guix}" \
|
||||
GUILE_BIN="${GUILE_BIN:-/tmp/guile-freebsd-validate-install/bin/guile}" \
|
||||
GUILE_EXTRA_PREFIX="${GUILE_EXTRA_PREFIX:-/tmp/guile-gnutls-freebsd-validate-install}" \
|
||||
SHEPHERD_PREFIX="${SHEPHERD_PREFIX:-/tmp/shepherd-freebsd-validate-install}" \
|
||||
"$@"
|
||||
}
|
||||
|
||||
action_env "$fruix_cmd" system build "$phase15_os_file" --system "$system_name" --store "$store_dir" >"$build_out"
|
||||
|
||||
closure_path=$(sed -n 's/^closure_path=//p' "$build_out")
|
||||
kernel_store=$(sed -n 's/^kernel_store=//p' "$build_out")
|
||||
bootloader_store=$(sed -n 's/^bootloader_store=//p' "$build_out")
|
||||
native_base_store_count=$(sed -n 's/^native_base_store_count=//p' "$build_out")
|
||||
native_base_stores=$(sed -n 's/^native_base_stores=//p' "$build_out")
|
||||
host_base_store_count=$(sed -n 's/^host_base_store_count=//p' "$build_out")
|
||||
freebsd_base_name_out=$(sed -n 's/^freebsd_base_name=//p' "$build_out")
|
||||
freebsd_base_version_label_out=$(sed -n 's/^freebsd_base_version_label=//p' "$build_out")
|
||||
freebsd_base_release_out=$(sed -n 's/^freebsd_base_release=//p' "$build_out")
|
||||
freebsd_base_branch_out=$(sed -n 's/^freebsd_base_branch=//p' "$build_out")
|
||||
freebsd_base_source_root_out=$(sed -n 's/^freebsd_base_source_root=//p' "$build_out")
|
||||
freebsd_base_kernconf_out=$(sed -n 's/^freebsd_base_kernconf=//p' "$build_out")
|
||||
freebsd_base_file=$(sed -n 's/^freebsd_base_file=//p' "$build_out")
|
||||
store_layout_file=$(sed -n 's/^store_layout_file=//p' "$build_out")
|
||||
|
||||
[ -n "$closure_path" ] || { echo "missing closure path" >&2; exit 1; }
|
||||
[ "$host_base_store_count" = 0 ] || { echo "expected zero host base stores, got: $host_base_store_count" >&2; exit 1; }
|
||||
[ "$native_base_store_count" = 3 ] || { echo "expected three native base stores, got: $native_base_store_count" >&2; exit 1; }
|
||||
[ "$freebsd_base_name_out" = "$base_name" ] || { echo "unexpected freebsd base name: $freebsd_base_name_out" >&2; exit 1; }
|
||||
[ "$freebsd_base_version_label_out" = "$base_version_label" ] || { echo "unexpected freebsd base version label: $freebsd_base_version_label_out" >&2; exit 1; }
|
||||
[ "$freebsd_base_release_out" = "$base_release" ] || { echo "unexpected freebsd base release: $freebsd_base_release_out" >&2; exit 1; }
|
||||
[ "$freebsd_base_branch_out" = "$base_branch" ] || { echo "unexpected freebsd base branch: $freebsd_base_branch_out" >&2; exit 1; }
|
||||
[ "$freebsd_base_source_root_out" = /usr/src ] || { echo "unexpected freebsd base source root: $freebsd_base_source_root_out" >&2; exit 1; }
|
||||
[ "$freebsd_base_kernconf_out" = GENERIC ] || { echo "unexpected freebsd base kernconf: $freebsd_base_kernconf_out" >&2; exit 1; }
|
||||
[ -f "$freebsd_base_file" ] || { echo "missing freebsd base file: $freebsd_base_file" >&2; exit 1; }
|
||||
[ -f "$store_layout_file" ] || { echo "missing store layout file: $store_layout_file" >&2; exit 1; }
|
||||
|
||||
case "$kernel_store" in
|
||||
/frx/store/*-freebsd-native-kernel-$base_version_label) : ;;
|
||||
*) echo "unexpected kernel store path: $kernel_store" >&2; exit 1 ;;
|
||||
esac
|
||||
case "$bootloader_store" in
|
||||
/frx/store/*-freebsd-native-bootloader-$base_version_label) : ;;
|
||||
*) echo "unexpected bootloader store path: $bootloader_store" >&2; exit 1 ;;
|
||||
esac
|
||||
runtime_store=$(printf '%s\n' "$native_base_stores" | tr ',' '\n' | grep "freebsd-native-runtime-$base_version_label$" | head -n 1)
|
||||
[ -n "$runtime_store" ] || { echo "failed to recover runtime store" >&2; exit 1; }
|
||||
|
||||
for path in "$kernel_store/.freebsd-native-build-info.scm" "$bootloader_store/.freebsd-native-build-info.scm" "$runtime_store/.freebsd-native-build-info.scm"; do
|
||||
[ -f "$path" ] || {
|
||||
echo "missing native build info file: $path" >&2
|
||||
exit 1
|
||||
}
|
||||
grep -F "version-label . \"$base_version_label\"" "$path" >/dev/null || {
|
||||
echo "native build info missing declared version label in $path" >&2
|
||||
exit 1
|
||||
}
|
||||
grep -F "branch . \"$base_branch\"" "$path" >/dev/null || {
|
||||
echo "native build info missing declared branch in $path" >&2
|
||||
exit 1
|
||||
}
|
||||
done
|
||||
|
||||
grep -F "(name . \"$base_name\")" "$freebsd_base_file" >/dev/null || {
|
||||
echo "freebsd base file missing name" >&2
|
||||
exit 1
|
||||
}
|
||||
grep -F "(version-label . \"$base_version_label\")" "$freebsd_base_file" >/dev/null || {
|
||||
echo "freebsd base file missing version label" >&2
|
||||
exit 1
|
||||
}
|
||||
grep -F "(branch . \"$base_branch\")" "$store_layout_file" >/dev/null || {
|
||||
echo "store layout file missing declared base branch" >&2
|
||||
exit 1
|
||||
}
|
||||
grep -F "(freebsd-base" "$closure_path/parameters.scm" >/dev/null || {
|
||||
echo "closure parameters do not record the freebsd base declaration" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
closure_base=$(basename "$closure_path")
|
||||
cat >"$metadata_file" <<EOF
|
||||
workdir=$workdir
|
||||
phase15_os_file=$phase15_os_file
|
||||
closure_path=$closure_path
|
||||
closure_base=$closure_base
|
||||
kernel_store=$kernel_store
|
||||
bootloader_store=$bootloader_store
|
||||
runtime_store=$runtime_store
|
||||
native_base_store_count=$native_base_store_count
|
||||
native_base_stores=$native_base_stores
|
||||
host_base_store_count=$host_base_store_count
|
||||
freebsd_base_name=$freebsd_base_name_out
|
||||
freebsd_base_version_label=$freebsd_base_version_label_out
|
||||
freebsd_base_release=$freebsd_base_release_out
|
||||
freebsd_base_branch=$freebsd_base_branch_out
|
||||
freebsd_base_source_root=$freebsd_base_source_root_out
|
||||
freebsd_base_kernconf=$freebsd_base_kernconf_out
|
||||
freebsd_base_file=$freebsd_base_file
|
||||
store_layout_file=$store_layout_file
|
||||
declarative_base_input=ok
|
||||
EOF
|
||||
|
||||
if [ -n "$metadata_target" ]; then
|
||||
mkdir -p "$(dirname "$metadata_target")"
|
||||
cp "$metadata_file" "$metadata_target"
|
||||
fi
|
||||
|
||||
printf 'PASS phase15-declarative-base-build\n'
|
||||
printf 'Work directory: %s\n' "$workdir"
|
||||
printf 'Metadata file: %s\n' "$metadata_file"
|
||||
if [ -n "$metadata_target" ]; then
|
||||
printf 'Copied metadata to: %s\n' "$metadata_target"
|
||||
fi
|
||||
printf '%s\n' '--- metadata ---'
|
||||
cat "$metadata_file"
|
||||
245
tests/system/run-phase16-declarative-source-build.sh
Executable file
245
tests/system/run-phase16-declarative-source-build.sh
Executable file
@@ -0,0 +1,245 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
project_root=${PROJECT_ROOT:-$(pwd)}
|
||||
script_dir=$(CDPATH= cd -- "$(dirname "$0")" && pwd)
|
||||
fruix_cmd=$project_root/bin/fruix
|
||||
os_template=${OS_TEMPLATE:-$script_dir/phase16-declarative-source-operating-system.scm.in}
|
||||
source_probe=${SOURCE_PROBE:-$script_dir/validate-phase16-freebsd-source.scm}
|
||||
system_name=${SYSTEM_NAME:-phase16-operating-system}
|
||||
store_dir=${STORE_DIR:-/frx/store}
|
||||
base_name=${BASE_NAME:-source-model}
|
||||
base_version_label=${BASE_VERSION_LABEL:-15.0-STABLE-source-model}
|
||||
base_release=${BASE_RELEASE:-15.0-STABLE}
|
||||
base_branch=${BASE_BRANCH:-stable/15}
|
||||
source_name=${SOURCE_NAME:-host-usr-src}
|
||||
metadata_target=${METADATA_OUT:-}
|
||||
root_authorized_key_file=${ROOT_AUTHORIZED_KEY_FILE:-$HOME/.ssh/id_ed25519.pub}
|
||||
|
||||
[ -x "$fruix_cmd" ] || {
|
||||
echo "fruix command is not executable: $fruix_cmd" >&2
|
||||
exit 1
|
||||
}
|
||||
[ -f "$os_template" ] || {
|
||||
echo "missing operating-system template: $os_template" >&2
|
||||
exit 1
|
||||
}
|
||||
[ -f "$source_probe" ] || {
|
||||
echo "missing source probe script: $source_probe" >&2
|
||||
exit 1
|
||||
}
|
||||
[ -f "$root_authorized_key_file" ] || {
|
||||
echo "missing root authorized key file: $root_authorized_key_file" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
cleanup=0
|
||||
if [ -n "${WORKDIR:-}" ]; then
|
||||
workdir=$WORKDIR
|
||||
mkdir -p "$workdir"
|
||||
else
|
||||
workdir=$(mktemp -d /tmp/fruix-phase16-declarative-source.XXXXXX)
|
||||
cleanup=1
|
||||
fi
|
||||
if [ "${KEEP_WORKDIR:-0}" -eq 1 ]; then
|
||||
cleanup=0
|
||||
fi
|
||||
|
||||
cleanup_workdir() {
|
||||
if [ "$cleanup" -eq 1 ]; then
|
||||
rm -rf "$workdir" 2>/dev/null || sudo rm -rf "$workdir"
|
||||
fi
|
||||
}
|
||||
trap cleanup_workdir EXIT INT TERM
|
||||
|
||||
phase16_os_file=$workdir/phase16-declarative-source-operating-system.scm
|
||||
source_probe_out=$workdir/source-probe.txt
|
||||
build_out=$workdir/build.txt
|
||||
metadata_file=$workdir/phase16-declarative-source-build-metadata.txt
|
||||
root_authorized_key=$(tr -d '\n' < "$root_authorized_key_file")
|
||||
sed \
|
||||
-e "s|__BASE_NAME__|$base_name|g" \
|
||||
-e "s|__BASE_VERSION_LABEL__|$base_version_label|g" \
|
||||
-e "s|__BASE_RELEASE__|$base_release|g" \
|
||||
-e "s|__BASE_BRANCH__|$base_branch|g" \
|
||||
-e "s|__SOURCE_NAME__|$source_name|g" \
|
||||
-e "s|__ROOT_AUTHORIZED_KEY__|$root_authorized_key|g" \
|
||||
"$os_template" > "$phase16_os_file"
|
||||
|
||||
action_env() {
|
||||
sudo env \
|
||||
HOME="$HOME" \
|
||||
GUILE_AUTO_COMPILE=0 \
|
||||
FRUIX_FREEBSD_BUILD_JOBS="${FRUIX_FREEBSD_BUILD_JOBS:-8}" \
|
||||
GUIX_SOURCE_DIR="${GUIX_SOURCE_DIR:-$HOME/repos/guix}" \
|
||||
GUILE_BIN="${GUILE_BIN:-/tmp/guile-freebsd-validate-install/bin/guile}" \
|
||||
GUILE_EXTRA_PREFIX="${GUILE_EXTRA_PREFIX:-/tmp/guile-gnutls-freebsd-validate-install}" \
|
||||
SHEPHERD_PREFIX="${SHEPHERD_PREFIX:-/tmp/shepherd-freebsd-validate-install}" \
|
||||
"$@"
|
||||
}
|
||||
|
||||
action_env "${GUILE_BIN:-/tmp/guile-freebsd-validate-install/bin/guile}" \
|
||||
-L "$project_root/modules" \
|
||||
-c "(primitive-load \"$source_probe\")" >"$source_probe_out"
|
||||
|
||||
for expected in \
|
||||
'local_kind=local-tree' \
|
||||
'local_path=/usr/src' \
|
||||
'git_kind=git' \
|
||||
'git_url=https://git.FreeBSD.org/src.git' \
|
||||
'git_ref=stable/15' \
|
||||
'txz_kind=src-txz' \
|
||||
'txz_url=https://download.freebsd.org/releases/amd64/15.0-RELEASE/src.txz' \
|
||||
'txz_sha256=example-sha256' \
|
||||
'base_source_accessor=ok'
|
||||
do
|
||||
grep -F "$expected" "$source_probe_out" >/dev/null || {
|
||||
echo "source probe missing expected line: $expected" >&2
|
||||
exit 1
|
||||
}
|
||||
done
|
||||
|
||||
action_env "$fruix_cmd" system build "$phase16_os_file" --system "$system_name" --store "$store_dir" >"$build_out"
|
||||
|
||||
closure_path=$(sed -n 's/^closure_path=//p' "$build_out")
|
||||
kernel_store=$(sed -n 's/^kernel_store=//p' "$build_out")
|
||||
bootloader_store=$(sed -n 's/^bootloader_store=//p' "$build_out")
|
||||
native_base_store_count=$(sed -n 's/^native_base_store_count=//p' "$build_out")
|
||||
native_base_stores=$(sed -n 's/^native_base_stores=//p' "$build_out")
|
||||
host_base_store_count=$(sed -n 's/^host_base_store_count=//p' "$build_out")
|
||||
freebsd_base_name_out=$(sed -n 's/^freebsd_base_name=//p' "$build_out")
|
||||
freebsd_base_version_label_out=$(sed -n 's/^freebsd_base_version_label=//p' "$build_out")
|
||||
freebsd_base_release_out=$(sed -n 's/^freebsd_base_release=//p' "$build_out")
|
||||
freebsd_base_branch_out=$(sed -n 's/^freebsd_base_branch=//p' "$build_out")
|
||||
freebsd_base_source_root_out=$(sed -n 's/^freebsd_base_source_root=//p' "$build_out")
|
||||
freebsd_base_file=$(sed -n 's/^freebsd_base_file=//p' "$build_out")
|
||||
freebsd_source_name_out=$(sed -n 's/^freebsd_source_name=//p' "$build_out")
|
||||
freebsd_source_kind_out=$(sed -n 's/^freebsd_source_kind=//p' "$build_out")
|
||||
freebsd_source_url_out=$(sed -n 's/^freebsd_source_url=//p' "$build_out")
|
||||
freebsd_source_path_out=$(sed -n 's/^freebsd_source_path=//p' "$build_out")
|
||||
freebsd_source_ref_out=$(sed -n 's/^freebsd_source_ref=//p' "$build_out")
|
||||
freebsd_source_commit_out=$(sed -n 's/^freebsd_source_commit=//p' "$build_out")
|
||||
freebsd_source_sha256_out=$(sed -n 's/^freebsd_source_sha256=//p' "$build_out")
|
||||
freebsd_source_file=$(sed -n 's/^freebsd_source_file=//p' "$build_out")
|
||||
store_layout_file=$(sed -n 's/^store_layout_file=//p' "$build_out")
|
||||
|
||||
[ -n "$closure_path" ] || { echo "missing closure path" >&2; exit 1; }
|
||||
[ "$host_base_store_count" = 0 ] || { echo "expected zero host base stores, got: $host_base_store_count" >&2; exit 1; }
|
||||
[ "$native_base_store_count" = 3 ] || { echo "expected three native base stores, got: $native_base_store_count" >&2; exit 1; }
|
||||
[ "$freebsd_base_name_out" = "$base_name" ] || { echo "unexpected freebsd base name: $freebsd_base_name_out" >&2; exit 1; }
|
||||
[ "$freebsd_base_version_label_out" = "$base_version_label" ] || { echo "unexpected freebsd base version label: $freebsd_base_version_label_out" >&2; exit 1; }
|
||||
[ "$freebsd_base_release_out" = "$base_release" ] || { echo "unexpected freebsd base release: $freebsd_base_release_out" >&2; exit 1; }
|
||||
[ "$freebsd_base_branch_out" = "$base_branch" ] || { echo "unexpected freebsd base branch: $freebsd_base_branch_out" >&2; exit 1; }
|
||||
[ "$freebsd_base_source_root_out" = /usr/src ] || { echo "unexpected freebsd base source root: $freebsd_base_source_root_out" >&2; exit 1; }
|
||||
[ "$freebsd_source_name_out" = "$source_name" ] || { echo "unexpected freebsd source name: $freebsd_source_name_out" >&2; exit 1; }
|
||||
[ "$freebsd_source_kind_out" = local-tree ] || { echo "unexpected freebsd source kind: $freebsd_source_kind_out" >&2; exit 1; }
|
||||
[ "$freebsd_source_url_out" = "" ] || { echo "unexpected freebsd source URL: $freebsd_source_url_out" >&2; exit 1; }
|
||||
[ "$freebsd_source_path_out" = /usr/src ] || { echo "unexpected freebsd source path: $freebsd_source_path_out" >&2; exit 1; }
|
||||
[ "$freebsd_source_ref_out" = "" ] || { echo "unexpected freebsd source ref: $freebsd_source_ref_out" >&2; exit 1; }
|
||||
[ "$freebsd_source_commit_out" = "" ] || { echo "unexpected freebsd source commit: $freebsd_source_commit_out" >&2; exit 1; }
|
||||
[ "$freebsd_source_sha256_out" = "" ] || { echo "unexpected freebsd source sha256: $freebsd_source_sha256_out" >&2; exit 1; }
|
||||
[ -f "$freebsd_base_file" ] || { echo "missing freebsd base file: $freebsd_base_file" >&2; exit 1; }
|
||||
[ -f "$freebsd_source_file" ] || { echo "missing freebsd source file: $freebsd_source_file" >&2; exit 1; }
|
||||
[ -f "$store_layout_file" ] || { echo "missing store layout file: $store_layout_file" >&2; exit 1; }
|
||||
|
||||
case "$kernel_store" in
|
||||
/frx/store/*-freebsd-native-kernel-$base_version_label) : ;;
|
||||
*) echo "unexpected kernel store path: $kernel_store" >&2; exit 1 ;;
|
||||
esac
|
||||
case "$bootloader_store" in
|
||||
/frx/store/*-freebsd-native-bootloader-$base_version_label) : ;;
|
||||
*) echo "unexpected bootloader store path: $bootloader_store" >&2; exit 1 ;;
|
||||
esac
|
||||
runtime_store=$(printf '%s\n' "$native_base_stores" | tr ',' '\n' | grep "freebsd-native-runtime-$base_version_label$" | head -n 1)
|
||||
[ -n "$runtime_store" ] || { echo "failed to recover runtime store" >&2; exit 1; }
|
||||
|
||||
for path in "$kernel_store/.freebsd-native-build-info.scm" "$bootloader_store/.freebsd-native-build-info.scm" "$runtime_store/.freebsd-native-build-info.scm"; do
|
||||
[ -f "$path" ] || {
|
||||
echo "missing native build info file: $path" >&2
|
||||
exit 1
|
||||
}
|
||||
grep -F "(declared-source" "$path" >/dev/null || {
|
||||
echo "native build info missing declared source block in $path" >&2
|
||||
exit 1
|
||||
}
|
||||
grep -F "(kind . local-tree)" "$path" >/dev/null || {
|
||||
echo "native build info missing declared source kind in $path" >&2
|
||||
exit 1
|
||||
}
|
||||
grep -F "(path . \"/usr/src\")" "$path" >/dev/null || {
|
||||
echo "native build info missing declared source path in $path" >&2
|
||||
exit 1
|
||||
}
|
||||
done
|
||||
|
||||
grep -F "(name . \"$source_name\")" "$freebsd_source_file" >/dev/null || {
|
||||
echo "freebsd source file missing name" >&2
|
||||
exit 1
|
||||
}
|
||||
grep -F "(kind . local-tree)" "$freebsd_source_file" >/dev/null || {
|
||||
echo "freebsd source file missing kind" >&2
|
||||
exit 1
|
||||
}
|
||||
grep -F "(path . \"/usr/src\")" "$freebsd_source_file" >/dev/null || {
|
||||
echo "freebsd source file missing path" >&2
|
||||
exit 1
|
||||
}
|
||||
grep -F "(source" "$freebsd_base_file" >/dev/null || {
|
||||
echo "freebsd base file missing nested source block" >&2
|
||||
exit 1
|
||||
}
|
||||
if ! grep -F "(source" "$closure_path/parameters.scm" >/dev/null; then
|
||||
echo "closure parameters do not record the declared source" >&2
|
||||
exit 1
|
||||
fi
|
||||
grep -F "(freebsd-source" "$store_layout_file" >/dev/null || {
|
||||
echo "store layout file missing declared source block" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
closure_base=$(basename "$closure_path")
|
||||
cat >"$metadata_file" <<EOF
|
||||
workdir=$workdir
|
||||
phase16_os_file=$phase16_os_file
|
||||
source_probe_out=$source_probe_out
|
||||
closure_path=$closure_path
|
||||
closure_base=$closure_base
|
||||
kernel_store=$kernel_store
|
||||
bootloader_store=$bootloader_store
|
||||
runtime_store=$runtime_store
|
||||
native_base_store_count=$native_base_store_count
|
||||
native_base_stores=$native_base_stores
|
||||
host_base_store_count=$host_base_store_count
|
||||
freebsd_base_name=$freebsd_base_name_out
|
||||
freebsd_base_version_label=$freebsd_base_version_label_out
|
||||
freebsd_base_release=$freebsd_base_release_out
|
||||
freebsd_base_branch=$freebsd_base_branch_out
|
||||
freebsd_base_source_root=$freebsd_base_source_root_out
|
||||
freebsd_base_file=$freebsd_base_file
|
||||
freebsd_source_name=$freebsd_source_name_out
|
||||
freebsd_source_kind=$freebsd_source_kind_out
|
||||
freebsd_source_url=$freebsd_source_url_out
|
||||
freebsd_source_path=$freebsd_source_path_out
|
||||
freebsd_source_ref=$freebsd_source_ref_out
|
||||
freebsd_source_commit=$freebsd_source_commit_out
|
||||
freebsd_source_sha256=$freebsd_source_sha256_out
|
||||
freebsd_source_file=$freebsd_source_file
|
||||
store_layout_file=$store_layout_file
|
||||
declarative_source_model=ok
|
||||
EOF
|
||||
|
||||
if [ -n "$metadata_target" ]; then
|
||||
mkdir -p "$(dirname "$metadata_target")"
|
||||
cp "$metadata_file" "$metadata_target"
|
||||
fi
|
||||
|
||||
printf 'PASS phase16-declarative-source-build\n'
|
||||
printf 'Work directory: %s\n' "$workdir"
|
||||
printf 'Metadata file: %s\n' "$metadata_file"
|
||||
if [ -n "$metadata_target" ]; then
|
||||
printf 'Copied metadata to: %s\n' "$metadata_target"
|
||||
fi
|
||||
printf '%s\n' '--- source probe ---'
|
||||
cat "$source_probe_out"
|
||||
printf '%s\n' '--- metadata ---'
|
||||
cat "$metadata_file"
|
||||
@@ -8,6 +8,7 @@ os_file=${OS_FILE:-$script_dir/phase7-minimal-operating-system.scm}
|
||||
system_name=${SYSTEM_NAME:-phase7-operating-system}
|
||||
store_dir=${STORE_DIR:-/frx/store}
|
||||
disk_capacity=${DISK_CAPACITY:-}
|
||||
root_size=${ROOT_SIZE:-}
|
||||
metadata_target=${METADATA_OUT:-}
|
||||
|
||||
[ -x "$fruix_cmd" ] || {
|
||||
@@ -61,21 +62,36 @@ printf 'Using fruix command: %s\n' "$fruix_cmd"
|
||||
printf 'Working directory: %s\n' "$workdir"
|
||||
printf 'Store directory: %s\n' "$store_dir"
|
||||
|
||||
set -- "$fruix_cmd" system image "$os_file" --system "$system_name" --store "$store_dir"
|
||||
if [ -n "$disk_capacity" ]; then
|
||||
action_env "$fruix_cmd" system image "$os_file" --system "$system_name" --store "$store_dir" --disk-capacity "$disk_capacity" >"$build_metadata"
|
||||
else
|
||||
action_env "$fruix_cmd" system image "$os_file" --system "$system_name" --store "$store_dir" >"$build_metadata"
|
||||
set -- "$@" --disk-capacity "$disk_capacity"
|
||||
fi
|
||||
if [ -n "$root_size" ]; then
|
||||
set -- "$@" --root-size "$root_size"
|
||||
fi
|
||||
action_env "$@" >"$build_metadata"
|
||||
|
||||
image_store_path=$(sed -n 's/^image_store_path=//p' "$build_metadata")
|
||||
disk_image=$(sed -n 's/^disk_image=//p' "$build_metadata")
|
||||
closure_path=$(sed -n 's/^closure_path=//p' "$build_metadata")
|
||||
disk_capacity_reported=$(sed -n 's/^disk_capacity=//p' "$build_metadata")
|
||||
root_size_reported=$(sed -n 's/^root_size=//p' "$build_metadata")
|
||||
store_item_count=$(sed -n 's/^store_item_count=//p' "$build_metadata")
|
||||
host_base_store_count=$(sed -n 's/^host_base_store_count=//p' "$build_metadata")
|
||||
host_base_stores=$(sed -n 's/^host_base_stores=//p' "$build_metadata")
|
||||
native_base_store_count=$(sed -n 's/^native_base_store_count=//p' "$build_metadata")
|
||||
native_base_stores=$(sed -n 's/^native_base_stores=//p' "$build_metadata")
|
||||
fruix_runtime_store_count=$(sed -n 's/^fruix_runtime_store_count=//p' "$build_metadata")
|
||||
fruix_runtime_stores=$(sed -n 's/^fruix_runtime_stores=//p' "$build_metadata")
|
||||
freebsd_base_name=$(sed -n 's/^freebsd_base_name=//p' "$build_metadata")
|
||||
freebsd_base_version_label=$(sed -n 's/^freebsd_base_version_label=//p' "$build_metadata")
|
||||
freebsd_base_release=$(sed -n 's/^freebsd_base_release=//p' "$build_metadata")
|
||||
freebsd_base_branch=$(sed -n 's/^freebsd_base_branch=//p' "$build_metadata")
|
||||
freebsd_base_source_root=$(sed -n 's/^freebsd_base_source_root=//p' "$build_metadata")
|
||||
freebsd_base_target=$(sed -n 's/^freebsd_base_target=//p' "$build_metadata")
|
||||
freebsd_base_target_arch=$(sed -n 's/^freebsd_base_target_arch=//p' "$build_metadata")
|
||||
freebsd_base_kernconf=$(sed -n 's/^freebsd_base_kernconf=//p' "$build_metadata")
|
||||
freebsd_base_file=$(sed -n 's/^freebsd_base_file=//p' "$build_metadata")
|
||||
host_base_provenance_file=$(sed -n 's/^host_base_provenance_file=//p' "$build_metadata")
|
||||
store_layout_file=$(sed -n 's/^store_layout_file=//p' "$build_metadata")
|
||||
host_freebsd_version=$(sed -n 's/^host_freebsd_version=//p' "$build_metadata")
|
||||
@@ -143,11 +159,23 @@ closure_base=$closure_base
|
||||
raw_sha256=$raw_sha256
|
||||
image_size_bytes=$image_size_bytes
|
||||
disk_capacity=$disk_capacity_reported
|
||||
root_size=$root_size_reported
|
||||
store_item_count=$store_item_count
|
||||
host_base_store_count=$host_base_store_count
|
||||
host_base_stores=$host_base_stores
|
||||
native_base_store_count=$native_base_store_count
|
||||
native_base_stores=$native_base_stores
|
||||
fruix_runtime_store_count=$fruix_runtime_store_count
|
||||
fruix_runtime_stores=$fruix_runtime_stores
|
||||
freebsd_base_name=$freebsd_base_name
|
||||
freebsd_base_version_label=$freebsd_base_version_label
|
||||
freebsd_base_release=$freebsd_base_release
|
||||
freebsd_base_branch=$freebsd_base_branch
|
||||
freebsd_base_source_root=$freebsd_base_source_root
|
||||
freebsd_base_target=$freebsd_base_target
|
||||
freebsd_base_target_arch=$freebsd_base_target_arch
|
||||
freebsd_base_kernconf=$freebsd_base_kernconf
|
||||
freebsd_base_file=$freebsd_base_file
|
||||
host_base_provenance_file=$host_base_provenance_file
|
||||
store_layout_file=$store_layout_file
|
||||
host_freebsd_version=$host_freebsd_version
|
||||
|
||||
69
tests/system/validate-phase16-freebsd-source.scm
Normal file
69
tests/system/validate-phase16-freebsd-source.scm
Normal file
@@ -0,0 +1,69 @@
|
||||
(use-modules (fruix packages freebsd)
|
||||
(ice-9 format))
|
||||
|
||||
(define (assert condition message . rest)
|
||||
(unless condition
|
||||
(apply error message rest)))
|
||||
|
||||
(define local-source
|
||||
(freebsd-source
|
||||
#:name "host-usr-src"
|
||||
#:kind 'local-tree
|
||||
#:path "/usr/src"))
|
||||
|
||||
(define git-source
|
||||
(freebsd-source
|
||||
#:name "stable15-git"
|
||||
#:kind 'git
|
||||
#:ref "stable/15"))
|
||||
|
||||
(define txz-source
|
||||
(freebsd-source
|
||||
#:name "release-15.0-txz"
|
||||
#:kind 'src-txz
|
||||
#:url "https://download.freebsd.org/releases/amd64/15.0-RELEASE/src.txz"
|
||||
#:sha256 "example-sha256"))
|
||||
|
||||
(define git-base
|
||||
(freebsd-base
|
||||
#:name "git-base"
|
||||
#:source git-source
|
||||
#:source-root "/usr/src"))
|
||||
|
||||
(define txz-base
|
||||
(freebsd-base
|
||||
#:name "txz-base"
|
||||
#:source txz-source
|
||||
#:source-root "/usr/src"))
|
||||
|
||||
(assert (eq? (freebsd-source-kind local-source) 'local-tree)
|
||||
"unexpected local source kind")
|
||||
(assert (string=? (freebsd-source-path local-source) "/usr/src")
|
||||
"unexpected local source path")
|
||||
(assert (eq? (freebsd-source-kind git-source) 'git)
|
||||
"unexpected git source kind")
|
||||
(assert (string=? (freebsd-source-url git-source) "https://git.FreeBSD.org/src.git")
|
||||
"unexpected default git source URL")
|
||||
(assert (string=? (freebsd-source-ref git-source) "stable/15")
|
||||
"unexpected git source ref")
|
||||
(assert (eq? (freebsd-source-kind txz-source) 'src-txz)
|
||||
"unexpected txz source kind")
|
||||
(assert (string=? (freebsd-source-url txz-source)
|
||||
"https://download.freebsd.org/releases/amd64/15.0-RELEASE/src.txz")
|
||||
"unexpected txz source URL")
|
||||
(assert (string=? (freebsd-source-sha256 txz-source) "example-sha256")
|
||||
"unexpected txz source sha256")
|
||||
(assert (freebsd-source? (freebsd-base-source git-base))
|
||||
"git base did not preserve source record")
|
||||
(assert (freebsd-source? (freebsd-base-source txz-base))
|
||||
"txz base did not preserve source record")
|
||||
|
||||
(format #t "local_kind=~a~%" (freebsd-source-kind local-source))
|
||||
(format #t "local_path=~a~%" (freebsd-source-path local-source))
|
||||
(format #t "git_kind=~a~%" (freebsd-source-kind git-source))
|
||||
(format #t "git_url=~a~%" (freebsd-source-url git-source))
|
||||
(format #t "git_ref=~a~%" (freebsd-source-ref git-source))
|
||||
(format #t "txz_kind=~a~%" (freebsd-source-kind txz-source))
|
||||
(format #t "txz_url=~a~%" (freebsd-source-url txz-source))
|
||||
(format #t "txz_sha256=~a~%" (freebsd-source-sha256 txz-source))
|
||||
(format #t "base_source_accessor=ok~%")
|
||||
Reference in New Issue
Block a user