Vendors Kicksecure derivative-maker as a pinned submodule (18.1.7.4), adds the wrapper + verify + diagnose scripts, the pinned builder image, and the reproducibility-gated Gitea Actions workflow. Base flavour only — no hardening overlay (that's M1.2). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
62 lines
2.6 KiB
Bash
Executable File
62 lines
2.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# SilverMetal Linux — reproducibility-failure diagnostic.
|
|
#
|
|
# Invoked by verify-reproducibility.sh when two builds disagree, but also
|
|
# safe to run by hand against any two ISOs:
|
|
#
|
|
# ISO_A=/path/a.iso ISO_B=/path/b.iso linux/build/scripts/diagnose-divergence.sh
|
|
#
|
|
# Produces a diffoscope report. The output is intentionally verbose — when
|
|
# this script runs in anger we want everything we can get.
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
|
REPO_ROOT="$(cd -- "${SCRIPT_DIR}/../../.." && pwd)"
|
|
|
|
: "${ISO_A:?ISO_A must point to the first ISO}"
|
|
: "${ISO_B:?ISO_B must point to the second ISO}"
|
|
|
|
if [[ ! -f "${ISO_A}" || ! -f "${ISO_B}" ]]; then
|
|
echo "diagnose: one of the ISOs is missing (A=${ISO_A} B=${ISO_B})" >&2
|
|
exit 1
|
|
fi
|
|
|
|
REPORT_DIR="${REPORT_DIR:-${REPO_ROOT}/linux/build/output/_divergence-$(date -u +%Y%m%dT%H%M%SZ)}"
|
|
mkdir -p "${REPORT_DIR}"
|
|
|
|
echo "diagnose: writing report to ${REPORT_DIR}"
|
|
|
|
# Quick wins first — these usually point straight at the culprit.
|
|
sha256sum "${ISO_A}" "${ISO_B}" > "${REPORT_DIR}/sha256.txt"
|
|
ls -la "${ISO_A}" "${ISO_B}" > "${REPORT_DIR}/sizes.txt" 2>&1 || true
|
|
|
|
# diffoscope — html if available (richer), text always.
|
|
if command -v diffoscope >/dev/null 2>&1; then
|
|
diffoscope --max-report-size 100000000 \
|
|
--html "${REPORT_DIR}/diff.html" \
|
|
--text "${REPORT_DIR}/diff.txt" \
|
|
"${ISO_A}" "${ISO_B}" \
|
|
|| true # non-zero exit just means "they differ"; that's why we're here
|
|
elif command -v cmp >/dev/null 2>&1; then
|
|
echo "diagnose: diffoscope not found, falling back to cmp" >&2
|
|
cmp -l "${ISO_A}" "${ISO_B}" > "${REPORT_DIR}/cmp.txt" || true
|
|
fi
|
|
|
|
# A first guess at the culprit, even when the diff is huge.
|
|
{
|
|
echo "## Likely-culprit checklist"
|
|
echo ""
|
|
echo "Walk these in order — most failures fall into the first two."
|
|
echo ""
|
|
echo " [ ] SOURCE_DATE_EPOCH was identical in both builds (compare BUILD_INFO files)"
|
|
echo " [ ] snapshot.debian.org timestamp matched (compare snapshot-pin.env files)"
|
|
echo " [ ] Same builder image digest (compare BUILD_INFO files)"
|
|
echo " [ ] mksquashfs reproducibility flags survived (-no-exports -no-xattrs -reproducible)"
|
|
echo " [ ] No build-id randomisation in kernel/initrd (look for differing .note.gnu.build-id)"
|
|
echo " [ ] No host hostname/username leakage (grep for the runner host name)"
|
|
echo " [ ] No locale drift (LC_ALL=C.UTF-8 enforced in container)"
|
|
} > "${REPORT_DIR}/checklist.md"
|
|
|
|
echo "diagnose: done. See ${REPORT_DIR}/checklist.md and ${REPORT_DIR}/diff.{html,txt}"
|