native-build: introduce executor model

This commit is contained in:
2026-04-06 05:26:34 +02:00
parent 006ffee615
commit f41a916f45
14 changed files with 961 additions and 106 deletions

View File

@@ -294,6 +294,22 @@ Compared with Guix, this is a more explicit split between:
- a mutable result/staging area for native build execution - a mutable result/staging area for native build execution
- and the immutable store identities that Fruix treats as the real promoted result - 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 ## 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. Fruix is not trying to improve on Guix's core semantics. Guix already got those right.

View File

@@ -53,6 +53,13 @@ Fruix currently has:
- `/frx/store/...-fruix-native-headers-...` - `/frx/store/...-fruix-native-headers-...`
- `/frx/store/...-fruix-native-bootloader-...` - `/frx/store/...-fruix-native-bootloader-...`
- `/frx/store/...-fruix-native-build-result-...` - `/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: Validated boot modes still are:
@@ -65,37 +72,30 @@ The validated Phase 18 installation work currently uses:
## Latest completed achievement ## 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: Highlights:
- guest self-hosted runs still record staged results under: - native base-build placement is now modeled as executor policy rather than as separate unrelated paths
- `/var/lib/fruix/native-builds/<run-id>` - current executor kinds are:
- `/var/lib/fruix/native-builds/latest` - `host`
- those result roots now carry promotion metadata describing: - `ssh-guest`
- executor / executor-version - `self-hosted`
- closure path - guest result roots now carry explicit executor metadata instead of only an ad hoc executor string
- source store provenance - both validated executor paths now converge on the same Fruix-native flow:
- build policy - stage mutable results under `/var/lib/fruix/native-builds/<run-id>`
- artifact entries for: - emit promotion metadata with shared provenance/build-policy/artifact shape
- `world` - promote immutable identities into `/frx/store/...`
- `kernel` - the `ssh-guest` path now also stages promotable native-build result roots rather than only temporary build directories under `/var/tmp`
- `headers` - the host can now promote both executor paths through the same command:
- `bootloader`
- the host can now run:
- `fruix native-build promote RESULT_ROOT` - `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: 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-self-hosted-native-build-xcpng`
- `PASS phase20-native-build-store-promotion-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-host-initiated-native-builds-freebsd.md`
- `docs/reports/phase20-self-hosted-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-store-promotion-freebsd.md`
- `docs/reports/phase20-native-build-executor-model-freebsd.md`
## Recent major milestones ## Recent major milestones
@@ -134,12 +135,12 @@ Reports:
The next practical follow-up is now clearer: The next practical follow-up is now clearer:
- unify host-initiated and self-hosted native-build execution behind a shared Fruix executor/result model - extend the shared executor/result model from validated `ssh-guest` and `self-hosted` paths to the `host` path as well
- 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 action
- decide how much of result import/promotion should remain host-side versus become a more integrated Fruix deployment 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?” The immediate architectural direction is no longer just “can guest self-hosting work?”
It is now: 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?

View 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.

View File

@@ -337,7 +337,7 @@ Current metadata split:
The promoted store objects record explicit Fruix-native metadata including at least: The promoted store objects record explicit Fruix-native metadata including at least:
- executor / executor-version - executor kind / name / version
- run-id / guest-host-name - run-id / guest-host-name
- closure path - closure path
- source store provenance - source store provenance
@@ -353,6 +353,42 @@ This is the current Fruix-native answer to the question:
- where should immutable native-build identity live? - where should immutable native-build identity live?
- `/frx/store/...` - `/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 ## Deployment patterns
### 1. Build-first workflow ### 1. Build-first workflow

View File

@@ -1,6 +1,7 @@
(define-module (fruix system freebsd) (define-module (fruix system freebsd)
#:use-module (fruix system freebsd model) #:use-module (fruix system freebsd model)
#:use-module (fruix system freebsd source) #:use-module (fruix system freebsd source)
#:use-module (fruix system freebsd executor)
#:use-module (fruix system freebsd build) #:use-module (fruix system freebsd build)
#:use-module (fruix system freebsd media) #:use-module (fruix system freebsd media)
#:re-export (user-group #:re-export (user-group
@@ -44,6 +45,17 @@
operating-system-root-authorized-keys operating-system-root-authorized-keys
validate-operating-system validate-operating-system
materialize-freebsd-source 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 promote-native-build-result
operating-system-closure-spec operating-system-closure-spec
operating-system-install-spec operating-system-install-spec

View File

@@ -2,6 +2,7 @@
#:use-module (fruix packages freebsd) #:use-module (fruix packages freebsd)
#:use-module (fruix system freebsd model) #:use-module (fruix system freebsd model)
#:use-module (fruix system freebsd source) #:use-module (fruix system freebsd source)
#:use-module (fruix system freebsd executor)
#:use-module (fruix system freebsd utils) #:use-module (fruix system freebsd utils)
#:use-module (guix build utils) #:use-module (guix build utils)
#:use-module (ice-9 format) #:use-module (ice-9 format)
@@ -396,6 +397,32 @@
((_ . value) value) ((_ . value) value)
(#f default))) (#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) (define (read-native-build-result result-root)
(let ((promotion-file (string-append result-root "/promotion.scm"))) (let ((promotion-file (string-append result-root "/promotion.scm")))
(unless (file-exists? promotion-file) (unless (file-exists? promotion-file)
@@ -442,21 +469,24 @@
(define (native-build-artifact-display-name result artifact-kind) (define (native-build-artifact-display-name result artifact-kind)
(let* ((base (native-build-result-ref result 'freebsd-base '())) (let* ((base (native-build-result-ref result 'freebsd-base '()))
(version-label (native-build-result-ref base 'version-label "unknown")) (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-" (string-append "fruix-native-"
(symbol->string artifact-kind) (symbol->string artifact-kind)
"-" "-"
version-label version-label
"-" "-"
executor))) executor-name)))
(define (native-build-promoted-artifact-metadata result artifact-kind content-signature) (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) `((native-build-object-version . ,native-build-result-promotion-version)
(object-kind . artifact) (object-kind . artifact)
(artifact-kind . ,artifact-kind) (artifact-kind . ,artifact-kind)
(executor . ,(native-build-result-ref result 'executor "unknown")) (executor . ,executor)
(executor-version . ,(native-build-result-ref result 'executor-version "unknown")) (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")) (run-id . ,(native-build-result-ref result 'run-id "unknown"))
(guest-host-name . ,(native-build-result-ref result 'guest-host-name "unknown")) (guest-host-name . ,(native-build-result-ref result 'guest-host-name "unknown"))
(closure-path . ,(native-build-result-ref result 'closure-path "")) (closure-path . ,(native-build-result-ref result 'closure-path ""))
@@ -494,28 +524,31 @@
(define (native-build-result-display-name result) (define (native-build-result-display-name result)
(let* ((base (native-build-result-ref result 'freebsd-base '())) (let* ((base (native-build-result-ref result 'freebsd-base '()))
(version-label (native-build-result-ref base 'version-label "unknown")) (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-build-result-" version-label "-" executor))) (string-append "fruix-native-build-result-" version-label "-" executor-name)))
(define (native-build-promoted-result-object result promoted-artifacts) (define (native-build-promoted-result-object result promoted-artifacts)
`((native-build-result-version . ,native-build-result-promotion-version) (let ((executor (native-build-result-executor result)))
(object-kind . result-bundle) `((native-build-result-version . ,native-build-result-promotion-version)
(executor . ,(native-build-result-ref result 'executor "unknown")) (object-kind . result-bundle)
(executor-version . ,(native-build-result-ref result 'executor-version "unknown")) (executor . ,executor)
(run-id . ,(native-build-result-ref result 'run-id "unknown")) (executor-kind . ,(native-build-result-executor-kind result))
(guest-host-name . ,(native-build-result-ref result 'guest-host-name "unknown")) (executor-name . ,(native-build-result-executor-name result))
(closure-path . ,(native-build-result-ref result 'closure-path "")) (executor-version . ,(native-build-result-executor-version result))
(development-profile . ,(native-build-result-ref result 'development-profile "")) (run-id . ,(native-build-result-ref result 'run-id "unknown"))
(freebsd-base . ,(native-build-result-ref result 'freebsd-base '())) (guest-host-name . ,(native-build-result-ref result 'guest-host-name "unknown"))
(source . ,(native-build-result-ref result 'source '())) (closure-path . ,(native-build-result-ref result 'closure-path ""))
(build-policy . ,(native-build-result-ref result 'build-policy '())) (development-profile . ,(native-build-result-ref result 'development-profile ""))
(artifact-count . ,(length promoted-artifacts)) (freebsd-base . ,(native-build-result-ref result 'freebsd-base '()))
(artifacts . ,(map (lambda (entry) (source . ,(native-build-result-ref result 'source '()))
`((artifact-kind . ,(assoc-ref entry 'artifact-kind)) (build-policy . ,(native-build-result-ref result 'build-policy '()))
(store-path . ,(assoc-ref entry 'store-path)) (artifact-count . ,(length promoted-artifacts))
(content-signature . ,(assoc-ref entry 'content-signature)) (artifacts . ,(map (lambda (entry)
(metadata-file . ,(assoc-ref entry 'metadata-file)))) `((artifact-kind . ,(assoc-ref entry 'artifact-kind))
promoted-artifacts)))) (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")) (define* (promote-native-build-result result-root #:key (store-dir "/frx/store"))
(let* ((result (read-native-build-result result-root)) (let* ((result (read-native-build-result result-root))
@@ -544,6 +577,9 @@
(write-file (string-append result-store "/.fruix-native-build-result.scm") (write-file (string-append result-store "/.fruix-native-build-result.scm")
payload)) payload))
`((result-root . ,result-root) `((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-store . ,result-store)
(result-metadata-file . ,(string-append result-store "/.fruix-native-build-result.scm")) (result-metadata-file . ,(string-append result-store "/.fruix-native-build-result.scm"))
(artifact-store-count . ,(length promoted-artifacts)) (artifact-store-count . ,(length promoted-artifacts))

View 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)))))

View File

@@ -334,7 +334,7 @@
(development-environment-helper-version (development-environment-helper-version
. ,(if (null? (operating-system-development-packages os)) #f "1")) . ,(if (null? (operating-system-development-packages os)) #f "1"))
(self-hosted-native-build-helper-version (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))) (user-count . ,(length (operating-system-users os)))
(users . ,(map user-account-name (operating-system-users os))) (users . ,(map user-account-name (operating-system-users os)))
(group-count . ,(length (operating-system-groups os))) (group-count . ,(length (operating-system-groups os)))

View File

@@ -928,8 +928,13 @@
"ln -s \"$result_root\" \"$latest_link\"\n" "ln -s \"$result_root\" \"$latest_link\"\n"
"cat >\"$promotion_file\" <<EOF\n" "cat >\"$promotion_file\" <<EOF\n"
"((native-build-result-version . \"1\")\n" "((native-build-result-version . \"1\")\n"
" (executor . \"guest-self-hosted\")\n" " (executor . ((kind . self-hosted)\n"
" (executor-version . \"3\")\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" " (run-id . \"$run_id\")\n"
" (guest-host-name . \"$guest_host_name\")\n" " (guest-host-name . \"$guest_host_name\")\n"
" (closure-path . \"$closure\")\n" " (closure-path . \"$closure\")\n"
@@ -961,7 +966,10 @@
"EOF\n" "EOF\n"
"cat >\"$metadata_file\" <<EOF\n" "cat >\"$metadata_file\" <<EOF\n"
"run_id=$run_id\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" "closure_path=$closure\n"
"guest_host_name=$guest_host_name\n" "guest_host_name=$guest_host_name\n"
"development_profile=$profile\n" "development_profile=$profile\n"

View File

@@ -580,6 +580,9 @@ Common options:\n\
`((action . "promote") `((action . "promote")
(result_root . ,result-root) (result_root . ,result-root)
(store_dir . ,store-dir) (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_store . ,(assoc-ref result 'result-store))
(result_metadata_file . ,(assoc-ref result 'result-metadata-file)) (result_metadata_file . ,(assoc-ref result 'result-metadata-file))
(artifact_store_count . ,(assoc-ref result 'artifact-store-count)) (artifact_store_count . ,(assoc-ref result 'artifact-store-count))

View 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"

View File

@@ -70,49 +70,75 @@ case "$guest_build_jobs" in
;; ;;
esac 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 set -eu
[ -L /run/current-development ] [ -L /run/current-development ]
[ -L /usr/include ] [ -L /usr/include ]
[ "$(readlink /usr/include)" = "/run/current-system/development-profile/usr/include" ] [ "$(readlink /usr/include)" = "/run/current-system/development-profile/usr/include" ]
[ -L /usr/share/mk ] [ -L /usr/share/mk ]
[ "$(readlink /usr/share/mk)" = "/run/current-system/development-profile/usr/share/mk" ] [ "$(readlink /usr/share/mk)" = "/run/current-system/development-profile/usr/share/mk" ]
guest_host_name=$(hostname)
closure=$(readlink /run/current-system) 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" 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 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 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 world_stage=$build_root/stage-world
kernel_stage=$build_root/stage-kernel kernel_stage=$build_root/stage-kernel
headers_stage=$build_root/artifact-headers headers_stage=$build_root/artifact-headers
bootloader_stage=$build_root/artifact-bootloader bootloader_stage=$build_root/artifact-bootloader
rm -rf "$build_root" world_artifact=$result_root/artifacts/world
mkdir -p "$logdir" 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" 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 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 -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" $install_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" $install_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="$kernel_stage" installkernel > "$logdir/installkernel.log" 2>&1
mkdir -p "$headers_stage/usr" "$bootloader_stage/boot" 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" cp -a "$world_stage/usr/include" "$headers_stage/usr/include"
mkdir -p "$headers_stage/usr/share" mkdir -p "$headers_stage/usr/share"
cp -a "$world_stage/usr/share/mk" "$headers_stage/usr/share/mk" 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" "$bootloader_stage/boot/loader"
cp -a "$world_stage/boot/loader.efi" "$bootloader_stage/boot/loader.efi" 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/device.hints" "$bootloader_stage/boot/device.hints"
cp -a "$world_stage/boot/defaults" "$bootloader_stage/boot/defaults" cp -a "$world_stage/boot/defaults" "$bootloader_stage/boot/defaults"
cp -a "$world_stage/boot/lua" "$bootloader_stage/boot/lua" cp -a "$world_stage/boot/lua" "$bootloader_stage/boot/lua"
[ -f "$kernel_stage/boot/kernel/kernel" ] cp -a "$bootloader_stage/boot/." "$bootloader_artifact/boot/"
[ -f "$headers_stage/usr/include/sys/param.h" ] [ -f "$world_artifact/bin/sh" ]
[ -f "$headers_stage/usr/share/mk/bsd.prog.mk" ] [ -f "$kernel_artifact/boot/kernel/kernel" ]
[ -f "$bootloader_stage/boot/loader.efi" ] [ -f "$headers_artifact/usr/include/sys/param.h" ]
[ -f "$bootloader_stage/boot/defaults/loader.conf" ] [ -f "$headers_artifact/usr/share/mk/bsd.prog.mk" ]
[ -f "$bootloader_stage/boot/lua/loader.lua" ] [ -f "$bootloader_artifact/boot/loader.efi" ]
sha_kernel=$(sha256 -q "$kernel_stage/boot/kernel/kernel") [ -f "$bootloader_artifact/boot/defaults/loader.conf" ]
sha_loader=$(sha256 -q "$bootloader_stage/boot/loader.efi") [ -f "$bootloader_artifact/boot/lua/loader.lua" ]
sha_param=$(sha256 -q "$headers_stage/usr/include/sys/param.h") 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' ' ') buildworld_tail=$(tail -n 20 "$logdir/buildworld.log" | tr '\n' ' ')
buildkernel_tail=$(tail -n 20 "$logdir/buildkernel.log" | tr '\n' ' ') buildkernel_tail=$(tail -n 20 "$logdir/buildkernel.log" | tr '\n' ' ')
installworld_tail=$(tail -n 20 "$logdir/installworld.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' ' ') installkernel_tail=$(tail -n 20 "$logdir/installkernel.log" | tr '\n' ' ')
root_df=$(df -h / | tail -n 1 | tr -s ' ' | tr '\t' ' ') root_df=$(df -h / | tail -n 1 | tr -s ' ' | tr '\t' ' ')
build_root_size=$(du -sh "$build_root" | awk '{print $1}') 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}') world_stage_size=$(du -sh "$world_stage" | awk '{print $1}')
kernel_stage_size=$(du -sh "$kernel_stage" | awk '{print $1}') kernel_stage_size=$(du -sh "$kernel_stage" | awk '{print $1}')
headers_stage_size=$(du -sh "$headers_stage" | awk '{print $1}') headers_stage_size=$(du -sh "$headers_stage" | awk '{print $1}')
bootloader_stage_size=$(du -sh "$bootloader_stage" | awk '{print $1}') bootloader_stage_size=$(du -sh "$bootloader_stage" | awk '{print $1}')
printf 'build_jobs=%s\n' "$BUILD_JOBS" world_artifact_size=$(du -sh "$world_artifact" | awk '{print $1}')
printf 'source_store=%s\n' "$source_store" kernel_artifact_size=$(du -sh "$kernel_artifact" | awk '{print $1}')
printf 'source_root=%s\n' "$source_root" headers_artifact_size=$(du -sh "$headers_artifact" | awk '{print $1}')
printf 'build_root=%s\n' "$build_root" bootloader_artifact_size=$(du -sh "$bootloader_artifact" | awk '{print $1}')
printf 'logdir=%s\n' "$logdir" rm -f "$latest_link"
printf 'buildworld_log=%s\n' "$logdir/buildworld.log" ln -s "$result_root" "$latest_link"
printf 'buildkernel_log=%s\n' "$logdir/buildkernel.log" cat >"$promotion_file" <<EOF2
printf 'installworld_log=%s\n' "$logdir/installworld.log" ((native-build-result-version . "1")
printf 'distribution_log=%s\n' "$logdir/distribution.log" (executor . ((kind . ssh-guest)
printf 'installkernel_log=%s\n' "$logdir/installkernel.log" (name . "ssh-guest")
printf 'world_stage=%s\n' "$world_stage" (version . "1")
printf 'kernel_stage=%s\n' "$kernel_stage" (properties . ((transport . "ssh")
printf 'headers_stage=%s\n' "$headers_stage" (orchestrator . "host")
printf 'bootloader_stage=%s\n' "$bootloader_stage" (guest-host-name . "$guest_host_name")
printf 'root_df=%s\n' "$root_df" (guest-ip . "$GUEST_IP")
printf 'build_root_size=%s\n' "$build_root_size" (vm-id . "$VM_ID")
printf 'world_stage_size=%s\n' "$world_stage_size" (vdi-id . "$VDI_ID")))))
printf 'kernel_stage_size=%s\n' "$kernel_stage_size" (run-id . "$run_id")
printf 'headers_stage_size=%s\n' "$headers_stage_size" (guest-host-name . "$guest_host_name")
printf 'bootloader_stage_size=%s\n' "$bootloader_stage_size" (closure-path . "$closure")
printf 'sha_kernel=%s\n' "$sha_kernel" (development-profile . "/run/current-system/development-profile")
printf 'sha_loader=%s\n' "$sha_loader" (freebsd-base . ((name . "default")
printf 'sha_param=%s\n' "$sha_param" (version-label . "15.0-STABLE")
printf 'buildworld_tail=%s\n' "$buildworld_tail" (release . "15.0-STABLE")
printf 'buildkernel_tail=%s\n' "$buildkernel_tail" (branch . "stable/15")
printf 'installworld_tail=%s\n' "$installworld_tail" (source-root . "/usr/src")
printf 'distribution_tail=%s\n' "$distribution_tail" (target . "amd64")
printf 'installkernel_tail=%s\n' "$installkernel_tail" (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 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_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') 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') 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') 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') 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') 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') 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') 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') 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') 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') 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') 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') 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') 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') 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') 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_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_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') 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') 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') 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 case "$source_store" in
/frx/store/*-freebsd-source-*) : ;; /frx/store/*-freebsd-source-*) : ;;
*) echo "unexpected source store path: $source_store" >&2; exit 1 ;; *) echo "unexpected source store path: $source_store" >&2; exit 1 ;;
@@ -196,6 +328,10 @@ case "$build_root" in
/var/tmp/fruix-phase20-native-build) : ;; /var/tmp/fruix-phase20-native-build) : ;;
*) echo "unexpected build root: $build_root" >&2; exit 1 ;; *) echo "unexpected build root: $build_root" >&2; exit 1 ;;
esac 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 || { printf '%s\n' "$sha_kernel" | grep -E '^[0-9a-f]{64}$' >/dev/null || {
echo "invalid kernel sha256: $sha_kernel" >&2 echo "invalid kernel sha256: $sha_kernel" >&2
exit 1 exit 1
@@ -227,11 +363,22 @@ vm_id=$vm_id
vdi_id=$vdi_id vdi_id=$vdi_id
guest_ip=$guest_ip guest_ip=$guest_ip
root_size=$root_size 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 build_jobs=$build_jobs
source_store=$source_store source_store=$source_store
source_root=$source_root source_root=$source_root
build_common=$build_common
install_common=$install_common
build_root=$build_root build_root=$build_root
result_root=$result_root
logdir=$logdir logdir=$logdir
status_file=$status_file
guest_metadata_file=$guest_metadata_file
promotion_file=$promotion_file
buildworld_log=$buildworld_log buildworld_log=$buildworld_log
buildkernel_log=$buildkernel_log buildkernel_log=$buildkernel_log
installworld_log=$installworld_log installworld_log=$installworld_log
@@ -241,12 +388,24 @@ world_stage=$world_stage
kernel_stage=$kernel_stage kernel_stage=$kernel_stage
headers_stage=$headers_stage headers_stage=$headers_stage
bootloader_stage=$bootloader_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 root_df=$root_df
build_root_size=$build_root_size build_root_size=$build_root_size
result_root_size=$result_root_size
world_stage_size=$world_stage_size world_stage_size=$world_stage_size
kernel_stage_size=$kernel_stage_size kernel_stage_size=$kernel_stage_size
headers_stage_size=$headers_stage_size headers_stage_size=$headers_stage_size
bootloader_stage_size=$bootloader_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_kernel=$sha_kernel
sha_loader=$sha_loader sha_loader=$sha_loader
sha_param=$sha_param sha_param=$sha_param

View File

@@ -104,6 +104,9 @@ field() {
sed -n "s/^$1=//p" "$promotion_out" | tail -n 1 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_store=$(field result_store)
result_metadata_file=$(field result_metadata_file) result_metadata_file=$(field result_metadata_file)
artifact_store_count=$(field artifact_store_count) artifact_store_count=$(field artifact_store_count)
@@ -113,6 +116,9 @@ kernel_store=$(field kernel_store)
headers_store=$(field headers_store) headers_store=$(field headers_store)
bootloader_store=$(field bootloader_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; } [ "$artifact_store_count" = 4 ] || { echo "unexpected artifact store count: $artifact_store_count" >&2; exit 1; }
case "$result_store" in case "$result_store" in
/frx/store/*-fruix-native-build-result-*-guest-self-hosted) : ;; /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_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; } [ "$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 || { grep -F '(executor-kind . self-hosted)' "$result_metadata_file" >/dev/null || {
echo "result metadata file is missing guest-self-hosted executor" >&2 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 exit 1
} }
grep -F "$source_store" "$result_metadata_file" >/dev/null || { grep -F "$source_store" "$result_metadata_file" >/dev/null || {
@@ -197,6 +207,9 @@ guest_headers_artifact=$headers_artifact
guest_bootloader_artifact=$bootloader_artifact guest_bootloader_artifact=$bootloader_artifact
local_result_root=$local_result_root local_result_root=$local_result_root
store_dir=$store_dir store_dir=$store_dir
executor_kind=$executor_kind
executor_name=$executor_name
executor_version=$executor_version
result_store=$result_store result_store=$result_store
result_metadata_file=$result_metadata_file result_metadata_file=$result_metadata_file
artifact_store_count=$artifact_store_count artifact_store_count=$artifact_store_count

View File

@@ -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') 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') 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_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') 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') 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 '$promotion_file' ]"
ssh_guest "[ -f '$world_artifact/bin/sh' ]" 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; } [ "$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; } [ "$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; } [ "$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 root_size=$root_size
run_id=$run_id run_id=$run_id
helper_version=$helper_version helper_version=$helper_version
executor_kind=$executor_kind
executor_name=$executor_name
executor_version=$executor_version
build_jobs=$build_jobs build_jobs=$build_jobs
source_store=$source_store source_store=$source_store
source_root=$source_root source_root=$source_root