Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions configs/airootfs/usr/local/bin/omarchy-install-diagnose-media
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,21 @@ corrupt_package() {
printf '%s' "$package"
}

# A retry in the same boot never gets as far as a checksum. The first failure
# unlinked the package through the bind mount, so pacman now fails opening it,
# and it names the mirror it read from rather than the cache it writes to.
deleted_package() {
local log match package=""

for log in "$@"; do
[[ -f $log ]] || continue
match=$(sed -n "s|.*Could not open file ${OFFLINE_MIRROR}/\([^ ]*\).*|\1|p" "$log" | tail -n 1)
[[ -n $match ]] && package="$match"
done

printf '%s' "$package"
}

expected_checksum() {
local package="$1" reader

Expand Down Expand Up @@ -77,7 +92,14 @@ actual_checksum() {
printf '%s' "${sum%% *}"
}

# The checksum failure is read first wherever both are in the log: it is the
# attempt that names the cause, and the open failures after it are its wake.
package=$(corrupt_package "$@")
deleted=""
if [[ -z $package ]]; then
package=$(deleted_package "$@")
deleted=1
fi
if [[ -z $package ]]; then
exit 1
fi
Expand All @@ -87,6 +109,20 @@ fi
# filename has no business containing before printing it.
display_package="${package//[^A-Za-z0-9._+:@%-]/}"

# Nothing can be weighed here: the bytes that failed are gone, and the copy in
# the mirror went with them. Say which attempt this is, because the screen
# otherwise repeats the same unreadable error for every retry and the one that
# explains it scrolled away with the first.
if [[ -n $deleted ]]; then
echo "An earlier attempt deleted this package"
echo "pacman rejected it off this ISO and unlinked it from the mirror:"
echo "$display_package"
echo
echo "Reboot before retrying: the deletion is in RAM, so the ISO's copy returns"
echo "The first error after that reboot is the one that names the fault"
exit 0
fi

expected=$(expected_checksum "$package")
actual=$(actual_checksum "$package")

Expand Down
59 changes: 59 additions & 0 deletions test/unit/install-media-diagnosis-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,65 @@ if grep -qF "no longer matches the checksum" <<<"$output"; then
fi
pass "a deleted package names the medium without claiming which way it failed"

# Every retry in the same boot fails on the open rather than the checksum, and
# pacman names the mirror it read from, not the cache it writes to.
write_retry_log() {
local log="$1" path="${2:-$mirror/$PACKAGE}"

{
echo "[dashboard] :: Retrieving packages..."
echo "[dashboard] error: failed retrieving file '${path##*/}' from disk : Could not open file $path"
echo "[dashboard] error: failed to commit transaction (download library error)"
echo "[dashboard] ==> ERROR: Failed to install packages to new root"
} >"$log"
}

write_retry_log "$work/retry.log"

set +e
output=$(diagnose "$work/retry.log")
status=$?
set -e

(( status == 0 )) || fail "a retry after the deletion is diagnosed" "exit status $status"
[[ $(head -n 1 <<<"$output") == "An earlier attempt deleted this package" ]] ||
fail "a retry is diagnosed as a retry" "$output"
grep -qF "$PACKAGE" <<<"$output" || fail "a retry names the package" "$output"
grep -qF "Reboot before retrying" <<<"$output" ||
fail "a retry says how to get the package back" "$output"
pass "a retry after the deletion says so instead of going undiagnosed"

# A log holding both attempts must answer with the one that names the cause.
# The retries come after it and would otherwise win on recency.
printf 'a package, but damaged\n' >"$mirror/$PACKAGE"
write_mirror_db "$(printf '0%.0s' {1..64})"
{
cat "$log"
cat "$work/retry.log"
} >"$work/both.log"

set +e
output=$(diagnose "$work/both.log")
set -e

[[ $(head -n 1 <<<"$output") == "The install medium is damaged" ]] ||
fail "the checksum failure outranks the retries that followed it" "$output"
pass "the checksum failure outranks the retries that followed it"

# An open failure somewhere other than the mirror was not read off this ISO.
write_retry_log "$work/retry-elsewhere.log" "/var/tmp/build/$PACKAGE"

set +e
output=$(diagnose "$work/retry-elsewhere.log")
status=$?
set -e

(( status == 1 )) || fail "an open failure outside the mirror is not diagnosed" "exit $status: $output"
[[ -z $output ]] || fail "an open failure outside the mirror prints nothing" "$output"
pass "an open failure outside the mirror is not blamed on the medium"

rm "$mirror/$PACKAGE"

# A record with no %SHA256SUM% must not borrow the next record's, which would
# compare a real file against another package's checksum.
printf 'a package, but damaged\n' >"$mirror/$PACKAGE"
Expand Down