native-build: introduce executor model
This commit is contained in:
@@ -294,6 +294,22 @@ Compared with Guix, this is a more explicit split between:
|
||||
- a mutable result/staging area for native build execution
|
||||
- and the immutable store identities that Fruix treats as the real promoted result
|
||||
|
||||
Fruix also now models native-build placement more explicitly as an executor choice.
|
||||
|
||||
Current executor kinds are:
|
||||
|
||||
- `host`
|
||||
- `ssh-guest`
|
||||
- `self-hosted`
|
||||
|
||||
So instead of treating:
|
||||
|
||||
- host-driven builds
|
||||
- host-initiated guest builds
|
||||
- guest self-hosted builds
|
||||
|
||||
as three unrelated architectural forks, Fruix is moving toward one native-build result model with different executor policies attached to it.
|
||||
|
||||
## Where Fruix is intentionally trying to improve on Guix's representation
|
||||
|
||||
Fruix is not trying to improve on Guix's core semantics. Guix already got those right.
|
||||
|
||||
@@ -53,6 +53,13 @@ Fruix currently has:
|
||||
- `/frx/store/...-fruix-native-headers-...`
|
||||
- `/frx/store/...-fruix-native-bootloader-...`
|
||||
- `/frx/store/...-fruix-native-build-result-...`
|
||||
- an explicit executor model for native base builds with current executor kinds:
|
||||
- `host`
|
||||
- `ssh-guest`
|
||||
- `self-hosted`
|
||||
- end-to-end validated staged-result-plus-promotion paths for executor policies:
|
||||
- `ssh-guest`
|
||||
- `self-hosted`
|
||||
|
||||
Validated boot modes still are:
|
||||
|
||||
@@ -65,37 +72,30 @@ The validated Phase 18 installation work currently uses:
|
||||
|
||||
## Latest completed achievement
|
||||
|
||||
### 2026-04-05 — Native base builds promoted into first-class Fruix store objects
|
||||
### 2026-04-06 — Native build executor model introduced and validated across two executor policies
|
||||
|
||||
Fruix now has a validated end-to-end path that treats guest native base-build results as **staged mutable results first**, and then promotes them into **immutable Fruix store identities**.
|
||||
Fruix now has an explicit executor model for native base builds, and the same staged-result-plus-promotion flow is validated across both host-initiated guest execution and guest self-hosted execution.
|
||||
|
||||
Highlights:
|
||||
|
||||
- guest self-hosted runs still record staged results under:
|
||||
- `/var/lib/fruix/native-builds/<run-id>`
|
||||
- `/var/lib/fruix/native-builds/latest`
|
||||
- those result roots now carry promotion metadata describing:
|
||||
- executor / executor-version
|
||||
- closure path
|
||||
- source store provenance
|
||||
- build policy
|
||||
- artifact entries for:
|
||||
- `world`
|
||||
- `kernel`
|
||||
- `headers`
|
||||
- `bootloader`
|
||||
- the host can now run:
|
||||
- native base-build placement is now modeled as executor policy rather than as separate unrelated paths
|
||||
- current executor kinds are:
|
||||
- `host`
|
||||
- `ssh-guest`
|
||||
- `self-hosted`
|
||||
- guest result roots now carry explicit executor metadata instead of only an ad hoc executor string
|
||||
- both validated executor paths now converge on the same Fruix-native flow:
|
||||
- stage mutable results under `/var/lib/fruix/native-builds/<run-id>`
|
||||
- emit promotion metadata with shared provenance/build-policy/artifact shape
|
||||
- promote immutable identities into `/frx/store/...`
|
||||
- the `ssh-guest` path now also stages promotable native-build result roots rather than only temporary build directories under `/var/tmp`
|
||||
- the host can now promote both executor paths through the same command:
|
||||
- `fruix native-build promote RESULT_ROOT`
|
||||
- promotion creates immutable `/frx/store` objects for:
|
||||
- `world`
|
||||
- `kernel`
|
||||
- `headers`
|
||||
- `bootloader`
|
||||
- promotion also creates a result-bundle store object that references those artifact stores
|
||||
- the validated promotion metadata now makes Fruix-native native-build identity explicit instead of leaving results only as ad hoc files under `/var/lib/fruix/native-builds/...`
|
||||
|
||||
Validation:
|
||||
|
||||
- `PASS phase20-host-initiated-native-build-xcpng`
|
||||
- `PASS phase20-host-initiated-native-build-store-promotion-xcpng`
|
||||
- `PASS phase20-self-hosted-native-build-xcpng`
|
||||
- `PASS phase20-native-build-store-promotion-xcpng`
|
||||
|
||||
@@ -107,6 +107,7 @@ Reports:
|
||||
- `docs/reports/phase20-host-initiated-native-builds-freebsd.md`
|
||||
- `docs/reports/phase20-self-hosted-native-builds-freebsd.md`
|
||||
- `docs/reports/phase20-native-build-store-promotion-freebsd.md`
|
||||
- `docs/reports/phase20-native-build-executor-model-freebsd.md`
|
||||
|
||||
## Recent major milestones
|
||||
|
||||
@@ -134,12 +135,12 @@ Reports:
|
||||
|
||||
The next practical follow-up is now clearer:
|
||||
|
||||
- unify host-initiated and self-hosted native-build execution behind a shared Fruix executor/result model
|
||||
- make the same first-class promotion story available regardless of whether the outer loop is host-driven or guest-driven
|
||||
- decide how much of result import/promotion should remain host-side versus become a more integrated Fruix deployment action
|
||||
- extend the shared executor/result model from validated `ssh-guest` and `self-hosted` paths to the `host` path as well
|
||||
- decide how much of result import/promotion should remain host-side versus become a more integrated Fruix action
|
||||
- determine whether executor selection should become part of a higher-level Fruix native-build/deployment command surface
|
||||
|
||||
The immediate architectural direction is no longer just “can guest self-hosting work?”
|
||||
|
||||
It is now:
|
||||
|
||||
- how should Fruix represent native base builds as real first-class objects and workflows across different executors?
|
||||
- how should Fruix expose executor selection, execution policy, and result promotion as one coherent operator-facing workflow?
|
||||
|
||||
202
docs/reports/phase20-native-build-executor-model-freebsd.md
Normal file
202
docs/reports/phase20-native-build-executor-model-freebsd.md
Normal file
@@ -0,0 +1,202 @@
|
||||
# Post-Phase 20: native build executor model
|
||||
|
||||
Date: 2026-04-06
|
||||
|
||||
## Goal
|
||||
|
||||
Turn the now-proven native base-build placement options into one Fruix abstraction instead of treating them as unrelated paths.
|
||||
|
||||
The desired model is:
|
||||
|
||||
- same declared source identity
|
||||
- same expected artifact kinds
|
||||
- same staged-result shape
|
||||
- same promotion/provenance shape
|
||||
- different executor policy
|
||||
|
||||
So the question becomes:
|
||||
|
||||
- where should the build run?
|
||||
|
||||
and the answer is expressed as executor policy rather than as a separate architecture each time.
|
||||
|
||||
## Executor model
|
||||
|
||||
Fruix now has an explicit native-build executor model with current executor kinds:
|
||||
|
||||
- `host`
|
||||
- `ssh-guest`
|
||||
- `self-hosted`
|
||||
|
||||
and intended future extension points:
|
||||
|
||||
- `jail`
|
||||
- `remote-builder`
|
||||
|
||||
The new executor model is implemented in:
|
||||
|
||||
- `modules/fruix/system/freebsd/executor.scm`
|
||||
|
||||
It defines a structured executor object that records at least:
|
||||
|
||||
- `kind`
|
||||
- `name`
|
||||
- `version`
|
||||
- `properties`
|
||||
|
||||
## What changed
|
||||
|
||||
### 1. Structured executor metadata
|
||||
|
||||
Native-build result metadata is no longer limited to a flat string such as:
|
||||
|
||||
- `guest-self-hosted`
|
||||
|
||||
Instead, result/promotion objects now carry a structured executor description.
|
||||
|
||||
Representative executor objects now look like:
|
||||
|
||||
```scheme
|
||||
((kind . self-hosted)
|
||||
(name . "guest-self-hosted")
|
||||
(version . "4")
|
||||
(properties . (...)))
|
||||
```
|
||||
|
||||
or:
|
||||
|
||||
```scheme
|
||||
((kind . ssh-guest)
|
||||
(name . "ssh-guest")
|
||||
(version . "1")
|
||||
(properties . (...)))
|
||||
```
|
||||
|
||||
Promoted store metadata also now records compatibility fields derived from that executor object:
|
||||
|
||||
- `executor-kind`
|
||||
- `executor-name`
|
||||
- `executor-version`
|
||||
|
||||
### 2. Shared staged-result shape across executors
|
||||
|
||||
Both validated executor paths now converge on the same mutable staging layout under:
|
||||
|
||||
- `/var/lib/fruix/native-builds/<run-id>`
|
||||
|
||||
with promoted artifacts staged under:
|
||||
|
||||
- `artifacts/world`
|
||||
- `artifacts/kernel`
|
||||
- `artifacts/headers`
|
||||
- `artifacts/bootloader`
|
||||
|
||||
and promotion metadata recorded in:
|
||||
|
||||
- `promotion.scm`
|
||||
|
||||
The heavy build work remains executor-specific, but the result shape is now shared.
|
||||
|
||||
### 3. Shared immutable promotion path
|
||||
|
||||
Both validated executor paths now promote through the same command:
|
||||
|
||||
```sh
|
||||
fruix native-build promote RESULT_ROOT
|
||||
```
|
||||
|
||||
That promotion creates immutable store identities for:
|
||||
|
||||
- `world`
|
||||
- `kernel`
|
||||
- `headers`
|
||||
- `bootloader`
|
||||
- result bundle
|
||||
|
||||
under `/frx/store/...`.
|
||||
|
||||
## Validated executor policies
|
||||
|
||||
### `self-hosted`
|
||||
|
||||
The self-hosted guest helper now emits the structured executor metadata directly from:
|
||||
|
||||
- `/usr/local/bin/fruix-self-hosted-native-build`
|
||||
|
||||
Validated self-hosted promotion flow:
|
||||
|
||||
- `PASS phase20-self-hosted-native-build-xcpng`
|
||||
- `PASS phase20-native-build-store-promotion-xcpng`
|
||||
|
||||
Representative promoted result:
|
||||
|
||||
```text
|
||||
result_store=/frx/store/0423193b9bd5e652bdb9d94d077e40dfcc3e9e78-fruix-native-build-result-15.0-STABLE-guest-self-hosted
|
||||
world_store=/frx/store/5f67e95058186147206ff6f5da2243a09212e358-fruix-native-world-15.0-STABLE-guest-self-hosted
|
||||
kernel_store=/frx/store/3a32797cc187a90e8273f205eababae6246568d9-fruix-native-kernel-15.0-STABLE-guest-self-hosted
|
||||
headers_store=/frx/store/1d54d9814461f003e91add8cd37e94ac5f3d04ce-fruix-native-headers-15.0-STABLE-guest-self-hosted
|
||||
bootloader_store=/frx/store/49f4885f0f05a324ac826f2618d4c7a923ca30d2-fruix-native-bootloader-15.0-STABLE-guest-self-hosted
|
||||
```
|
||||
|
||||
### `ssh-guest`
|
||||
|
||||
The host-initiated guest path now also stages a shared native-build result root under:
|
||||
|
||||
- `/var/lib/fruix/native-builds/<run-id>`
|
||||
|
||||
instead of stopping at temporary build directories alone.
|
||||
|
||||
Its promotion metadata records executor policy as:
|
||||
|
||||
- `kind = ssh-guest`
|
||||
- `name = ssh-guest`
|
||||
- `version = 1`
|
||||
|
||||
with executor properties including:
|
||||
|
||||
- `transport = ssh`
|
||||
- `orchestrator = host`
|
||||
- guest addressing / VM identity metadata
|
||||
|
||||
Validated host-initiated promotion flow:
|
||||
|
||||
- `PASS phase20-host-initiated-native-build-xcpng`
|
||||
- `PASS phase20-host-initiated-native-build-store-promotion-xcpng`
|
||||
|
||||
Representative promoted result:
|
||||
|
||||
```text
|
||||
result_store=/frx/store/ffe44f5d1ba576e1f811ad3fe3a526a242b5c4a5-fruix-native-build-result-15.0-STABLE-ssh-guest
|
||||
world_store=/frx/store/89c7a71c3df148a1f99b13d57fd6be88243eb2cb-fruix-native-world-15.0-STABLE-ssh-guest
|
||||
kernel_store=/frx/store/93bac81122022b40438d356146a6854b4ee48513-fruix-native-kernel-15.0-STABLE-ssh-guest
|
||||
headers_store=/frx/store/dd7f39f526bca4849caf1eaf96ae25d29b43493c-fruix-native-headers-15.0-STABLE-ssh-guest
|
||||
bootloader_store=/frx/store/78b1c6b0b5c0c2c1549f5f42f3d64b6d9293669b-fruix-native-bootloader-15.0-STABLE-ssh-guest
|
||||
```
|
||||
|
||||
## Important result
|
||||
|
||||
The same declared source and artifact contract now works across two different executor policies:
|
||||
|
||||
- `ssh-guest`
|
||||
- `self-hosted`
|
||||
|
||||
while preserving the same Fruix-native staging/promotion split:
|
||||
|
||||
- mutable result roots under `/var/lib/fruix/native-builds/...`
|
||||
- immutable promoted identities under `/frx/store/...`
|
||||
|
||||
That is the core architectural win of the executor model.
|
||||
|
||||
## What is not yet fully unified
|
||||
|
||||
The `host` executor kind now exists in the model, but the fully shared staged-result-plus-promotion workflow is not yet wired through the existing host-local native build path.
|
||||
|
||||
So the executor model is introduced and real-VM validated across two policies, but not yet uniformly productized across every native-build entry point.
|
||||
|
||||
## Result
|
||||
|
||||
Fruix now treats native-build placement as executor policy rather than as an architectural fork.
|
||||
|
||||
That means the next step is no longer to invent another build path from scratch.
|
||||
|
||||
It is to keep extending the same executor/result/promotion model so additional execution policies can plug into the same Fruix-native object story.
|
||||
@@ -337,7 +337,7 @@ Current metadata split:
|
||||
|
||||
The promoted store objects record explicit Fruix-native metadata including at least:
|
||||
|
||||
- executor / executor-version
|
||||
- executor kind / name / version
|
||||
- run-id / guest-host-name
|
||||
- closure path
|
||||
- source store provenance
|
||||
@@ -353,6 +353,42 @@ This is the current Fruix-native answer to the question:
|
||||
- where should immutable native-build identity live?
|
||||
- `/frx/store/...`
|
||||
|
||||
### Native-build executor model
|
||||
|
||||
Fruix now has an explicit executor model for native base builds.
|
||||
|
||||
Current executor kinds are:
|
||||
|
||||
- `host`
|
||||
- `ssh-guest`
|
||||
- `self-hosted`
|
||||
|
||||
and the intended future extension points are:
|
||||
|
||||
- `jail`
|
||||
- `remote-builder`
|
||||
|
||||
The important change is architectural:
|
||||
|
||||
- declared source identity stays the same
|
||||
- expected artifact kinds stay the same
|
||||
- result/promotion metadata shape stays the same
|
||||
- only the executor policy changes
|
||||
|
||||
So “where the build runs” is now treated as executor policy rather than as a separate native-build architecture each time.
|
||||
|
||||
Current end-to-end validated executors for the staged-result-plus-promotion model are:
|
||||
|
||||
- `ssh-guest`
|
||||
- `self-hosted`
|
||||
|
||||
Both now converge on the same Fruix-native flow:
|
||||
|
||||
1. run the build under a selected executor
|
||||
2. stage a result root under `/var/lib/fruix/native-builds/...`
|
||||
3. emit the same promotion/provenance shape
|
||||
4. promote the result into immutable `/frx/store/...` objects
|
||||
|
||||
## Deployment patterns
|
||||
|
||||
### 1. Build-first workflow
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
(define-module (fruix system freebsd)
|
||||
#:use-module (fruix system freebsd model)
|
||||
#:use-module (fruix system freebsd source)
|
||||
#:use-module (fruix system freebsd executor)
|
||||
#:use-module (fruix system freebsd build)
|
||||
#:use-module (fruix system freebsd media)
|
||||
#:re-export (user-group
|
||||
@@ -44,6 +45,17 @@
|
||||
operating-system-root-authorized-keys
|
||||
validate-operating-system
|
||||
materialize-freebsd-source
|
||||
native-build-executor
|
||||
native-build-executor?
|
||||
native-build-executor-ref
|
||||
native-build-executor-kind
|
||||
native-build-executor-name
|
||||
native-build-executor-version
|
||||
native-build-executor-properties
|
||||
normalize-native-build-executor
|
||||
host-native-build-executor
|
||||
ssh-guest-native-build-executor
|
||||
self-hosted-native-build-executor
|
||||
promote-native-build-result
|
||||
operating-system-closure-spec
|
||||
operating-system-install-spec
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#:use-module (fruix packages freebsd)
|
||||
#:use-module (fruix system freebsd model)
|
||||
#:use-module (fruix system freebsd source)
|
||||
#:use-module (fruix system freebsd executor)
|
||||
#:use-module (fruix system freebsd utils)
|
||||
#:use-module (guix build utils)
|
||||
#:use-module (ice-9 format)
|
||||
@@ -396,6 +397,32 @@
|
||||
((_ . value) value)
|
||||
(#f default)))
|
||||
|
||||
(define (native-build-result-executor result)
|
||||
(let* ((executor (native-build-result-ref result 'executor #f))
|
||||
(legacy-version (native-build-result-ref result 'executor-version "legacy")))
|
||||
(cond
|
||||
((native-build-executor? executor)
|
||||
executor)
|
||||
((string? executor)
|
||||
(let ((normalized (normalize-native-build-executor executor)))
|
||||
`((kind . ,(native-build-executor-kind normalized))
|
||||
(name . ,(native-build-executor-name normalized))
|
||||
(version . ,legacy-version)
|
||||
(properties . ,(native-build-executor-properties normalized)))))
|
||||
(else
|
||||
(native-build-executor #:kind 'unknown
|
||||
#:name "unknown"
|
||||
#:version legacy-version)))))
|
||||
|
||||
(define (native-build-result-executor-kind result)
|
||||
(native-build-executor-kind (native-build-result-executor result)))
|
||||
|
||||
(define (native-build-result-executor-name result)
|
||||
(native-build-executor-name (native-build-result-executor result)))
|
||||
|
||||
(define (native-build-result-executor-version result)
|
||||
(native-build-executor-version (native-build-result-executor result)))
|
||||
|
||||
(define (read-native-build-result result-root)
|
||||
(let ((promotion-file (string-append result-root "/promotion.scm")))
|
||||
(unless (file-exists? promotion-file)
|
||||
@@ -442,21 +469,24 @@
|
||||
(define (native-build-artifact-display-name result artifact-kind)
|
||||
(let* ((base (native-build-result-ref result 'freebsd-base '()))
|
||||
(version-label (native-build-result-ref base 'version-label "unknown"))
|
||||
(executor (native-build-result-ref result 'executor "unknown")))
|
||||
(executor-name (native-build-result-executor-name result)))
|
||||
(string-append "fruix-native-"
|
||||
(symbol->string artifact-kind)
|
||||
"-"
|
||||
version-label
|
||||
"-"
|
||||
executor)))
|
||||
executor-name)))
|
||||
|
||||
(define (native-build-promoted-artifact-metadata result artifact-kind content-signature)
|
||||
(let* ((entry (native-build-artifact-entry result artifact-kind)))
|
||||
(let* ((entry (native-build-artifact-entry result artifact-kind))
|
||||
(executor (native-build-result-executor result)))
|
||||
`((native-build-object-version . ,native-build-result-promotion-version)
|
||||
(object-kind . artifact)
|
||||
(artifact-kind . ,artifact-kind)
|
||||
(executor . ,(native-build-result-ref result 'executor "unknown"))
|
||||
(executor-version . ,(native-build-result-ref result 'executor-version "unknown"))
|
||||
(executor . ,executor)
|
||||
(executor-kind . ,(native-build-result-executor-kind result))
|
||||
(executor-name . ,(native-build-result-executor-name result))
|
||||
(executor-version . ,(native-build-result-executor-version result))
|
||||
(run-id . ,(native-build-result-ref result 'run-id "unknown"))
|
||||
(guest-host-name . ,(native-build-result-ref result 'guest-host-name "unknown"))
|
||||
(closure-path . ,(native-build-result-ref result 'closure-path ""))
|
||||
@@ -494,28 +524,31 @@
|
||||
(define (native-build-result-display-name result)
|
||||
(let* ((base (native-build-result-ref result 'freebsd-base '()))
|
||||
(version-label (native-build-result-ref base 'version-label "unknown"))
|
||||
(executor (native-build-result-ref result 'executor "unknown")))
|
||||
(string-append "fruix-native-build-result-" version-label "-" executor)))
|
||||
(executor-name (native-build-result-executor-name result)))
|
||||
(string-append "fruix-native-build-result-" version-label "-" executor-name)))
|
||||
|
||||
(define (native-build-promoted-result-object result promoted-artifacts)
|
||||
`((native-build-result-version . ,native-build-result-promotion-version)
|
||||
(object-kind . result-bundle)
|
||||
(executor . ,(native-build-result-ref result 'executor "unknown"))
|
||||
(executor-version . ,(native-build-result-ref result 'executor-version "unknown"))
|
||||
(run-id . ,(native-build-result-ref result 'run-id "unknown"))
|
||||
(guest-host-name . ,(native-build-result-ref result 'guest-host-name "unknown"))
|
||||
(closure-path . ,(native-build-result-ref result 'closure-path ""))
|
||||
(development-profile . ,(native-build-result-ref result 'development-profile ""))
|
||||
(freebsd-base . ,(native-build-result-ref result 'freebsd-base '()))
|
||||
(source . ,(native-build-result-ref result 'source '()))
|
||||
(build-policy . ,(native-build-result-ref result 'build-policy '()))
|
||||
(artifact-count . ,(length promoted-artifacts))
|
||||
(artifacts . ,(map (lambda (entry)
|
||||
`((artifact-kind . ,(assoc-ref entry 'artifact-kind))
|
||||
(store-path . ,(assoc-ref entry 'store-path))
|
||||
(content-signature . ,(assoc-ref entry 'content-signature))
|
||||
(metadata-file . ,(assoc-ref entry 'metadata-file))))
|
||||
promoted-artifacts))))
|
||||
(let ((executor (native-build-result-executor result)))
|
||||
`((native-build-result-version . ,native-build-result-promotion-version)
|
||||
(object-kind . result-bundle)
|
||||
(executor . ,executor)
|
||||
(executor-kind . ,(native-build-result-executor-kind result))
|
||||
(executor-name . ,(native-build-result-executor-name result))
|
||||
(executor-version . ,(native-build-result-executor-version result))
|
||||
(run-id . ,(native-build-result-ref result 'run-id "unknown"))
|
||||
(guest-host-name . ,(native-build-result-ref result 'guest-host-name "unknown"))
|
||||
(closure-path . ,(native-build-result-ref result 'closure-path ""))
|
||||
(development-profile . ,(native-build-result-ref result 'development-profile ""))
|
||||
(freebsd-base . ,(native-build-result-ref result 'freebsd-base '()))
|
||||
(source . ,(native-build-result-ref result 'source '()))
|
||||
(build-policy . ,(native-build-result-ref result 'build-policy '()))
|
||||
(artifact-count . ,(length promoted-artifacts))
|
||||
(artifacts . ,(map (lambda (entry)
|
||||
`((artifact-kind . ,(assoc-ref entry 'artifact-kind))
|
||||
(store-path . ,(assoc-ref entry 'store-path))
|
||||
(content-signature . ,(assoc-ref entry 'content-signature))
|
||||
(metadata-file . ,(assoc-ref entry 'metadata-file))))
|
||||
promoted-artifacts)))))
|
||||
|
||||
(define* (promote-native-build-result result-root #:key (store-dir "/frx/store"))
|
||||
(let* ((result (read-native-build-result result-root))
|
||||
@@ -544,6 +577,9 @@
|
||||
(write-file (string-append result-store "/.fruix-native-build-result.scm")
|
||||
payload))
|
||||
`((result-root . ,result-root)
|
||||
(executor-kind . ,(native-build-result-executor-kind result))
|
||||
(executor-name . ,(native-build-result-executor-name result))
|
||||
(executor-version . ,(native-build-result-executor-version result))
|
||||
(result-store . ,result-store)
|
||||
(result-metadata-file . ,(string-append result-store "/.fruix-native-build-result.scm"))
|
||||
(artifact-store-count . ,(length promoted-artifacts))
|
||||
|
||||
121
modules/fruix/system/freebsd/executor.scm
Normal file
121
modules/fruix/system/freebsd/executor.scm
Normal file
@@ -0,0 +1,121 @@
|
||||
(define-module (fruix system freebsd executor)
|
||||
#:use-module (ice-9 match)
|
||||
#:use-module (srfi srfi-1)
|
||||
#:export (native-build-executor-model-version
|
||||
native-build-executor
|
||||
native-build-executor?
|
||||
native-build-executor-ref
|
||||
native-build-executor-kind
|
||||
native-build-executor-name
|
||||
native-build-executor-version
|
||||
native-build-executor-properties
|
||||
normalize-native-build-executor
|
||||
host-native-build-executor
|
||||
ssh-guest-native-build-executor
|
||||
self-hosted-native-build-executor))
|
||||
|
||||
(define native-build-executor-model-version "1")
|
||||
|
||||
(define (association-list? value)
|
||||
(and (list? value)
|
||||
(every pair? value)))
|
||||
|
||||
(define (executor-name kind provided-name)
|
||||
(or provided-name
|
||||
(symbol->string kind)))
|
||||
|
||||
(define* (native-build-executor #:key kind name
|
||||
(version native-build-executor-model-version)
|
||||
(properties '()))
|
||||
(unless (symbol? kind)
|
||||
(error "native build executor kind must be a symbol" kind))
|
||||
(unless (string? (executor-name kind name))
|
||||
(error "native build executor name must be a string" name))
|
||||
(unless (string? version)
|
||||
(error "native build executor version must be a string" version))
|
||||
(unless (association-list? properties)
|
||||
(error "native build executor properties must be an association list" properties))
|
||||
`((kind . ,kind)
|
||||
(name . ,(executor-name kind name))
|
||||
(version . ,version)
|
||||
(properties . ,properties)))
|
||||
|
||||
(define (native-build-executor-ref executor key default)
|
||||
(match (assoc key executor)
|
||||
((_ . value) value)
|
||||
(#f default)))
|
||||
|
||||
(define (native-build-executor? value)
|
||||
(and (association-list? value)
|
||||
(symbol? (native-build-executor-ref value 'kind #f))
|
||||
(string? (native-build-executor-ref value 'name #f))
|
||||
(string? (native-build-executor-ref value 'version #f))
|
||||
(association-list? (native-build-executor-ref value 'properties '()))))
|
||||
|
||||
(define (native-build-executor-kind executor)
|
||||
(native-build-executor-ref executor 'kind 'unknown))
|
||||
|
||||
(define (native-build-executor-name executor)
|
||||
(native-build-executor-ref executor 'name "unknown"))
|
||||
|
||||
(define (native-build-executor-version executor)
|
||||
(native-build-executor-ref executor 'version "unknown"))
|
||||
|
||||
(define (native-build-executor-properties executor)
|
||||
(native-build-executor-ref executor 'properties '()))
|
||||
|
||||
(define (legacy-executor-kind name)
|
||||
(cond
|
||||
((member name '("host")) 'host)
|
||||
((member name '("ssh-guest" "guest-ssh" "guest-host-initiated")) 'ssh-guest)
|
||||
((member name '("self-hosted" "guest-self-hosted")) 'self-hosted)
|
||||
((member name '("jail")) 'jail)
|
||||
((member name '("remote-builder")) 'remote-builder)
|
||||
(else 'legacy)))
|
||||
|
||||
(define (normalize-native-build-executor value)
|
||||
(cond
|
||||
((native-build-executor? value)
|
||||
value)
|
||||
((string? value)
|
||||
(native-build-executor #:kind (legacy-executor-kind value)
|
||||
#:name value
|
||||
#:version "legacy"))
|
||||
(else
|
||||
(error "unsupported native build executor representation" value))))
|
||||
|
||||
(define* (host-native-build-executor #:key (name "host")
|
||||
host-name working-directory)
|
||||
(native-build-executor
|
||||
#:kind 'host
|
||||
#:name name
|
||||
#:properties (filter-map identity
|
||||
`((host-name . ,host-name)
|
||||
(working-directory . ,working-directory)))))
|
||||
|
||||
(define* (ssh-guest-native-build-executor #:key (name "ssh-guest")
|
||||
transport orchestrator
|
||||
guest-host-name guest-ip vm-id vdi-id)
|
||||
(native-build-executor
|
||||
#:kind 'ssh-guest
|
||||
#:name name
|
||||
#:properties (filter-map identity
|
||||
`((transport . ,(or transport "ssh"))
|
||||
(orchestrator . ,(or orchestrator "host"))
|
||||
(guest-host-name . ,guest-host-name)
|
||||
(guest-ip . ,guest-ip)
|
||||
(vm-id . ,vm-id)
|
||||
(vdi-id . ,vdi-id)))))
|
||||
|
||||
(define* (self-hosted-native-build-executor #:key (name "self-hosted")
|
||||
helper-path helper-version
|
||||
guest-host-name build-root-base result-root-base)
|
||||
(native-build-executor
|
||||
#:kind 'self-hosted
|
||||
#:name name
|
||||
#:version (or helper-version native-build-executor-model-version)
|
||||
#:properties (filter-map identity
|
||||
`((helper-path . ,helper-path)
|
||||
(guest-host-name . ,guest-host-name)
|
||||
(build-root-base . ,build-root-base)
|
||||
(result-root-base . ,result-root-base)))))
|
||||
@@ -334,7 +334,7 @@
|
||||
(development-environment-helper-version
|
||||
. ,(if (null? (operating-system-development-packages os)) #f "1"))
|
||||
(self-hosted-native-build-helper-version
|
||||
. ,(if (null? (operating-system-development-packages os)) #f "3"))
|
||||
. ,(if (null? (operating-system-development-packages os)) #f "4"))
|
||||
(user-count . ,(length (operating-system-users os)))
|
||||
(users . ,(map user-account-name (operating-system-users os)))
|
||||
(group-count . ,(length (operating-system-groups os)))
|
||||
|
||||
@@ -928,8 +928,13 @@
|
||||
"ln -s \"$result_root\" \"$latest_link\"\n"
|
||||
"cat >\"$promotion_file\" <<EOF\n"
|
||||
"((native-build-result-version . \"1\")\n"
|
||||
" (executor . \"guest-self-hosted\")\n"
|
||||
" (executor-version . \"3\")\n"
|
||||
" (executor . ((kind . self-hosted)\n"
|
||||
" (name . \"guest-self-hosted\")\n"
|
||||
" (version . \"4\")\n"
|
||||
" (properties . ((helper-path . \"/usr/local/bin/fruix-self-hosted-native-build\")\n"
|
||||
" (guest-host-name . \"$guest_host_name\")\n"
|
||||
" (build-root-base . \"$build_root_base\")\n"
|
||||
" (result-root-base . \"$result_root_base\")))))\n"
|
||||
" (run-id . \"$run_id\")\n"
|
||||
" (guest-host-name . \"$guest_host_name\")\n"
|
||||
" (closure-path . \"$closure\")\n"
|
||||
@@ -961,7 +966,10 @@
|
||||
"EOF\n"
|
||||
"cat >\"$metadata_file\" <<EOF\n"
|
||||
"run_id=$run_id\n"
|
||||
"helper_version=3\n"
|
||||
"helper_version=4\n"
|
||||
"executor_kind=self-hosted\n"
|
||||
"executor_name=guest-self-hosted\n"
|
||||
"executor_version=4\n"
|
||||
"closure_path=$closure\n"
|
||||
"guest_host_name=$guest_host_name\n"
|
||||
"development_profile=$profile\n"
|
||||
|
||||
@@ -580,6 +580,9 @@ Common options:\n\
|
||||
`((action . "promote")
|
||||
(result_root . ,result-root)
|
||||
(store_dir . ,store-dir)
|
||||
(executor_kind . ,(assoc-ref result 'executor-kind))
|
||||
(executor_name . ,(assoc-ref result 'executor-name))
|
||||
(executor_version . ,(assoc-ref result 'executor-version))
|
||||
(result_store . ,(assoc-ref result 'result-store))
|
||||
(result_metadata_file . ,(assoc-ref result 'result-metadata-file))
|
||||
(artifact_store_count . ,(assoc-ref result 'artifact-store-count))
|
||||
|
||||
239
tests/system/run-phase20-host-initiated-native-build-store-promotion-xcpng.sh
Executable file
239
tests/system/run-phase20-host-initiated-native-build-store-promotion-xcpng.sh
Executable file
@@ -0,0 +1,239 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
repo_root=${PROJECT_ROOT:-$(pwd)}
|
||||
os_template=${OS_TEMPLATE:-$repo_root/tests/system/phase20-development-operating-system.scm.in}
|
||||
system_name=${SYSTEM_NAME:-phase20-operating-system}
|
||||
root_size=${ROOT_SIZE:-20g}
|
||||
store_dir=${STORE_DIR:-/frx/store}
|
||||
metadata_target=${METADATA_OUT:-}
|
||||
root_authorized_key_file=${ROOT_AUTHORIZED_KEY_FILE:-$HOME/.ssh/id_ed25519.pub}
|
||||
root_ssh_private_key_file=${ROOT_SSH_PRIVATE_KEY_FILE:-$HOME/.ssh/id_ed25519}
|
||||
cleanup=0
|
||||
|
||||
if [ -n "${WORKDIR:-}" ]; then
|
||||
workdir=$WORKDIR
|
||||
mkdir -p "$workdir"
|
||||
else
|
||||
workdir=$(mktemp -d /tmp/fruix-phase20-host-initiated-native-build-store-promotion-xcpng.XXXXXX)
|
||||
cleanup=1
|
||||
fi
|
||||
if [ "${KEEP_WORKDIR:-0}" -eq 1 ]; then
|
||||
cleanup=0
|
||||
fi
|
||||
|
||||
inner_metadata=$workdir/phase20-host-initiated-native-build-store-promotion-inner-metadata.txt
|
||||
promotion_out=$workdir/native-build-promote.txt
|
||||
metadata_file=$workdir/phase20-host-initiated-native-build-store-promotion-xcpng-metadata.txt
|
||||
import_root=$workdir/import
|
||||
|
||||
action_cleanup() {
|
||||
if [ "$cleanup" -eq 1 ]; then
|
||||
rm -rf "$workdir"
|
||||
fi
|
||||
}
|
||||
trap action_cleanup EXIT INT TERM
|
||||
|
||||
KEEP_WORKDIR=1 WORKDIR="$workdir/inner" METADATA_OUT="$inner_metadata" \
|
||||
ROOT_AUTHORIZED_KEY_FILE="$root_authorized_key_file" \
|
||||
ROOT_SSH_PRIVATE_KEY_FILE="$root_ssh_private_key_file" \
|
||||
OS_TEMPLATE="$os_template" SYSTEM_NAME="$system_name" ROOT_SIZE="$root_size" \
|
||||
"$repo_root/tests/system/run-phase20-host-initiated-native-build-xcpng.sh"
|
||||
|
||||
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")
|
||||
closure_path=$(sed -n 's/^closure_path=//p' "$inner_metadata")
|
||||
closure_base=$(sed -n 's/^closure_base=//p' "$inner_metadata")
|
||||
run_id=$(sed -n 's/^run_id=//p' "$inner_metadata")
|
||||
source_store=$(sed -n 's/^source_store=//p' "$inner_metadata")
|
||||
result_root=$(sed -n 's/^result_root=//p' "$inner_metadata")
|
||||
promotion_file=$(sed -n 's/^promotion_file=//p' "$inner_metadata")
|
||||
world_artifact=$(sed -n 's/^world_artifact=//p' "$inner_metadata")
|
||||
kernel_artifact=$(sed -n 's/^kernel_artifact=//p' "$inner_metadata")
|
||||
headers_artifact=$(sed -n 's/^headers_artifact=//p' "$inner_metadata")
|
||||
bootloader_artifact=$(sed -n 's/^bootloader_artifact=//p' "$inner_metadata")
|
||||
sha_kernel=$(sed -n 's/^sha_kernel=//p' "$inner_metadata")
|
||||
sha_loader=$(sed -n 's/^sha_loader=//p' "$inner_metadata")
|
||||
sha_param=$(sed -n 's/^sha_param=//p' "$inner_metadata")
|
||||
|
||||
ssh_guest() {
|
||||
ssh -i "$root_ssh_private_key_file" \
|
||||
-o BatchMode=yes \
|
||||
-o StrictHostKeyChecking=no \
|
||||
-o UserKnownHostsFile=/dev/null \
|
||||
-o ConnectTimeout=5 \
|
||||
root@"$guest_ip" "$@"
|
||||
}
|
||||
|
||||
mkdir -p "$import_root"
|
||||
result_base=$(basename "$result_root")
|
||||
ssh -i "$root_ssh_private_key_file" \
|
||||
-o BatchMode=yes \
|
||||
-o StrictHostKeyChecking=no \
|
||||
-o UserKnownHostsFile=/dev/null \
|
||||
-o ConnectTimeout=5 \
|
||||
root@"$guest_ip" "tar -C '$(dirname "$result_root")' -cf - '$result_base'" | tar -C "$import_root" -xf -
|
||||
local_result_root=$import_root/$result_base
|
||||
[ -d "$local_result_root" ] || { echo "failed to import native build result root" >&2; exit 1; }
|
||||
[ -f "$local_result_root/promotion.scm" ] || { echo "imported result is missing promotion.scm" >&2; exit 1; }
|
||||
[ -f "$local_result_root/artifacts/world/bin/sh" ] || { echo "imported result is missing world artifact" >&2; exit 1; }
|
||||
[ -f "$local_result_root/artifacts/kernel/boot/kernel/kernel" ] || { echo "imported result is missing kernel artifact" >&2; exit 1; }
|
||||
[ -f "$local_result_root/artifacts/headers/usr/include/sys/param.h" ] || { echo "imported result is missing headers artifact" >&2; exit 1; }
|
||||
[ -f "$local_result_root/artifacts/bootloader/boot/loader.efi" ] || { echo "imported result is missing bootloader artifact" >&2; exit 1; }
|
||||
|
||||
action_env() {
|
||||
sudo env \
|
||||
HOME="$HOME" \
|
||||
GUILE_AUTO_COMPILE=0 \
|
||||
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 "$repo_root/bin/fruix" native-build promote "$local_result_root" --store "$store_dir" >"$promotion_out"
|
||||
|
||||
field() {
|
||||
sed -n "s/^$1=//p" "$promotion_out" | tail -n 1
|
||||
}
|
||||
|
||||
executor_kind=$(field executor_kind)
|
||||
executor_name=$(field executor_name)
|
||||
executor_version=$(field executor_version)
|
||||
result_store=$(field result_store)
|
||||
result_metadata_file=$(field result_metadata_file)
|
||||
artifact_store_count=$(field artifact_store_count)
|
||||
artifact_stores=$(field artifact_stores)
|
||||
world_store=$(field world_store)
|
||||
kernel_store=$(field kernel_store)
|
||||
headers_store=$(field headers_store)
|
||||
bootloader_store=$(field bootloader_store)
|
||||
|
||||
[ "$executor_kind" = ssh-guest ] || { echo "unexpected executor kind: $executor_kind" >&2; exit 1; }
|
||||
[ "$executor_name" = ssh-guest ] || { echo "unexpected executor name: $executor_name" >&2; exit 1; }
|
||||
[ "$executor_version" = 1 ] || { echo "unexpected executor version: $executor_version" >&2; exit 1; }
|
||||
[ "$artifact_store_count" = 4 ] || { echo "unexpected artifact store count: $artifact_store_count" >&2; exit 1; }
|
||||
case "$result_store" in
|
||||
/frx/store/*-fruix-native-build-result-*-ssh-guest) : ;;
|
||||
*) echo "unexpected result store path: $result_store" >&2; exit 1 ;;
|
||||
esac
|
||||
case "$world_store" in
|
||||
/frx/store/*-fruix-native-world-*-ssh-guest) : ;;
|
||||
*) echo "unexpected world store path: $world_store" >&2; exit 1 ;;
|
||||
esac
|
||||
case "$kernel_store" in
|
||||
/frx/store/*-fruix-native-kernel-*-ssh-guest) : ;;
|
||||
*) echo "unexpected kernel store path: $kernel_store" >&2; exit 1 ;;
|
||||
esac
|
||||
case "$headers_store" in
|
||||
/frx/store/*-fruix-native-headers-*-ssh-guest) : ;;
|
||||
*) echo "unexpected headers store path: $headers_store" >&2; exit 1 ;;
|
||||
esac
|
||||
case "$bootloader_store" in
|
||||
/frx/store/*-fruix-native-bootloader-*-ssh-guest) : ;;
|
||||
*) echo "unexpected bootloader store path: $bootloader_store" >&2; exit 1 ;;
|
||||
esac
|
||||
|
||||
[ -f "$result_metadata_file" ] || { echo "missing result metadata file: $result_metadata_file" >&2; exit 1; }
|
||||
[ -f "$world_store/.fruix-native-build-object.scm" ] || { echo "missing world store metadata" >&2; exit 1; }
|
||||
[ -f "$kernel_store/.fruix-native-build-object.scm" ] || { echo "missing kernel store metadata" >&2; exit 1; }
|
||||
[ -f "$headers_store/.fruix-native-build-object.scm" ] || { echo "missing headers store metadata" >&2; exit 1; }
|
||||
[ -f "$bootloader_store/.fruix-native-build-object.scm" ] || { echo "missing bootloader store metadata" >&2; exit 1; }
|
||||
[ -L "$result_store/artifacts/world" ] || { echo "missing promoted world artifact link" >&2; exit 1; }
|
||||
[ -L "$result_store/artifacts/kernel" ] || { echo "missing promoted kernel artifact link" >&2; exit 1; }
|
||||
[ -L "$result_store/artifacts/headers" ] || { echo "missing promoted headers artifact link" >&2; exit 1; }
|
||||
[ -L "$result_store/artifacts/bootloader" ] || { echo "missing promoted bootloader artifact link" >&2; exit 1; }
|
||||
[ "$(readlink "$result_store/artifacts/world")" = "$world_store" ] || { echo "world artifact link mismatch" >&2; exit 1; }
|
||||
[ "$(readlink "$result_store/artifacts/kernel")" = "$kernel_store" ] || { echo "kernel artifact link mismatch" >&2; exit 1; }
|
||||
[ "$(readlink "$result_store/artifacts/headers")" = "$headers_store" ] || { echo "headers artifact link mismatch" >&2; exit 1; }
|
||||
[ "$(readlink "$result_store/artifacts/bootloader")" = "$bootloader_store" ] || { echo "bootloader artifact link mismatch" >&2; exit 1; }
|
||||
[ -f "$world_store/bin/sh" ] || { echo "promoted world store missing /bin/sh" >&2; exit 1; }
|
||||
[ -f "$kernel_store/boot/kernel/kernel" ] || { echo "promoted kernel store missing kernel" >&2; exit 1; }
|
||||
[ -f "$headers_store/usr/include/sys/param.h" ] || { echo "promoted headers store missing param.h" >&2; exit 1; }
|
||||
[ -f "$bootloader_store/boot/loader.efi" ] || { echo "promoted bootloader store missing loader.efi" >&2; exit 1; }
|
||||
|
||||
promoted_kernel_sha=$(sha256 -q "$kernel_store/boot/kernel/kernel")
|
||||
promoted_loader_sha=$(sha256 -q "$bootloader_store/boot/loader.efi")
|
||||
promoted_param_sha=$(sha256 -q "$headers_store/usr/include/sys/param.h")
|
||||
[ "$promoted_kernel_sha" = "$sha_kernel" ] || { echo "kernel sha mismatch after promotion" >&2; exit 1; }
|
||||
[ "$promoted_loader_sha" = "$sha_loader" ] || { echo "loader sha mismatch after promotion" >&2; exit 1; }
|
||||
[ "$promoted_param_sha" = "$sha_param" ] || { echo "param.h sha mismatch after promotion" >&2; exit 1; }
|
||||
|
||||
grep -F '(executor-kind . ssh-guest)' "$result_metadata_file" >/dev/null || {
|
||||
echo "result metadata file is missing ssh-guest executor kind" >&2
|
||||
exit 1
|
||||
}
|
||||
grep -F '(executor-name . "ssh-guest")' "$result_metadata_file" >/dev/null || {
|
||||
echo "result metadata file is missing ssh-guest executor name" >&2
|
||||
exit 1
|
||||
}
|
||||
grep -F "$source_store" "$result_metadata_file" >/dev/null || {
|
||||
echo "result metadata file is missing source store provenance" >&2
|
||||
exit 1
|
||||
}
|
||||
grep -F '(artifact-kind . kernel)' "$kernel_store/.fruix-native-build-object.scm" >/dev/null || {
|
||||
echo "kernel store metadata is missing artifact kind" >&2
|
||||
exit 1
|
||||
}
|
||||
grep -F '(artifact-kind . world)' "$world_store/.fruix-native-build-object.scm" >/dev/null || {
|
||||
echo "world store metadata is missing artifact kind" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
cat >"$metadata_file" <<EOF
|
||||
workdir=$workdir
|
||||
inner_metadata=$inner_metadata
|
||||
promotion_out=$promotion_out
|
||||
closure_path=$closure_path
|
||||
closure_base=$closure_base
|
||||
vm_id=$vm_id
|
||||
vdi_id=$vdi_id
|
||||
guest_ip=$guest_ip
|
||||
root_size=$root_size
|
||||
run_id=$run_id
|
||||
source_store=$source_store
|
||||
guest_result_root=$result_root
|
||||
guest_promotion_file=$promotion_file
|
||||
guest_world_artifact=$world_artifact
|
||||
guest_kernel_artifact=$kernel_artifact
|
||||
guest_headers_artifact=$headers_artifact
|
||||
guest_bootloader_artifact=$bootloader_artifact
|
||||
local_result_root=$local_result_root
|
||||
store_dir=$store_dir
|
||||
executor_kind=$executor_kind
|
||||
executor_name=$executor_name
|
||||
executor_version=$executor_version
|
||||
result_store=$result_store
|
||||
result_metadata_file=$result_metadata_file
|
||||
artifact_store_count=$artifact_store_count
|
||||
artifact_stores=$artifact_stores
|
||||
world_store=$world_store
|
||||
kernel_store=$kernel_store
|
||||
headers_store=$headers_store
|
||||
bootloader_store=$bootloader_store
|
||||
sha_kernel=$sha_kernel
|
||||
sha_loader=$sha_loader
|
||||
sha_param=$sha_param
|
||||
promoted_kernel_sha=$promoted_kernel_sha
|
||||
promoted_loader_sha=$promoted_loader_sha
|
||||
promoted_param_sha=$promoted_param_sha
|
||||
boot_backend=xcp-ng-xo-cli
|
||||
init_mode=shepherd-pid1
|
||||
host_initiated_native_build_store_promotion=ok
|
||||
EOF
|
||||
|
||||
if [ -n "$metadata_target" ]; then
|
||||
mkdir -p "$(dirname "$metadata_target")"
|
||||
cp "$metadata_file" "$metadata_target"
|
||||
fi
|
||||
|
||||
printf 'PASS phase20-host-initiated-native-build-store-promotion-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"
|
||||
@@ -70,49 +70,75 @@ case "$guest_build_jobs" in
|
||||
;;
|
||||
esac
|
||||
|
||||
native_build_metadata=$(ssh_guest env BUILD_JOBS="$guest_build_jobs" sh -s <<'EOF'
|
||||
native_build_metadata=$(ssh_guest env BUILD_JOBS="$guest_build_jobs" GUEST_IP="$guest_ip" VM_ID="$vm_id" VDI_ID="$vdi_id" sh -s <<'EOF'
|
||||
set -eu
|
||||
[ -L /run/current-development ]
|
||||
[ -L /usr/include ]
|
||||
[ "$(readlink /usr/include)" = "/run/current-system/development-profile/usr/include" ]
|
||||
[ -L /usr/share/mk ]
|
||||
[ "$(readlink /usr/share/mk)" = "/run/current-system/development-profile/usr/share/mk" ]
|
||||
guest_host_name=$(hostname)
|
||||
closure=$(readlink /run/current-system)
|
||||
source_store=$(sed -n 's/.*"\(\/frx\/store\/[^\"]*-freebsd-source-[^\"]*\)".*/\1/p' "$closure/metadata/store-layout.scm" | head -n 1)
|
||||
source_store=$(sed -n 's/.*"\(\/frx\/store\/[^"]*-freebsd-source-[^"]*\)".*/\1/p' "$closure/metadata/store-layout.scm" | head -n 1)
|
||||
source_root="$source_store/tree"
|
||||
build_common='TARGET=amd64 TARGET_ARCH=amd64 KERNCONF=GENERIC __MAKE_CONF=/dev/null SRCCONF=/dev/null SRC_ENV_CONF=/dev/null MK_DEBUG_FILES=no MK_TESTS=no'
|
||||
install_common="$build_common DB_FROM_SRC=yes"
|
||||
build_root=/var/tmp/fruix-phase20-native-build
|
||||
run_id=${FRUIX_HOST_INITIATED_NATIVE_BUILD_ID:-$(date -u +%Y%m%dT%H%M%SZ)}
|
||||
result_root_base=/var/lib/fruix/native-builds
|
||||
result_root=$result_root_base/$run_id
|
||||
logdir=$build_root/logs
|
||||
status_file=$result_root/status
|
||||
guest_metadata_file=$result_root/metadata.txt
|
||||
promotion_file=$result_root/promotion.scm
|
||||
world_stage=$build_root/stage-world
|
||||
kernel_stage=$build_root/stage-kernel
|
||||
headers_stage=$build_root/artifact-headers
|
||||
bootloader_stage=$build_root/artifact-bootloader
|
||||
rm -rf "$build_root"
|
||||
mkdir -p "$logdir"
|
||||
world_artifact=$result_root/artifacts/world
|
||||
kernel_artifact=$result_root/artifacts/kernel
|
||||
headers_artifact=$result_root/artifacts/headers
|
||||
bootloader_artifact=$result_root/artifacts/bootloader
|
||||
latest_link=$result_root_base/latest
|
||||
rm -rf "$build_root" "$result_root"
|
||||
mkdir -p "$logdir" "$result_root" "$world_artifact" "$kernel_artifact/boot" "$headers_artifact/usr" "$bootloader_artifact/boot"
|
||||
printf 'running\n' > "$status_file"
|
||||
fail_mark() {
|
||||
rc=$?
|
||||
if [ "$rc" -ne 0 ]; then
|
||||
printf 'failed\n' > "$status_file"
|
||||
fi
|
||||
}
|
||||
trap fail_mark EXIT HUP INT TERM
|
||||
export MAKEOBJDIRPREFIX="$build_root/obj"
|
||||
common='TARGET=amd64 TARGET_ARCH=amd64 KERNCONF=GENERIC __MAKE_CONF=/dev/null SRCCONF=/dev/null SRC_ENV_CONF=/dev/null MK_DEBUG_FILES=no MK_TESTS=no DB_FROM_SRC=yes'
|
||||
make -j"$BUILD_JOBS" -C "$source_root" TARGET=amd64 TARGET_ARCH=amd64 KERNCONF=GENERIC __MAKE_CONF=/dev/null SRCCONF=/dev/null SRC_ENV_CONF=/dev/null MK_DEBUG_FILES=no MK_TESTS=no buildworld > "$logdir/buildworld.log" 2>&1
|
||||
make -j"$BUILD_JOBS" -C "$source_root" TARGET=amd64 TARGET_ARCH=amd64 KERNCONF=GENERIC __MAKE_CONF=/dev/null SRCCONF=/dev/null SRC_ENV_CONF=/dev/null MK_DEBUG_FILES=no MK_TESTS=no buildkernel > "$logdir/buildkernel.log" 2>&1
|
||||
make -C "$source_root" $common DESTDIR="$world_stage" installworld > "$logdir/installworld.log" 2>&1
|
||||
make -C "$source_root" $common DESTDIR="$world_stage" distribution > "$logdir/distribution.log" 2>&1
|
||||
make -C "$source_root" $common DESTDIR="$kernel_stage" installkernel > "$logdir/installkernel.log" 2>&1
|
||||
make -C "$source_root" $install_common DESTDIR="$world_stage" installworld > "$logdir/installworld.log" 2>&1
|
||||
make -C "$source_root" $install_common DESTDIR="$world_stage" distribution > "$logdir/distribution.log" 2>&1
|
||||
make -C "$source_root" $install_common DESTDIR="$kernel_stage" installkernel > "$logdir/installkernel.log" 2>&1
|
||||
mkdir -p "$headers_stage/usr" "$bootloader_stage/boot"
|
||||
cp -a "$world_stage/." "$world_artifact/"
|
||||
cp -a "$kernel_stage/boot/kernel" "$kernel_artifact/boot/kernel"
|
||||
cp -a "$world_stage/usr/include" "$headers_stage/usr/include"
|
||||
mkdir -p "$headers_stage/usr/share"
|
||||
cp -a "$world_stage/usr/share/mk" "$headers_stage/usr/share/mk"
|
||||
cp -a "$headers_stage/usr/." "$headers_artifact/usr/"
|
||||
cp -a "$world_stage/boot/loader" "$bootloader_stage/boot/loader"
|
||||
cp -a "$world_stage/boot/loader.efi" "$bootloader_stage/boot/loader.efi"
|
||||
cp -a "$world_stage/boot/device.hints" "$bootloader_stage/boot/device.hints"
|
||||
cp -a "$world_stage/boot/defaults" "$bootloader_stage/boot/defaults"
|
||||
cp -a "$world_stage/boot/lua" "$bootloader_stage/boot/lua"
|
||||
[ -f "$kernel_stage/boot/kernel/kernel" ]
|
||||
[ -f "$headers_stage/usr/include/sys/param.h" ]
|
||||
[ -f "$headers_stage/usr/share/mk/bsd.prog.mk" ]
|
||||
[ -f "$bootloader_stage/boot/loader.efi" ]
|
||||
[ -f "$bootloader_stage/boot/defaults/loader.conf" ]
|
||||
[ -f "$bootloader_stage/boot/lua/loader.lua" ]
|
||||
sha_kernel=$(sha256 -q "$kernel_stage/boot/kernel/kernel")
|
||||
sha_loader=$(sha256 -q "$bootloader_stage/boot/loader.efi")
|
||||
sha_param=$(sha256 -q "$headers_stage/usr/include/sys/param.h")
|
||||
cp -a "$bootloader_stage/boot/." "$bootloader_artifact/boot/"
|
||||
[ -f "$world_artifact/bin/sh" ]
|
||||
[ -f "$kernel_artifact/boot/kernel/kernel" ]
|
||||
[ -f "$headers_artifact/usr/include/sys/param.h" ]
|
||||
[ -f "$headers_artifact/usr/share/mk/bsd.prog.mk" ]
|
||||
[ -f "$bootloader_artifact/boot/loader.efi" ]
|
||||
[ -f "$bootloader_artifact/boot/defaults/loader.conf" ]
|
||||
[ -f "$bootloader_artifact/boot/lua/loader.lua" ]
|
||||
sha_kernel=$(sha256 -q "$kernel_artifact/boot/kernel/kernel")
|
||||
sha_loader=$(sha256 -q "$bootloader_artifact/boot/loader.efi")
|
||||
sha_param=$(sha256 -q "$headers_artifact/usr/include/sys/param.h")
|
||||
buildworld_tail=$(tail -n 20 "$logdir/buildworld.log" | tr '\n' ' ')
|
||||
buildkernel_tail=$(tail -n 20 "$logdir/buildkernel.log" | tr '\n' ' ')
|
||||
installworld_tail=$(tail -n 20 "$logdir/installworld.log" | tr '\n' ' ')
|
||||
@@ -120,46 +146,131 @@ distribution_tail=$(tail -n 20 "$logdir/distribution.log" | tr '\n' ' ')
|
||||
installkernel_tail=$(tail -n 20 "$logdir/installkernel.log" | tr '\n' ' ')
|
||||
root_df=$(df -h / | tail -n 1 | tr -s ' ' | tr '\t' ' ')
|
||||
build_root_size=$(du -sh "$build_root" | awk '{print $1}')
|
||||
result_root_size=$(du -sh "$result_root" | awk '{print $1}')
|
||||
world_stage_size=$(du -sh "$world_stage" | awk '{print $1}')
|
||||
kernel_stage_size=$(du -sh "$kernel_stage" | awk '{print $1}')
|
||||
headers_stage_size=$(du -sh "$headers_stage" | awk '{print $1}')
|
||||
bootloader_stage_size=$(du -sh "$bootloader_stage" | awk '{print $1}')
|
||||
printf 'build_jobs=%s\n' "$BUILD_JOBS"
|
||||
printf 'source_store=%s\n' "$source_store"
|
||||
printf 'source_root=%s\n' "$source_root"
|
||||
printf 'build_root=%s\n' "$build_root"
|
||||
printf 'logdir=%s\n' "$logdir"
|
||||
printf 'buildworld_log=%s\n' "$logdir/buildworld.log"
|
||||
printf 'buildkernel_log=%s\n' "$logdir/buildkernel.log"
|
||||
printf 'installworld_log=%s\n' "$logdir/installworld.log"
|
||||
printf 'distribution_log=%s\n' "$logdir/distribution.log"
|
||||
printf 'installkernel_log=%s\n' "$logdir/installkernel.log"
|
||||
printf 'world_stage=%s\n' "$world_stage"
|
||||
printf 'kernel_stage=%s\n' "$kernel_stage"
|
||||
printf 'headers_stage=%s\n' "$headers_stage"
|
||||
printf 'bootloader_stage=%s\n' "$bootloader_stage"
|
||||
printf 'root_df=%s\n' "$root_df"
|
||||
printf 'build_root_size=%s\n' "$build_root_size"
|
||||
printf 'world_stage_size=%s\n' "$world_stage_size"
|
||||
printf 'kernel_stage_size=%s\n' "$kernel_stage_size"
|
||||
printf 'headers_stage_size=%s\n' "$headers_stage_size"
|
||||
printf 'bootloader_stage_size=%s\n' "$bootloader_stage_size"
|
||||
printf 'sha_kernel=%s\n' "$sha_kernel"
|
||||
printf 'sha_loader=%s\n' "$sha_loader"
|
||||
printf 'sha_param=%s\n' "$sha_param"
|
||||
printf 'buildworld_tail=%s\n' "$buildworld_tail"
|
||||
printf 'buildkernel_tail=%s\n' "$buildkernel_tail"
|
||||
printf 'installworld_tail=%s\n' "$installworld_tail"
|
||||
printf 'distribution_tail=%s\n' "$distribution_tail"
|
||||
printf 'installkernel_tail=%s\n' "$installkernel_tail"
|
||||
world_artifact_size=$(du -sh "$world_artifact" | awk '{print $1}')
|
||||
kernel_artifact_size=$(du -sh "$kernel_artifact" | awk '{print $1}')
|
||||
headers_artifact_size=$(du -sh "$headers_artifact" | awk '{print $1}')
|
||||
bootloader_artifact_size=$(du -sh "$bootloader_artifact" | awk '{print $1}')
|
||||
rm -f "$latest_link"
|
||||
ln -s "$result_root" "$latest_link"
|
||||
cat >"$promotion_file" <<EOF2
|
||||
((native-build-result-version . "1")
|
||||
(executor . ((kind . ssh-guest)
|
||||
(name . "ssh-guest")
|
||||
(version . "1")
|
||||
(properties . ((transport . "ssh")
|
||||
(orchestrator . "host")
|
||||
(guest-host-name . "$guest_host_name")
|
||||
(guest-ip . "$GUEST_IP")
|
||||
(vm-id . "$VM_ID")
|
||||
(vdi-id . "$VDI_ID")))))
|
||||
(run-id . "$run_id")
|
||||
(guest-host-name . "$guest_host_name")
|
||||
(closure-path . "$closure")
|
||||
(development-profile . "/run/current-system/development-profile")
|
||||
(freebsd-base . ((name . "default")
|
||||
(version-label . "15.0-STABLE")
|
||||
(release . "15.0-STABLE")
|
||||
(branch . "stable/15")
|
||||
(source-root . "/usr/src")
|
||||
(target . "amd64")
|
||||
(target-arch . "amd64")
|
||||
(kernconf . "GENERIC")))
|
||||
(source . ((store-path . "$source_store")
|
||||
(source-root . "$source_root")))
|
||||
(build-policy . ((jobs . "$BUILD_JOBS")
|
||||
(build-common . "$build_common")
|
||||
(install-common . "$install_common")))
|
||||
(artifacts . ((world . ((path . "artifacts/world")
|
||||
(required-file . "bin/sh")))
|
||||
(kernel . ((path . "artifacts/kernel")
|
||||
(required-file . "boot/kernel/kernel")
|
||||
(recorded-sha256 . "$sha_kernel")))
|
||||
(headers . ((path . "artifacts/headers")
|
||||
(required-file . "usr/include/sys/param.h")
|
||||
(recorded-sha256 . "$sha_param")))
|
||||
(bootloader . ((path . "artifacts/bootloader")
|
||||
(required-file . "boot/loader.efi")
|
||||
(recorded-sha256 . "$sha_loader"))))))
|
||||
EOF2
|
||||
cat >"$guest_metadata_file" <<EOF2
|
||||
run_id=$run_id
|
||||
executor_kind=ssh-guest
|
||||
executor_name=ssh-guest
|
||||
executor_version=1
|
||||
guest_host_name=$guest_host_name
|
||||
closure_path=$closure
|
||||
source_store=$source_store
|
||||
source_root=$source_root
|
||||
build_jobs=$BUILD_JOBS
|
||||
build_common=$build_common
|
||||
install_common=$install_common
|
||||
build_root=$build_root
|
||||
result_root=$result_root
|
||||
logdir=$logdir
|
||||
status_file=$status_file
|
||||
metadata_file=$guest_metadata_file
|
||||
promotion_file=$promotion_file
|
||||
world_stage=$world_stage
|
||||
kernel_stage=$kernel_stage
|
||||
headers_stage=$headers_stage
|
||||
bootloader_stage=$bootloader_stage
|
||||
world_artifact=$world_artifact
|
||||
kernel_artifact=$kernel_artifact
|
||||
headers_artifact=$headers_artifact
|
||||
bootloader_artifact=$bootloader_artifact
|
||||
latest_link=$latest_link
|
||||
root_df=$root_df
|
||||
build_root_size=$build_root_size
|
||||
result_root_size=$result_root_size
|
||||
world_stage_size=$world_stage_size
|
||||
kernel_stage_size=$kernel_stage_size
|
||||
headers_stage_size=$headers_stage_size
|
||||
bootloader_stage_size=$bootloader_stage_size
|
||||
world_artifact_size=$world_artifact_size
|
||||
kernel_artifact_size=$kernel_artifact_size
|
||||
headers_artifact_size=$headers_artifact_size
|
||||
bootloader_artifact_size=$bootloader_artifact_size
|
||||
buildworld_log=$logdir/buildworld.log
|
||||
buildkernel_log=$logdir/buildkernel.log
|
||||
installworld_log=$logdir/installworld.log
|
||||
distribution_log=$logdir/distribution.log
|
||||
installkernel_log=$logdir/installkernel.log
|
||||
sha_kernel=$sha_kernel
|
||||
sha_loader=$sha_loader
|
||||
sha_param=$sha_param
|
||||
buildworld_tail=$buildworld_tail
|
||||
buildkernel_tail=$buildkernel_tail
|
||||
installworld_tail=$installworld_tail
|
||||
distribution_tail=$distribution_tail
|
||||
installkernel_tail=$installkernel_tail
|
||||
host_initiated_native_build=ok
|
||||
EOF2
|
||||
printf 'ok\n' > "$status_file"
|
||||
cat "$guest_metadata_file"
|
||||
EOF
|
||||
)
|
||||
|
||||
build_jobs=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^build_jobs=//p')
|
||||
run_id=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^run_id=//p')
|
||||
executor_kind=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^executor_kind=//p')
|
||||
executor_name=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^executor_name=//p')
|
||||
executor_version=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^executor_version=//p')
|
||||
guest_host_name=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^guest_host_name=//p')
|
||||
source_store=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^source_store=//p')
|
||||
source_root=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^source_root=//p')
|
||||
build_jobs=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^build_jobs=//p')
|
||||
build_common=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^build_common=//p')
|
||||
install_common=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^install_common=//p')
|
||||
build_root=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^build_root=//p')
|
||||
result_root=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^result_root=//p')
|
||||
logdir=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^logdir=//p')
|
||||
status_file=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^status_file=//p')
|
||||
guest_metadata_file=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^metadata_file=//p')
|
||||
promotion_file=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^promotion_file=//p')
|
||||
buildworld_log=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^buildworld_log=//p')
|
||||
buildkernel_log=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^buildkernel_log=//p')
|
||||
installworld_log=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^installworld_log=//p')
|
||||
@@ -169,12 +280,22 @@ world_stage=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^world_stage=//
|
||||
kernel_stage=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^kernel_stage=//p')
|
||||
headers_stage=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^headers_stage=//p')
|
||||
bootloader_stage=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^bootloader_stage=//p')
|
||||
world_artifact=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^world_artifact=//p')
|
||||
kernel_artifact=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^kernel_artifact=//p')
|
||||
headers_artifact=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^headers_artifact=//p')
|
||||
bootloader_artifact=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^bootloader_artifact=//p')
|
||||
latest_link=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^latest_link=//p')
|
||||
root_df=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^root_df=//p')
|
||||
build_root_size=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^build_root_size=//p')
|
||||
result_root_size=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^result_root_size=//p')
|
||||
world_stage_size=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^world_stage_size=//p')
|
||||
kernel_stage_size=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^kernel_stage_size=//p')
|
||||
headers_stage_size=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^headers_stage_size=//p')
|
||||
bootloader_stage_size=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^bootloader_stage_size=//p')
|
||||
world_artifact_size=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^world_artifact_size=//p')
|
||||
kernel_artifact_size=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^kernel_artifact_size=//p')
|
||||
headers_artifact_size=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^headers_artifact_size=//p')
|
||||
bootloader_artifact_size=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^bootloader_artifact_size=//p')
|
||||
sha_kernel=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^sha_kernel=//p')
|
||||
sha_loader=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^sha_loader=//p')
|
||||
sha_param=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^sha_param=//p')
|
||||
@@ -184,6 +305,17 @@ installworld_tail=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^installw
|
||||
distribution_tail=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^distribution_tail=//p')
|
||||
installkernel_tail=$(printf '%s\n' "$native_build_metadata" | sed -n 's/^installkernel_tail=//p')
|
||||
|
||||
status_value=$(ssh_guest "cat '$status_file'")
|
||||
latest_target=$(ssh_guest "readlink '$latest_link'")
|
||||
ssh_guest "[ -f '$promotion_file' ]"
|
||||
ssh_guest "[ -f '$world_artifact/bin/sh' ]"
|
||||
|
||||
[ "$executor_kind" = ssh-guest ] || { echo "unexpected executor kind: $executor_kind" >&2; exit 1; }
|
||||
[ "$executor_name" = ssh-guest ] || { echo "unexpected executor name: $executor_name" >&2; exit 1; }
|
||||
[ "$executor_version" = 1 ] || { echo "unexpected executor version: $executor_version" >&2; exit 1; }
|
||||
[ "$status_value" = ok ] || { echo "host-initiated build status is not ok: $status_value" >&2; exit 1; }
|
||||
[ "$latest_target" = "$result_root" ] || { echo "latest link target mismatch: $latest_target" >&2; exit 1; }
|
||||
|
||||
case "$source_store" in
|
||||
/frx/store/*-freebsd-source-*) : ;;
|
||||
*) echo "unexpected source store path: $source_store" >&2; exit 1 ;;
|
||||
@@ -196,6 +328,10 @@ case "$build_root" in
|
||||
/var/tmp/fruix-phase20-native-build) : ;;
|
||||
*) echo "unexpected build root: $build_root" >&2; exit 1 ;;
|
||||
esac
|
||||
case "$result_root" in
|
||||
/var/lib/fruix/native-builds/*) : ;;
|
||||
*) echo "unexpected result root: $result_root" >&2; exit 1 ;;
|
||||
esac
|
||||
printf '%s\n' "$sha_kernel" | grep -E '^[0-9a-f]{64}$' >/dev/null || {
|
||||
echo "invalid kernel sha256: $sha_kernel" >&2
|
||||
exit 1
|
||||
@@ -227,11 +363,22 @@ vm_id=$vm_id
|
||||
vdi_id=$vdi_id
|
||||
guest_ip=$guest_ip
|
||||
root_size=$root_size
|
||||
run_id=$run_id
|
||||
executor_kind=$executor_kind
|
||||
executor_name=$executor_name
|
||||
executor_version=$executor_version
|
||||
guest_host_name=$guest_host_name
|
||||
build_jobs=$build_jobs
|
||||
source_store=$source_store
|
||||
source_root=$source_root
|
||||
build_common=$build_common
|
||||
install_common=$install_common
|
||||
build_root=$build_root
|
||||
result_root=$result_root
|
||||
logdir=$logdir
|
||||
status_file=$status_file
|
||||
guest_metadata_file=$guest_metadata_file
|
||||
promotion_file=$promotion_file
|
||||
buildworld_log=$buildworld_log
|
||||
buildkernel_log=$buildkernel_log
|
||||
installworld_log=$installworld_log
|
||||
@@ -241,12 +388,24 @@ world_stage=$world_stage
|
||||
kernel_stage=$kernel_stage
|
||||
headers_stage=$headers_stage
|
||||
bootloader_stage=$bootloader_stage
|
||||
world_artifact=$world_artifact
|
||||
kernel_artifact=$kernel_artifact
|
||||
headers_artifact=$headers_artifact
|
||||
bootloader_artifact=$bootloader_artifact
|
||||
latest_link=$latest_link
|
||||
latest_target=$latest_target
|
||||
status_value=$status_value
|
||||
root_df=$root_df
|
||||
build_root_size=$build_root_size
|
||||
result_root_size=$result_root_size
|
||||
world_stage_size=$world_stage_size
|
||||
kernel_stage_size=$kernel_stage_size
|
||||
headers_stage_size=$headers_stage_size
|
||||
bootloader_stage_size=$bootloader_stage_size
|
||||
world_artifact_size=$world_artifact_size
|
||||
kernel_artifact_size=$kernel_artifact_size
|
||||
headers_artifact_size=$headers_artifact_size
|
||||
bootloader_artifact_size=$bootloader_artifact_size
|
||||
sha_kernel=$sha_kernel
|
||||
sha_loader=$sha_loader
|
||||
sha_param=$sha_param
|
||||
|
||||
@@ -104,6 +104,9 @@ field() {
|
||||
sed -n "s/^$1=//p" "$promotion_out" | tail -n 1
|
||||
}
|
||||
|
||||
executor_kind=$(field executor_kind)
|
||||
executor_name=$(field executor_name)
|
||||
executor_version=$(field executor_version)
|
||||
result_store=$(field result_store)
|
||||
result_metadata_file=$(field result_metadata_file)
|
||||
artifact_store_count=$(field artifact_store_count)
|
||||
@@ -113,6 +116,9 @@ kernel_store=$(field kernel_store)
|
||||
headers_store=$(field headers_store)
|
||||
bootloader_store=$(field bootloader_store)
|
||||
|
||||
[ "$executor_kind" = self-hosted ] || { echo "unexpected executor kind: $executor_kind" >&2; exit 1; }
|
||||
[ "$executor_name" = guest-self-hosted ] || { echo "unexpected executor name: $executor_name" >&2; exit 1; }
|
||||
[ "$executor_version" = 4 ] || { echo "unexpected executor version: $executor_version" >&2; exit 1; }
|
||||
[ "$artifact_store_count" = 4 ] || { echo "unexpected artifact store count: $artifact_store_count" >&2; exit 1; }
|
||||
case "$result_store" in
|
||||
/frx/store/*-fruix-native-build-result-*-guest-self-hosted) : ;;
|
||||
@@ -160,8 +166,12 @@ promoted_param_sha=$(sha256 -q "$headers_store/usr/include/sys/param.h")
|
||||
[ "$promoted_loader_sha" = "$sha_loader" ] || { echo "loader sha mismatch after promotion" >&2; exit 1; }
|
||||
[ "$promoted_param_sha" = "$sha_param" ] || { echo "param.h sha mismatch after promotion" >&2; exit 1; }
|
||||
|
||||
grep -F '(executor . "guest-self-hosted")' "$result_metadata_file" >/dev/null || {
|
||||
echo "result metadata file is missing guest-self-hosted executor" >&2
|
||||
grep -F '(executor-kind . self-hosted)' "$result_metadata_file" >/dev/null || {
|
||||
echo "result metadata file is missing self-hosted executor kind" >&2
|
||||
exit 1
|
||||
}
|
||||
grep -F '(executor-name . "guest-self-hosted")' "$result_metadata_file" >/dev/null || {
|
||||
echo "result metadata file is missing guest-self-hosted executor name" >&2
|
||||
exit 1
|
||||
}
|
||||
grep -F "$source_store" "$result_metadata_file" >/dev/null || {
|
||||
@@ -197,6 +207,9 @@ guest_headers_artifact=$headers_artifact
|
||||
guest_bootloader_artifact=$bootloader_artifact
|
||||
local_result_root=$local_result_root
|
||||
store_dir=$store_dir
|
||||
executor_kind=$executor_kind
|
||||
executor_name=$executor_name
|
||||
executor_version=$executor_version
|
||||
result_store=$result_store
|
||||
result_metadata_file=$result_metadata_file
|
||||
artifact_store_count=$artifact_store_count
|
||||
|
||||
@@ -78,6 +78,9 @@ self_hosted_metadata=$(ssh_guest env FRUIX_SELF_HOSTED_NATIVE_BUILD_JOBS="$guest
|
||||
|
||||
run_id=$(printf '%s\n' "$self_hosted_metadata" | sed -n 's/^run_id=//p')
|
||||
helper_version=$(printf '%s\n' "$self_hosted_metadata" | sed -n 's/^helper_version=//p')
|
||||
executor_kind=$(printf '%s\n' "$self_hosted_metadata" | sed -n 's/^executor_kind=//p')
|
||||
executor_name=$(printf '%s\n' "$self_hosted_metadata" | sed -n 's/^executor_name=//p')
|
||||
executor_version=$(printf '%s\n' "$self_hosted_metadata" | sed -n 's/^executor_version=//p')
|
||||
source_store=$(printf '%s\n' "$self_hosted_metadata" | sed -n 's/^source_store=//p')
|
||||
source_root=$(printf '%s\n' "$self_hosted_metadata" | sed -n 's/^source_root=//p')
|
||||
build_jobs=$(printf '%s\n' "$self_hosted_metadata" | sed -n 's/^build_jobs=//p')
|
||||
@@ -118,7 +121,10 @@ latest_target=$(ssh_guest "readlink '$latest_link'")
|
||||
ssh_guest "[ -f '$promotion_file' ]"
|
||||
ssh_guest "[ -f '$world_artifact/bin/sh' ]"
|
||||
|
||||
[ "$helper_version" = 3 ] || { echo "unexpected helper version: $helper_version" >&2; exit 1; }
|
||||
[ "$helper_version" = 4 ] || { echo "unexpected helper version: $helper_version" >&2; exit 1; }
|
||||
[ "$executor_kind" = self-hosted ] || { echo "unexpected executor kind: $executor_kind" >&2; exit 1; }
|
||||
[ "$executor_name" = guest-self-hosted ] || { echo "unexpected executor name: $executor_name" >&2; exit 1; }
|
||||
[ "$executor_version" = 4 ] || { echo "unexpected executor version: $executor_version" >&2; exit 1; }
|
||||
[ "$build_jobs" = "$guest_build_jobs" ] || { echo "unexpected build job count: $build_jobs" >&2; exit 1; }
|
||||
[ "$status_value" = ok ] || { echo "self-hosted build status is not ok: $status_value" >&2; exit 1; }
|
||||
[ "$latest_target" = "$result_root" ] || { echo "latest link target mismatch: $latest_target" >&2; exit 1; }
|
||||
@@ -197,6 +203,9 @@ guest_ip=$guest_ip
|
||||
root_size=$root_size
|
||||
run_id=$run_id
|
||||
helper_version=$helper_version
|
||||
executor_kind=$executor_kind
|
||||
executor_name=$executor_name
|
||||
executor_version=$executor_version
|
||||
build_jobs=$build_jobs
|
||||
source_store=$source_store
|
||||
source_root=$source_root
|
||||
|
||||
Reference in New Issue
Block a user