64 lines
2.8 KiB
Bash
Executable File
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
|