add Phase 2B contained runtime artifacts
This commit is contained in:
parent
a9fec0d83d
commit
82e64cec43
35 changed files with 5177 additions and 40 deletions
|
|
@ -0,0 +1,101 @@
|
|||
#!/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 ]
|
||||
Loading…
Add table
Add a link
Reference in a new issue