#!/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" <