Files
2026-09-21 22:29:23 +08:00

64 lines
2.8 KiB
Bash
Executable File

#!/usr/bin/env bash
# Run the packaged s6 graph with a read-only root and no physical device access.
source "$(dirname -- "${BASH_SOURCE[0]}")/../../tools/lib.sh"
[[ $# == 2 ]] || die 'Usage: dasung-s6-check EXTRACTED_PACKAGE COMPILED_DATABASE'
payload=$1
compiled=$2
scratch=$(mktemp -d "$FDS_ROOT/out/dasung-s6-run.XXXXXX")
trap 'rm -rf -- "$scratch"' EXIT
# Use copies, not hard links: adding the native test binary must not alter masterdir.
cp -a --reflink=auto "$FDS_VOID/masterdir-x86_64/usr/bin" "$scratch/bin"
cp "$FDS_ROOT/target/x86_64-unknown-linux-gnu/release/dasungd" "$scratch/bin/dasungd"
mkdir -p "$scratch/root"/{usr,etc,run,tmp,dev,proc,sys,var}
ln -s usr/bin "$scratch/root/bin"
ln -s usr/bin "$scratch/root/sbin"
ln -s usr/lib "$scratch/root/lib"
ln -s usr/lib "$scratch/root/lib64"
cat >"$scratch/run-test" <<'TEST'
set -euo pipefail
export PATH=/usr/bin:/bin
mkdir -p /run/service
mkfifo /run/scan-ready
s6-svscan -d 3 /run/service 3>/run/scan-ready &
scan=$!
cleanup() {
s6-svscanctl -t /run/service 2>/dev/null || true
wait "$scan" || true
}
trap cleanup EXIT
read -r < /run/scan-ready
s6-rc-init -t 3000 -d -c /tmp/compiled -l /run/s6-rc /run/service
s6-rc -l /run/s6-rc -t 3000 -u change boot
# Poll only the test assertion; target startup has no artificial waiting period.
for attempt in {1..50}; do
if dasungd status >/run/status.json 2>/dev/null; then break; fi
sleep 0.02
done
grep -q '"connected": false' /run/status.json
[[ $(stat -c %a /run/dasungd) == 750 ]]
[[ $(stat -c %a /run/dasungd/control.sock) == 660 ]]
s6-svstat /run/service/dasungd
s6-svstat /run/service/dasungd-log
# A real supervisor restart must restore the socket without requiring hardware.
s6-rc -l /run/s6-rc -t 3000 -d change boot
s6-rc -l /run/s6-rc -t 3000 -u change boot
for attempt in {1..50}; do
if dasungd status >/run/status.json 2>/dev/null; then break; fi
sleep 0.02
done
grep -q '"connected": false' /run/status.json
s6-rc -l /run/s6-rc -t 3000 -d change boot
printf 'PASS: s6 boot, logs, socket permissions, restart and stop with no monitor and read-only root\n'
TEST
# No host /sys or USB nodes are exposed. Only /run and the private test copies
# are writable. The PID namespace and outer timeout contain failed supervision.
timeout 20 bwrap --unshare-user --uid 0 --gid 0 --unshare-pid --die-with-parent \
--ro-bind "$scratch/root" / --ro-bind "$FDS_VOID/masterdir-x86_64/usr" /usr \
--ro-bind "$scratch/bin" /usr/bin --tmpfs /etc \
--ro-bind "$FDS_VOID/masterdir-x86_64/etc/passwd" /etc/passwd \
--ro-bind "$FDS_VOID/masterdir-x86_64/etc/group" /etc/group \
--ro-bind "$payload/etc/dasungd.toml" /etc/dasungd.toml \
--dev /dev --proc /proc --tmpfs /run --tmpfs /tmp \
--ro-bind "$compiled" /tmp/compiled --ro-bind "$scratch/run-test" /tmp/run-test \
--chdir / /usr/bin/bash /tmp/run-test