Validate FreeBSD daemon store RPC

This commit is contained in:
2026-04-01 14:10:53 +02:00
parent 12afb2bab3
commit c3a2d45a02
3 changed files with 363 additions and 0 deletions

View File

@@ -0,0 +1,215 @@
#!/bin/sh
set -eu
repo_root=$(CDPATH= cd -- "$(dirname "$0")/../.." && pwd)
metadata_target=${METADATA_OUT:-}
cleanup=0
if [ -n "${WORKDIR:-}" ]; then
workdir=$WORKDIR
mkdir -p "$workdir"
else
workdir=$(mktemp -d /tmp/fruix-phase5-daemon.XXXXXX)
cleanup=1
fi
if [ "${KEEP_WORKDIR:-0}" -eq 1 ]; then
cleanup=0
fi
setup_metadata=$workdir/setup-metadata.txt
setup_env=$workdir/setup-env.sh
metadata_file=$workdir/phase5-daemon-rpc-metadata.txt
daemon_socket=$workdir/guix-daemon.sock
daemon_log=$workdir/guix-daemon.log
scheme_log=$workdir/phase5-build.log
scheme_template=$workdir/phase5-build.scm.in
scheme_file=$workdir/phase5-build.scm
source_file=$workdir/phase5-source.txt
daemon_pid=
cleanup_workdir() {
if [ -n "$daemon_pid" ]; then
sudo kill "$daemon_pid" >/dev/null 2>&1 || true
wait "$daemon_pid" 2>/dev/null || true
fi
rm -f "$daemon_socket"
if [ "$cleanup" -eq 1 ]; then
rm -rf "$workdir"
fi
}
trap cleanup_workdir EXIT INT TERM
WORKDIR=$workdir/setup KEEP_WORKDIR=1 \
METADATA_OUT=$setup_metadata ENV_OUT=$setup_env \
"$repo_root/tests/guix/setup-phase5-checkout.sh" >"$workdir/setup.log" 2>&1
# shellcheck disable=SC1090
. "$setup_env"
cd "$PHASE5_BUILDDIR"
export LD_LIBRARY_PATH GUILE_LOAD_PATH GUILE_LOAD_COMPILED_PATH GUILE_EXTENSIONS_PATH
export GUILE_AUTO_COMPILE=0
printf 'phase5-daemon-build-source\n' > "$source_file"
cat >"$scheme_template" <<'EOF'
(use-modules (guix store)
(guix monads)
(guix gexp)
(guix packages)
(guix build-system)
(guix derivations)
(ice-9 match)
(srfi srfi-1)
(rnrs io ports))
(define source-file "__SOURCE_FILE__")
(call-with-output-file source-file
(lambda (port)
(display "phase5-daemon-build-source\n" port)))
(define source-item
(local-file source-file "__SOURCE_NAME__"))
(define* (phase5-lower name #:key source inputs native-inputs outputs system target #:allow-other-keys)
(bag
(name name)
(system system)
(target target)
(host-inputs `(,@(if source `(("source" ,source)) '()) ,@inputs))
(build-inputs native-inputs)
(outputs outputs)
(build phase5-build)
(arguments `(#:source ,source))))
(define* (phase5-build name inputs #:key source (outputs '("out")) (system (%current-system)) #:allow-other-keys)
(mlet* %store-monad ((shell (interned-file "/bin/sh" "sh" #:recursive? #t))
(source* (lower-object source system))
(builder (text-file "phase5-builder.sh"
"#!/bin/sh\nset -eu\n/bin/mkdir -p \"$out\"\n/bin/cp \"$1\" \"$out/payload.txt\"\nprintf '%s\\n' \"$1\" > \"$out/source-path.txt\"\n"
(list (if (derivation? source*)
(derivation->output-path source*)
source*)))))
(lambda (store)
(values (derivation store name shell
(list "-e" builder
(if (derivation? source*)
(derivation->output-path source*)
source*))
#:env-vars '(("HOME" . "/homeless"))
#:inputs `(,@(if (derivation? source*)
`((,source*))
'())
(,shell) (,builder))
#:sources `(,shell ,builder)
#:system system
#:outputs outputs)
store))))
(define phase5-build-system
(build-system
(name 'phase5-freebsd)
(description "Phase 5 FreeBSD daemon test build system")
(lower phase5-lower)))
(define phase5-package
(package
(name "phase5-freebsd-daemon-build")
(version "0")
(source source-item)
(build-system phase5-build-system)
(synopsis "Phase 5 daemon build test package")
(description "Minimal package used to validate daemon-backed builds on FreeBSD.")
(home-page "https://example.invalid/fruix")
(license #f)))
(let* ((store (open-connection))
(drv (run-with-store store
(mlet* %store-monad ((bag -> (package->bag phase5-package (%current-system) #f))
(drv (bag->derivation bag phase5-package)))
(return drv)))))
(build-derivations store (list drv))
(let* ((out (derivation->output-path drv))
(payload (call-with-input-file (string-append out "/payload.txt") get-string-all))
(source-path (call-with-input-file (string-append out "/source-path.txt") get-string-all)))
(format #t "drv-path=~a~%" (derivation-file-name drv))
(format #t "out-path=~a~%" out)
(format #t "payload=~a" payload)
(format #t "source-path=~a" source-path)))
EOF
sed \
-e "s|__SOURCE_FILE__|$source_file|g" \
-e "s|__SOURCE_NAME__|$(basename "$source_file")|g" \
"$scheme_template" > "$scheme_file"
sudo env GUIX_DAEMON_SOCKET=unix://$daemon_socket \
"$PHASE5_GUIX_DAEMON" --disable-chroot --listen "$daemon_socket" --no-substitutes \
>"$daemon_log" 2>&1 &
daemon_pid=$!
for _ in 1 2 3 4 5 6 7 8 9 10; do
[ -S "$daemon_socket" ] && break
sleep 1
done
[ -S "$daemon_socket" ] || {
echo "daemon socket was not created: $daemon_socket" >&2
exit 1
}
GUIX_DAEMON_SOCKET=unix://$daemon_socket \
./pre-inst-env fruix repl -- "$scheme_file" >"$scheme_log" 2>&1
drv_path=$(sed -n 's/^drv-path=//p' "$scheme_log")
out_path=$(sed -n 's/^out-path=//p' "$scheme_log")
payload=$(sed -n 's/^payload=//p' "$scheme_log")
source_path=$(sed -n 's/^source-path=//p' "$scheme_log")
[ -n "$drv_path" ] || { echo "missing drv-path in $scheme_log" >&2; exit 1; }
[ -n "$out_path" ] || { echo "missing out-path in $scheme_log" >&2; exit 1; }
[ -n "$payload" ] || { echo "missing payload in $scheme_log" >&2; exit 1; }
[ -n "$source_path" ] || { echo "missing source-path in $scheme_log" >&2; exit 1; }
case "$drv_path" in
/frx/store/*.drv) : ;;
*) echo "unexpected derivation path: $drv_path" >&2; exit 1 ;;
esac
case "$out_path" in
/frx/store/*) : ;;
*) echo "unexpected output path: $out_path" >&2; exit 1 ;;
esac
[ "$payload" = 'phase5-daemon-build-source' ] || {
echo "unexpected payload content: $payload" >&2
exit 1
}
case "$source_path" in
/frx/store/*) : ;;
*) echo "unexpected source store path: $source_path" >&2; exit 1 ;;
esac
cat >"$metadata_file" <<EOF
workdir=$workdir
setup_metadata=$setup_metadata
setup_env=$setup_env
phase5_builddir=$PHASE5_BUILDDIR
daemon_socket=$daemon_socket
daemon_log=$daemon_log
scheme_log=$scheme_log
source_file=$source_file
scheme_file=$scheme_file
drv_path=$drv_path
out_path=$out_path
payload=$payload
source_path=$source_path
frontend_invocation=./pre-inst-env fruix repl -- $scheme_file
EOF
if [ -n "$metadata_target" ]; then
mkdir -p "$(dirname "$metadata_target")"
cp "$metadata_file" "$metadata_target"
fi
printf 'PASS phase5-daemon-rpc\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"