Add ARCHY_TEST_PACKAGE=gashboard with hardcoded Node test entry, synthetic data settings, private network/PID namespace and wallet/container/app tmpfs masks. Reject arbitrary command arguments and conflicting fixture modes; keep existing Rust/C01/container paths intact. Retain only the Rust runner DAC traversal capability for the read-only worktree. Six runner regressions pass, including existing modes; update the existing C01 test sudo mock for its exec-profile inventory call. Nine actual Gashboard API regressions pass in the new isolated systemd namespace with patched Zod/Express dependencies. Initial namespace file-access failure preserved before aligning traversal capability. No production app entry or installed service was run.
35 lines
2.1 KiB
Bash
Executable File
35 lines
2.1 KiB
Bash
Executable File
#!/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"
|