Skip to content
Merged
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
16 changes: 14 additions & 2 deletions pve/vm-core.func
Original file line number Diff line number Diff line change
Expand Up @@ -1678,7 +1678,9 @@ vm_image_cache_path() {

# A cached image that no longer matches usually means the upstream was rebuilt,
# not that anything is wrong. Offer the choice instead of silently re-downloading
# several hundred MB. Unattended or without a terminal, take the new one.
# several hundred MB. Unattended or without a terminal, take the new one. A
# "Keep cached" answer is remembered in <file>.keep with the upstream checksum
# it was given against, so the question returns only when the upstream changes.
_vm_cache_choice() {
local file="$1" url="$2" local_size local_date remote_size remote_date head

Expand Down Expand Up @@ -1742,13 +1744,23 @@ vm_fetch_image() {
fi

if [[ "$cache" == yes && -e "$target" ]]; then
local keep="${target}.keep"
if _vm_image_ok "$target" "$exact_bytes" "$min_bytes" "$sha_tool" "$sha_want" "$xz"; then
rm -f "$keep"
msg_ok "Using cached ${CL}${BL}$(basename "$target")${CL}"
return 0
fi
if [[ -n "$sha_want" && -f "$keep" && "$(<"$keep")" == "${sha_tool}:${sha_want}" ]]; then
msg_ok "Using cached ${CL}${BL}$(basename "$target")${CL} (kept; the upstream has not changed)"
return 0
fi
if _vm_cache_choice "$target" "$url"; then
msg_warn "Replacing the cached $(basename "$target")"
rm -f "$target"
rm -f "$target" "$keep"
elif [[ -n "$sha_want" ]]; then
printf '%s' "${sha_tool}:${sha_want}" >"$keep"
msg_ok "Using cached ${CL}${BL}$(basename "$target")${CL} (kept until the upstream changes)"
return 0
else
msg_ok "Using cached ${CL}${BL}$(basename "$target")${CL}"
return 0
Expand Down
17 changes: 17 additions & 0 deletions tests/vm-helpers.sh
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,23 @@ vm_fetch_image "https://dl.test/openwrt.img.gz" "$TEST_DIR/cache/nosums.img" --c
assert_contains "$WARNINGS" "checking the size only"
ok "digest case is ignored; missing checksum list warns and continues"

CHOICE_CALLS="$TEST_DIR/choice-calls"
: >"$CHOICE_CALLS"
_vm_cache_choice() { echo keep >>"$CHOICE_CALLS"; return 1; }
KEPT="$TEST_DIR/cache/kept.img"
mkdir -p "$TEST_DIR/cache" && printf 'old build\n' >"$KEPT"
vm_fetch_image "https://dl.test/openwrt.img.gz" "$KEPT" --cache --sha256 "$IMAGE_SHA256" || fail "keep cached"
[[ -f "$KEPT.keep" ]] || fail "a kept cache gets a marker"
vm_fetch_image "https://dl.test/openwrt.img.gz" "$KEPT" --cache --sha256 "$IMAGE_SHA256" || fail "kept cache reused"
assert_eq "$(grep -c keep "$CHOICE_CALLS")" 1 "asked once while the upstream is unchanged"
vm_fetch_image "https://dl.test/openwrt.img.gz" "$KEPT" --cache --sha256 "$(printf '%064d' 1)" || fail "keep again after a change"
assert_eq "$(grep -c keep "$CHOICE_CALLS")" 2 "asked again once the upstream changed"
_vm_cache_choice() { return 0; }
vm_fetch_image "https://dl.test/openwrt.img.gz" "$KEPT" --cache --sha256 "$IMAGE_SHA256" || fail "replace cached"
[[ ! -f "$KEPT.keep" ]] || fail "the marker goes with the replaced file"
assert_eq "$(sha256sum "$KEPT" | cut -d' ' -f1)" "$IMAGE_SHA256" "fresh download in place"
ok "a kept cache is reused until the upstream checksum changes"

# ── vm_import_disk ──────────────────────────────────────────────────────────
VMID=100
QM_MODERN=yes
Expand Down
Loading