You've already forked fruix-bootstrap
system: add in-node build and reconfigure
This commit is contained in:
@@ -171,8 +171,10 @@ So compared with Guix-on-Linux intuition, Fruix operators should be more explici
|
||||
|
||||
This remains the biggest operational gap, but it is no longer a complete gap.
|
||||
|
||||
Installed Fruix systems now provide a small in-guest helper:
|
||||
Installed Fruix systems now provide a larger in-guest helper surface:
|
||||
|
||||
- `fruix system build`
|
||||
- `fruix system reconfigure`
|
||||
- `fruix system status`
|
||||
- `fruix system switch /frx/store/...-fruix-system-...`
|
||||
- `fruix system rollback`
|
||||
@@ -183,11 +185,14 @@ What this gives you today:
|
||||
- explicit rollback-generation tracking
|
||||
- in-place switching between already-staged closures on the installed target
|
||||
- rollback without reinstalling the whole system image again
|
||||
- a validated in-node build path that can read the embedded current declaration inputs
|
||||
- a validated in-node `reconfigure` path that can build a candidate closure locally and stage it as the next generation
|
||||
|
||||
What it still does **not** give you yet compared with Guix:
|
||||
|
||||
- a mature `reconfigure`-style workflow that builds and stages the new closure from inside the target system
|
||||
- a mature end-to-end `upgrade` story for advancing declared inputs automatically
|
||||
- automatic closure transfer/fetch as part of `switch`
|
||||
- a higher-level `deploy` workflow across multiple machines or targets
|
||||
- the broader generation-management UX Guix operators expect
|
||||
|
||||
So if you come from Guix, assume that Fruix now has:
|
||||
@@ -195,7 +200,8 @@ So if you come from Guix, assume that Fruix now has:
|
||||
- strong closure/store semantics
|
||||
- explicit install artifacts
|
||||
- explicit generation metadata roots
|
||||
- a real but still modest installed-system switch/rollback UX
|
||||
- a real installed-system build/reconfigure/switch/rollback surface
|
||||
- but not yet the fuller long-term node/deployment UX that Guix users may expect
|
||||
|
||||
## 7. Fruix keeps Guix-like store semantics, but not Guix/Nix hash-prefix machinery exactly
|
||||
|
||||
|
||||
+41
-22
@@ -64,6 +64,11 @@ Fruix currently has:
|
||||
- `promoted-native-build-result`
|
||||
- `operating-system-from-promoted-native-build-result`
|
||||
- a real XCP-ng boot validation of a system materialized from a promoted native-build result identity
|
||||
- installed systems that now carry their own canonical declaration inputs and bundled Fruix node CLI sources
|
||||
- a real XCP-ng validation of in-node:
|
||||
- `fruix system build`
|
||||
- `fruix system reconfigure`
|
||||
- `fruix system rollback`
|
||||
|
||||
Validated boot modes still are:
|
||||
|
||||
@@ -76,34 +81,45 @@ The validated Phase 18 installation work currently uses:
|
||||
|
||||
## Latest completed achievement
|
||||
|
||||
### 2026-04-06 — Promoted native-base result sets are now first-class declaration inputs
|
||||
### 2026-04-06 — Installed systems can now build and reconfigure themselves from local declaration state
|
||||
|
||||
Fruix can now materialize and boot a normal system declaration directly from a promoted native-build result bundle in `/frx/store`.
|
||||
Fruix-installed systems are now meaningfully closer to real Fruix nodes.
|
||||
|
||||
Highlights:
|
||||
|
||||
- promoted native-build result bundles are no longer only post-build artifacts
|
||||
- system declarations can now refer directly to those promoted identities via:
|
||||
- `promoted-native-build-result`
|
||||
- `operating-system-from-promoted-native-build-result`
|
||||
- promoted result bundles now drive:
|
||||
- kernel selection
|
||||
- bootloader selection
|
||||
- base world selection
|
||||
- optional promoted headers selection
|
||||
- the resulting system closure now records promoted-result provenance explicitly in:
|
||||
- `metadata/promoted-native-build-result.scm`
|
||||
- `metadata/store-layout.scm`
|
||||
- closure `.references`
|
||||
- the validated real-VM boot used the promoted `ssh-guest` result bundle as the declaration input, proving that the result/promotion model is now consumable by ordinary Fruix system materialization
|
||||
- system closures now carry canonical declaration metadata in:
|
||||
- `metadata/system-declaration.scm`
|
||||
- `metadata/system-declaration-info.scm`
|
||||
- `metadata/system-declaration-system`
|
||||
- system closures now also carry bundled Fruix node CLI sources in:
|
||||
- `share/fruix/node/scripts/fruix.scm`
|
||||
- `share/fruix/node/modules/...`
|
||||
- `share/fruix/node/guix/guix/build/utils.scm`
|
||||
- the installed helper at `/usr/local/bin/fruix` now supports:
|
||||
- `fruix system build`
|
||||
- `fruix system reconfigure`
|
||||
- `fruix system status`
|
||||
- `fruix system switch`
|
||||
- `fruix system rollback`
|
||||
- no-argument in-node `build` and `reconfigure` now use the node's own embedded declaration inputs
|
||||
- in-node Fruix builds now reuse the installed Guile/Shepherd runtime stores already referenced by the system instead of assuming host-only `/tmp/...` build prefixes
|
||||
- the real XCP-ng validation proved the full installed-node flow:
|
||||
- boot current system
|
||||
- build from local declaration state
|
||||
- build a candidate declaration on-node
|
||||
- `reconfigure` into that candidate generation
|
||||
- reboot into the candidate generation
|
||||
- `rollback`
|
||||
- reboot back into the original generation
|
||||
|
||||
Validation:
|
||||
|
||||
- `PASS phase20-promoted-native-base-declaration-xcpng`
|
||||
- `PASS postphase20-installed-node-build-reconfigure-xcpng`
|
||||
|
||||
Report:
|
||||
Reports:
|
||||
|
||||
- `docs/reports/postphase20-promoted-native-base-declarations-freebsd.md`
|
||||
- `docs/reports/postphase20-installed-node-management-freebsd.md`
|
||||
- `docs/system-deployment-workflow.md`
|
||||
- `docs/GUIX_DIFFERENCES.md`
|
||||
|
||||
@@ -133,12 +149,15 @@ Report:
|
||||
|
||||
The next practical follow-up is now clearer:
|
||||
|
||||
- decide how much of result creation, validation, promotion, and declaration consumption should be wrapped into one higher-level Fruix workflow
|
||||
- determine whether native-build result selection should become a more explicit operator-facing deployment/declaration surface rather than a lower-level helper step
|
||||
- continue tightening how executor policy and promoted-result identity are presented to operators without losing the new first-class declaration-input model
|
||||
- grow the installed-node command surface from validated `build`/`reconfigure`/`rollback` toward:
|
||||
- `upgrade`
|
||||
- `build-base`
|
||||
- `deploy`
|
||||
- decide how executor policy, native-base promotion, and installed-node reconfiguration should compose in one operator-facing workflow
|
||||
- determine how much of native-build request/promotion should remain explicit versus being absorbed into higher-level Fruix node actions
|
||||
|
||||
The immediate architectural direction is no longer just “can guest self-hosting work?”
|
||||
|
||||
It is now:
|
||||
|
||||
- how should Fruix expose build executor choice, promoted native-base identities, and deployment materialization as one coherent product workflow?
|
||||
- how should Fruix expose real managed-node behavior across declaration inputs, native-base results, generation switching, and deployment actions?
|
||||
|
||||
@@ -0,0 +1,178 @@
|
||||
# Post-Phase 20: installed systems as real Fruix nodes
|
||||
|
||||
Date: 2026-04-06
|
||||
|
||||
## Goal
|
||||
|
||||
Make a Fruix-installed machine feel like a managed Fruix node instead of only a deployed image with switch/rollback helpers.
|
||||
|
||||
The immediate target was not yet the full long-term command surface of:
|
||||
|
||||
- `fruix system upgrade`
|
||||
- `fruix system build-base`
|
||||
- `fruix system deploy`
|
||||
|
||||
but it was enough to cross an important product threshold:
|
||||
|
||||
- installed nodes can now remember their own declaration inputs
|
||||
- installed nodes can build from those inputs locally
|
||||
- installed nodes can reconfigure themselves into a newly built generation
|
||||
- installed nodes can still roll back cleanly
|
||||
|
||||
## What changed
|
||||
|
||||
### Canonical declaration state now ships inside the system closure
|
||||
|
||||
Fruix system closures now carry explicit declaration metadata:
|
||||
|
||||
- `metadata/system-declaration.scm`
|
||||
- `metadata/system-declaration-info.scm`
|
||||
- `metadata/system-declaration-system`
|
||||
|
||||
That gives an installed system a canonical local answer to:
|
||||
|
||||
- what declaration source produced me?
|
||||
- what top-level system variable should be used?
|
||||
|
||||
This declaration metadata is also recorded through the installed generation layout metadata.
|
||||
|
||||
### Bundled Fruix node CLI sources now ship inside the closure
|
||||
|
||||
Installed system closures now also carry a self-contained Fruix node CLI source bundle under:
|
||||
|
||||
- `share/fruix/node/scripts/fruix.scm`
|
||||
- `share/fruix/node/modules/...`
|
||||
- `share/fruix/node/guix/guix/build/utils.scm`
|
||||
|
||||
This gives the installed node enough local Fruix/Guix Scheme source to run Fruix system actions from the node itself.
|
||||
|
||||
### Installed `fruix` helper gained local build/reconfigure support
|
||||
|
||||
The installed helper at:
|
||||
|
||||
- `/usr/local/bin/fruix`
|
||||
|
||||
now supports:
|
||||
|
||||
- `fruix system build`
|
||||
- `fruix system reconfigure`
|
||||
- `fruix system status`
|
||||
- `fruix system switch`
|
||||
- `fruix system rollback`
|
||||
|
||||
Current behavior:
|
||||
|
||||
- `fruix system build` with no extra arguments uses:
|
||||
- `/run/current-system/metadata/system-declaration.scm`
|
||||
- `/run/current-system/metadata/system-declaration-system`
|
||||
- `fruix system reconfigure` with no extra arguments builds from that same embedded declaration and then stages a switch to the resulting closure
|
||||
- both commands can also take an explicit declaration file plus `--system NAME`, using the same general CLI shape as the host-side Fruix frontend
|
||||
|
||||
### In-node builds now reuse the installed Fruix runtime stores
|
||||
|
||||
A crucial implementation fix was needed here.
|
||||
|
||||
An installed node should not try to reconstruct the Guile/Shepherd runtime prefixes from host-side `/tmp/...` build roots or host `/usr/local/lib/...` assumptions.
|
||||
|
||||
Instead, in-node Fruix builds now explicitly reuse the installed runtime stores already referenced by the current system closure.
|
||||
|
||||
That allows the in-node build path to work on the real installed system rather than depending on build-host-only paths.
|
||||
|
||||
## Validation harness
|
||||
|
||||
Added:
|
||||
|
||||
- `tests/system/postphase20-installed-node-operating-system.scm.in`
|
||||
- `tests/system/run-postphase20-installed-node-build-reconfigure-xcpng.sh`
|
||||
|
||||
This harness validates the new installed-node workflow on the approved real XCP-ng path.
|
||||
|
||||
## Validation performed
|
||||
|
||||
Approved real XCP-ng path:
|
||||
|
||||
- VM `90490f2e-e8fc-4b7a-388e-5c26f0157289`
|
||||
- VDI `0f1f90d3-48ca-4fa2-91d8-fc6339b95743`
|
||||
|
||||
Promoted native-base result consumed by the installed node declaration:
|
||||
|
||||
- `/frx/store/ffe44f5d1ba576e1f811ad3fe3a526a242b5c4a5-fruix-native-build-result-15.0-STABLE-ssh-guest`
|
||||
|
||||
Validated flow:
|
||||
|
||||
1. boot a Fruix-installed node built from the promoted native-base result
|
||||
2. confirm the installed node exposes:
|
||||
- embedded declaration metadata
|
||||
- bundled node CLI sources
|
||||
3. run in-guest:
|
||||
- `fruix system build`
|
||||
using the node's own embedded declaration inputs
|
||||
4. copy a candidate declaration to the guest
|
||||
5. run in-guest:
|
||||
- `fruix system build /root/candidate.scm --system postphase20-installed-node-operating-system`
|
||||
6. run in-guest:
|
||||
- `fruix system reconfigure /root/candidate.scm --system postphase20-installed-node-operating-system`
|
||||
7. reboot and verify the candidate generation boots
|
||||
8. run in-guest:
|
||||
- `fruix system rollback`
|
||||
9. reboot and verify the original generation boots again
|
||||
|
||||
Passing run:
|
||||
|
||||
- `PASS postphase20-installed-node-build-reconfigure-xcpng`
|
||||
|
||||
Representative metadata:
|
||||
|
||||
```text
|
||||
closure_path=/frx/store/cd4e52d8bff348953939401c8623d4189d7c9432-fruix-system-fruix-node-current
|
||||
current_built_closure=/frx/store/18ee10925a15b48c676463a3359c45ff766e16a0-fruix-system-fruix-node-current
|
||||
candidate_closure=/frx/store/46fc9631faf556c30a1a5f39f718d5d38a3f6ba8-fruix-system-fruix-node-canary
|
||||
reconfigure_closure=/frx/store/46fc9631faf556c30a1a5f39f718d5d38a3f6ba8-fruix-system-fruix-node-canary
|
||||
reconfigure_current_generation=2
|
||||
reconfigure_current_closure=/frx/store/46fc9631faf556c30a1a5f39f718d5d38a3f6ba8-fruix-system-fruix-node-canary
|
||||
reconfigure_rollback_generation=1
|
||||
reconfigure_rollback_closure=/frx/store/cd4e52d8bff348953939401c8623d4189d7c9432-fruix-system-fruix-node-current
|
||||
candidate_hostname=fruix-node-canary
|
||||
rollback_current_generation=1
|
||||
rollback_current_closure=/frx/store/cd4e52d8bff348953939401c8623d4189d7c9432-fruix-system-fruix-node-current
|
||||
rollback_rollback_generation=2
|
||||
rollback_rollback_closure=/frx/store/46fc9631faf556c30a1a5f39f718d5d38a3f6ba8-fruix-system-fruix-node-canary
|
||||
rollback_hostname=fruix-node-current
|
||||
installed_node_build_reconfigure=ok
|
||||
```
|
||||
|
||||
## Important observation
|
||||
|
||||
The no-argument in-node build of the current declaration did not necessarily reproduce the exact original current closure path.
|
||||
|
||||
That is expected with the current model because closure metadata still records builder-local provenance such as the current build host context.
|
||||
|
||||
So the significant validated fact is not strict bit-for-bit closure reuse.
|
||||
|
||||
It is that the installed node can now:
|
||||
|
||||
- read its own declaration inputs locally
|
||||
- build a valid local candidate closure from them
|
||||
- build a different candidate declaration locally
|
||||
- reconfigure itself into that candidate generation
|
||||
- boot the candidate generation
|
||||
- roll back and boot the prior generation again
|
||||
|
||||
## Result
|
||||
|
||||
Fruix-installed machines are now meaningfully closer to real Fruix nodes.
|
||||
|
||||
They no longer only support:
|
||||
|
||||
- `status`
|
||||
- `switch`
|
||||
- `rollback`
|
||||
|
||||
They now also support a validated local node workflow for:
|
||||
|
||||
- reading embedded declaration inputs
|
||||
- building a local candidate closure
|
||||
- reconfiguring into that locally built candidate
|
||||
- rolling back through the same installed generation model
|
||||
|
||||
This is the first concrete step toward a fuller operator-facing Fruix node command surface.
|
||||
@@ -178,12 +178,32 @@ Installed Fruix systems now also ship a small in-guest deployment helper at:
|
||||
Current validated in-guest commands are:
|
||||
|
||||
```sh
|
||||
fruix system build
|
||||
fruix system reconfigure
|
||||
fruix system status
|
||||
fruix system switch /frx/store/...-fruix-system-...
|
||||
fruix system rollback
|
||||
```
|
||||
|
||||
Current intended usage:
|
||||
Installed systems now carry canonical declaration state in:
|
||||
|
||||
- `/run/current-system/metadata/system-declaration.scm`
|
||||
- `/run/current-system/metadata/system-declaration-info.scm`
|
||||
- `/run/current-system/metadata/system-declaration-system`
|
||||
|
||||
So the in-guest helper can now build from the node's own embedded declaration inputs.
|
||||
|
||||
Current validated build/reconfigure behavior is:
|
||||
|
||||
- `fruix system build`
|
||||
- with no extra arguments, builds from the embedded current declaration
|
||||
- `fruix system reconfigure`
|
||||
- with no extra arguments, builds from the embedded current declaration and stages a switch to the resulting closure
|
||||
- both commands can also take an explicit declaration file plus `--system NAME`
|
||||
|
||||
Current intended usage now has two validated patterns.
|
||||
|
||||
### Pattern A: build elsewhere, then switch/rollback locally
|
||||
|
||||
1. build a candidate closure on the operator side with `./bin/fruix system build`
|
||||
2. ensure that candidate closure is present on the installed target's `/frx/store`
|
||||
@@ -192,11 +212,44 @@ Current intended usage:
|
||||
5. if needed, run `fruix system rollback`
|
||||
6. reboot back into the recorded rollback generation
|
||||
|
||||
Important current limitation:
|
||||
Important current limitation of this lower-level pattern:
|
||||
|
||||
- `fruix system switch` does **not** yet fetch or copy the candidate closure onto the target for you
|
||||
- it assumes the selected closure is already present in the installed system's `/frx/store`
|
||||
|
||||
### Pattern B: build and reconfigure from the node itself
|
||||
|
||||
1. inspect or edit the node declaration inputs
|
||||
- embedded current declaration, or
|
||||
- an explicit replacement declaration file
|
||||
2. run:
|
||||
|
||||
```sh
|
||||
fruix system build
|
||||
```
|
||||
|
||||
or:
|
||||
|
||||
```sh
|
||||
fruix system build /path/to/candidate.scm --system my-operating-system
|
||||
```
|
||||
|
||||
3. stage a local generation update with:
|
||||
|
||||
```sh
|
||||
fruix system reconfigure
|
||||
```
|
||||
|
||||
or:
|
||||
|
||||
```sh
|
||||
fruix system reconfigure /path/to/candidate.scm --system my-operating-system
|
||||
```
|
||||
|
||||
4. reboot into the staged generation
|
||||
5. if needed, run `fruix system rollback`
|
||||
6. reboot back into the recorded prior generation
|
||||
|
||||
### In-guest development environment
|
||||
|
||||
Opt-in systems can also expose a separate development overlay under:
|
||||
|
||||
@@ -72,7 +72,13 @@
|
||||
(store-dir "/frx/store")
|
||||
(guile-prefix "/tmp/guile-freebsd-validate-install")
|
||||
(guile-extra-prefix "/tmp/guile-gnutls-freebsd-validate-install")
|
||||
(shepherd-prefix "/tmp/shepherd-freebsd-validate-install"))
|
||||
(shepherd-prefix "/tmp/shepherd-freebsd-validate-install")
|
||||
(guile-store-path #f)
|
||||
(guile-extra-store-path #f)
|
||||
(shepherd-store-path #f)
|
||||
(declaration-source #f)
|
||||
(declaration-origin #f)
|
||||
(declaration-system-symbol #f))
|
||||
(validate-operating-system os)
|
||||
(let* ((cache (make-hash-table))
|
||||
(source-cache (make-hash-table))
|
||||
@@ -110,12 +116,15 @@
|
||||
("/usr/local/lib/libtasn1.so.6" . "lib/libtasn1.so.6")
|
||||
("/usr/local/lib/libhogweed.so.6" . "lib/libhogweed.so.6")
|
||||
("/usr/local/lib/libnettle.so.8" . "lib/libnettle.so.8")))
|
||||
(guile-store (materialize-prefix guile-prefix "fruix-guile-runtime" "3.0" store-dir
|
||||
#:extra-files guile-runtime-extra-files))
|
||||
(guile-extra-store (materialize-prefix guile-extra-prefix "fruix-guile-extra" "3.0" store-dir
|
||||
#:extra-files (append guile-runtime-extra-files
|
||||
guile-extra-runtime-files)))
|
||||
(shepherd-store (materialize-prefix shepherd-prefix "fruix-shepherd-runtime" "1.0.9" store-dir))
|
||||
(guile-store (or guile-store-path
|
||||
(materialize-prefix guile-prefix "fruix-guile-runtime" "3.0" store-dir
|
||||
#:extra-files guile-runtime-extra-files)))
|
||||
(guile-extra-store (or guile-extra-store-path
|
||||
(materialize-prefix guile-extra-prefix "fruix-guile-extra" "3.0" store-dir
|
||||
#:extra-files (append guile-runtime-extra-files
|
||||
guile-extra-runtime-files))))
|
||||
(shepherd-store (or shepherd-store-path
|
||||
(materialize-prefix shepherd-prefix "fruix-shepherd-runtime" "1.0.9" store-dir)))
|
||||
(host-base-stores
|
||||
(delete-duplicates
|
||||
(map cdr
|
||||
@@ -149,6 +158,19 @@
|
||||
(promoted-native-build-result-artifact-store native-build-result artifact-kind))
|
||||
'(world kernel headers bootloader))
|
||||
'()))))
|
||||
(declaration-source-text
|
||||
(or declaration-source
|
||||
";; Fruix declaration source is unavailable for this closure.\n"))
|
||||
(declaration-origin-text (or declaration-origin ""))
|
||||
(declaration-system-text
|
||||
(cond ((symbol? declaration-system-symbol)
|
||||
(symbol->string declaration-system-symbol))
|
||||
((string? declaration-system-symbol)
|
||||
declaration-system-symbol)
|
||||
(else "")))
|
||||
(declaration-info-object
|
||||
`((available? . ,(not (not declaration-source)))
|
||||
(system-variable . ,declaration-system-text)))
|
||||
(metadata-files
|
||||
(append
|
||||
(list (cons "metadata/freebsd-base.scm"
|
||||
@@ -159,10 +181,18 @@
|
||||
(object->string (map freebsd-source-materialization-spec source-materializations)))
|
||||
(cons "metadata/host-base-provenance.scm"
|
||||
(object->string (host-freebsd-provenance)))
|
||||
(cons "metadata/system-declaration.scm"
|
||||
declaration-source-text)
|
||||
(cons "metadata/system-declaration-info.scm"
|
||||
(object->string declaration-info-object))
|
||||
(cons "metadata/system-declaration-system"
|
||||
(string-append declaration-system-text "\n"))
|
||||
(cons "metadata/store-layout.scm"
|
||||
(object->string
|
||||
`((freebsd-base . ,(freebsd-base-spec (operating-system-freebsd-base os)))
|
||||
(freebsd-source . ,(freebsd-source-spec (freebsd-base-source (operating-system-freebsd-base os))))
|
||||
(system-declaration-available? . ,(not (not declaration-source)))
|
||||
(system-declaration-system-variable . ,declaration-system-text)
|
||||
(promoted-native-build-result . ,promoted-native-build-result-summary)
|
||||
(promoted-native-build-artifact-store-count . ,(length promoted-native-build-artifact-stores))
|
||||
(promoted-native-build-artifact-stores . ,promoted-native-build-artifact-stores)
|
||||
@@ -277,6 +307,9 @@
|
||||
(freebsd-source-materializations-file . ,(string-append closure-path "/metadata/freebsd-source-materializations.scm"))
|
||||
(materialized-source-stores . ,materialized-source-stores)
|
||||
(host-base-provenance-file . ,(string-append closure-path "/metadata/host-base-provenance.scm"))
|
||||
(system-declaration-file . ,(string-append closure-path "/metadata/system-declaration.scm"))
|
||||
(system-declaration-info-file . ,(string-append closure-path "/metadata/system-declaration-info.scm"))
|
||||
(system-declaration-system-file . ,(string-append closure-path "/metadata/system-declaration-system"))
|
||||
(store-layout-file . ,(string-append closure-path "/metadata/store-layout.scm"))
|
||||
(promoted-native-build-result-file
|
||||
. ,(and promoted-native-build-result-summary
|
||||
@@ -309,6 +342,9 @@
|
||||
(freebsd-source-materializations-file
|
||||
. ,(string-append closure-path "/metadata/freebsd-source-materializations.scm"))
|
||||
(host-base-provenance-file . ,(string-append closure-path "/metadata/host-base-provenance.scm"))
|
||||
(system-declaration-file . ,(string-append closure-path "/metadata/system-declaration.scm"))
|
||||
(system-declaration-info-file . ,(string-append closure-path "/metadata/system-declaration-info.scm"))
|
||||
(system-declaration-system-file . ,(string-append closure-path "/metadata/system-declaration-system"))
|
||||
(store-layout-file . ,(string-append closure-path "/metadata/store-layout.scm"))
|
||||
(install-metadata-path . ,install-metadata-path)
|
||||
(install-spec . ,install-spec)))
|
||||
@@ -321,6 +357,9 @@
|
||||
(freebsd-source-materializations-file
|
||||
. ,(string-append closure-path "/metadata/freebsd-source-materializations.scm"))
|
||||
(host-base-provenance-file . ,(string-append closure-path "/metadata/host-base-provenance.scm"))
|
||||
(system-declaration-file . ,(string-append closure-path "/metadata/system-declaration.scm"))
|
||||
(system-declaration-info-file . ,(string-append closure-path "/metadata/system-declaration-info.scm"))
|
||||
(system-declaration-system-file . ,(string-append closure-path "/metadata/system-declaration-system"))
|
||||
(store-layout-file . ,(string-append closure-path "/metadata/store-layout.scm"))))
|
||||
|
||||
(define* (populate-system-generation-layout os rootfs closure-path
|
||||
@@ -437,12 +476,18 @@
|
||||
(store-dir "/frx/store")
|
||||
(guile-prefix "/tmp/guile-freebsd-validate-install")
|
||||
(guile-extra-prefix "/tmp/guile-gnutls-freebsd-validate-install")
|
||||
(shepherd-prefix "/tmp/shepherd-freebsd-validate-install"))
|
||||
(shepherd-prefix "/tmp/shepherd-freebsd-validate-install")
|
||||
(declaration-source #f)
|
||||
(declaration-origin #f)
|
||||
(declaration-system-symbol #f))
|
||||
(let* ((closure (materialize-operating-system os
|
||||
#:store-dir store-dir
|
||||
#:guile-prefix guile-prefix
|
||||
#:guile-extra-prefix guile-extra-prefix
|
||||
#:shepherd-prefix shepherd-prefix))
|
||||
#:shepherd-prefix shepherd-prefix
|
||||
#:declaration-source declaration-source
|
||||
#:declaration-origin declaration-origin
|
||||
#:declaration-system-symbol declaration-system-symbol))
|
||||
(closure-path (assoc-ref closure 'closure-path)))
|
||||
(populate-rootfs-from-closure os rootfs closure-path)))
|
||||
|
||||
@@ -783,6 +828,9 @@
|
||||
(guile-prefix "/tmp/guile-freebsd-validate-install")
|
||||
(guile-extra-prefix "/tmp/guile-gnutls-freebsd-validate-install")
|
||||
(shepherd-prefix "/tmp/shepherd-freebsd-validate-install")
|
||||
(declaration-source #f)
|
||||
(declaration-origin #f)
|
||||
(declaration-system-symbol #f)
|
||||
(efi-size "64m")
|
||||
(root-size #f)
|
||||
(disk-capacity #f)
|
||||
@@ -795,7 +843,10 @@
|
||||
#:store-dir store-dir
|
||||
#:guile-prefix guile-prefix
|
||||
#:guile-extra-prefix guile-extra-prefix
|
||||
#:shepherd-prefix shepherd-prefix))
|
||||
#:shepherd-prefix shepherd-prefix
|
||||
#:declaration-source declaration-source
|
||||
#:declaration-origin declaration-origin
|
||||
#:declaration-system-symbol declaration-system-symbol))
|
||||
(closure-path (assoc-ref closure 'closure-path))
|
||||
(store-items (store-reference-closure (list closure-path)))
|
||||
(target-kind (if (string-prefix? "/dev/" target)
|
||||
@@ -910,6 +961,9 @@
|
||||
(guile-prefix "/tmp/guile-freebsd-validate-install")
|
||||
(guile-extra-prefix "/tmp/guile-gnutls-freebsd-validate-install")
|
||||
(shepherd-prefix "/tmp/shepherd-freebsd-validate-install")
|
||||
(declaration-source #f)
|
||||
(declaration-origin #f)
|
||||
(declaration-system-symbol #f)
|
||||
(efi-size "64m")
|
||||
(root-size "256m")
|
||||
(disk-capacity #f)
|
||||
@@ -920,7 +974,10 @@
|
||||
#:store-dir store-dir
|
||||
#:guile-prefix guile-prefix
|
||||
#:guile-extra-prefix guile-extra-prefix
|
||||
#:shepherd-prefix shepherd-prefix))
|
||||
#:shepherd-prefix shepherd-prefix
|
||||
#:declaration-source declaration-source
|
||||
#:declaration-origin declaration-origin
|
||||
#:declaration-system-symbol declaration-system-symbol))
|
||||
(closure-path (assoc-ref closure 'closure-path))
|
||||
(image-spec (operating-system-image-spec os
|
||||
#:efi-size efi-size
|
||||
@@ -963,7 +1020,10 @@
|
||||
#:store-dir store-dir
|
||||
#:guile-prefix guile-prefix
|
||||
#:guile-extra-prefix guile-extra-prefix
|
||||
#:shepherd-prefix shepherd-prefix)
|
||||
#:shepherd-prefix shepherd-prefix
|
||||
#:declaration-source declaration-source
|
||||
#:declaration-origin declaration-origin
|
||||
#:declaration-system-symbol declaration-system-symbol)
|
||||
(copy-rootfs-for-image rootfs image-rootfs)
|
||||
(copy-store-items-into-rootfs image-rootfs store-dir store-items)
|
||||
(mkdir-p (string-append esp-stage "/EFI/BOOT"))
|
||||
@@ -1031,6 +1091,9 @@
|
||||
(guile-prefix "/tmp/guile-freebsd-validate-install")
|
||||
(guile-extra-prefix "/tmp/guile-gnutls-freebsd-validate-install")
|
||||
(shepherd-prefix "/tmp/shepherd-freebsd-validate-install")
|
||||
(declaration-source #f)
|
||||
(declaration-origin #f)
|
||||
(declaration-system-symbol #f)
|
||||
(install-target-device "/dev/vtbd1")
|
||||
(efi-size "64m")
|
||||
(root-size "10g")
|
||||
@@ -1049,12 +1112,18 @@
|
||||
#:store-dir store-dir
|
||||
#:guile-prefix guile-prefix
|
||||
#:guile-extra-prefix guile-extra-prefix
|
||||
#:shepherd-prefix shepherd-prefix))
|
||||
#:shepherd-prefix shepherd-prefix
|
||||
#:declaration-source declaration-source
|
||||
#:declaration-origin declaration-origin
|
||||
#:declaration-system-symbol declaration-system-symbol))
|
||||
(installer-closure (materialize-operating-system installer-os
|
||||
#:store-dir store-dir
|
||||
#:guile-prefix guile-prefix
|
||||
#:guile-extra-prefix guile-extra-prefix
|
||||
#:shepherd-prefix shepherd-prefix))
|
||||
#:shepherd-prefix shepherd-prefix
|
||||
#:declaration-source declaration-source
|
||||
#:declaration-origin declaration-origin
|
||||
#:declaration-system-symbol declaration-system-symbol))
|
||||
(target-closure-path (assoc-ref target-closure 'closure-path))
|
||||
(installer-closure-path (assoc-ref installer-closure 'closure-path))
|
||||
(target-store-items (store-reference-closure (list target-closure-path)))
|
||||
@@ -1339,6 +1408,9 @@
|
||||
(guile-prefix "/tmp/guile-freebsd-validate-install")
|
||||
(guile-extra-prefix "/tmp/guile-gnutls-freebsd-validate-install")
|
||||
(shepherd-prefix "/tmp/shepherd-freebsd-validate-install")
|
||||
(declaration-source #f)
|
||||
(declaration-origin #f)
|
||||
(declaration-system-symbol #f)
|
||||
(install-target-device "/dev/vtbd0")
|
||||
(root-size #f)
|
||||
(installer-host-name (string-append (operating-system-host-name os)
|
||||
@@ -1355,12 +1427,18 @@
|
||||
#:store-dir store-dir
|
||||
#:guile-prefix guile-prefix
|
||||
#:guile-extra-prefix guile-extra-prefix
|
||||
#:shepherd-prefix shepherd-prefix))
|
||||
#:shepherd-prefix shepherd-prefix
|
||||
#:declaration-source declaration-source
|
||||
#:declaration-origin declaration-origin
|
||||
#:declaration-system-symbol declaration-system-symbol))
|
||||
(installer-closure (materialize-operating-system installer-os
|
||||
#:store-dir store-dir
|
||||
#:guile-prefix guile-prefix
|
||||
#:guile-extra-prefix guile-extra-prefix
|
||||
#:shepherd-prefix shepherd-prefix))
|
||||
#:shepherd-prefix shepherd-prefix
|
||||
#:declaration-source declaration-source
|
||||
#:declaration-origin declaration-origin
|
||||
#:declaration-system-symbol declaration-system-symbol))
|
||||
(target-closure-path (assoc-ref target-closure 'closure-path))
|
||||
(installer-closure-path (assoc-ref installer-closure 'closure-path))
|
||||
(target-closure-store-items (store-reference-closure (list target-closure-path)))
|
||||
|
||||
@@ -369,8 +369,12 @@
|
||||
"metadata/freebsd-base.scm"
|
||||
"metadata/host-base-provenance.scm"
|
||||
"metadata/store-layout.scm"
|
||||
"metadata/system-declaration.scm"
|
||||
"metadata/system-declaration-info.scm"
|
||||
"metadata/system-declaration-system"
|
||||
"activate"
|
||||
"shepherd/init.scm"
|
||||
"share/fruix/node/scripts/fruix.scm"
|
||||
"usr/local/bin/fruix")
|
||||
(if (operating-system-native-build-result os)
|
||||
'("metadata/promoted-native-build-result.scm")
|
||||
@@ -404,6 +408,8 @@
|
||||
(base-packages . ,(package-names (operating-system-base-packages os)))
|
||||
(development-package-count . ,(length (operating-system-development-packages os)))
|
||||
(development-packages . ,(package-names (operating-system-development-packages os)))
|
||||
(installed-system-command-surface-version . "2")
|
||||
(bundled-fruix-node-cli-version . "1")
|
||||
(development-environment-helper-version
|
||||
. ,(if (null? (operating-system-development-packages os)) #f "1"))
|
||||
(self-hosted-native-build-helper-version
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#:use-module (ice-9 match)
|
||||
#:use-module (srfi srfi-1)
|
||||
#:use-module (srfi srfi-13)
|
||||
#:use-module (rnrs io ports)
|
||||
#:export (operating-system-generated-files
|
||||
render-activation-rc-script
|
||||
render-rc-script))
|
||||
@@ -467,7 +468,57 @@
|
||||
"}\n\n"
|
||||
"load_rc_config $name\n"
|
||||
"run_rc_command \"$1\"\n")))
|
||||
(define (render-installed-system-fruix os)
|
||||
|
||||
(define (path-parent path)
|
||||
(let ((index (string-rindex path #\/)))
|
||||
(cond
|
||||
((not index) ".")
|
||||
((zero? index) "/")
|
||||
(else (substring path 0 index)))))
|
||||
|
||||
(define (read-source-file-string path)
|
||||
(call-with-input-file path get-string-all))
|
||||
|
||||
(define (bundled-fruix-node-files)
|
||||
(let* ((repo-root (or (getenv "FRUIX_PROJECT_ROOT")
|
||||
(let ((render-file (current-filename)))
|
||||
(and render-file
|
||||
(path-parent
|
||||
(path-parent
|
||||
(path-parent
|
||||
(path-parent
|
||||
(path-parent render-file)))))))
|
||||
(getcwd)))
|
||||
(guix-root (or (getenv "GUIX_SOURCE_DIR")
|
||||
(string-append (getenv "HOME") "/repos/guix")))
|
||||
(specs `((,(string-append repo-root "/scripts/fruix.scm")
|
||||
. "share/fruix/node/scripts/fruix.scm")
|
||||
(,(string-append repo-root "/modules/fruix/packages/freebsd.scm")
|
||||
. "share/fruix/node/modules/fruix/packages/freebsd.scm")
|
||||
(,(string-append repo-root "/modules/fruix/system/freebsd.scm")
|
||||
. "share/fruix/node/modules/fruix/system/freebsd.scm")
|
||||
(,(string-append repo-root "/modules/fruix/system/freebsd/build.scm")
|
||||
. "share/fruix/node/modules/fruix/system/freebsd/build.scm")
|
||||
(,(string-append repo-root "/modules/fruix/system/freebsd/executor.scm")
|
||||
. "share/fruix/node/modules/fruix/system/freebsd/executor.scm")
|
||||
(,(string-append repo-root "/modules/fruix/system/freebsd/media.scm")
|
||||
. "share/fruix/node/modules/fruix/system/freebsd/media.scm")
|
||||
(,(string-append repo-root "/modules/fruix/system/freebsd/model.scm")
|
||||
. "share/fruix/node/modules/fruix/system/freebsd/model.scm")
|
||||
(,(string-append repo-root "/modules/fruix/system/freebsd/render.scm")
|
||||
. "share/fruix/node/modules/fruix/system/freebsd/render.scm")
|
||||
(,(string-append repo-root "/modules/fruix/system/freebsd/source.scm")
|
||||
. "share/fruix/node/modules/fruix/system/freebsd/source.scm")
|
||||
(,(string-append repo-root "/modules/fruix/system/freebsd/utils.scm")
|
||||
. "share/fruix/node/modules/fruix/system/freebsd/utils.scm")
|
||||
(,(string-append guix-root "/guix/build/utils.scm")
|
||||
. "share/fruix/node/guix/guix/build/utils.scm"))))
|
||||
(map (lambda (entry)
|
||||
(cons (cdr entry)
|
||||
(read-source-file-string (car entry))))
|
||||
specs)))
|
||||
|
||||
(define (render-installed-system-fruix os guile-store guile-extra-store shepherd-store)
|
||||
(string-append
|
||||
"#!/bin/sh\n"
|
||||
"set -eu\n"
|
||||
@@ -485,6 +536,17 @@
|
||||
"rollback_generation_file=\"$system_root/rollback-generation\"\n"
|
||||
"gcroots_root=/frx/var/fruix/gcroots\n"
|
||||
"run_current_link=/run/current-system\n"
|
||||
"node_root=/run/current-system/share/fruix/node\n"
|
||||
"node_script=\"$node_root/scripts/fruix.scm\"\n"
|
||||
"node_module_root=\"$node_root/modules\"\n"
|
||||
"node_guix_root=\"$node_root/guix\"\n"
|
||||
"declaration_file=/run/current-system/metadata/system-declaration.scm\n"
|
||||
"declaration_info_file=/run/current-system/metadata/system-declaration-info.scm\n"
|
||||
"declaration_system_file=/run/current-system/metadata/system-declaration-system\n"
|
||||
"default_store_dir=/frx/store\n"
|
||||
"guile_store='" guile-store "'\n"
|
||||
"guile_extra_store='" guile-extra-store "'\n"
|
||||
"shepherd_store='" shepherd-store "'\n"
|
||||
"layout_version=2\n"
|
||||
"host_name='" (operating-system-host-name os) "'\n"
|
||||
"ready_marker='" (operating-system-ready-marker os) "'\n"
|
||||
@@ -493,6 +555,8 @@
|
||||
"{\n"
|
||||
" cat <<'EOF'\n"
|
||||
"Usage: fruix system status\n"
|
||||
" fruix system build [DECLARATION [--system NAME] ...]\n"
|
||||
" fruix system reconfigure [DECLARATION [--system NAME] ...]\n"
|
||||
" fruix system switch /frx/store/...-fruix-system-...\n"
|
||||
" fruix system rollback\n"
|
||||
"EOF\n"
|
||||
@@ -514,6 +578,10 @@
|
||||
" tr -d '\\n' < \"$1\"\n"
|
||||
" fi\n"
|
||||
"}\n\n"
|
||||
"default_system_name()\n"
|
||||
"{\n"
|
||||
" read_file_maybe \"$declaration_system_file\"\n"
|
||||
"}\n\n"
|
||||
"symlink_force()\n"
|
||||
"{\n"
|
||||
" target=$1\n"
|
||||
@@ -537,6 +605,79 @@
|
||||
" [ -f \"$closure/shepherd/init.scm\" ] || die \"closure is missing shepherd config: $closure\"\n"
|
||||
" [ -f \"$closure/boot/loader.efi\" ] || die \"closure is missing loader.efi: $closure\"\n"
|
||||
"}\n\n"
|
||||
"ensure_default_declaration()\n"
|
||||
"{\n"
|
||||
" [ -f \"$declaration_file\" ] || die \"current declaration file is missing: $declaration_file\"\n"
|
||||
" [ -f \"$declaration_info_file\" ] || die \"current declaration info file is missing: $declaration_info_file\"\n"
|
||||
" current_system_name=$(default_system_name)\n"
|
||||
" [ -n \"$current_system_name\" ] || die \"current declaration is missing a system variable name\"\n"
|
||||
"}\n\n"
|
||||
"run_node_cli()\n"
|
||||
"{\n"
|
||||
" [ -x \"$guile_store/bin/guile\" ] || die \"missing Guile runtime: $guile_store/bin/guile\"\n"
|
||||
" [ -f \"$node_script\" ] || die \"missing bundled Fruix node CLI: $node_script\"\n"
|
||||
" [ -d \"$node_module_root\" ] || die \"missing bundled Fruix modules: $node_module_root\"\n"
|
||||
" [ -d \"$node_guix_root\" ] || die \"missing bundled Guix modules: $node_guix_root\"\n"
|
||||
" guile_load_path=\"$node_module_root:$node_guix_root:$shepherd_store/share/guile/site/3.0:$guile_extra_store/share/guile/site/3.0\"\n"
|
||||
" guile_system_path=\"$guile_store/share/guile/3.0:$guile_store/share/guile/site/3.0:$guile_store/share/guile/site:$guile_store/share/guile\"\n"
|
||||
" guile_system_compiled_path=\"$guile_store/lib/guile/3.0/ccache:$guile_store/lib/guile/3.0/site-ccache\"\n"
|
||||
" guile_load_compiled_path=\"$shepherd_store/lib/guile/3.0/site-ccache:$guile_extra_store/lib/guile/3.0/site-ccache\"\n"
|
||||
" guile_system_extensions_path=\"$guile_store/lib/guile/3.0/extensions\"\n"
|
||||
" guile_extensions_path=\"$guile_extra_store/lib/guile/3.0/extensions\"\n"
|
||||
" ld_library_path=\"$guile_extra_store/lib:$guile_store/lib:/usr/local/lib\"\n"
|
||||
" env \\\n"
|
||||
" GUILE_AUTO_COMPILE=0 \\\n"
|
||||
" GUILE_SYSTEM_PATH=\"$guile_system_path\" \\\n"
|
||||
" GUILE_LOAD_PATH=\"$guile_load_path\" \\\n"
|
||||
" GUILE_SYSTEM_COMPILED_PATH=\"$guile_system_compiled_path\" \\\n"
|
||||
" GUILE_LOAD_COMPILED_PATH=\"$guile_load_compiled_path\" \\\n"
|
||||
" GUILE_SYSTEM_EXTENSIONS_PATH=\"$guile_system_extensions_path\" \\\n"
|
||||
" GUILE_EXTENSIONS_PATH=\"$guile_extensions_path\" \\\n"
|
||||
" LD_LIBRARY_PATH=\"$ld_library_path\" \\\n"
|
||||
" GUILE_PREFIX=\"$guile_store\" \\\n"
|
||||
" GUILE_EXTRA_PREFIX=\"$guile_extra_store\" \\\n"
|
||||
" SHEPHERD_PREFIX=\"$shepherd_store\" \\\n"
|
||||
" FRUIX_GUILE_STORE=\"$guile_store\" \\\n"
|
||||
" FRUIX_GUILE_EXTRA_STORE=\"$guile_extra_store\" \\\n"
|
||||
" FRUIX_SHEPHERD_STORE=\"$shepherd_store\" \\\n"
|
||||
" GUIX_SOURCE_DIR=\"$node_guix_root\" \\\n"
|
||||
" FRUIX_PROJECT_ROOT=\"$node_root\" \\\n"
|
||||
" \"$guile_store/bin/guile\" --no-auto-compile -s \"$node_script\" \"$@\"\n"
|
||||
"}\n\n"
|
||||
"system_build()\n"
|
||||
"{\n"
|
||||
" if [ $# -eq 0 ]; then\n"
|
||||
" ensure_default_declaration\n"
|
||||
" run_node_cli system build \"$declaration_file\" --system \"$current_system_name\" --store \"$default_store_dir\"\n"
|
||||
" else\n"
|
||||
" run_node_cli system build \"$@\"\n"
|
||||
" fi\n"
|
||||
"}\n\n"
|
||||
"reconfigure_system()\n"
|
||||
"{\n"
|
||||
" build_output=$(mktemp /tmp/fruix-system-reconfigure.XXXXXX)\n"
|
||||
" if [ $# -eq 0 ]; then\n"
|
||||
" ensure_default_declaration\n"
|
||||
" if ! run_node_cli system build \"$declaration_file\" --system \"$current_system_name\" --store \"$default_store_dir\" > \"$build_output\"; then\n"
|
||||
" cat \"$build_output\" >&2 || true\n"
|
||||
" rm -f \"$build_output\"\n"
|
||||
" exit 1\n"
|
||||
" fi\n"
|
||||
" else\n"
|
||||
" if ! run_node_cli system build \"$@\" > \"$build_output\"; then\n"
|
||||
" cat \"$build_output\" >&2 || true\n"
|
||||
" rm -f \"$build_output\"\n"
|
||||
" exit 1\n"
|
||||
" fi\n"
|
||||
" fi\n"
|
||||
" closure=$(sed -n 's/^closure_path=//p' \"$build_output\" | tail -n 1)\n"
|
||||
" [ -n \"$closure\" ] || die \"failed to recover closure_path from in-system build output\"\n"
|
||||
" cat \"$build_output\"\n"
|
||||
" rm -f \"$build_output\"\n"
|
||||
" switch_to_closure \"$closure\"\n"
|
||||
" printf 'reconfigure_closure=%s\\n' \"$closure\"\n"
|
||||
" printf 'reboot_required=true\\n'\n"
|
||||
"}\n\n"
|
||||
"max_generation_number()\n"
|
||||
"{\n"
|
||||
" max=0\n"
|
||||
@@ -726,6 +867,14 @@
|
||||
" [ $# -eq 2 ] || { usage >&2; exit 1; }\n"
|
||||
" status\n"
|
||||
" ;;\n"
|
||||
" build)\n"
|
||||
" shift 2\n"
|
||||
" system_build \"$@\"\n"
|
||||
" ;;\n"
|
||||
" reconfigure)\n"
|
||||
" shift 2\n"
|
||||
" reconfigure_system \"$@\"\n"
|
||||
" ;;\n"
|
||||
" switch)\n"
|
||||
" [ $# -eq 3 ] || { usage >&2; exit 1; }\n"
|
||||
" switch_to_closure \"$3\"\n"
|
||||
@@ -1030,7 +1179,9 @@
|
||||
#:guile-extra-store guile-extra-store
|
||||
#:shepherd-store shepherd-store))
|
||||
("shepherd/init.scm" . ,(render-shepherd-config os))
|
||||
("usr/local/bin/fruix" . ,(render-installed-system-fruix os)))
|
||||
("usr/local/bin/fruix"
|
||||
. ,(render-installed-system-fruix os guile-store guile-extra-store shepherd-store)))
|
||||
(bundled-fruix-node-files)
|
||||
(if (null? (operating-system-development-packages os))
|
||||
'()
|
||||
`(("usr/local/bin/fruix-development-environment"
|
||||
|
||||
+33
-4
@@ -6,7 +6,8 @@
|
||||
(ice-9 format)
|
||||
(ice-9 match)
|
||||
(srfi srfi-1)
|
||||
(srfi srfi-13))
|
||||
(srfi srfi-13)
|
||||
(rnrs io ports))
|
||||
|
||||
(define (usage code)
|
||||
(format (if (= code 0) #t (current-error-port))
|
||||
@@ -69,6 +70,9 @@ Common options:\n\
|
||||
(format #t "~a=~a~%" (car field) (stringify (cdr field))))
|
||||
fields))
|
||||
|
||||
(define (read-file-string file)
|
||||
(call-with-input-file file get-string-all))
|
||||
|
||||
(define (lookup-bound-value module symbol)
|
||||
(let ((var (module-variable module symbol)))
|
||||
(and var (variable-ref var))))
|
||||
@@ -629,7 +633,11 @@ Common options:\n\
|
||||
(lambda (os resolved-symbol)
|
||||
(let* ((guile-prefix (or (getenv "GUILE_PREFIX") "/tmp/guile-freebsd-validate-install"))
|
||||
(guile-extra-prefix (or (getenv "GUILE_EXTRA_PREFIX") "/tmp/guile-gnutls-freebsd-validate-install"))
|
||||
(shepherd-prefix (or (getenv "SHEPHERD_PREFIX") "/tmp/shepherd-freebsd-validate-install")))
|
||||
(shepherd-prefix (or (getenv "SHEPHERD_PREFIX") "/tmp/shepherd-freebsd-validate-install"))
|
||||
(guile-store-path (getenv "FRUIX_GUILE_STORE"))
|
||||
(guile-extra-store-path (getenv "FRUIX_GUILE_EXTRA_STORE"))
|
||||
(shepherd-store-path (getenv "FRUIX_SHEPHERD_STORE"))
|
||||
(declaration-source (read-file-string os-file)))
|
||||
(cond
|
||||
((string=? action "build")
|
||||
(emit-system-build-metadata
|
||||
@@ -638,7 +646,13 @@ Common options:\n\
|
||||
#:store-dir store-dir
|
||||
#:guile-prefix guile-prefix
|
||||
#:guile-extra-prefix guile-extra-prefix
|
||||
#:shepherd-prefix shepherd-prefix)))
|
||||
#:shepherd-prefix shepherd-prefix
|
||||
#:guile-store-path guile-store-path
|
||||
#:guile-extra-store-path guile-extra-store-path
|
||||
#:shepherd-store-path shepherd-store-path
|
||||
#:declaration-source declaration-source
|
||||
#:declaration-origin os-file
|
||||
#:declaration-system-symbol resolved-symbol)))
|
||||
((string=? action "rootfs")
|
||||
(unless rootfs
|
||||
(error "rootfs action requires ROOTFS-DIR or --rootfs DIR"))
|
||||
@@ -646,7 +660,10 @@ Common options:\n\
|
||||
#:store-dir store-dir
|
||||
#:guile-prefix guile-prefix
|
||||
#:guile-extra-prefix guile-extra-prefix
|
||||
#:shepherd-prefix shepherd-prefix)))
|
||||
#:shepherd-prefix shepherd-prefix
|
||||
#:declaration-source declaration-source
|
||||
#:declaration-origin os-file
|
||||
#:declaration-system-symbol resolved-symbol)))
|
||||
(emit-metadata
|
||||
`((action . "rootfs")
|
||||
(os_file . ,os-file)
|
||||
@@ -664,6 +681,9 @@ Common options:\n\
|
||||
#:guile-prefix guile-prefix
|
||||
#:guile-extra-prefix guile-extra-prefix
|
||||
#:shepherd-prefix shepherd-prefix
|
||||
#:declaration-source declaration-source
|
||||
#:declaration-origin os-file
|
||||
#:declaration-system-symbol resolved-symbol
|
||||
#:root-size (or root-size "256m")
|
||||
#:disk-capacity disk-capacity)))
|
||||
((string=? action "installer")
|
||||
@@ -674,6 +694,9 @@ Common options:\n\
|
||||
#:guile-prefix guile-prefix
|
||||
#:guile-extra-prefix guile-extra-prefix
|
||||
#:shepherd-prefix shepherd-prefix
|
||||
#:declaration-source declaration-source
|
||||
#:declaration-origin os-file
|
||||
#:declaration-system-symbol resolved-symbol
|
||||
#:install-target-device (or install-target-device "/dev/vtbd1")
|
||||
#:root-size (or root-size "10g")
|
||||
#:disk-capacity disk-capacity)))
|
||||
@@ -685,6 +708,9 @@ Common options:\n\
|
||||
#:guile-prefix guile-prefix
|
||||
#:guile-extra-prefix guile-extra-prefix
|
||||
#:shepherd-prefix shepherd-prefix
|
||||
#:declaration-source declaration-source
|
||||
#:declaration-origin os-file
|
||||
#:declaration-system-symbol resolved-symbol
|
||||
#:install-target-device (or install-target-device "/dev/vtbd0")
|
||||
#:root-size root-size)))
|
||||
((string=? action "install")
|
||||
@@ -698,6 +724,9 @@ Common options:\n\
|
||||
#:guile-prefix guile-prefix
|
||||
#:guile-extra-prefix guile-extra-prefix
|
||||
#:shepherd-prefix shepherd-prefix
|
||||
#:declaration-source declaration-source
|
||||
#:declaration-origin os-file
|
||||
#:declaration-system-symbol resolved-symbol
|
||||
#:root-size root-size
|
||||
#:disk-capacity disk-capacity))))))))))
|
||||
((string=? command "source")
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
(use-modules (fruix system freebsd)
|
||||
(fruix packages freebsd))
|
||||
|
||||
(define postphase20-promoted-native-build-result
|
||||
(promoted-native-build-result
|
||||
#:store-path "__PROMOTED_RESULT_STORE__"))
|
||||
|
||||
(define postphase20-installed-node-operating-system
|
||||
(operating-system-from-promoted-native-build-result
|
||||
postphase20-promoted-native-build-result
|
||||
#:host-name "__HOST_NAME__"
|
||||
#:groups (list (user-group #:name "wheel" #:gid 0 #:system? #t)
|
||||
(user-group #:name "sshd" #:gid 22 #:system? #t)
|
||||
(user-group #:name "_dhcp" #:gid 65 #:system? #t)
|
||||
(user-group #:name "operator" #:gid 1000 #:system? #f))
|
||||
#:users (list (user-account #:name "root"
|
||||
#:uid 0
|
||||
#:group "wheel"
|
||||
#:comment "Charlie &"
|
||||
#:home "/root"
|
||||
#:shell "/bin/sh"
|
||||
#:system? #t)
|
||||
(user-account #:name "sshd"
|
||||
#:uid 22
|
||||
#:group "sshd"
|
||||
#:comment "Secure Shell Daemon"
|
||||
#:home "/var/empty"
|
||||
#:shell "/usr/sbin/nologin"
|
||||
#:system? #t)
|
||||
(user-account #:name "_dhcp"
|
||||
#:uid 65
|
||||
#:group "_dhcp"
|
||||
#:comment "dhcp programs"
|
||||
#:home "/var/empty"
|
||||
#:shell "/usr/sbin/nologin"
|
||||
#:system? #t)
|
||||
(user-account #:name "operator"
|
||||
#:uid 1000
|
||||
#:group "operator"
|
||||
#:supplementary-groups '("wheel")
|
||||
#:comment "Fruix Operator"
|
||||
#:home "/home/operator"
|
||||
#:shell "/bin/sh"
|
||||
#:system? #f))
|
||||
#:file-systems (list (file-system #:device "/dev/gpt/fruix-root"
|
||||
#:mount-point "/"
|
||||
#:type "ufs"
|
||||
#:options "rw"
|
||||
#:needed-for-boot? #t)
|
||||
(file-system #:device "devfs"
|
||||
#:mount-point "/dev"
|
||||
#:type "devfs"
|
||||
#:options "rw"
|
||||
#:needed-for-boot? #t)
|
||||
(file-system #:device "tmpfs"
|
||||
#:mount-point "/tmp"
|
||||
#:type "tmpfs"
|
||||
#:options "rw,size=64m"))
|
||||
#:services '(shepherd ready-marker sshd)
|
||||
#:loader-entries '(("autoboot_delay" . "1")
|
||||
("boot_multicons" . "YES")
|
||||
("boot_serial" . "YES")
|
||||
("console" . "comconsole,vidconsole"))
|
||||
#:rc-conf-entries '(("clear_tmp_enable" . "NO")
|
||||
("hostid_enable" . "NO")
|
||||
("sendmail_enable" . "NONE")
|
||||
("sshd_enable" . "YES")
|
||||
("ifconfig_xn0" . "SYNCDHCP")
|
||||
("ifconfig_em0" . "SYNCDHCP")
|
||||
("ifconfig_vtnet0" . "SYNCDHCP"))
|
||||
#:init-mode 'shepherd-pid1
|
||||
#:ready-marker "/var/lib/fruix/ready"
|
||||
#:root-authorized-keys '("__ROOT_AUTHORIZED_KEY__")))
|
||||
@@ -104,11 +104,11 @@ image_size_bytes=$(stat -f '%z' "$disk_image")
|
||||
closure_base=$(basename "$closure_path")
|
||||
|
||||
case "$image_store_path" in
|
||||
/frx/store/*-fruix-bhyve-image-fruix-freebsd) : ;;
|
||||
/frx/store/*-fruix-bhyve-image-*) : ;;
|
||||
*) echo "unexpected image store path: $image_store_path" >&2; exit 1 ;;
|
||||
esac
|
||||
case "$disk_image" in
|
||||
/frx/store/*-fruix-bhyve-image-fruix-freebsd/disk.img) : ;;
|
||||
/frx/store/*-fruix-bhyve-image-*/disk.img) : ;;
|
||||
*) echo "unexpected disk image path: $disk_image" >&2; exit 1 ;;
|
||||
esac
|
||||
|
||||
@@ -142,7 +142,7 @@ if [ -L "$mnt_root/etc/master.passwd" ]; then master_passwd_kind=symlink; elif [
|
||||
loader_conf_image=$mnt_root/frx/store/$closure_base/boot/loader.conf
|
||||
rc_conf_image=$mnt_root/frx/store/$closure_base/etc/rc.conf
|
||||
grep -F 'comconsole' "$loader_conf_image" >/dev/null || { echo "loader.conf is missing serial console config" >&2; exit 1; }
|
||||
grep -F 'hostname="fruix-freebsd"' "$rc_conf_image" >/dev/null || { echo "rc.conf is missing hostname" >&2; exit 1; }
|
||||
grep -E '^hostname=".+"$' "$rc_conf_image" >/dev/null || { echo "rc.conf is missing hostname" >&2; exit 1; }
|
||||
[ -f "$host_base_provenance_file" ] || { echo "missing host base provenance file: $host_base_provenance_file" >&2; exit 1; }
|
||||
[ -f "$store_layout_file" ] || { echo "missing store layout file: $store_layout_file" >&2; exit 1; }
|
||||
[ -n "$host_freebsd_version" ] || { echo "missing host freebsd version provenance" >&2; exit 1; }
|
||||
|
||||
@@ -0,0 +1,271 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
repo_root=${PROJECT_ROOT:-$(pwd)}
|
||||
os_template=${OS_TEMPLATE:-$repo_root/tests/system/postphase20-installed-node-operating-system.scm.in}
|
||||
system_name=${SYSTEM_NAME:-postphase20-installed-node-operating-system}
|
||||
result_store=${RESULT_STORE:-/frx/store/ffe44f5d1ba576e1f811ad3fe3a526a242b5c4a5-fruix-native-build-result-15.0-STABLE-ssh-guest}
|
||||
root_size=${ROOT_SIZE:-12g}
|
||||
current_host_name=${CURRENT_HOST_NAME:-fruix-node-current}
|
||||
candidate_host_name=${CANDIDATE_HOST_NAME:-fruix-node-canary}
|
||||
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-postphase20-installed-node-xcpng.XXXXXX)
|
||||
cleanup=1
|
||||
fi
|
||||
if [ "${KEEP_WORKDIR:-0}" -eq 1 ]; then
|
||||
cleanup=0
|
||||
fi
|
||||
|
||||
current_os_file=$workdir/current-operating-system.scm
|
||||
candidate_os_file=$workdir/candidate-operating-system.scm
|
||||
inner_metadata=$workdir/postphase20-installed-node-inner-metadata.txt
|
||||
current_build_out=$workdir/current-build.txt
|
||||
candidate_build_out=$workdir/candidate-build.txt
|
||||
reconfigure_out=$workdir/reconfigure.txt
|
||||
rollback_out=$workdir/rollback.txt
|
||||
post_reconfigure_status=$workdir/post-reconfigure-status.txt
|
||||
post_boot_candidate_status=$workdir/post-boot-candidate-status.txt
|
||||
post_boot_rollback_status=$workdir/post-boot-rollback-status.txt
|
||||
metadata_file=$workdir/postphase20-installed-node-build-reconfigure-xcpng-metadata.txt
|
||||
|
||||
cleanup_workdir() {
|
||||
if [ "$cleanup" -eq 1 ]; then
|
||||
rm -rf "$workdir"
|
||||
fi
|
||||
}
|
||||
trap cleanup_workdir EXIT INT TERM
|
||||
|
||||
[ -f "$os_template" ] || { echo "missing operating-system template: $os_template" >&2; exit 1; }
|
||||
[ -f "$root_authorized_key_file" ] || { echo "missing root authorized key file: $root_authorized_key_file" >&2; exit 1; }
|
||||
[ -f "$root_ssh_private_key_file" ] || { echo "missing root SSH private key file: $root_ssh_private_key_file" >&2; exit 1; }
|
||||
[ -d "$result_store" ] || { echo "promoted result store does not exist: $result_store" >&2; exit 1; }
|
||||
|
||||
root_authorized_key=$(tr -d '\n' < "$root_authorized_key_file")
|
||||
|
||||
render_os() {
|
||||
output=$1
|
||||
host_name=$2
|
||||
sed \
|
||||
-e "s|__PROMOTED_RESULT_STORE__|$result_store|g" \
|
||||
-e "s|__HOST_NAME__|$host_name|g" \
|
||||
-e "s|__ROOT_AUTHORIZED_KEY__|$root_authorized_key|g" \
|
||||
"$os_template" > "$output"
|
||||
}
|
||||
|
||||
render_os "$current_os_file" "$current_host_name"
|
||||
render_os "$candidate_os_file" "$candidate_host_name"
|
||||
|
||||
KEEP_WORKDIR=1 WORKDIR="$workdir/boot" METADATA_OUT="$inner_metadata" \
|
||||
ROOT_AUTHORIZED_KEY_FILE="$root_authorized_key_file" \
|
||||
ROOT_SSH_PRIVATE_KEY_FILE="$root_ssh_private_key_file" \
|
||||
OS_TEMPLATE="$current_os_file" SYSTEM_NAME="$system_name" ROOT_SIZE="$root_size" \
|
||||
"$repo_root/tests/system/run-phase11-shepherd-pid1-xcpng.sh"
|
||||
|
||||
phase8_metadata=$(sed -n 's/^phase8_metadata=//p' "$inner_metadata")
|
||||
closure_path=$(sed -n 's/^closure_path=//p' "$inner_metadata")
|
||||
closure_base=$(sed -n 's/^closure_base=//p' "$inner_metadata")
|
||||
guest_ip=$(sed -n 's/^guest_ip=//p' "$inner_metadata")
|
||||
vm_id=$(sed -n 's/^vm_id=//p' "$inner_metadata")
|
||||
vdi_id=$(sed -n 's/^vdi_id=//p' "$inner_metadata")
|
||||
shepherd_pid=$(sed -n 's/^shepherd_pid=//p' "$inner_metadata")
|
||||
sshd_status=$(sed -n 's/^sshd_status=//p' "$inner_metadata")
|
||||
compat_prefix_shims=$(sed -n 's/^compat_prefix_shims=//p' "$inner_metadata")
|
||||
guile_module_smoke=$(sed -n 's/^guile_module_smoke=//p' "$inner_metadata")
|
||||
activate_log=$(sed -n 's/^activate_log=//p' "$inner_metadata")
|
||||
|
||||
[ "$shepherd_pid" = 1 ] || { echo "shepherd was not PID 1" >&2; exit 1; }
|
||||
[ "$sshd_status" = running ] || { echo "sshd is not running" >&2; exit 1; }
|
||||
[ "$compat_prefix_shims" = absent ] || { echo "compatibility prefix shims reappeared" >&2; exit 1; }
|
||||
[ "$guile_module_smoke" = ok ] || { echo "guest Guile module smoke failed" >&2; exit 1; }
|
||||
case "$activate_log" in
|
||||
*fruix-activate:done*) : ;;
|
||||
*) echo "activation log does not show success" >&2; exit 1 ;;
|
||||
esac
|
||||
|
||||
for path in \
|
||||
"$closure_path/metadata/system-declaration.scm" \
|
||||
"$closure_path/metadata/system-declaration-info.scm" \
|
||||
"$closure_path/metadata/system-declaration-system" \
|
||||
"$closure_path/share/fruix/node/scripts/fruix.scm" \
|
||||
"$closure_path/share/fruix/node/modules/fruix/system/freebsd/render.scm" \
|
||||
"$closure_path/share/fruix/node/guix/guix/build/utils.scm"
|
||||
do
|
||||
[ -f "$path" ] || {
|
||||
echo "required installed-node path missing: $path" >&2
|
||||
exit 1
|
||||
}
|
||||
done
|
||||
|
||||
grep -F "$current_host_name" "$closure_path/metadata/system-declaration.scm" >/dev/null || {
|
||||
echo "embedded declaration does not mention current host name" >&2
|
||||
exit 1
|
||||
}
|
||||
grep -F "$system_name" "$closure_path/metadata/system-declaration-system" >/dev/null || {
|
||||
echo "embedded declaration system name is missing" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
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" "$@"
|
||||
}
|
||||
|
||||
scp_guest() {
|
||||
scp -O -i "$root_ssh_private_key_file" \
|
||||
-o BatchMode=yes \
|
||||
-o StrictHostKeyChecking=no \
|
||||
-o UserKnownHostsFile=/dev/null \
|
||||
-o ConnectTimeout=5 \
|
||||
"$@"
|
||||
}
|
||||
|
||||
wait_for_ssh() {
|
||||
for attempt in $(jot 120 1 120); do
|
||||
if ssh_guest 'service sshd onestatus >/dev/null 2>&1' >/dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
reboot_guest() {
|
||||
ssh_guest 'shutdown -r now >/dev/null 2>&1 || reboot >/dev/null 2>&1 || true' >/dev/null 2>&1 || true
|
||||
sleep 5
|
||||
wait_for_ssh || {
|
||||
echo "guest did not return over SSH after reboot" >&2
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
ssh_guest 'sh -s' <<EOF
|
||||
set -eu
|
||||
[ -x /usr/local/bin/fruix ]
|
||||
[ -f /run/current-system/metadata/system-declaration.scm ]
|
||||
[ -f /run/current-system/metadata/system-declaration-info.scm ]
|
||||
[ -f /run/current-system/metadata/system-declaration-system ]
|
||||
[ -f /run/current-system/share/fruix/node/scripts/fruix.scm ]
|
||||
[ -f /run/current-system/share/fruix/node/modules/fruix/system/freebsd/media.scm ]
|
||||
[ -f /run/current-system/share/fruix/node/guix/guix/build/utils.scm ]
|
||||
grep -F '$system_name' /run/current-system/metadata/system-declaration-system >/dev/null
|
||||
EOF
|
||||
|
||||
ssh_guest '/usr/local/bin/fruix system build' > "$current_build_out"
|
||||
current_built_closure=$(sed -n 's/^closure_path=//p' "$current_build_out" | tail -n 1)
|
||||
[ -n "$current_built_closure" ] || { echo "missing closure_path from in-system build output" >&2; exit 1; }
|
||||
case "$current_built_closure" in
|
||||
/frx/store/*-fruix-system-$current_host_name) : ;;
|
||||
*)
|
||||
echo "in-system build of current declaration produced an unexpected closure path: $current_built_closure" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
scp_guest "$candidate_os_file" root@"$guest_ip":/root/candidate.scm >/dev/null
|
||||
ssh_guest "/usr/local/bin/fruix system build /root/candidate.scm --system $system_name" > "$candidate_build_out"
|
||||
candidate_closure=$(sed -n 's/^closure_path=//p' "$candidate_build_out" | tail -n 1)
|
||||
[ -n "$candidate_closure" ] || { echo "missing candidate closure_path from in-system build output" >&2; exit 1; }
|
||||
[ "$candidate_closure" != "$closure_path" ] || {
|
||||
echo "candidate closure unexpectedly matches current closure" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
ssh_guest "/usr/local/bin/fruix system reconfigure /root/candidate.scm --system $system_name" > "$reconfigure_out"
|
||||
reconfigure_closure=$(sed -n 's/^reconfigure_closure=//p' "$reconfigure_out" | tail -n 1)
|
||||
reconfigure_current_generation=$(sed -n 's/^current_generation=//p' "$reconfigure_out" | tail -n 1)
|
||||
reconfigure_current_closure=$(sed -n 's/^current_closure=//p' "$reconfigure_out" | tail -n 1)
|
||||
reconfigure_rollback_generation=$(sed -n 's/^rollback_generation=//p' "$reconfigure_out" | tail -n 1)
|
||||
reconfigure_rollback_closure=$(sed -n 's/^rollback_closure=//p' "$reconfigure_out" | tail -n 1)
|
||||
[ "$reconfigure_closure" = "$candidate_closure" ] || { echo "reconfigure closure mismatch" >&2; exit 1; }
|
||||
[ "$reconfigure_current_generation" = 2 ] || { echo "unexpected current generation after reconfigure: $reconfigure_current_generation" >&2; exit 1; }
|
||||
[ "$reconfigure_current_closure" = "$candidate_closure" ] || { echo "unexpected current closure after reconfigure" >&2; exit 1; }
|
||||
[ "$reconfigure_rollback_generation" = 1 ] || { echo "unexpected rollback generation after reconfigure: $reconfigure_rollback_generation" >&2; exit 1; }
|
||||
[ "$reconfigure_rollback_closure" = "$closure_path" ] || { echo "unexpected rollback closure after reconfigure" >&2; exit 1; }
|
||||
ssh_guest '/usr/local/bin/fruix system status' > "$post_reconfigure_status"
|
||||
|
||||
reboot_guest
|
||||
candidate_hostname=$(ssh_guest 'hostname')
|
||||
candidate_run_current=$(ssh_guest 'readlink /run/current-system')
|
||||
ssh_guest '/usr/local/bin/fruix system status' > "$post_boot_candidate_status"
|
||||
[ "$candidate_hostname" = "$candidate_host_name" ] || { echo "unexpected host name after candidate boot: $candidate_hostname" >&2; exit 1; }
|
||||
[ "$candidate_run_current" = "$candidate_closure" ] || { echo "unexpected current closure after candidate boot: $candidate_run_current" >&2; exit 1; }
|
||||
|
||||
ssh_guest '/usr/local/bin/fruix system rollback' > "$rollback_out"
|
||||
rollback_current_generation=$(sed -n 's/^current_generation=//p' "$rollback_out" | tail -n 1)
|
||||
rollback_current_closure=$(sed -n 's/^current_closure=//p' "$rollback_out" | tail -n 1)
|
||||
rollback_rollback_generation=$(sed -n 's/^rollback_generation=//p' "$rollback_out" | tail -n 1)
|
||||
rollback_rollback_closure=$(sed -n 's/^rollback_closure=//p' "$rollback_out" | tail -n 1)
|
||||
[ "$rollback_current_generation" = 1 ] || { echo "unexpected current generation after rollback: $rollback_current_generation" >&2; exit 1; }
|
||||
[ "$rollback_current_closure" = "$closure_path" ] || { echo "unexpected current closure after rollback" >&2; exit 1; }
|
||||
[ "$rollback_rollback_generation" = 2 ] || { echo "unexpected rollback generation after rollback: $rollback_rollback_generation" >&2; exit 1; }
|
||||
[ "$rollback_rollback_closure" = "$candidate_closure" ] || { echo "unexpected rollback closure after rollback" >&2; exit 1; }
|
||||
|
||||
reboot_guest
|
||||
rollback_hostname=$(ssh_guest 'hostname')
|
||||
rollback_run_current=$(ssh_guest 'readlink /run/current-system')
|
||||
ssh_guest '/usr/local/bin/fruix system status' > "$post_boot_rollback_status"
|
||||
[ "$rollback_hostname" = "$current_host_name" ] || { echo "unexpected host name after rollback boot: $rollback_hostname" >&2; exit 1; }
|
||||
[ "$rollback_run_current" = "$closure_path" ] || { echo "unexpected current closure after rollback boot: $rollback_run_current" >&2; exit 1; }
|
||||
|
||||
cat > "$metadata_file" <<EOF
|
||||
workdir=$workdir
|
||||
inner_metadata=$inner_metadata
|
||||
phase8_metadata=$phase8_metadata
|
||||
closure_path=$closure_path
|
||||
closure_base=$closure_base
|
||||
vm_id=$vm_id
|
||||
vdi_id=$vdi_id
|
||||
guest_ip=$guest_ip
|
||||
root_size=$root_size
|
||||
result_store=$result_store
|
||||
current_host_name=$current_host_name
|
||||
candidate_host_name=$candidate_host_name
|
||||
current_build_out=$current_build_out
|
||||
current_built_closure=$current_built_closure
|
||||
candidate_build_out=$candidate_build_out
|
||||
candidate_closure=$candidate_closure
|
||||
reconfigure_out=$reconfigure_out
|
||||
reconfigure_closure=$reconfigure_closure
|
||||
reconfigure_current_generation=$reconfigure_current_generation
|
||||
reconfigure_current_closure=$reconfigure_current_closure
|
||||
reconfigure_rollback_generation=$reconfigure_rollback_generation
|
||||
reconfigure_rollback_closure=$reconfigure_rollback_closure
|
||||
candidate_hostname=$candidate_hostname
|
||||
candidate_run_current=$candidate_run_current
|
||||
rollback_out=$rollback_out
|
||||
rollback_current_generation=$rollback_current_generation
|
||||
rollback_current_closure=$rollback_current_closure
|
||||
rollback_rollback_generation=$rollback_rollback_generation
|
||||
rollback_rollback_closure=$rollback_rollback_closure
|
||||
rollback_hostname=$rollback_hostname
|
||||
rollback_run_current=$rollback_run_current
|
||||
boot_backend=xcp-ng-xo-cli
|
||||
init_mode=shepherd-pid1
|
||||
installed_node_build_reconfigure=ok
|
||||
EOF
|
||||
|
||||
if [ -n "$metadata_target" ]; then
|
||||
mkdir -p "$(dirname "$metadata_target")"
|
||||
cp "$metadata_file" "$metadata_target"
|
||||
fi
|
||||
|
||||
printf 'PASS postphase20-installed-node-build-reconfigure-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"
|
||||
Reference in New Issue
Block a user