Skip to content

Commit accc536

Browse files
committed
fix(offline): honor OFFLINE_WORK in git-ref2info and memoize TTL
Fixes #6439. memoized_git_ref_to_info() unconditionally ran 'git ls-remote' against the upstream source even with OFFLINE_WORK=yes; when the remote was unreachable the build aborted with a misleading network error. Two coordinated guards: * memoize-cached.sh: when OFFLINE_WORK=yes, serve the cache file regardless of TTL (alternative is a network call that will fail). The "stale cache served" event is logged. * git-ref2info.sh: early offline guard before the ls-remote loop. For ref_type=commit the SHA1 is taken from the ref itself (no network); for branch/tag we look up a pinned SHA1 in config/sources/git_sources.json. If neither is available, exit_with_error with a clear message instead of letting curl/ls-remote surface as 502. Same guard applied to the include_makefile_body block (curl to git host) since there is no local-bare fallback in scope here. Behaviour matrix unchanged for OFFLINE_WORK=no (default). Assisted-by: Claude:claude-opus-4.7
1 parent 4a09ca3 commit accc536

2 files changed

Lines changed: 40 additions & 3 deletions

File tree

lib/functions/general/git-ref2info.sh

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,26 @@ function memoized_git_ref_to_info() {
3131
# Get the SHA1 of the commit
3232
declare sha1
3333

34+
# OFFLINE_WORK guard: do not perform 'git ls-remote' when offline (#6439).
35+
# Honored sources, in order: ref_type=commit (sha1 from ref itself); pinned in
36+
# config/sources/git_sources.json. If neither yields a sha1 we fail with a clear
37+
# message instead of letting the network call surface as a misleading 502/timeout.
38+
if [[ "${OFFLINE_WORK}" == "yes" && "${ref_type}" != "commit" ]]; then
39+
declare offline_pinned=""
40+
if [[ -f "${SRC}/config/sources/git_sources.json" ]]; then
41+
offline_pinned=$(jq --raw-output --arg s "${MEMO_DICT[GIT_SOURCE]}" --arg b "${ref_name}" \
42+
'.[] | select(.source == $s and .branch == $b) | .sha1' \
43+
"${SRC}/config/sources/git_sources.json")
44+
fi
45+
if [[ "${offline_pinned}" =~ ^[0-9a-f]{40}$ ]]; then
46+
display_alert "OFFLINE_WORK: using pinned SHA1 from git_sources.json" "${ref_name} -> ${offline_pinned}" "info"
47+
sha1="${offline_pinned}"
48+
refs_to_try=() # skip ls-remote loop below
49+
else
50+
exit_with_error "OFFLINE_WORK=yes but no SHA1 available for '${MEMO_DICT[GIT_SOURCE]}' '${ref_type}' '${ref_name}' - run online once to populate cache, or pin sha1 in config/sources/git_sources.json"
51+
fi
52+
fi
53+
3454
# Enter loop. The first that resolves to a valid sha1 wins.
3555
declare to_try
3656
for to_try in "${refs_to_try[@]}"; do
@@ -228,6 +248,14 @@ function memoized_git_ref_to_info() {
228248
return 0
229249
}
230250

251+
# OFFLINE_WORK guard: Makefile body is fetched via curl to git host(s) — no
252+
# network when offline. We have no local fallback here (no bare-clone path in
253+
# scope), so fail with a clear message instead of letting curl surface as a
254+
# misleading 'undetermined' kernel version downstream (#6439).
255+
if [[ "${OFFLINE_WORK}" == "yes" ]]; then
256+
exit_with_error "OFFLINE_WORK=yes but Makefile body for '${MEMO_DICT[GIT_SOURCE]}' '${ref_name}' (sha1 ${sha1}) not in cache - run online once to populate ${SRC}/cache/memoize/"
257+
fi
258+
231259
display_alert "Fetching Makefile body" "${ref_name}" "debug"
232260
declare makefile_body makefile_url
233261
declare makefile_version makefile_codename makefile_full_version

lib/functions/general/memoize-cached.sh

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ function run_memoized() {
5050
# Lock is held by another process, inform user and wait with periodic feedback
5151
display_alert "Waiting for lock" "another build may be running; check: docker ps -a | grep armbian" "info"
5252

53-
declare -i lock_wait_interval=${MEMOIZE_FLOCK_WAIT_INTERVAL:-10} # seconds between retries/messages
54-
declare -i lock_max_wait=${MEMOIZE_FLOCK_MAX_WAIT:-0} # 0 = infinite (default for compatibility)
53+
declare -i lock_wait_interval=${MEMOIZE_FLOCK_WAIT_INTERVAL:-10} # seconds between retries/messages
54+
declare -i lock_max_wait=${MEMOIZE_FLOCK_MAX_WAIT:-0} # 0 = infinite (default for compatibility)
5555
declare -i lock_total_wait=0
5656
declare -i lock_acquired=0
5757

@@ -79,8 +79,17 @@ function run_memoized() {
7979
if [[ -f "${disk_cache_file}" ]]; then
8080
declare disk_cache_file_mtime_seconds
8181
disk_cache_file_mtime_seconds="$(stat -c %Y "${disk_cache_file}")"
82-
# if disk_cache_file is older than the ttl, delete it and continue.
82+
declare cache_is_stale="no"
8383
if [[ "${disk_cache_file_mtime_seconds}" -lt "$(($(date +%s) - memoize_cache_ttl))" ]]; then
84+
cache_is_stale="yes"
85+
fi
86+
# OFFLINE_WORK: serve any cached entry regardless of TTL — the alternative is
87+
# a network call that will fail (#6439). Surface that we're using a stale entry.
88+
if [[ "${cache_is_stale}" == "yes" && "${OFFLINE_WORK}" == "yes" ]]; then
89+
display_alert "OFFLINE_WORK: using stale cache" "${var_n}" "info"
90+
cache_is_stale="no"
91+
fi
92+
if [[ "${cache_is_stale}" == "yes" ]]; then
8493
display_alert "Deleting stale cache file" "${disk_cache_file}" "debug"
8594
rm -f "${disk_cache_file}"
8695
else

0 commit comments

Comments
 (0)