Fix installer state and launcher freshness checks

This commit is contained in:
Gabriel Brown
2026-08-27 17:31:46 -04:00
parent 99156442b5
commit b5832fc94a
6 changed files with 156 additions and 19 deletions
+19 -9
View File
@@ -71,7 +71,7 @@ source "$PANAMA_PATH/bin/ascii"
# time. On an upgrade it is worth running only when its package lists or
# reviewed installer trust inputs changed, so this hashes them and remembers
# the result. The framed, sorted stream includes top-level package files, the
# package-stage adapter, the provenance helper, and regular provenance files;
# package-stage adapter, every helper it sources, and regular provenance files;
# both relative paths and bytes are part of the state.
#
# A content hash rather than a git range, because Panama is developed in place:
@@ -93,7 +93,10 @@ hash_packages() {
for fixed_input in \
"$PANAMA_PATH/setup/scripts/install-packages" \
"$PANAMA_PATH/setup/lib/artifact-provenance"; do
"$PANAMA_PATH/setup/lib/artifact-provenance" \
"$PANAMA_PATH/setup/lib/chatgpt-package" \
"$PANAMA_PATH/setup/lib/extras-catalog" \
"$PANAMA_PATH/setup/lib/machine-role"; do
[[ -f "$fixed_input" && ! -L "$fixed_input" && -r "$fixed_input" ]] || return 1
done
@@ -102,7 +105,10 @@ hash_packages() {
find "$PANAMA_PATH/setup/packages" -maxdepth 1 -type f -print0 || exit 1
printf '%s\0' \
"$PANAMA_PATH/setup/scripts/install-packages" \
"$PANAMA_PATH/setup/lib/artifact-provenance" || exit 1
"$PANAMA_PATH/setup/lib/artifact-provenance" \
"$PANAMA_PATH/setup/lib/chatgpt-package" \
"$PANAMA_PATH/setup/lib/extras-catalog" \
"$PANAMA_PATH/setup/lib/machine-role" || exit 1
find "$PANAMA_PATH/setup/provenance" -type f -print0 || exit 1
} | LC_ALL=C sort -z | while IFS= read -r -d '' file; do
relative="${file#"$PANAMA_PATH"/}"
@@ -116,12 +122,11 @@ hash_packages() {
}
packages_needed() {
local current_hash recorded_hash
local current_hash="$1" recorded_hash
(( FORCE_PACKAGES )) && return 0
(( UPGRADE )) || return 0
[[ -r "$PACKAGES_HASH" ]] || return 0
current_hash="$(hash_packages)" || return 2
recorded_hash="$(cat "$PACKAGES_HASH")" || return 2
[[ "$current_hash" != "$recorded_hash" ]]
}
@@ -130,10 +135,12 @@ packages_needed() {
# documents for its markers: a step that did not complete has not happened, and
# recording it as done hides it forever.
record_packages_hash() {
local temporary_hash
local starting_hash="$1" current_hash temporary_hash
current_hash="$(hash_packages)" || return 1
[[ "$current_hash" == "$starting_hash" ]] || return 1
mkdir -p "$STATE_DIR"
temporary_hash="$(mktemp "$STATE_DIR/.packages-hash.XXXXXX")" || return 1
if hash_packages >"$temporary_hash"; then
if printf '%s\n' "$starting_hash" >"$temporary_hash"; then
mv -f -- "$temporary_hash" "$PACKAGES_HASH"
else
rm -f -- "$temporary_hash"
@@ -344,7 +351,10 @@ for stage in "${STAGES[@]}"; do
printf '\n=== %s ===\n' "$stage"
if [[ "$stage" == install-packages ]]; then
package_state_status=0
packages_needed || package_state_status=$?
package_start_hash="$(hash_packages)" || package_state_status=2
if (( package_state_status == 0 )); then
packages_needed "$package_start_hash" || package_state_status=$?
fi
if (( package_state_status == 1 )); then
echo "The package lists have not changed since the last run; skipping."
echo "Run with --packages to install them anyway."
@@ -357,7 +367,7 @@ for stage in "${STAGES[@]}"; do
fi
if "$script"; then
if [[ "$stage" == install-packages ]]; then
if ! record_packages_hash; then
if ! record_packages_hash "$package_start_hash"; then
failed+=("$stage")
printf '!!! %s could not record its tracked installation inputs\n' "$stage" >&2
fi