#!/bin/sh failures=0 artifact_root=$(CDPATH= cd -- "$(dirname -- "$0")/.." 2>/dev/null && pwd) pass() { printf 'PASS: %s\n' "$1"; } fail() { printf 'FAIL: %s\n' "$1" >&2; failures=$((failures + 1)); } run_check() { label=$1 shift if "$@"; then pass "$label"; else fail "$label"; fi } expect_stat() { path=$1 expected=$2 actual=$(/usr/bin/stat -c '%u:%g:%a:%F' "$path" 2>/dev/null) if [ "$actual" = "$expected" ]; then pass "$path ownership/mode"; else fail "$path expected $expected, got ${actual:-missing}"; fi } expect_absent() { path=$1 if [ ! -e "$path" ] && [ ! -L "$path" ]; then pass "$path absent"; else fail "$path must not already exist"; fi } if [ "$(id -u)" = 0 ]; then pass 'running as root'; else fail 'must be run as root'; fi if [ -n "$artifact_root" ] && [ -d "$artifact_root/payload" ]; then pass 'artifact root resolved'; else fail 'artifact root not found'; fi if (cd "$artifact_root" && /usr/bin/sha256sum -c MANIFEST.sha256); then pass 'complete artifact manifest'; else fail 'complete artifact manifest'; fi if (cd "$artifact_root/inventory" && /usr/bin/sha256sum -c SHA256SUMS); then pass 'original root inventory'; else fail 'original root inventory'; fi run_check 'staged nftables syntax' /usr/bin/nft --check -f "$artifact_root/payload/etc/nftables.d/50-le-app-codex.nft" system_unit_path="$artifact_root/payload/etc/systemd/system:/etc/systemd/system:/run/systemd/system:/usr/local/lib/systemd/system:/usr/lib/systemd/system" systemd_output=$(SYSTEMD_UNIT_PATH="$system_unit_path" /usr/bin/systemd-analyze verify --recursive-errors=no user@1200.service user-1200.slice le-app-codex-netns.service 2>&1) systemd_rc=$? printf '%s\n' "$systemd_output" systemd_unexpected=$(printf '%s\n' "$systemd_output" | /usr/bin/sed -e '\#le-app-codex-netns.service: Command /usr/local/libexec/le-app-codex-netns is not executable: No such file or directory#d') if [ "$systemd_rc" -eq 0 ] || [ -z "$systemd_unexpected" ]; then pass 'staged system units/drop-ins via host search path'; else fail 'staged system units/drop-ins via host search path'; fi user_unit_path="$artifact_root/payload/srv/le-app-codex/home/.config/systemd/user:/etc/systemd/user:/run/systemd/user:/usr/local/lib/systemd/user:/usr/lib/systemd/user" user_systemd_output=$(SYSTEMD_UNIT_PATH="$user_unit_path" /usr/bin/systemd-analyze verify --recursive-errors=no docker.service 2>&1) user_systemd_rc=$? printf '%s\n' "$user_systemd_output" user_systemd_unexpected=$(printf '%s\n' "$user_systemd_output" | /usr/bin/sed -e '\#docker.service: Command /usr/local/libexec/dockerd-rootless-29.6.1.sh is not executable: No such file or directory#d') if [ "$user_systemd_rc" -eq 0 ] || [ -z "$user_systemd_unexpected" ]; then pass 'staged Docker user unit via host search path'; else fail 'staged Docker user unit via host search path'; fi shell_failures=0 for file in "$artifact_root"/tests/*.sh "$artifact_root"/payload/usr/local/libexec/*; do /bin/sh -n "$file" || shell_failures=$((shell_failures + 1)) done if [ "$shell_failures" -eq 0 ]; then pass 'shell syntax'; else fail 'shell syntax'; fi json_failures=0 for file in "$artifact_root"/payload/srv/le-app-codex/home/.config/docker/daemon.json \ "$artifact_root"/payload/srv/le-app-codex/home/.docker/config.json \ "$artifact_root"/payload/srv/le-app-codex/home/.docker/contexts/meta/1b645e55bd6af77d420732b143423e7a27b12fbb5a71497e5d89c52481b6a535/meta.json \ "$artifact_root"/inventory/docker-networks.json; do /usr/bin/jq empty "$file" || json_failures=$((json_failures + 1)) done if [ "$json_failures" -eq 0 ]; then pass 'JSON syntax'; else fail 'JSON syntax'; fi expect_stat /srv/le-app-codex '0:1200:750:directory' expect_stat /srv/le-app-codex/home '1200:1200:700:directory' expect_stat /srv/le-app-codex/lasereverything.net.db '1200:1200:700:directory' expect_stat /srv/le-app-codex/database-source-readonly '0:1200:550:directory' expect_stat /srv/le-app-codex/nonproduction-secrets '0:1200:750:directory' expect_stat /srv/le-app-codex/container-runtime '1200:1200:700:directory' expect_stat /srv/le-app-codex/testing-data '1200:1200:700:directory' expect_stat /srv/le-app-codex/build-artifacts '1200:1200:700:directory' project_mounts=$(/usr/bin/findmnt -rn -o TARGET | /usr/bin/awk '$0 == "/srv/le-app-codex" || index($0, "/srv/le-app-codex/") == 1 { print }') if [ -z "$project_mounts" ]; then pass 'no project-rooted mounts'; else fail "unexpected project-rooted mounts: $project_mounts"; fi expect_absent /etc/le-app-codex-runtime/OPERATOR-INPUTS-APPROVED expect_absent /etc/le-app-codex-runtime/resolv.conf expect_absent /etc/nftables.d/50-le-app-codex.nft expect_absent /etc/systemd/system/le-app-codex-netns.service expect_absent /etc/systemd/system/user-1200.slice.d/50-le-app-codex-resources.conf expect_absent /etc/systemd/system/user@1200.service.d/50-le-app-codex-containment.conf expect_absent /usr/local/libexec/dockerd-rootless-29.6.1.sh expect_absent /usr/local/libexec/le-app-codex-netns expect_absent /srv/le-app-codex/home/.config/systemd/user/docker.service expect_absent /srv/le-app-codex/home/.config/docker/daemon.json expect_absent /srv/le-app-codex/home/.docker/config.json expect_absent /srv/le-app-codex/home/.docker/contexts/meta/1b645e55bd6af77d420732b143423e7a27b12fbb5a71497e5d89c52481b6a535/meta.json expect_absent /srv/le-app-codex/phase2b-tests/00-root-preinstall-validate.sh expect_absent /srv/le-app-codex/phase2b-tests/00-read-only-preflight.sh expect_absent /srv/le-app-codex/phase2b-tests/10-inert-containment.sh expect_absent /srv/le-app-codex/phase2b-tests/20-rootless-docker.sh expect_absent /srv/le-app-codex/phase2b-tests/run-inert-without-user-manager.sh active_state=$(/usr/bin/systemctl show user@1200.service -p ActiveState --value 2>/dev/null) if [ "$active_state" = inactive ]; then pass 'user@1200.service inactive'; else fail "user@1200.service state is ${active_state:-unknown}"; fi if [ ! -e /var/lib/systemd/linger/le_app_codex ] && [ ! -e /var/lib/systemd/linger/1200 ]; then pass 'linger absent'; else fail 'linger present'; fi uid_processes=$(/usr/bin/pgrep -u 1200 2>/dev/null) if [ -z "$uid_processes" ]; then pass 'UID 1200 has no processes'; else fail "UID 1200 processes found: $uid_processes"; fi if [ ! -S /run/user/1200/docker.sock ]; then pass 'rootless Docker socket absent'; else fail 'rootless Docker socket exists'; fi public_ipv4=$(/usr/bin/curl -4fsS --max-time 10 https://api.ipify.org 2>/dev/null) if [ "$public_ipv4" = 74.67.173.56 ]; then pass 'public/NAT IPv4 unchanged'; else fail "public/NAT IPv4 drift or lookup failure: ${public_ipv4:-unavailable}"; fi printf 'root pre-install validation failures=%s\n' "$failures" [ "$failures" -eq 0 ]