#!/usr/bin/env bash # Fixed Node API qualification target. Invoked only by test-backend-isolated.sh. set -euo pipefail [[ $# == 1 ]] || { echo 'Expected repository root only' >&2; exit 2; } [[ ${ARCHY_TEST_ISOLATOR:-systemd} == systemd ]] || { echo 'Gashboard tests require the systemd fixture namespace' >&2; exit 2; } REPO=$(cd "$1" && pwd) node_binary=$(realpath -- "$(command -v node)") [[ -x $node_binary && -f $REPO/scripts/tests/gashboard-isolated-entry.mjs && -d $REPO/docker/gashboard/apps/api/node_modules/tsx ]] || { echo 'Install the frozen Gashboard dependencies before isolated testing' >&2; exit 2; } command -v systemd-run >/dev/null command -v unshare >/dev/null command -v setpriv >/dev/null sudo -n true || { echo 'Isolated Gashboard tests require noninteractive sudo for namespaces' >&2; exit 1; } unit="archy-gashboard-tests-$(date +%s)-$$" # Match the Rust runner's wallet, bus, container, PID and network boundaries. # Retain only the Rust runner's DAC traversal capability for the read-only home/worktree. # Also hide container app paths, including default Gashboard data/provider paths. filesystems='/run:rw /var/lib/archipelago:rw /var/lib/containers:rw /root:rw /var/lib/tor:rw,size=64m /tmp:rw,size=512M,mode=1777 /var/tmp:rw,size=64M,mode=1777 /data:rw,size=64M /app:rw,size=16M' sudo -n systemd-run --unit="$unit" --wait --pipe --collect \ --property=RuntimeMaxSec=120 --property=CPUQuota=100% --property=MemoryMax=2G --property=MemorySwapMax=0 \ --property="WorkingDirectory=$REPO/docker/gashboard/apps/api" \ --property="BindReadOnlyPaths=$REPO" \ --property=PrivateNetwork=yes --property=PrivateTmp=no --property=PrivateDevices=yes \ --property=ProtectSystem=strict --property=ProtectHome=read-only \ --property=NoNewPrivileges=yes \ --property="TemporaryFileSystem=$filesystems" \ --setenv=ARCHY_TEST_ISOLATED=1 --setenv=NODE_OPTIONS= --setenv=TSX_DISABLE_CACHE=1 \ /usr/bin/unshare --pid --fork --mount-proc --kill-child \ /usr/bin/setpriv --bounding-set=-all,+dac_override \ "$node_binary" "$REPO/scripts/tests/gashboard-isolated-entry.mjs"