Fix: Lock installer input state
This commit is contained in:
@@ -89,36 +89,56 @@ STATE_DIR="${XDG_STATE_HOME:-$HOME/.local/state}/panama"
|
||||
PACKAGES_HASH="$STATE_DIR/packages-hash"
|
||||
|
||||
hash_packages() {
|
||||
local file relative size
|
||||
local file relative size fixed_input digest
|
||||
|
||||
{
|
||||
find "$PANAMA_PATH/setup/packages" -maxdepth 1 -type f -print0
|
||||
printf '%s\0' \
|
||||
"$PANAMA_PATH/setup/scripts/install-packages" \
|
||||
"$PANAMA_PATH/setup/lib/artifact-provenance"
|
||||
find "$PANAMA_PATH/setup/provenance" -type f -print0
|
||||
} | LC_ALL=C sort -z | while IFS= read -r -d '' file; do
|
||||
relative="${file#"$PANAMA_PATH"/}"
|
||||
size="$(wc -c <"$file")"
|
||||
printf '%s\0%s\0' "$relative" "$size"
|
||||
cat -- "$file"
|
||||
printf '\0'
|
||||
done | sha256sum | cut -d' ' -f1
|
||||
for fixed_input in \
|
||||
"$PANAMA_PATH/setup/scripts/install-packages" \
|
||||
"$PANAMA_PATH/setup/lib/artifact-provenance"; do
|
||||
[[ -f "$fixed_input" && ! -L "$fixed_input" && -r "$fixed_input" ]] || return 1
|
||||
done
|
||||
|
||||
digest="$(
|
||||
{
|
||||
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
|
||||
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"/}"
|
||||
size="$(wc -c <"$file")" || exit 1
|
||||
printf '%s\0%s\0' "$relative" "$size" || exit 1
|
||||
cat -- "$file" || exit 1
|
||||
printf '\0' || exit 1
|
||||
done | sha256sum | cut -d' ' -f1
|
||||
)" || return 1
|
||||
printf '%s\n' "$digest"
|
||||
}
|
||||
|
||||
packages_needed() {
|
||||
local current_hash recorded_hash
|
||||
|
||||
(( FORCE_PACKAGES )) && return 0
|
||||
(( UPGRADE )) || return 0
|
||||
[[ -r "$PACKAGES_HASH" ]] || return 0
|
||||
[[ "$(hash_packages)" != "$(cat "$PACKAGES_HASH")" ]]
|
||||
current_hash="$(hash_packages)" || return 2
|
||||
recorded_hash="$(cat "$PACKAGES_HASH")" || return 2
|
||||
[[ "$current_hash" != "$recorded_hash" ]]
|
||||
}
|
||||
|
||||
# Written only after the stage succeeds, mirroring the rule panama-migrate
|
||||
# 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
|
||||
mkdir -p "$STATE_DIR"
|
||||
hash_packages >"$PACKAGES_HASH"
|
||||
temporary_hash="$(mktemp "$STATE_DIR/.packages-hash.XXXXXX")" || return 1
|
||||
if hash_packages >"$temporary_hash"; then
|
||||
mv -f -- "$temporary_hash" "$PACKAGES_HASH"
|
||||
else
|
||||
rm -f -- "$temporary_hash"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Repository trust is checked before the installer can reach its bootstrap DNF.
|
||||
@@ -322,14 +342,25 @@ for stage in "${STAGES[@]}"; do
|
||||
script="$PANAMA_PATH/setup/scripts/$stage"
|
||||
[[ -x "$script" ]] || continue
|
||||
printf '\n=== %s ===\n' "$stage"
|
||||
if [[ "$stage" == install-packages ]] && ! packages_needed; then
|
||||
echo "The package lists have not changed since the last run; skipping."
|
||||
echo "Run with --packages to install them anyway."
|
||||
continue
|
||||
if [[ "$stage" == install-packages ]]; then
|
||||
package_state_status=0
|
||||
packages_needed || package_state_status=$?
|
||||
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."
|
||||
continue
|
||||
elif (( package_state_status != 0 )); then
|
||||
failed+=("$stage")
|
||||
printf '!!! %s could not read its tracked installation inputs\n' "$stage" >&2
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
if "$script"; then
|
||||
if [[ "$stage" == install-packages ]]; then
|
||||
record_packages_hash
|
||||
if ! record_packages_hash; then
|
||||
failed+=("$stage")
|
||||
printf '!!! %s could not record its tracked installation inputs\n' "$stage" >&2
|
||||
fi
|
||||
fi
|
||||
else
|
||||
stage_status=$?
|
||||
|
||||
Reference in New Issue
Block a user