From 0f3a8c84065b58bcdcc0d7a024202d4b8a4a6f61 Mon Sep 17 00:00:00 2001 From: "CanbiZ (MickLesk)" <47820557+MickLesk@users.noreply.github.com> Date: Thu, 26 Mar 2026 13:48:56 +0100 Subject: [PATCH] Improve apt-get retry and mirror fallback Add robust retry logic for APT operations in misc/build.func and misc/install.func. Introduces an apt_retry helper and multiple fallback steps: disable by-hash, switch to a country mirror (ftp.de.debian.org), wait and retry to allow mirror sync, and as a last resort temporarily relax APT verification to allow insecure repositories to complete updates. Ensures cleanup and restores secure settings where possible, with clearer failure handling and messages to increase resilience of package installation during container builds and installs. --- misc/build.func | 56 +++++++++++++++++++++++++++++++++++++---------- misc/install.func | 33 +++++++++++++++++++++++----- 2 files changed, 71 insertions(+), 18 deletions(-) diff --git a/misc/build.func b/misc/build.func index 8f92afa8..e68b0fd9 100644 --- a/misc/build.func +++ b/misc/build.func @@ -4602,20 +4602,52 @@ EOF' pct exec "$CTID" -- bash -c "apt-get update >/dev/null && apt-get install -y sudo curl mc gnupg2 jq >/dev/null" || { msg_warn "apt-get base packages failed, retrying with by-hash bypass and alternate mirror..." - pct exec "$CTID" -- bash -c " - echo 'Acquire::By-Hash \"no\";' >/etc/apt/apt.conf.d/99no-by-hash + pct exec "$CTID" -- bash -c ' + APT_BASE="sudo curl mc gnupg2 jq" + apt_retry() { + rm -rf /var/lib/apt/lists/* + apt-get update >/dev/null 2>&1 && apt-get install -y $APT_BASE >/dev/null 2>&1 + } + + # Retry 1: Disable by-hash (stale CDN by-hash index) + echo "Acquire::By-Hash \"no\";" >/etc/apt/apt.conf.d/99no-by-hash + apt_retry && exit 0 + + # Retry 2: Switch to country mirror (may lag behind primary) + for src in /etc/apt/sources.list.d/debian.sources /etc/apt/sources.list; do + [ -f "$src" ] && sed -i "s|deb.debian.org|ftp.de.debian.org|g" "$src" + done + apt_retry && exit 0 + + # Retry 3: Wait 30s for mirror sync, try original mirror + sleep 30 + for src in /etc/apt/sources.list.d/debian.sources /etc/apt/sources.list; do + [ -f "$src" ] && sed -i "s|ftp.de.debian.org|deb.debian.org|g" "$src" + done + apt_retry && exit 0 + + # Retry 4: Temporarily allow hash mismatch (Release/Packages desync) + echo "Acquire::AllowInsecureRepositories \"true\";" >>/etc/apt/apt.conf.d/99no-by-hash + for src in /etc/apt/sources.list.d/debian.sources /etc/apt/sources.list; do + [ -f "$src" ] && sed -i "s|deb.debian.org|ftp.debian.org|g" "$src" + done rm -rf /var/lib/apt/lists/* - if apt-get update >/dev/null 2>&1 && apt-get install -y sudo curl mc gnupg2 jq >/dev/null 2>&1; then - exit 0 + if apt-get update --allow-insecure-repositories >/dev/null 2>&1; then + apt-get install -y --allow-unauthenticated $APT_BASE >/dev/null 2>&1 + ret=$? + # Restore secure settings immediately + echo "Acquire::By-Hash \"no\";" >/etc/apt/apt.conf.d/99no-by-hash + for src in /etc/apt/sources.list.d/debian.sources /etc/apt/sources.list; do + [ -f "$src" ] && sed -i "s|ftp.debian.org|deb.debian.org|g" "$src" + done + rm -rf /var/lib/apt/lists/* + apt-get update >/dev/null 2>&1 || true + [ $ret -eq 0 ] && exit 0 fi - if [ -f /etc/apt/sources.list.d/debian.sources ]; then - sed -i 's|deb.debian.org|ftp.debian.org|g' /etc/apt/sources.list.d/debian.sources - elif [ -f /etc/apt/sources.list ]; then - sed -i 's|deb.debian.org|ftp.debian.org|g' /etc/apt/sources.list - fi - rm -rf /var/lib/apt/lists/* - apt-get update >/dev/null && apt-get install -y sudo curl mc gnupg2 jq >/dev/null - " || { + # Cleanup on failure + echo "Acquire::By-Hash \"no\";" >/etc/apt/apt.conf.d/99no-by-hash + exit 1 + ' || { msg_error "apt-get base packages installation failed" exit 1 } diff --git a/misc/install.func b/misc/install.func index 6f8ae80e..41016f9d 100644 --- a/misc/install.func +++ b/misc/install.func @@ -205,13 +205,34 @@ pkg_update() { echo 'Acquire::By-Hash "no";' >/etc/apt/apt.conf.d/99no-by-hash rm -rf /var/lib/apt/lists/* if ! $STD apt-get update; then - if [[ -f /etc/apt/sources.list.d/debian.sources ]]; then - sed -i 's|deb.debian.org|ftp.debian.org|g' /etc/apt/sources.list.d/debian.sources - elif [[ -f /etc/apt/sources.list ]]; then - sed -i 's|deb.debian.org|ftp.debian.org|g' /etc/apt/sources.list - fi + # Retry with country mirror + for src in /etc/apt/sources.list.d/debian.sources /etc/apt/sources.list; do + [[ -f "$src" ]] && sed -i 's|deb.debian.org|ftp.de.debian.org|g' "$src" + done rm -rf /var/lib/apt/lists/* - $STD apt-get update + if ! $STD apt-get update; then + # Wait for mirror sync, try original + sleep 30 + for src in /etc/apt/sources.list.d/debian.sources /etc/apt/sources.list; do + [[ -f "$src" ]] && sed -i 's|ftp.de.debian.org|deb.debian.org|g' "$src" + done + rm -rf /var/lib/apt/lists/* + if ! $STD apt-get update; then + # Last resort: temporarily allow insecure repos + msg_warn "All mirrors have hash mismatch, temporarily relaxing APT verification..." + echo 'Acquire::AllowInsecureRepositories "true";' >>/etc/apt/apt.conf.d/99no-by-hash + for src in /etc/apt/sources.list.d/debian.sources /etc/apt/sources.list; do + [[ -f "$src" ]] && sed -i 's|deb.debian.org|ftp.debian.org|g' "$src" + done + rm -rf /var/lib/apt/lists/* + $STD apt-get update --allow-insecure-repositories + # Restore secure settings immediately + echo 'Acquire::By-Hash "no";' >/etc/apt/apt.conf.d/99no-by-hash + for src in /etc/apt/sources.list.d/debian.sources /etc/apt/sources.list; do + [[ -f "$src" ]] && sed -i 's|ftp.debian.org|deb.debian.org|g' "$src" + done + fi + fi fi fi ;;