198 lines
6.4 KiB
Bash
Executable File
198 lines
6.4 KiB
Bash
Executable File
#!/bin/sh
|
|
set -eu
|
|
|
|
script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
|
repo_dir=$(dirname "$script_dir")
|
|
lock_dir="$repo_dir/release"
|
|
temporary=$(mktemp -d "${TMPDIR:-/tmp}/mouse-source-lock-check.XXXXXX")
|
|
|
|
cleanup() {
|
|
rm -rf "$temporary"
|
|
}
|
|
trap cleanup EXIT HUP INT TERM
|
|
|
|
MOUSE_VALIDATE_ONLY=1 "$script_dir/fetch-sources.sh"
|
|
|
|
awk 'NF && $1 !~ /^#/ { print $3 }' \
|
|
"$lock_dir/toolchain.lock" \
|
|
"$lock_dir/kernel.lock" \
|
|
"$lock_dir/facilities.lock" \
|
|
"$lock_dir/storage.lock" \
|
|
"$lock_dir/software.lock" |
|
|
LC_ALL=C sort -u >"$temporary/locked"
|
|
|
|
awk '$1 == "extract" { print $2 }' "$script_dir/static-base"/*.sh |
|
|
LC_ALL=C sort -u >"$temporary/referenced-archives"
|
|
sed -n 's/.*"$source_dir\/\([^"$]*\)".*/\1/p' \
|
|
"$script_dir/static-base"/*.sh \
|
|
"$script_dir/build-boot-disk.sh" |
|
|
LC_ALL=C sort -u >"$temporary/referenced-files"
|
|
cat "$temporary/referenced-archives" "$temporary/referenced-files" |
|
|
LC_ALL=C sort -u >"$temporary/referenced"
|
|
|
|
if ! diff -u "$temporary/locked" "$temporary/referenced"; then
|
|
printf '%s\n' "source locks do not match static-base component inputs" >&2
|
|
exit 1
|
|
fi
|
|
|
|
toolchain_count=$(awk 'NF && $1 !~ /^#/ { count++ } END { print count + 0 }' \
|
|
"$lock_dir/toolchain.lock")
|
|
kernel_count=$(awk 'NF && $1 !~ /^#/ { count++ } END { print count + 0 }' \
|
|
"$lock_dir/kernel.lock")
|
|
if [ "$toolchain_count" -ne 1 ] || \
|
|
! awk 'NF && $1 !~ /^#/ { print $3 }' "$lock_dir/toolchain.lock" |
|
|
grep -Eq '^llvm-project-[^/]+$'
|
|
then
|
|
printf '%s\n' "toolchain.lock must contain exactly the LLVM source" >&2
|
|
exit 1
|
|
fi
|
|
if [ "$kernel_count" -ne 1 ] || \
|
|
! awk 'NF && $1 !~ /^#/ { print $3 }' "$lock_dir/kernel.lock" |
|
|
grep -Eq '^linux-[^/]+$'
|
|
then
|
|
printf '%s\n' "kernel.lock must contain exactly the Linux source" >&2
|
|
exit 1
|
|
fi
|
|
pkgsrc_count=$(awk 'NF && $1 !~ /^#/ { count++ } END { print count + 0 }' \
|
|
"$lock_dir/pkgsrc.lock")
|
|
if [ "$pkgsrc_count" -ne 1 ] || \
|
|
! awk 'NF && $1 !~ /^#/ { print $3 }' "$lock_dir/pkgsrc.lock" |
|
|
grep -Eq '^pkgsrc-[0-9]{4}Q[1-4]\.tar\.gz$'
|
|
then
|
|
printf '%s\n' "pkgsrc.lock must contain exactly one stable pkgsrc archive" >&2
|
|
exit 1
|
|
fi
|
|
firmware_count=$(awk 'NF && $1 !~ /^#/ { count++ } END { print count + 0 }' \
|
|
"$lock_dir/firmware.lock")
|
|
if [ "$firmware_count" -ne 1 ] || \
|
|
! awk 'NF && $1 !~ /^#/ { print $3 }' "$lock_dir/firmware.lock" |
|
|
grep -Eq '^ovmf-[^/]+\.apk$'
|
|
then
|
|
printf '%s\n' "firmware.lock must contain exactly one OVMF package" >&2
|
|
exit 1
|
|
fi
|
|
storage_count=$(awk 'NF && $1 !~ /^#/ { count++ } END { print count + 0 }' \
|
|
"$lock_dir/storage.lock")
|
|
if [ "$storage_count" -lt 1 ] || \
|
|
! awk 'NF && $1 !~ /^#/ { print $3 }' "$lock_dir/storage.lock" |
|
|
grep -Eq '^btrfs-progs-[^/]+$'
|
|
then
|
|
printf '%s\n' "storage.lock must contain the btrfs-progs source" >&2
|
|
exit 1
|
|
fi
|
|
if awk 'NF && $1 !~ /^#/ { print $3 }' "$lock_dir/software.lock" |
|
|
grep -Eq '^(llvm-project|linux|btrfs-progs|less|mandoc|iproute2|nftables)-'
|
|
then
|
|
printf '%s\n' "software.lock contains a source owned by another cache domain" >&2
|
|
exit 1
|
|
fi
|
|
if awk 'NF && $1 !~ /^#/ { print $3 }' "$lock_dir/facilities.lock" |
|
|
grep -Eq '^(llvm-project|linux|btrfs-progs)-'
|
|
then
|
|
printf '%s\n' "facilities.lock contains a kernel, toolchain, or storage source" >&2
|
|
exit 1
|
|
fi
|
|
|
|
awk '
|
|
/^FROM toolchain AS kernel-builder$/ { in_kernel = 1; next }
|
|
/^FROM / && in_kernel { exit }
|
|
in_kernel { print }
|
|
' "$repo_dir/Containerfile" >"$temporary/kernel-stage"
|
|
|
|
if ! grep -Fq 'COPY --from=kernel-sources ' "$temporary/kernel-stage"; then
|
|
printf '%s\n' "kernel-builder does not import kernel-sources" >&2
|
|
exit 1
|
|
fi
|
|
if grep -Eq 'COPY --from=(toolchain|storage|software)-sources ' \
|
|
"$temporary/kernel-stage"
|
|
then
|
|
printf '%s\n' "kernel-builder imports an unrelated source domain" >&2
|
|
exit 1
|
|
fi
|
|
if grep -Fq 'tests/fixtures' "$temporary/kernel-stage"; then
|
|
printf '%s\n' "production kernel stage imports test fixtures" >&2
|
|
exit 1
|
|
fi
|
|
|
|
awk '
|
|
/^FROM kernel-builder AS kernel-ready$/ { in_marker = 1; next }
|
|
/^FROM / && in_marker { exit }
|
|
in_marker { print }
|
|
' "$repo_dir/Containerfile" >"$temporary/kernel-ready-stage"
|
|
|
|
if ! grep -Fq 'RUN install -m 0444 /dev/null /kernel-ready' \
|
|
"$temporary/kernel-ready-stage"
|
|
then
|
|
printf '%s\n' "kernel-ready does not create its completion marker" >&2
|
|
exit 1
|
|
fi
|
|
|
|
for stage_script in \
|
|
static-base-bootstrap:bootstrap.sh \
|
|
static-base-libraries:libraries-and-accounts.sh \
|
|
static-base-system:system-services.sh \
|
|
static-base-facilities:facilities.sh \
|
|
static-base-toolchain:native-toolchain.sh \
|
|
static-base-storage:storage.sh \
|
|
static-base-builder:finish.sh
|
|
do
|
|
stage=${stage_script%%:*}
|
|
component=${stage_script#*:}
|
|
awk -v heading="AS $stage" '
|
|
/^FROM / {
|
|
if (active) exit
|
|
active = index($0, heading) != 0
|
|
next
|
|
}
|
|
active { print }
|
|
' "$repo_dir/Containerfile" >"$temporary/$stage"
|
|
if ! grep -Fq \
|
|
"COPY mouse-src/scripts/static-base/$component " \
|
|
"$temporary/$stage"
|
|
then
|
|
printf '%s\n' \
|
|
"$stage does not own static-base component $component" >&2
|
|
exit 1
|
|
fi
|
|
if [ "$(grep -Fc \
|
|
"COPY mouse-src/scripts/static-base/$component " \
|
|
"$repo_dir/Containerfile")" -ne 1 ]
|
|
then
|
|
printf '%s\n' \
|
|
"$component must enter exactly one container cache stage" >&2
|
|
exit 1
|
|
fi
|
|
done
|
|
|
|
if ! grep -Fq \
|
|
'COPY --from=kernel-ready /kernel-ready /tmp/kernel-ready' \
|
|
"$temporary/static-base-bootstrap"
|
|
then
|
|
printf '%s\n' "static-base build does not wait for kernel completion" >&2
|
|
exit 1
|
|
fi
|
|
|
|
for production_stage in image-commands-builder rootfs-builder; do
|
|
awk -v heading="AS $production_stage" '
|
|
/^FROM / {
|
|
if (active) exit
|
|
active = index($0, heading) != 0
|
|
next
|
|
}
|
|
active { print }
|
|
' "$repo_dir/Containerfile" >"$temporary/$production_stage"
|
|
if grep -Fq 'tests/fixtures' "$temporary/$production_stage"; then
|
|
printf '%s\n' "$production_stage imports test fixtures" >&2
|
|
exit 1
|
|
fi
|
|
done
|
|
|
|
for test_stage in kernel-test-builder test-fixtures-builder rootfs-test-builder; do
|
|
if ! grep -Fq "AS $test_stage" "$repo_dir/Containerfile"; then
|
|
printf '%s\n' "missing isolated test stage: $test_stage" >&2
|
|
exit 1
|
|
fi
|
|
done
|
|
|
|
printf '%s\n' "source lock and cache-boundary checks passed"
|