Recover installer TUI runtime and self-test flow
This commit is contained in:
@@ -7,6 +7,10 @@ legacy_guile_bin=/tmp/guile-freebsd-validate-install/bin/guile
|
||||
legacy_guile_extra_prefix=/tmp/guile-gnutls-freebsd-validate-install
|
||||
legacy_shepherd_prefix=/tmp/shepherd-freebsd-validate-install
|
||||
legacy_guix_source_dir=$HOME/repos/guix
|
||||
fruix_channel_url=${FRUIX_CHANNEL_URL:-https://git.teralink.net/self/fruix.git}
|
||||
script=$project_root/scripts/fruix.scm
|
||||
modules_dir=$project_root/modules
|
||||
|
||||
if [ -x "$builder_root/guile/bin/guile" ]; then
|
||||
default_guile_bin=$builder_root/guile/bin/guile
|
||||
else
|
||||
@@ -27,13 +31,23 @@ if [ -d "$builder_root/src/guix/guix" ]; then
|
||||
else
|
||||
default_guix_source_dir=$legacy_guix_source_dir
|
||||
fi
|
||||
|
||||
guix_source_dir=${GUIX_SOURCE_DIR:-$default_guix_source_dir}
|
||||
guile_bin=${GUILE_BIN:-$default_guile_bin}
|
||||
guile_extra_prefix=${GUILE_EXTRA_PREFIX:-$default_guile_extra_prefix}
|
||||
shepherd_prefix=${SHEPHERD_PREFIX:-$default_shepherd_prefix}
|
||||
fruix_channel_url=${FRUIX_CHANNEL_URL:-https://git.teralink.net/self/fruix.git}
|
||||
script=$project_root/scripts/fruix.scm
|
||||
modules_dir=$project_root/modules
|
||||
|
||||
discover_guile_newt_store()
|
||||
{
|
||||
if [ -n "${FRUIX_GUILE_NEWT_STORE:-}" ] && [ -d "$FRUIX_GUILE_NEWT_STORE" ]; then
|
||||
printf '%s\n' "$FRUIX_GUILE_NEWT_STORE"
|
||||
return 0
|
||||
fi
|
||||
for path in /frx/store/*-fruix-guile-newt-*; do
|
||||
[ -d "$path" ] || continue
|
||||
printf '%s\n' "$path"
|
||||
done | sort | tail -n 1
|
||||
}
|
||||
|
||||
if [ ! -x "$guile_bin" ]; then
|
||||
echo "Guile binary is not executable: $guile_bin" >&2
|
||||
@@ -49,21 +63,71 @@ fi
|
||||
|
||||
guile_prefix=$(CDPATH= cd -- "$(dirname "$guile_bin")/.." && pwd)
|
||||
guile_lib_dir=$guile_prefix/lib
|
||||
guile_version=$(LD_LIBRARY_PATH="$guile_lib_dir${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" "$guile_bin" -c '(display (effective-version))')
|
||||
guile_newt_store=$(discover_guile_newt_store || true)
|
||||
|
||||
guile_load_path="$modules_dir:$guix_source_dir"
|
||||
if [ -d "$shepherd_prefix/share/guile/site/$guile_version" ]; then
|
||||
guile_load_path="$guile_load_path:$shepherd_prefix/share/guile/site/$guile_version"
|
||||
fi
|
||||
if [ -d "$guile_extra_prefix/share/guile/site/$guile_version" ]; then
|
||||
guile_load_path="$guile_load_path:$guile_extra_prefix/share/guile/site/$guile_version"
|
||||
fi
|
||||
if [ -n "$guile_newt_store" ] && [ -d "$guile_newt_store/share/guile/site/$guile_version" ]; then
|
||||
guile_load_path="$guile_load_path:$guile_newt_store/share/guile/site/$guile_version"
|
||||
fi
|
||||
if [ -n "${GUILE_LOAD_PATH:-}" ]; then
|
||||
guile_load_path="$modules_dir:$guix_source_dir:$GUILE_LOAD_PATH"
|
||||
else
|
||||
guile_load_path="$modules_dir:$guix_source_dir"
|
||||
guile_load_path="$guile_load_path:$GUILE_LOAD_PATH"
|
||||
fi
|
||||
|
||||
guile_load_compiled_path=
|
||||
if [ -d "$shepherd_prefix/lib/guile/$guile_version/site-ccache" ]; then
|
||||
guile_load_compiled_path="$shepherd_prefix/lib/guile/$guile_version/site-ccache"
|
||||
fi
|
||||
if [ -d "$guile_extra_prefix/lib/guile/$guile_version/site-ccache" ]; then
|
||||
guile_load_compiled_path="${guile_load_compiled_path:+$guile_load_compiled_path:}$guile_extra_prefix/lib/guile/$guile_version/site-ccache"
|
||||
fi
|
||||
if [ -n "${GUILE_LOAD_COMPILED_PATH:-}" ]; then
|
||||
guile_load_compiled_path="${guile_load_compiled_path:+$guile_load_compiled_path:}$GUILE_LOAD_COMPILED_PATH"
|
||||
fi
|
||||
|
||||
guile_extensions_path=
|
||||
if [ -d "$guile_extra_prefix/lib/guile/$guile_version/extensions" ]; then
|
||||
guile_extensions_path="$guile_extra_prefix/lib/guile/$guile_version/extensions"
|
||||
fi
|
||||
if [ -n "$guile_newt_store" ] && [ -d "$guile_newt_store/lib/guile/$guile_version/extensions" ]; then
|
||||
guile_extensions_path="${guile_extensions_path:+$guile_extensions_path:}$guile_newt_store/lib/guile/$guile_version/extensions"
|
||||
fi
|
||||
if [ -n "${GUILE_EXTENSIONS_PATH:-}" ]; then
|
||||
guile_extensions_path="${guile_extensions_path:+$guile_extensions_path:}$GUILE_EXTENSIONS_PATH"
|
||||
fi
|
||||
|
||||
ld_library_path="$guile_extra_prefix/lib:$guile_lib_dir:/usr/local/lib"
|
||||
ltdl_library_path="$ld_library_path"
|
||||
if [ -n "$guile_newt_store" ] && [ -d "$guile_newt_store/lib" ]; then
|
||||
ld_library_path="$guile_newt_store/lib:$ld_library_path"
|
||||
ltdl_library_path="$guile_newt_store/lib:$ltdl_library_path"
|
||||
fi
|
||||
if [ -n "${LD_LIBRARY_PATH:-}" ]; then
|
||||
ld_library_path="$ld_library_path:$LD_LIBRARY_PATH"
|
||||
fi
|
||||
if [ -n "${LTDL_LIBRARY_PATH:-}" ]; then
|
||||
ltdl_library_path="$ltdl_library_path:$LTDL_LIBRARY_PATH"
|
||||
fi
|
||||
|
||||
exec env \
|
||||
GUILE_AUTO_COMPILE=0 \
|
||||
GUILE_LOAD_PATH="$guile_load_path" \
|
||||
LD_LIBRARY_PATH="$guile_lib_dir${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" \
|
||||
GUILE_LOAD_COMPILED_PATH="$guile_load_compiled_path" \
|
||||
GUILE_EXTENSIONS_PATH="$guile_extensions_path" \
|
||||
LD_LIBRARY_PATH="$ld_library_path" \
|
||||
LTDL_LIBRARY_PATH="$ltdl_library_path" \
|
||||
GUILE_PREFIX="$guile_prefix" \
|
||||
GUILE_EXTRA_PREFIX="$guile_extra_prefix" \
|
||||
GUILE_NEWT_PREFIX="$guile_newt_store" \
|
||||
SHEPHERD_PREFIX="$shepherd_prefix" \
|
||||
GUIX_SOURCE_DIR="$guix_source_dir" \
|
||||
FRUIX_GUILE_NEWT_STORE="$guile_newt_store" \
|
||||
FRUIX_PROJECT_ROOT="$project_root" \
|
||||
FRUIX_CHANNEL_DIR="$project_root" \
|
||||
FRUIX_CHANNEL_URL="$fruix_channel_url" \
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
What we lost
|
||||
|
||||
Everything below was local-only in fruix and is now gone from the repo checkout.
|
||||
|
||||
### 1. Newt runtime integration on real FreeBSD
|
||||
|
||||
Lost code/work around:
|
||||
- guile-newt runtime integration into Fruix
|
||||
- auto-discovery of prepared guile-newt from bin/fruix
|
||||
- threading Newt runtime into installer artifacts
|
||||
- installed wrapper env support for Newt
|
||||
- LTDL_LIBRARY_PATH handling
|
||||
- installer-only shared-lib exposure under /usr/local/lib
|
||||
|
||||
### 2. Installer frontend self-test and launcher split
|
||||
|
||||
Lost:
|
||||
- run-newt-self-test
|
||||
- --self-test CLI support for installer-tui
|
||||
- headless tmux-based TUI smoke harness
|
||||
- installer media launcher split into:
|
||||
- dispatcher
|
||||
- backend apply engine
|
||||
- rc.d frontend-selection knobs
|
||||
- headless installer-media self-test harness
|
||||
- XCP-ng installer-media self-test harness
|
||||
|
||||
### 3. Real XCP-ng validation of the booted installer frontend
|
||||
|
||||
Lost from repo:
|
||||
- the actual harness/scripts/docs for the successful XCP-ng self-test run
|
||||
- all code fixes uncovered by that run:
|
||||
- termcap exposure
|
||||
- metadata cleaning fix
|
||||
- Newt media runtime fixes
|
||||
- frontend dispatch behavior
|
||||
|
||||
### 4. Installed system console/default tty work
|
||||
|
||||
Lost:
|
||||
- declarative console-configuration model
|
||||
- sane default dual console policy
|
||||
- default gettys on:
|
||||
- ttyv0..ttyv7
|
||||
- ttyu0
|
||||
- xc0
|
||||
- freebsd-userland additions needed for real login/getty behavior
|
||||
- getty
|
||||
- login
|
||||
- passwd
|
||||
- su
|
||||
- who
|
||||
- last
|
||||
- nologin
|
||||
- /etc/gettytab exposure into installed rootfs
|
||||
- QEMU and XCP-ng validation scripts/reports for console defaults
|
||||
|
||||
### 5. The package CLI and dev-tool package work
|
||||
|
||||
Lost:
|
||||
- fruix package list/search/show/build
|
||||
- package lookup helpers
|
||||
- added package defs for:
|
||||
- freebsd-ripgrep
|
||||
- freebsd-tmux
|
||||
- freebsd-nodejs
|
||||
- freebsd-npm
|
||||
- freebsd-neovim
|
||||
|
||||
This part was not committed yet.
|
||||
@@ -0,0 +1,189 @@
|
||||
Yes — there are useful recovery artifacts, especially in /tmp and /frx/store.
|
||||
|
||||
Best stuff I found
|
||||
|
||||
### 1. Generated shell scripts in /tmp
|
||||
|
||||
These are very helpful because they capture the rendered output of lost Scheme code.
|
||||
|
||||
Especially:
|
||||
|
||||
- /tmp/fruix-installer-run.sh
|
||||
- /tmp/fruix-installer-apply.sh
|
||||
- /tmp/fruix-installer-rc.sh
|
||||
- /tmp/fruix-installed-fruix.sh
|
||||
|
||||
Those are gold for reconstructing:
|
||||
|
||||
- installer launcher/dispatcher behavior
|
||||
- self-test flow
|
||||
- frontend/apply split
|
||||
- installed wrapper behavior
|
||||
- Newt-related environment wiring
|
||||
|
||||
Example: /tmp/fruix-installed-fruix.sh still clearly contains:
|
||||
- build-base
|
||||
- deploy
|
||||
- installer-tui
|
||||
- GUILE_NEWT_PREFIX
|
||||
- FRUIX_GUILE_NEWT_STORE
|
||||
- LTDL_LIBRARY_PATH
|
||||
|
||||
So a lot of the lost render.scm work is still recoverable from there.
|
||||
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
### 2. Validation workdirs in /tmp
|
||||
|
||||
There are lots of preserved run directories.
|
||||
|
||||
Most valuable:
|
||||
|
||||
#### Installer media / Newt / XCP-ng
|
||||
|
||||
- /tmp/current-installer-media-self-test-xcpng-pass3
|
||||
- /tmp/current-installer-media-self-test-xcpng-debug*
|
||||
- /tmp/current-installer-media-self-test-xcpng-fix*
|
||||
|
||||
These contain:
|
||||
- metadata
|
||||
- debug logs
|
||||
- generated declarations
|
||||
- installer outputs
|
||||
|
||||
Key file:
|
||||
- /tmp/current-installer-media-self-test-xcpng-pass3/installer-media-self-test-xcpng-metadata.txt
|
||||
|
||||
That preserves the successful real validation result.
|
||||
|
||||
#### Installed console defaults
|
||||
|
||||
- /tmp/current-installed-console-defaults-qemu3
|
||||
- /tmp/current-installed-console-defaults-xcpng3
|
||||
|
||||
These contain:
|
||||
- generated declarations
|
||||
- metadata proving the getty/default-console behavior
|
||||
|
||||
Key file:
|
||||
- /tmp/current-installed-console-defaults-xcpng3/installed-console-defaults-xcpng-metadata.txt
|
||||
|
||||
That preserves the successful real XCP-ng console-default validation.
|
||||
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
### 3. Package build outputs are still in /frx/store
|
||||
|
||||
The package work is not in git anymore, but the built package outputs still exist:
|
||||
|
||||
- /frx/store/0d75ed1b2220ced7766a72ff72f0908d8683d2e6-freebsd-ripgrep-15.1.0_4
|
||||
- /frx/store/4e91ae1c446a61f5056165c73db0a0018378dbe9-freebsd-tmux-3.6a
|
||||
- /frx/store/9484fd141436bc6e0d6fa19a7a14a360ece3be42-freebsd-nodejs-24.14.0_2
|
||||
- /frx/store/a445350b103e45a6841045bb190e50063edfe6a8-freebsd-npm-11.11.0
|
||||
- /frx/store/21da570210730ef32025c4010eca138a37b53dc6-freebsd-neovim-0.12.0
|
||||
|
||||
And importantly, their manifests are still there:
|
||||
|
||||
- .../.fruix-package
|
||||
|
||||
Those manifests preserve enough to reconstruct package definitions pretty well:
|
||||
- package name
|
||||
- version
|
||||
- build system
|
||||
- input store paths
|
||||
- install-plan signatures
|
||||
|
||||
So the package work is not fully lost.
|
||||
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
### 4. Relevant system closures are still in /frx/store
|
||||
|
||||
Useful recovery closures include:
|
||||
|
||||
#### Console-default system closures
|
||||
|
||||
- /frx/store/8f615a0413ec2ad8596055e18b69795e9d37a2f3-fruix-system-fruix-console-defaults
|
||||
- plus older variants
|
||||
|
||||
These preserve:
|
||||
- /etc/ttys
|
||||
- /boot/loader.conf
|
||||
- generated installed Fruix wrapper
|
||||
- actual realized output of the lost console/default logic
|
||||
|
||||
#### Installer / Newt closures and ISOs
|
||||
|
||||
- /frx/store/1616e555f705ae2f6be8a7c671d382afa5346535-fruix-guile-newt-0.0.3
|
||||
- various fruix-system-fruix-installer-self-test*
|
||||
- various fruix-installer-iso-fruix-installer-self-test-installer
|
||||
|
||||
Those preserve the actual built results of the lost integration work.
|
||||
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
Less useful, but still maybe helpful
|
||||
|
||||
### /var/tmp
|
||||
|
||||
I only found one notable thing:
|
||||
|
||||
- /var/tmp/fruix-freebsd-native-build-f2b94d7bfd1feb56a1c597f15a3a2d527653d5571f7a9dc50c47f94cf9758db8
|
||||
|
||||
This looks like native-build staging/log output.
|
||||
Useful for native-base archaeology, but not the main recovery source for the lost installer/package work.
|
||||
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
What I did not find
|
||||
|
||||
I do not currently see:
|
||||
- another full up-to-date checkout
|
||||
- another git repo with the lost commits
|
||||
- an obvious source backup of the lost modules/... files
|
||||
- hidden extra git objects preserving the lost local commits
|
||||
|
||||
So this is not a simple “recover the repo” situation.
|
||||
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
Best recovery sources now
|
||||
|
||||
If we want to reconstruct efficiently, I’d prioritize:
|
||||
|
||||
### Source reconstruction from /tmp
|
||||
|
||||
- /tmp/fruix-installed-fruix.sh
|
||||
- /tmp/fruix-installer-run.sh
|
||||
- /tmp/fruix-installer-apply.sh
|
||||
- /tmp/fruix-installer-rc.sh
|
||||
|
||||
### Behavioral truth from /frx/store
|
||||
|
||||
- console-default system closure(s)
|
||||
- installer self-test closure(s)
|
||||
- package outputs + .fruix-package
|
||||
|
||||
### Validation truth from /tmp/current-*
|
||||
|
||||
- current-installer-media-self-test-xcpng-pass3
|
||||
- current-installed-console-defaults-qemu3
|
||||
- current-installed-console-defaults-xcpng3
|
||||
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
My recommendation
|
||||
|
||||
Yes, these are worth preserving immediately before we do anything else.
|
||||
|
||||
I’d suggest we first copy/tar:
|
||||
- the key /tmp workdirs and generated scripts
|
||||
- the relevant /frx/store paths list
|
||||
- maybe the one /var/tmp/fruix-freebsd-native-build-* dir
|
||||
|
||||
That would give us a solid recovery bundle.
|
||||
|
||||
If you want, I can do exactly that next:
|
||||
1. collect the useful artifacts into a rescue directory
|
||||
2. write an inventory file
|
||||
3. then start reconstructing the lost code from them.
|
||||
@@ -39,4 +39,5 @@
|
||||
newt-required-bindings
|
||||
missing-newt-bindings
|
||||
newt-available?
|
||||
run-newt-self-test
|
||||
run-newt-installer))
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#:export (newt-required-bindings
|
||||
missing-newt-bindings
|
||||
newt-available?
|
||||
run-newt-self-test
|
||||
run-newt-installer))
|
||||
|
||||
(define newt-required-bindings
|
||||
@@ -38,38 +39,69 @@
|
||||
(error "missing required Newt binding" name))
|
||||
(apply proc args)))
|
||||
|
||||
(define* (run-newt-installer state #:key (steps %default-installer-steps))
|
||||
(let ((missing (missing-newt-bindings)))
|
||||
(define (newt-result base-fields mode available? result error missing)
|
||||
(append `((ui . newt)
|
||||
(mode . ,mode)
|
||||
(available? . ,available?)
|
||||
(result . ,result)
|
||||
(error . ,error)
|
||||
(missing-bindings . ,missing))
|
||||
base-fields))
|
||||
|
||||
(define* (run-newt-self-test #:key (steps %default-installer-steps))
|
||||
(let* ((missing (missing-newt-bindings))
|
||||
(base-fields `((step-count . ,(length steps))
|
||||
(step-ids . ,(map installer-step-id steps)))))
|
||||
(if (pair? missing)
|
||||
`((ui . newt)
|
||||
(available? . #f)
|
||||
(missing-bindings . ,missing)
|
||||
(result . unavailable)
|
||||
(state . ,(installer-state-spec state))
|
||||
(step-count . ,(length steps))
|
||||
(step-ids . ,(map installer-step-id steps)))
|
||||
(dynamic-wind
|
||||
(newt-result base-fields 'self-test #f 'unavailable #f missing)
|
||||
(catch #t
|
||||
(lambda ()
|
||||
(call-newt 'newt-init)
|
||||
(call-newt 'clear-screen))
|
||||
(dynamic-wind
|
||||
(lambda ()
|
||||
(call-newt 'newt-init)
|
||||
(call-newt 'clear-screen))
|
||||
(lambda ()
|
||||
(newt-result base-fields 'self-test #t 'self-test-ok #f '()))
|
||||
(lambda ()
|
||||
(false-if-exception
|
||||
(call-newt 'newt-finish)))))
|
||||
(lambda args
|
||||
(newt-result base-fields 'self-test #t 'error args '()))))))
|
||||
|
||||
(define* (run-newt-installer state #:key (steps %default-installer-steps))
|
||||
(let* ((missing (missing-newt-bindings))
|
||||
(base-fields `((state . ,(installer-state-spec state))
|
||||
(step-count . ,(length steps))
|
||||
(step-ids . ,(map installer-step-id steps)))))
|
||||
(if (pair? missing)
|
||||
(newt-result base-fields 'interactive #f 'unavailable #f missing)
|
||||
(catch #t
|
||||
(lambda ()
|
||||
(call-newt 'message-window
|
||||
"Fruix installer"
|
||||
"Continue"
|
||||
(installer-state-summary state))
|
||||
(let ((result (call-newt 'choice-window
|
||||
"Fruix installer review"
|
||||
"Proceed"
|
||||
"Abort"
|
||||
(installer-final-summary-text state))))
|
||||
`((ui . newt)
|
||||
(available? . #t)
|
||||
(result . ,(match result
|
||||
(1 'proceed)
|
||||
(2 'abort)
|
||||
(_ 'unknown)))
|
||||
(state . ,(installer-state-spec state))
|
||||
(step-count . ,(length steps))
|
||||
(step-ids . ,(map installer-step-id steps)))))
|
||||
(lambda ()
|
||||
(call-newt 'newt-finish))))))
|
||||
(dynamic-wind
|
||||
(lambda ()
|
||||
(call-newt 'newt-init)
|
||||
(call-newt 'clear-screen))
|
||||
(lambda ()
|
||||
(call-newt 'message-window
|
||||
"Fruix installer"
|
||||
"Continue"
|
||||
(installer-state-summary state))
|
||||
(let ((result (call-newt 'choice-window
|
||||
"Fruix installer review"
|
||||
"Proceed"
|
||||
"Abort"
|
||||
(installer-final-summary-text state))))
|
||||
(newt-result base-fields
|
||||
'interactive
|
||||
#t
|
||||
(match result
|
||||
(1 'proceed)
|
||||
(2 'abort)
|
||||
(_ 'unknown))
|
||||
#f
|
||||
'())))
|
||||
(lambda ()
|
||||
(false-if-exception
|
||||
(call-newt 'newt-finish)))))
|
||||
(lambda args
|
||||
(newt-result base-fields 'interactive #t 'error args '()))))))
|
||||
|
||||
@@ -68,6 +68,18 @@
|
||||
'()
|
||||
table))
|
||||
|
||||
(define (discover-fruix-runtime-store store-dir name-fragment)
|
||||
(and store-dir
|
||||
(file-exists? store-dir)
|
||||
(let ((matches
|
||||
(sort (filter (lambda (entry)
|
||||
(and (not (member entry '("." "..")))
|
||||
(string-contains entry name-fragment)
|
||||
(file-is-directory? (string-append store-dir "/" entry))))
|
||||
(directory-entries store-dir))
|
||||
string<?)))
|
||||
(and (pair? matches)
|
||||
(string-append store-dir "/" (car (reverse matches)))))))
|
||||
|
||||
(define* (materialize-operating-system os
|
||||
#:key
|
||||
@@ -78,6 +90,7 @@
|
||||
(guile-store-path #f)
|
||||
(guile-extra-store-path #f)
|
||||
(shepherd-store-path #f)
|
||||
(guile-newt-store-path #f)
|
||||
(declaration-source #f)
|
||||
(declaration-origin #f)
|
||||
(declaration-system-symbol #f))
|
||||
@@ -132,6 +145,8 @@
|
||||
guile-extra-runtime-files))))
|
||||
(shepherd-store (or shepherd-store-path
|
||||
(materialize-prefix shepherd-prefix "fruix-shepherd-runtime" "1.0.9" store-dir)))
|
||||
(guile-newt-store (or guile-newt-store-path
|
||||
(discover-fruix-runtime-store store-dir "-fruix-guile-newt-")))
|
||||
(host-base-stores
|
||||
(delete-duplicates
|
||||
(map cdr
|
||||
@@ -144,7 +159,8 @@
|
||||
(filter (lambda (entry)
|
||||
(freebsd-native-build-package? (car entry)))
|
||||
store-classification))))
|
||||
(fruix-runtime-stores (list guile-store guile-extra-store shepherd-store))
|
||||
(fruix-runtime-stores (filter identity
|
||||
(list guile-store guile-extra-store shepherd-store guile-newt-store)))
|
||||
(source-materializations
|
||||
(delete-duplicates (hash-table-values source-cache)))
|
||||
(materialized-source-stores
|
||||
@@ -224,7 +240,8 @@
|
||||
(generated-files (append (operating-system-generated-files os
|
||||
#:guile-store guile-store
|
||||
#:guile-extra-store guile-extra-store
|
||||
#:shepherd-store shepherd-store)
|
||||
#:shepherd-store shepherd-store
|
||||
#:guile-newt-store guile-newt-store)
|
||||
metadata-files
|
||||
`(("usr/local/etc/rc.d/fruix-activate"
|
||||
. ,(render-activation-rc-script))
|
||||
@@ -315,6 +332,7 @@
|
||||
(guile-store . ,guile-store)
|
||||
(guile-extra-store . ,guile-extra-store)
|
||||
(shepherd-store . ,shepherd-store)
|
||||
(guile-newt-store . ,guile-newt-store)
|
||||
(base-package-stores . ,base-package-stores)
|
||||
(development-package-stores . ,development-package-stores)
|
||||
(build-package-stores . ,build-package-stores)
|
||||
@@ -425,7 +443,7 @@
|
||||
(mkdir-p rootfs)
|
||||
(for-each (lambda (dir)
|
||||
(mkdir-p (string-append rootfs dir)))
|
||||
'("/run" "/boot" "/etc" "/etc/ssh" "/usr" "/usr/share" "/usr/local"
|
||||
'("/run" "/boot" "/etc" "/etc/ssh" "/usr" "/usr/share" "/usr/share/misc" "/usr/local"
|
||||
"/usr/local/bin" "/usr/local/etc" "/usr/local/etc/rc.d" "/var"
|
||||
"/var/cron" "/var/db" "/var/lib" "/var/lib/fruix"
|
||||
"/var/log" "/var/run" "/tmp" "/dev" "/root" "/home"))
|
||||
@@ -456,6 +474,17 @@
|
||||
(copy-regular-file (string-append closure-path "/etc/" path)
|
||||
(string-append rootfs "/etc/" path)))
|
||||
'("passwd" "master.passwd" "group" "login.conf"))
|
||||
(when (file-exists? (string-append closure-path "/profile/usr/share/misc/termcap"))
|
||||
(symlink-force "/run/current-system/profile/usr/share/misc/termcap"
|
||||
(string-append rootfs "/usr/share/misc/termcap"))
|
||||
(symlink-force "/run/current-system/profile/etc/termcap"
|
||||
(string-append rootfs "/etc/termcap")))
|
||||
(when (file-exists? (string-append closure-path "/profile/usr/share/misc/termcap.db"))
|
||||
(symlink-force "/run/current-system/profile/usr/share/misc/termcap.db"
|
||||
(string-append rootfs "/usr/share/misc/termcap.db")))
|
||||
(when (file-exists? (string-append closure-path "/profile/etc/termcap.small"))
|
||||
(symlink-force "/run/current-system/profile/etc/termcap.small"
|
||||
(string-append rootfs "/etc/termcap.small")))
|
||||
(when (file-exists? (string-append closure-path "/etc/ssh/sshd_config"))
|
||||
(symlink-force "/run/current-system/etc/ssh/sshd_config"
|
||||
(string-append rootfs "/etc/ssh/sshd_config")))
|
||||
@@ -729,8 +758,8 @@
|
||||
|
||||
(define image-builder-version "3")
|
||||
(define install-builder-version "3")
|
||||
(define installer-image-builder-version "3")
|
||||
(define installer-iso-builder-version "4")
|
||||
(define installer-image-builder-version "4")
|
||||
(define installer-iso-builder-version "5")
|
||||
|
||||
(define* (operating-system-install-storage-layout os
|
||||
#:key
|
||||
@@ -776,7 +805,7 @@
|
||||
(object->string realized-storage-layout))
|
||||
(chmod (string-append install-root "/realized-storage-layout.scm") #o644))))
|
||||
|
||||
(define (render-installer-run-script store-dir plan-directory)
|
||||
(define (render-installer-apply-script store-dir plan-directory)
|
||||
(let ((target-rootfs (string-append plan-directory "/target-rootfs"))
|
||||
(store-items-file (string-append plan-directory "/store-items"))
|
||||
(install-metadata-source (string-append plan-directory "/install.scm"))
|
||||
@@ -855,6 +884,198 @@
|
||||
"echo 'fruix-installer:done'\n"
|
||||
"write_state done\n")))
|
||||
|
||||
(define (render-installer-run-script store-dir plan-directory)
|
||||
(let ((state-file (string-append plan-directory "/state"))
|
||||
(dispatcher-log-file "/var/log/fruix-installer-dispatch.log")
|
||||
(apply-script "/usr/local/libexec/fruix-installer-apply")
|
||||
(tui-transcript (string-append plan-directory "/installer-tui.typescript"))
|
||||
(tui-metadata-file (string-append plan-directory "/installer-tui-metadata.txt")))
|
||||
(string-append
|
||||
"#!/bin/sh\n"
|
||||
"set -eu\n"
|
||||
"PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin\n"
|
||||
"umask 022\n"
|
||||
"state_file='" state-file "'\n"
|
||||
"dispatcher_log_file='" dispatcher-log-file "'\n"
|
||||
"apply_script='" apply-script "'\n"
|
||||
"tui_transcript='" tui-transcript "'\n"
|
||||
"tui_metadata_file='" tui-metadata-file "'\n"
|
||||
"frontend=${FRUIX_INSTALLER_FRONTEND:-auto}\n"
|
||||
"installer_term=${FRUIX_INSTALLER_TERM:-xterm}\n"
|
||||
"write_state()\n"
|
||||
"{\n"
|
||||
" mkdir -p \"$(dirname \"$state_file\")\"\n"
|
||||
" printf '%s\\n' \"$1\" >\"$state_file\"\n"
|
||||
"}\n"
|
||||
"log()\n"
|
||||
"{\n"
|
||||
" mkdir -p \"$(dirname \"$dispatcher_log_file\")\"\n"
|
||||
" printf '%s %s\\n' \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\" \"$*\" >>\"$dispatcher_log_file\"\n"
|
||||
"}\n"
|
||||
"clean_tui_metadata()\n"
|
||||
"{\n"
|
||||
" source=$1\n"
|
||||
" destination=$2\n"
|
||||
" [ -f \"$source\" ] || return 1\n"
|
||||
" tr -d '\\15' < \"$source\" | tr -cd '\\11\\12\\40-\\176' | awk 'match($0, /[a-z_][a-z_]*=.*/){print substr($0, RSTART)}' > \"$destination\"\n"
|
||||
"}\n"
|
||||
"metadata_value()\n"
|
||||
"{\n"
|
||||
" key=$1\n"
|
||||
" file=$2\n"
|
||||
" [ -f \"$file\" ] || return 1\n"
|
||||
" sed -n \"s/^${key}=//p\" \"$file\" | tail -n 1\n"
|
||||
"}\n"
|
||||
"can_run_tui()\n"
|
||||
"{\n"
|
||||
" [ -x /usr/local/bin/fruix ] && command -v script >/dev/null 2>&1\n"
|
||||
"}\n"
|
||||
"select_tty_device()\n"
|
||||
"{\n"
|
||||
" if [ -n \"${FRUIX_INSTALLER_TTY:-}\" ] && [ -e \"$FRUIX_INSTALLER_TTY\" ]; then\n"
|
||||
" printf '%s\\n' \"$FRUIX_INSTALLER_TTY\"\n"
|
||||
" return 0\n"
|
||||
" fi\n"
|
||||
" boot_console=$(kenv console 2>/dev/null || true)\n"
|
||||
" case \"$boot_console\" in\n"
|
||||
" *vidconsole*)\n"
|
||||
" if [ -e /dev/ttyv0 ]; then\n"
|
||||
" printf '%s\\n' /dev/ttyv0\n"
|
||||
" return 0\n"
|
||||
" fi\n"
|
||||
" ;;\n"
|
||||
" esac\n"
|
||||
" return 1\n"
|
||||
"}\n"
|
||||
"run_apply()\n"
|
||||
"{\n"
|
||||
" [ -x \"$apply_script\" ] || { log \"missing apply script: $apply_script\"; write_state apply-missing; exit 1; }\n"
|
||||
" log \"running noninteractive apply\"\n"
|
||||
" exec \"$apply_script\"\n"
|
||||
"}\n"
|
||||
"run_tui_self_test()\n"
|
||||
"{\n"
|
||||
" write_state tui-self-test\n"
|
||||
" rm -f \"$tui_transcript\" \"$tui_metadata_file\"\n"
|
||||
" if ! env TERM=\"$installer_term\" script -aq \"$tui_transcript\" /usr/local/bin/fruix system installer-tui --self-test >/dev/null 2>&1; then\n"
|
||||
" clean_tui_metadata \"$tui_transcript\" \"$tui_metadata_file\" || true\n"
|
||||
" log \"tui self-test command failed\"\n"
|
||||
" write_state tui-self-test-failed\n"
|
||||
" return 1\n"
|
||||
" fi\n"
|
||||
" clean_tui_metadata \"$tui_transcript\" \"$tui_metadata_file\" || true\n"
|
||||
" newt_result=$(metadata_value newt_result \"$tui_metadata_file\" || true)\n"
|
||||
" if [ \"$newt_result\" = self-test-ok ]; then\n"
|
||||
" log \"tui self-test ok\"\n"
|
||||
" write_state tui-self-test-ok\n"
|
||||
" return 0\n"
|
||||
" fi\n"
|
||||
" log \"tui self-test unexpected result: ${newt_result:-missing}\"\n"
|
||||
" write_state tui-self-test-failed\n"
|
||||
" return 1\n"
|
||||
"}\n"
|
||||
"run_tui_session()\n"
|
||||
"{\n"
|
||||
" tty_device=$1\n"
|
||||
" write_state launching-tui\n"
|
||||
" rm -f \"$tui_transcript\" \"$tui_metadata_file\"\n"
|
||||
" if env TERM=\"$installer_term\" script -aq \"$tui_transcript\" /usr/local/bin/fruix system installer-tui < \"$tty_device\" > \"$tty_device\" 2>&1; then\n"
|
||||
" status=0\n"
|
||||
" else\n"
|
||||
" status=$?\n"
|
||||
" fi\n"
|
||||
" clean_tui_metadata \"$tui_transcript\" \"$tui_metadata_file\" || true\n"
|
||||
" newt_result=$(metadata_value newt_result \"$tui_metadata_file\" || true)\n"
|
||||
" case \"$newt_result\" in\n"
|
||||
" proceed)\n"
|
||||
" log \"tui proceed\"\n"
|
||||
" write_state tui-proceed\n"
|
||||
" return 0\n"
|
||||
" ;;\n"
|
||||
" abort)\n"
|
||||
" log \"tui abort\"\n"
|
||||
" write_state tui-abort\n"
|
||||
" return 20\n"
|
||||
" ;;\n"
|
||||
" unavailable)\n"
|
||||
" log \"tui unavailable\"\n"
|
||||
" return 30\n"
|
||||
" ;;\n"
|
||||
" '')\n"
|
||||
" log \"tui missing result status=$status\"\n"
|
||||
" return 31\n"
|
||||
" ;;\n"
|
||||
" *)\n"
|
||||
" log \"tui unexpected result: $newt_result status=$status\"\n"
|
||||
" return 31\n"
|
||||
" ;;\n"
|
||||
" esac\n"
|
||||
"}\n"
|
||||
"log \"frontend=$frontend\"\n"
|
||||
"case \"$frontend\" in\n"
|
||||
" self-test)\n"
|
||||
" if ! can_run_tui; then\n"
|
||||
" log \"self-test requested but TUI runtime is unavailable\"\n"
|
||||
" write_state tui-unavailable\n"
|
||||
" exit 1\n"
|
||||
" fi\n"
|
||||
" run_tui_self_test\n"
|
||||
" ;;\n"
|
||||
" auto|tui)\n"
|
||||
" if ! can_run_tui; then\n"
|
||||
" if [ \"$frontend\" = auto ]; then\n"
|
||||
" log \"tui runtime unavailable, falling back to noninteractive apply\"\n"
|
||||
" run_apply\n"
|
||||
" fi\n"
|
||||
" write_state tui-unavailable\n"
|
||||
" exit 1\n"
|
||||
" fi\n"
|
||||
" tty_device=$(select_tty_device || true)\n"
|
||||
" if [ -z \"$tty_device\" ]; then\n"
|
||||
" if [ \"$frontend\" = auto ]; then\n"
|
||||
" log \"no TTY device found, falling back to noninteractive apply\"\n"
|
||||
" run_apply\n"
|
||||
" fi\n"
|
||||
" write_state tui-no-tty\n"
|
||||
" exit 1\n"
|
||||
" fi\n"
|
||||
" run_tui_session \"$tty_device\"\n"
|
||||
" status=$?\n"
|
||||
" case \"$status\" in\n"
|
||||
" 0)\n"
|
||||
" run_apply\n"
|
||||
" ;;\n"
|
||||
" 20)\n"
|
||||
" exit 0\n"
|
||||
" ;;\n"
|
||||
" 30|31)\n"
|
||||
" if [ \"$frontend\" = auto ]; then\n"
|
||||
" log \"tui did not complete cleanly, falling back to noninteractive apply status=$status\"\n"
|
||||
" run_apply\n"
|
||||
" fi\n"
|
||||
" write_state tui-failed\n"
|
||||
" exit 1\n"
|
||||
" ;;\n"
|
||||
" *)\n"
|
||||
" if [ \"$frontend\" = auto ]; then\n"
|
||||
" log \"tui command failed, falling back to noninteractive apply status=$status\"\n"
|
||||
" run_apply\n"
|
||||
" fi\n"
|
||||
" write_state tui-failed\n"
|
||||
" exit \"$status\"\n"
|
||||
" ;;\n"
|
||||
" esac\n"
|
||||
" ;;\n"
|
||||
" noninteractive|apply)\n"
|
||||
" run_apply\n"
|
||||
" ;;\n"
|
||||
" *)\n"
|
||||
" log \"unknown frontend mode: $frontend\"\n"
|
||||
" write_state invalid-frontend\n"
|
||||
" exit 1\n"
|
||||
" ;;\n"
|
||||
"esac\n")))
|
||||
|
||||
(define (render-installer-rc-script plan-directory)
|
||||
(string-append
|
||||
"#!/bin/sh\n"
|
||||
@@ -865,16 +1086,17 @@
|
||||
"name=fruix_installer\n"
|
||||
"rcvar=fruix_installer_enable\n"
|
||||
": ${fruix_installer_enable:=YES}\n"
|
||||
": ${fruix_installer_frontend:=auto}\n"
|
||||
": ${fruix_installer_tty:=}\n"
|
||||
"pidfile=/var/run/fruix-installer.pid\n"
|
||||
"command=/usr/sbin/daemon\n"
|
||||
"command_args='-c -f -p /var/run/fruix-installer.pid -o /var/log/fruix-installer-bootstrap.out /usr/local/libexec/fruix-installer-run'\n"
|
||||
"start_cmd=fruix_installer_start\n"
|
||||
"stop_cmd=fruix_installer_stop\n"
|
||||
"status_cmd=fruix_installer_status\n\n"
|
||||
"fruix_installer_start()\n"
|
||||
"{\n"
|
||||
" mkdir -p '" plan-directory "' /var/run\n"
|
||||
" $command $command_args\n"
|
||||
" $command -c -f -p \"$pidfile\" -o /var/log/fruix-installer-bootstrap.out /usr/bin/env \"FRUIX_INSTALLER_FRONTEND=$fruix_installer_frontend\" \"FRUIX_INSTALLER_TTY=$fruix_installer_tty\" /usr/local/libexec/fruix-installer-run\n"
|
||||
"}\n\n"
|
||||
"fruix_installer_stop()\n"
|
||||
"{\n"
|
||||
@@ -1312,10 +1534,13 @@
|
||||
(string-append (string-join (freebsd-storage-plan-mount-targets target-storage-plan) "\n")
|
||||
"\n"))
|
||||
(write-file (string-append plan-root "/state") "pending\n")
|
||||
(write-file (string-append image-rootfs "/usr/local/libexec/fruix-installer-apply")
|
||||
(render-installer-apply-script store-dir installer-plan-directory))
|
||||
(write-file (string-append image-rootfs "/usr/local/libexec/fruix-installer-run")
|
||||
(render-installer-run-script store-dir installer-plan-directory))
|
||||
(write-file (string-append image-rootfs "/usr/local/etc/rc.d/fruix-installer")
|
||||
(render-installer-rc-script installer-plan-directory))
|
||||
(chmod (string-append image-rootfs "/usr/local/libexec/fruix-installer-apply") #o555)
|
||||
(chmod (string-append image-rootfs "/usr/local/libexec/fruix-installer-run") #o555)
|
||||
(chmod (string-append image-rootfs "/usr/local/etc/rc.d/fruix-installer") #o555)
|
||||
(mkdir-p (string-append esp-stage "/EFI/BOOT"))
|
||||
@@ -1641,10 +1866,13 @@
|
||||
(string-append (string-join (freebsd-storage-plan-mount-targets target-storage-plan) "\n")
|
||||
"\n"))
|
||||
(write-file (string-append plan-root "/state") "pending\n")
|
||||
(write-file (string-append image-rootfs "/usr/local/libexec/fruix-installer-apply")
|
||||
(render-installer-apply-script store-dir installer-plan-directory))
|
||||
(write-file (string-append image-rootfs "/usr/local/libexec/fruix-installer-run")
|
||||
(render-installer-run-script store-dir installer-plan-directory))
|
||||
(write-file (string-append image-rootfs "/usr/local/etc/rc.d/fruix-installer")
|
||||
(render-installer-rc-script installer-plan-directory))
|
||||
(chmod (string-append image-rootfs "/usr/local/libexec/fruix-installer-apply") #o555)
|
||||
(chmod (string-append image-rootfs "/usr/local/libexec/fruix-installer-run") #o555)
|
||||
(chmod (string-append image-rootfs "/usr/local/etc/rc.d/fruix-installer") #o555)
|
||||
(rewrite-installer-iso-fstab image-rootfs installer-closure-path)
|
||||
|
||||
@@ -493,8 +493,26 @@
|
||||
(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/installer.scm")
|
||||
. "share/fruix/node/modules/fruix/installer.scm")
|
||||
(,(string-append repo-root "/modules/fruix/installer/final.scm")
|
||||
. "share/fruix/node/modules/fruix/installer/final.scm")
|
||||
(,(string-append repo-root "/modules/fruix/installer/newt.scm")
|
||||
. "share/fruix/node/modules/fruix/installer/newt.scm")
|
||||
(,(string-append repo-root "/modules/fruix/installer/state.scm")
|
||||
. "share/fruix/node/modules/fruix/installer/state.scm")
|
||||
(,(string-append repo-root "/modules/fruix/installer/steps.scm")
|
||||
. "share/fruix/node/modules/fruix/installer/steps.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/storage.scm")
|
||||
. "share/fruix/node/modules/fruix/system/storage.scm")
|
||||
(,(string-append repo-root "/modules/fruix/system/storage/model.scm")
|
||||
. "share/fruix/node/modules/fruix/system/storage/model.scm")
|
||||
(,(string-append repo-root "/modules/fruix/system/storage/render.scm")
|
||||
. "share/fruix/node/modules/fruix/system/storage/render.scm")
|
||||
(,(string-append repo-root "/modules/fruix/system/storage/validate.scm")
|
||||
. "share/fruix/node/modules/fruix/system/storage/validate.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")
|
||||
@@ -509,6 +527,8 @@
|
||||
. "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/storage.scm")
|
||||
. "share/fruix/node/modules/fruix/system/freebsd/storage.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")
|
||||
@@ -518,7 +538,7 @@
|
||||
(read-source-file-string (car entry))))
|
||||
specs)))
|
||||
|
||||
(define (render-installed-system-fruix os guile-store guile-extra-store shepherd-store)
|
||||
(define (render-installed-system-fruix os guile-store guile-extra-store shepherd-store guile-newt-store)
|
||||
(string-append
|
||||
"#!/bin/sh\n"
|
||||
"set -eu\n"
|
||||
@@ -547,6 +567,7 @@
|
||||
"guile_store='" guile-store "'\n"
|
||||
"guile_extra_store='" guile-extra-store "'\n"
|
||||
"shepherd_store='" shepherd-store "'\n"
|
||||
"guile_newt_store='" (or guile-newt-store "") "'\n"
|
||||
"layout_version=2\n"
|
||||
"host_name='" (operating-system-host-name os) "'\n"
|
||||
"ready_marker='" (operating-system-ready-marker os) "'\n"
|
||||
@@ -558,6 +579,7 @@
|
||||
" fruix system build [DECLARATION [--system NAME] ...]\n"
|
||||
" fruix system build-base [--jobs COUNT] [--store DIR]\n"
|
||||
" fruix system deploy TARGET DECLARATION [--system NAME] ...\n"
|
||||
" fruix system installer-tui [DECLARATION [--system NAME] ...]\n"
|
||||
" fruix system reconfigure [DECLARATION [--system NAME] ...]\n"
|
||||
" fruix system switch /frx/store/...-fruix-system-...\n"
|
||||
" fruix system rollback\n"
|
||||
@@ -621,12 +643,23 @@
|
||||
" [ -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"
|
||||
" if [ -n \"$guile_newt_store\" ] && [ -d \"$guile_newt_store/share/guile/site/3.0\" ]; then\n"
|
||||
" guile_load_path=\"$guile_load_path:$guile_newt_store/share/guile/site/3.0\"\n"
|
||||
" fi\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"
|
||||
" if [ -n \"$guile_newt_store\" ] && [ -d \"$guile_newt_store/lib/guile/3.0/extensions\" ]; then\n"
|
||||
" guile_extensions_path=\"$guile_extensions_path:$guile_newt_store/lib/guile/3.0/extensions\"\n"
|
||||
" fi\n"
|
||||
" ld_library_path=\"$guile_extra_store/lib:$guile_store/lib:/usr/local/lib\"\n"
|
||||
" ltdl_library_path=\"$ld_library_path\"\n"
|
||||
" if [ -n \"$guile_newt_store\" ] && [ -d \"$guile_newt_store/lib\" ]; then\n"
|
||||
" ld_library_path=\"$guile_newt_store/lib:$ld_library_path\"\n"
|
||||
" ltdl_library_path=\"$guile_newt_store/lib:$ltdl_library_path\"\n"
|
||||
" fi\n"
|
||||
" env \\\n"
|
||||
" GUILE_AUTO_COMPILE=0 \\\n"
|
||||
" GUILE_SYSTEM_PATH=\"$guile_system_path\" \\\n"
|
||||
@@ -636,11 +669,14 @@
|
||||
" GUILE_SYSTEM_EXTENSIONS_PATH=\"$guile_system_extensions_path\" \\\n"
|
||||
" GUILE_EXTENSIONS_PATH=\"$guile_extensions_path\" \\\n"
|
||||
" LD_LIBRARY_PATH=\"$ld_library_path\" \\\n"
|
||||
" LTDL_LIBRARY_PATH=\"$ltdl_library_path\" \\\n"
|
||||
" GUILE_PREFIX=\"$guile_store\" \\\n"
|
||||
" GUILE_EXTRA_PREFIX=\"$guile_extra_store\" \\\n"
|
||||
" GUILE_NEWT_PREFIX=\"$guile_newt_store\" \\\n"
|
||||
" SHEPHERD_PREFIX=\"$shepherd_store\" \\\n"
|
||||
" FRUIX_GUILE_STORE=\"$guile_store\" \\\n"
|
||||
" FRUIX_GUILE_EXTRA_STORE=\"$guile_extra_store\" \\\n"
|
||||
" FRUIX_GUILE_NEWT_STORE=\"$guile_newt_store\" \\\n"
|
||||
" FRUIX_SHEPHERD_STORE=\"$shepherd_store\" \\\n"
|
||||
" GUIX_SOURCE_DIR=\"$node_guix_root\" \\\n"
|
||||
" FRUIX_PROJECT_ROOT=\"$node_root\" \\\n"
|
||||
@@ -740,6 +776,23 @@
|
||||
" printf 'build_base=ok\\n'\n"
|
||||
" cleanup_build_base\n"
|
||||
"}\n\n"
|
||||
"installer_tui()\n"
|
||||
"{\n"
|
||||
" if [ $# -eq 0 ]; then\n"
|
||||
" ensure_default_declaration\n"
|
||||
" run_node_cli system installer-tui \"$declaration_file\" --system \"$current_system_name\" --store \"$default_store_dir\"\n"
|
||||
" else\n"
|
||||
" case \"$1\" in\n"
|
||||
" --*)\n"
|
||||
" ensure_default_declaration\n"
|
||||
" run_node_cli system installer-tui \"$declaration_file\" --system \"$current_system_name\" --store \"$default_store_dir\" \"$@\"\n"
|
||||
" ;;\n"
|
||||
" *)\n"
|
||||
" run_node_cli system installer-tui \"$@\"\n"
|
||||
" ;;\n"
|
||||
" esac\n"
|
||||
" fi\n"
|
||||
"}\n\n"
|
||||
"reconfigure_system()\n"
|
||||
"{\n"
|
||||
" build_output=$(mktemp /tmp/fruix-system-reconfigure.XXXXXX)\n"
|
||||
@@ -966,6 +1019,10 @@
|
||||
" shift 2\n"
|
||||
" deploy_system \"$@\"\n"
|
||||
" ;;\n"
|
||||
" installer-tui)\n"
|
||||
" shift 2\n"
|
||||
" installer_tui \"$@\"\n"
|
||||
" ;;\n"
|
||||
" reconfigure)\n"
|
||||
" shift 2\n"
|
||||
" reconfigure_system \"$@\"\n"
|
||||
@@ -1285,7 +1342,7 @@
|
||||
"cat \"$metadata_file\"\n")))
|
||||
|
||||
|
||||
(define* (operating-system-generated-files os #:key guile-store guile-extra-store shepherd-store)
|
||||
(define* (operating-system-generated-files os #:key guile-store guile-extra-store shepherd-store guile-newt-store)
|
||||
(append
|
||||
`(("boot/loader.conf" . ,(render-loader-conf os))
|
||||
("etc/rc.conf" . ,(render-rc.conf os))
|
||||
@@ -1304,7 +1361,7 @@
|
||||
#:shepherd-store shepherd-store))
|
||||
("shepherd/init.scm" . ,(render-shepherd-config os))
|
||||
("usr/local/bin/fruix"
|
||||
. ,(render-installed-system-fruix os guile-store guile-extra-store shepherd-store)))
|
||||
. ,(render-installed-system-fruix os guile-store guile-extra-store shepherd-store guile-newt-store)))
|
||||
(bundled-fruix-node-files)
|
||||
(if (null? (operating-system-development-packages os))
|
||||
'()
|
||||
|
||||
+42
-28
@@ -39,6 +39,7 @@ System options:\n\
|
||||
--target PATH Install target for 'install' (raw image file or /dev/... device).\n\
|
||||
--install-target-device DEVICE\n\
|
||||
Target block device used by the booted 'installer' environment.\n\
|
||||
--self-test Use the Newt self-test path for 'installer-tui'.\n\
|
||||
--rootfs DIR Rootfs target for 'rootfs'.\n\
|
||||
--host HOST Remote host for 'deploy' (or use TARGET as first positional argument).\n\
|
||||
--user USER Remote SSH user for 'deploy' (default: root).\n\
|
||||
@@ -157,7 +158,8 @@ Common options:\n\
|
||||
(deploy-user "root")
|
||||
(deploy-port "22")
|
||||
(identity-file #f)
|
||||
(reboot? #f))
|
||||
(reboot? #f)
|
||||
(self-test? #f))
|
||||
(match args
|
||||
(()
|
||||
(let ((positional (reverse positional)))
|
||||
@@ -175,65 +177,68 @@ Common options:\n\
|
||||
(deploy-user . ,deploy-user)
|
||||
(deploy-port . ,deploy-port)
|
||||
(identity-file . ,identity-file)
|
||||
(reboot? . ,reboot?))))
|
||||
(reboot? . ,reboot?)
|
||||
(self-test? . ,self-test?))))
|
||||
(("--help")
|
||||
(usage 0))
|
||||
(((? (lambda (arg) (string-prefix? "--system=" arg)) arg) . tail)
|
||||
(loop tail positional (option-value arg "--system=") store-dir disk-capacity root-size target install-target-device rootfs deploy-host deploy-user deploy-port identity-file reboot?))
|
||||
(loop tail positional (option-value arg "--system=") store-dir disk-capacity root-size target install-target-device rootfs deploy-host deploy-user deploy-port identity-file reboot? self-test?))
|
||||
(("--system" value . tail)
|
||||
(loop tail positional value store-dir disk-capacity root-size target install-target-device rootfs deploy-host deploy-user deploy-port identity-file reboot?))
|
||||
(loop tail positional value store-dir disk-capacity root-size target install-target-device rootfs deploy-host deploy-user deploy-port identity-file reboot? self-test?))
|
||||
(((? (lambda (arg) (string-prefix? "--store=" arg)) arg) . tail)
|
||||
(loop tail positional system-name (option-value arg "--store=") disk-capacity root-size target install-target-device rootfs deploy-host deploy-user deploy-port identity-file reboot?))
|
||||
(loop tail positional system-name (option-value arg "--store=") disk-capacity root-size target install-target-device rootfs deploy-host deploy-user deploy-port identity-file reboot? self-test?))
|
||||
(("--store" value . tail)
|
||||
(loop tail positional system-name value disk-capacity root-size target install-target-device rootfs deploy-host deploy-user deploy-port identity-file reboot?))
|
||||
(loop tail positional system-name value disk-capacity root-size target install-target-device rootfs deploy-host deploy-user deploy-port identity-file reboot? self-test?))
|
||||
(((? (lambda (arg) (string-prefix? "--disk-capacity=" arg)) arg) . tail)
|
||||
(loop tail positional system-name store-dir (option-value arg "--disk-capacity=") root-size target install-target-device rootfs deploy-host deploy-user deploy-port identity-file reboot?))
|
||||
(loop tail positional system-name store-dir (option-value arg "--disk-capacity=") root-size target install-target-device rootfs deploy-host deploy-user deploy-port identity-file reboot? self-test?))
|
||||
(("--disk-capacity" value . tail)
|
||||
(loop tail positional system-name store-dir value root-size target install-target-device rootfs deploy-host deploy-user deploy-port identity-file reboot?))
|
||||
(loop tail positional system-name store-dir value root-size target install-target-device rootfs deploy-host deploy-user deploy-port identity-file reboot? self-test?))
|
||||
(((? (lambda (arg) (string-prefix? "--root-size=" arg)) arg) . tail)
|
||||
(loop tail positional system-name store-dir disk-capacity (option-value arg "--root-size=") target install-target-device rootfs deploy-host deploy-user deploy-port identity-file reboot?))
|
||||
(loop tail positional system-name store-dir disk-capacity (option-value arg "--root-size=") target install-target-device rootfs deploy-host deploy-user deploy-port identity-file reboot? self-test?))
|
||||
(("--root-size" value . tail)
|
||||
(loop tail positional system-name store-dir disk-capacity value target install-target-device rootfs deploy-host deploy-user deploy-port identity-file reboot?))
|
||||
(loop tail positional system-name store-dir disk-capacity value target install-target-device rootfs deploy-host deploy-user deploy-port identity-file reboot? self-test?))
|
||||
(((? (lambda (arg) (string-prefix? "--target=" arg)) arg) . tail)
|
||||
(loop tail positional system-name store-dir disk-capacity root-size (option-value arg "--target=") install-target-device rootfs deploy-host deploy-user deploy-port identity-file reboot?))
|
||||
(loop tail positional system-name store-dir disk-capacity root-size (option-value arg "--target=") install-target-device rootfs deploy-host deploy-user deploy-port identity-file reboot? self-test?))
|
||||
(("--target" value . tail)
|
||||
(loop tail positional system-name store-dir disk-capacity root-size value install-target-device rootfs deploy-host deploy-user deploy-port identity-file reboot?))
|
||||
(loop tail positional system-name store-dir disk-capacity root-size value install-target-device rootfs deploy-host deploy-user deploy-port identity-file reboot? self-test?))
|
||||
(((? (lambda (arg) (string-prefix? "--install-target-device=" arg)) arg) . tail)
|
||||
(loop tail positional system-name store-dir disk-capacity root-size target
|
||||
(option-value arg "--install-target-device=") rootfs deploy-host deploy-user deploy-port identity-file reboot?))
|
||||
(option-value arg "--install-target-device=") rootfs deploy-host deploy-user deploy-port identity-file reboot? self-test?))
|
||||
(("--install-target-device" value . tail)
|
||||
(loop tail positional system-name store-dir disk-capacity root-size target value rootfs deploy-host deploy-user deploy-port identity-file reboot?))
|
||||
(loop tail positional system-name store-dir disk-capacity root-size target value rootfs deploy-host deploy-user deploy-port identity-file reboot? self-test?))
|
||||
(((? (lambda (arg) (string-prefix? "--rootfs=" arg)) arg) . tail)
|
||||
(loop tail positional system-name store-dir disk-capacity root-size target install-target-device
|
||||
(option-value arg "--rootfs=") deploy-host deploy-user deploy-port identity-file reboot?))
|
||||
(option-value arg "--rootfs=") deploy-host deploy-user deploy-port identity-file reboot? self-test?))
|
||||
(("--rootfs" value . tail)
|
||||
(loop tail positional system-name store-dir disk-capacity root-size target install-target-device value deploy-host deploy-user deploy-port identity-file reboot?))
|
||||
(loop tail positional system-name store-dir disk-capacity root-size target install-target-device value deploy-host deploy-user deploy-port identity-file reboot? self-test?))
|
||||
(((? (lambda (arg) (string-prefix? "--host=" arg)) arg) . tail)
|
||||
(loop tail positional system-name store-dir disk-capacity root-size target install-target-device rootfs
|
||||
(option-value arg "--host=") deploy-user deploy-port identity-file reboot?))
|
||||
(option-value arg "--host=") deploy-user deploy-port identity-file reboot? self-test?))
|
||||
(("--host" value . tail)
|
||||
(loop tail positional system-name store-dir disk-capacity root-size target install-target-device rootfs value deploy-user deploy-port identity-file reboot?))
|
||||
(loop tail positional system-name store-dir disk-capacity root-size target install-target-device rootfs value deploy-user deploy-port identity-file reboot? self-test?))
|
||||
(((? (lambda (arg) (string-prefix? "--user=" arg)) arg) . tail)
|
||||
(loop tail positional system-name store-dir disk-capacity root-size target install-target-device rootfs
|
||||
deploy-host (option-value arg "--user=") deploy-port identity-file reboot?))
|
||||
deploy-host (option-value arg "--user=") deploy-port identity-file reboot? self-test?))
|
||||
(("--user" value . tail)
|
||||
(loop tail positional system-name store-dir disk-capacity root-size target install-target-device rootfs deploy-host value deploy-port identity-file reboot?))
|
||||
(loop tail positional system-name store-dir disk-capacity root-size target install-target-device rootfs deploy-host value deploy-port identity-file reboot? self-test?))
|
||||
(((? (lambda (arg) (string-prefix? "--port=" arg)) arg) . tail)
|
||||
(loop tail positional system-name store-dir disk-capacity root-size target install-target-device rootfs
|
||||
deploy-host deploy-user (option-value arg "--port=") identity-file reboot?))
|
||||
deploy-host deploy-user (option-value arg "--port=") identity-file reboot? self-test?))
|
||||
(("--port" value . tail)
|
||||
(loop tail positional system-name store-dir disk-capacity root-size target install-target-device rootfs deploy-host deploy-user value identity-file reboot?))
|
||||
(loop tail positional system-name store-dir disk-capacity root-size target install-target-device rootfs deploy-host deploy-user value identity-file reboot? self-test?))
|
||||
(((? (lambda (arg) (string-prefix? "--identity=" arg)) arg) . tail)
|
||||
(loop tail positional system-name store-dir disk-capacity root-size target install-target-device rootfs
|
||||
deploy-host deploy-user deploy-port (option-value arg "--identity=") reboot?))
|
||||
deploy-host deploy-user deploy-port (option-value arg "--identity=") reboot? self-test?))
|
||||
(("--identity" value . tail)
|
||||
(loop tail positional system-name store-dir disk-capacity root-size target install-target-device rootfs deploy-host deploy-user deploy-port value reboot?))
|
||||
(loop tail positional system-name store-dir disk-capacity root-size target install-target-device rootfs deploy-host deploy-user deploy-port value reboot? self-test?))
|
||||
(("--reboot" . tail)
|
||||
(loop tail positional system-name store-dir disk-capacity root-size target install-target-device rootfs deploy-host deploy-user deploy-port identity-file #t))
|
||||
(loop tail positional system-name store-dir disk-capacity root-size target install-target-device rootfs deploy-host deploy-user deploy-port identity-file #t self-test?))
|
||||
(("--self-test" . tail)
|
||||
(loop tail positional system-name store-dir disk-capacity root-size target install-target-device rootfs deploy-host deploy-user deploy-port identity-file reboot? #t))
|
||||
(((? (lambda (arg) (string-prefix? "--" arg)) arg) . _)
|
||||
(error "unknown option" arg))
|
||||
((arg . tail)
|
||||
(loop tail (cons arg positional) system-name store-dir disk-capacity root-size target install-target-device rootfs deploy-host deploy-user deploy-port identity-file reboot?)))))
|
||||
(loop tail (cons arg positional) system-name store-dir disk-capacity root-size target install-target-device rootfs deploy-host deploy-user deploy-port identity-file reboot? self-test?)))))
|
||||
|
||||
(define (parse-source-arguments action rest)
|
||||
(let loop ((args rest)
|
||||
@@ -627,8 +632,10 @@ Common options:\n\
|
||||
(os_file . ,os-file)
|
||||
(system_variable . ,resolved-symbol)
|
||||
(store_dir . ,store-dir)
|
||||
(newt_mode . ,(assoc-ref result 'mode))
|
||||
(newt_available . ,(assoc-ref result 'available?))
|
||||
(newt_result . ,(assoc-ref result 'result))
|
||||
(newt_error . ,(or (assoc-ref result 'error) #f))
|
||||
(missing_bindings . ,(assoc-ref result 'missing-bindings))
|
||||
(step_count . ,(assoc-ref result 'step-count))
|
||||
(step_ids . ,(assoc-ref result 'step-ids))
|
||||
@@ -862,6 +869,7 @@ Common options:\n\
|
||||
(deploy-port (assoc-ref parsed 'deploy-port))
|
||||
(identity-file (assoc-ref parsed 'identity-file))
|
||||
(reboot? (assoc-ref parsed 'reboot?))
|
||||
(self-test? (assoc-ref parsed 'self-test?))
|
||||
(system-name (assoc-ref parsed 'system-name))
|
||||
(requested-symbol (and system-name (string->symbol system-name))))
|
||||
(unless (member action '("build" "deploy" "image" "installer" "installer-iso" "installer-tui" "install" "rootfs"))
|
||||
@@ -899,7 +907,8 @@ Common options:\n\
|
||||
(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")))
|
||||
(shepherd-store-path (getenv "FRUIX_SHEPHERD_STORE"))
|
||||
(guile-newt-store-path (getenv "FRUIX_GUILE_NEWT_STORE")))
|
||||
(unless deploy-source
|
||||
(error "deploy action requires a declaration file or system closure path"))
|
||||
(if (system-closure-path? deploy-source)
|
||||
@@ -925,6 +934,7 @@ Common options:\n\
|
||||
#:guile-store-path guile-store-path
|
||||
#:guile-extra-store-path guile-extra-store-path
|
||||
#:shepherd-store-path shepherd-store-path
|
||||
#:guile-newt-store-path guile-newt-store-path
|
||||
#:declaration-source declaration-source
|
||||
#:declaration-origin deploy-source
|
||||
#:declaration-system-symbol resolved-symbol)))
|
||||
@@ -947,6 +957,7 @@ Common options:\n\
|
||||
(guile-store-path (getenv "FRUIX_GUILE_STORE"))
|
||||
(guile-extra-store-path (getenv "FRUIX_GUILE_EXTRA_STORE"))
|
||||
(shepherd-store-path (getenv "FRUIX_SHEPHERD_STORE"))
|
||||
(guile-newt-store-path (getenv "FRUIX_GUILE_NEWT_STORE"))
|
||||
(declaration-source (read-file-string os-file)))
|
||||
(cond
|
||||
((string=? action "build")
|
||||
@@ -960,6 +971,7 @@ Common options:\n\
|
||||
#:guile-store-path guile-store-path
|
||||
#:guile-extra-store-path guile-extra-store-path
|
||||
#:shepherd-store-path shepherd-store-path
|
||||
#:guile-newt-store-path guile-newt-store-path
|
||||
#:declaration-source declaration-source
|
||||
#:declaration-origin os-file
|
||||
#:declaration-system-symbol resolved-symbol)))
|
||||
@@ -1032,7 +1044,9 @@ Common options:\n\
|
||||
#:target-device seed-target-device
|
||||
#:root-size root-size
|
||||
#:disk-capacity disk-capacity))
|
||||
(result (run-newt-installer state)))
|
||||
(result (if self-test?
|
||||
(run-newt-self-test)
|
||||
(run-newt-installer state))))
|
||||
(emit-installer-tui-metadata
|
||||
os-file resolved-symbol store-dir state result)))
|
||||
((string=? action "install")
|
||||
|
||||
Reference in New Issue
Block a user