#!/usr/bin/env bash # Fail-closed checks for the build guardrails, without root or ARM hardware. source "$(dirname -- "${BASH_SOURCE[0]}")/../../tools/lib.sh" cd "$FDS_ROOT" expect_failure() { local label=$1 shift if "$@" >"$scratch/rejection.log" 2>&1; then die "Validation incorrectly accepted: $label" fi printf 'PASS: rejects %s\n' "$label" } scratch=$(mktemp -d) trap 'rm -rf -- "$scratch"' EXIT for script in tools/* tests/integration/m0-checks; do [[ -f $script ]] || continue [[ $(head -n 1 "$script") == '#!/usr/bin/env bash' ]] || continue bash -n "$script" done tools/verify-elf target/aarch64-unknown-linux-musl/release/fds-smoketest aarch64 static expect_failure 'static musl executable as a glibc package' tools/verify-elf \ target/aarch64-unknown-linux-musl/release/fds-smoketest aarch64 glibc expect_failure 'wrong target architecture' tools/verify-elf /bin/bash aarch64 static expect_failure 'dynamic host executable as static' tools/verify-elf /bin/bash x86_64 static expect_failure 'non-ELF input' tools/verify-elf README.md aarch64 static expect_failure 'missing artifact' tools/verify-elf "$scratch/missing" aarch64 static expect_failure 'unknown linkage mode' tools/verify-elf /bin/bash x86_64 unknown expect_failure 'invalid package path' tools/build-package ../hello expect_failure 'unsupported bootstrap option' tools/bootstrap-host --unknown # Use a disposable minimal checkout to exercise pin and dirty-tree detection. mkdir -p "$scratch/repo/tools" "$scratch/repo/vendor/void-packages" cp tools/lib.sh tools/prepare-void tools/prepare-void-workspace tools/version tools/fds_version.py "$scratch/repo/tools/" printf "1.0\n" >"$scratch/repo/FDS_VERSION" fake="$scratch/repo/vendor/void-packages" git -C "$fake" init -q printf '# fixture\n' >"$fake/xbps-src" mkdir -p "$fake/srcpkgs/fds-upstream" "$fake/etc" "$scratch/repo/config" "$scratch/repo/packages/fds-fixture" printf '# upstream\n' >"$fake/srcpkgs/fds-upstream/template" printf 'etc/conf\nhostdir/\nmasterdir-*/\n' >"$fake/.gitignore" cp config/xbps-src.conf "$scratch/repo/config/" printf '# inert overlay fixture\n' >"$scratch/repo/packages/fds-fixture/template" git -C "$fake" add . git -C "$fake" -c user.name=FDS -c user.email=test@example.invalid commit -qm fixture git -C "$fake" rev-parse HEAD >"$scratch/repo/VOID_PACKAGES_COMMIT" bash -c 'source "$1"; check_void_source' _ "$scratch/repo/tools/lib.sh" printf 'PASS: accepts exact clean Void commit\n' # Existing generated files and caches move without copying their payloads. cp -a "$scratch/repo/packages/fds-fixture" "$fake/srcpkgs/" cp config/xbps-src.conf "$fake/etc/conf" mkdir -p "$fake/hostdir" "$fake/masterdir-x86_64" printf 'cached input\n' >"$fake/hostdir/cache" cache_inode=$(stat -c %i "$fake/hostdir/cache") "$scratch/repo/tools/prepare-void" build="$scratch/repo/.host/void-packages" [[ -z $(git -C "$fake" status --porcelain --untracked-files=all) ]] || die 'Migration dirtied upstream' [[ ! -e $fake/hostdir && ! -e $fake/etc/conf && ! -e $fake/srcpkgs/fds-fixture ]] || die 'Migration left build state in upstream' [[ $(stat -c %i "$build/hostdir/cache") == "$cache_inode" ]] || die 'Migration copied cache data' [[ ! -f $build/.git/objects/info/alternates ]] || die 'Build checkout depends on upstream object storage' bash -c 'source "$1"; check_void_pin' _ "$scratch/repo/tools/lib.sh" cmp "$scratch/repo/packages/fds-fixture/template" "$build/srcpkgs/fds-fixture/template" "$scratch/repo/tools/prepare-void" printf 'PASS: overlays and caches moved outside clean upstream; preparation is idempotent\n' printf '# changed\n' >>"$scratch/repo/packages/fds-fixture/template" expect_failure 'stale generated overlay' "$scratch/repo/tools/prepare-void" cp "$build/srcpkgs/fds-fixture/template" "$scratch/repo/packages/fds-fixture/template" # Preserve unexpected upstream additions and independently edited legacy copies. printf 'personal source\n' >"$fake/personal-file" expect_failure 'unknown upstream addition' "$scratch/repo/tools/prepare-void" [[ -f $fake/personal-file ]] || die 'Unknown file was removed' rm "$fake/personal-file" cp -a "$scratch/repo/packages/fds-fixture" "$fake/srcpkgs/" printf '# independent edit\n' >>"$fake/srcpkgs/fds-fixture/template" expect_failure 'edited legacy overlay' "$scratch/repo/tools/prepare-void" grep -q 'independent edit' "$fake/srcpkgs/fds-fixture/template" rm -r "$fake/srcpkgs/fds-fixture" # An explicit upstream pin update advances the build checkout and keeps caches. printf 'new upstream revision\n' >"$fake/README" git -C "$fake" add README git -C "$fake" -c user.name=FDS -c user.email=test@example.invalid commit -qm update git -C "$fake" rev-parse HEAD >"$scratch/repo/VOID_PACKAGES_COMMIT" # Production initializes upstream with depth 1; updating that boundary must work. git -C "$fake" rev-parse HEAD >"$fake/.git/shallow" expect_failure 'outdated build checkout' bash -c 'source "$1"; check_void_pin' _ "$scratch/repo/tools/lib.sh" "$scratch/repo/tools/prepare-void" [[ $(stat -c %i "$build/hostdir/cache") == "$cache_inode" ]] || die 'Pin update replaced cache' [[ $(git -C "$build" rev-parse HEAD) == "$(cat "$scratch/repo/VOID_PACKAGES_COMMIT")" ]] || die 'Build pin not advanced' mkdir -p "$scratch/repo/packages/fds-upstream" printf '# collision\n' >"$scratch/repo/packages/fds-upstream/template" expect_failure 'overlay replacing upstream package' "$scratch/repo/tools/prepare-void" rm -r "$scratch/repo/packages/fds-upstream" printf '# changed config\n' >>"$build/etc/conf" expect_failure 'overwriting local xbps configuration' "$scratch/repo/tools/prepare-void" printf '\n# dirty\n' >>"$fake/xbps-src" expect_failure 'modified Void source' bash -c 'source "$1"; check_void_pin' _ "$scratch/repo/tools/lib.sh" printf '%040d\n' 0 >"$scratch/repo/VOID_PACKAGES_COMMIT" expect_failure 'wrong Void commit' bash -c 'source "$1"; check_void_pin' _ "$scratch/repo/tools/lib.sh" printf 'PASS: M0 guardrail checks complete\n'