diff --git a/misc/build.func b/misc/build.func index 12eebc96..3d3ba3a6 100644 --- a/misc/build.func +++ b/misc/build.func @@ -4604,48 +4604,73 @@ EOF' msg_warn "apt-get update failed, trying alternate mirrors..." pct exec "$CTID" -- bash -c ' APT_BASE="sudo curl mc gnupg2 jq" - MIRRORS=" - ftp.debian.org - ftp.us.debian.org - ftp.de.debian.org - ftp.fr.debian.org - ftp.nl.debian.org - ftp.uk.debian.org - ftp.ch.debian.org - ftp.se.debian.org - ftp.it.debian.org - ftp.au.debian.org - ftp.jp.debian.org - ftp.ca.debian.org - debian.csail.mit.edu - mirrors.ocf.berkeley.edu - mirrors.wikimedia.org - debian.osuosl.org - mirror.cogentco.com - ftp.fau.de - ftp.halifax.rwth-aachen.de - debian.mirror.lrz.de - mirror.init7.net - debian.ethz.ch - mirrors.dotsrc.org - debian.mirrors.ovh.net - mirror.aarnet.edu.au - " + EU_MIRRORS="ftp.de.debian.org ftp.fr.debian.org ftp.nl.debian.org ftp.uk.debian.org ftp.ch.debian.org ftp.se.debian.org ftp.it.debian.org ftp.fau.de ftp.halifax.rwth-aachen.de debian.mirror.lrz.de mirror.init7.net debian.ethz.ch mirrors.dotsrc.org debian.mirrors.ovh.net" + US_MIRRORS="ftp.us.debian.org ftp.ca.debian.org debian.csail.mit.edu mirrors.ocf.berkeley.edu mirrors.wikimedia.org debian.osuosl.org mirror.cogentco.com" + AP_MIRRORS="ftp.au.debian.org ftp.jp.debian.org ftp.tw.debian.org ftp.kr.debian.org ftp.in.debian.org ftp.hk.debian.org ftp.sg.debian.org mirror.aarnet.edu.au mirror.nitc.ac.in" + + TZ=$(cat /etc/timezone 2>/dev/null || echo "UTC") + case "$TZ" in + Europe/*|Arctic/*) REGIONAL="$EU_MIRRORS"; OTHERS="$US_MIRRORS $AP_MIRRORS" ;; + America/*) REGIONAL="$US_MIRRORS"; OTHERS="$EU_MIRRORS $AP_MIRRORS" ;; + Asia/*|Australia/*|Pacific/*) REGIONAL="$AP_MIRRORS"; OTHERS="$EU_MIRRORS $US_MIRRORS" ;; + *) REGIONAL=""; OTHERS="$EU_MIRRORS $US_MIRRORS $AP_MIRRORS" ;; + esac + MIRRORS="$(printf "%s\n" $REGIONAL | shuf) ftp.debian.org $(printf "%s\n" $OTHERS | shuf)" + echo "Acquire::By-Hash \"no\";" >/etc/apt/apt.conf.d/99no-by-hash + FAIL_COUNT=0 for mirror in $MIRRORS; do + timeout 2 bash -c "echo >/dev/tcp/$mirror/80" 2>/dev/null || { echo " [skip] $mirror (unreachable)"; continue; } + echo " [try] $mirror ..." for src in /etc/apt/sources.list.d/debian.sources /etc/apt/sources.list; do [ -f "$src" ] && sed -i "s|URIs: http[s]*://[^/]*/|URIs: https://${mirror}/|g; s|deb http[s]*://[^/]*/|deb https://${mirror}/|g" "$src" done rm -rf /var/lib/apt/lists/* - if apt-get update >/dev/null 2>&1 && apt-get install -y $APT_BASE >/dev/null 2>&1; then + APT_OUT=$(apt-get update 2>&1) + if echo "$APT_OUT" | grep -qi "hashsum\|hash sum"; then + echo " [fail] $mirror (hash mismatch)" + echo "$APT_OUT" | grep -i "hash" | head -3 | sed "s/^/ /" + elif apt-get install -y $APT_BASE >/dev/null 2>&1; then + echo " [ok] $mirror" exit 0 + else + echo " [fail] $mirror" fi + FAIL_COUNT=$((FAIL_COUNT + 1)) + [ "$FAIL_COUNT" -ge 3 ] && exit 2 done exit 1 - ' || { + ' + mirror_exit=$? + if [[ $mirror_exit -eq 2 ]]; then + msg_warn "Multiple mirrors failed (possible CDN synchronization issue)." + msg_info "Find Debian mirrors at: https://www.debian.org/mirror/list" + local custom_mirror="" + while true; do + read -rp " Enter a Debian mirror hostname (or 'skip' to abort): " custom_mirror /dev/null 2>&1 && apt-get install -y sudo curl mc gnupg2 jq >/dev/null 2>&1 + " && break + msg_warn "Mirror '${custom_mirror}' also failed. Try another or type 'skip'." + done + if [[ "$custom_mirror" == "skip" ]]; then + msg_error "apt-get base packages installation failed" + exit 1 + fi + elif [[ $mirror_exit -ne 0 ]]; then msg_error "apt-get base packages installation failed" exit 1 - } + fi } fi diff --git a/misc/install.func b/misc/install.func index cc395211..bfb149ec 100644 --- a/misc/install.func +++ b/misc/install.func @@ -202,44 +202,82 @@ pkg_update() { apt) if ! $STD apt-get update; then msg_warn "apt-get update failed, trying alternate mirrors..." - local mirrors=" - ftp.debian.org - ftp.us.debian.org - ftp.de.debian.org - ftp.fr.debian.org - ftp.nl.debian.org - ftp.uk.debian.org - ftp.ch.debian.org - ftp.se.debian.org - ftp.it.debian.org - ftp.au.debian.org - ftp.jp.debian.org - ftp.ca.debian.org - debian.csail.mit.edu - mirrors.ocf.berkeley.edu - mirrors.wikimedia.org - debian.osuosl.org - mirror.cogentco.com - ftp.fau.de - ftp.halifax.rwth-aachen.de - debian.mirror.lrz.de - mirror.init7.net - debian.ethz.ch - mirrors.dotsrc.org - debian.mirrors.ovh.net - mirror.aarnet.edu.au - " + local eu_mirrors="ftp.de.debian.org ftp.fr.debian.org ftp.nl.debian.org ftp.uk.debian.org ftp.ch.debian.org ftp.se.debian.org ftp.it.debian.org ftp.fau.de ftp.halifax.rwth-aachen.de debian.mirror.lrz.de mirror.init7.net debian.ethz.ch mirrors.dotsrc.org debian.mirrors.ovh.net" + local us_mirrors="ftp.us.debian.org ftp.ca.debian.org debian.csail.mit.edu mirrors.ocf.berkeley.edu mirrors.wikimedia.org debian.osuosl.org mirror.cogentco.com" + local ap_mirrors="ftp.au.debian.org ftp.jp.debian.org ftp.tw.debian.org ftp.kr.debian.org ftp.in.debian.org ftp.hk.debian.org ftp.sg.debian.org mirror.aarnet.edu.au mirror.nitc.ac.in" + + local tz regional others + tz=$(cat /etc/timezone 2>/dev/null || echo "UTC") + case "$tz" in + Europe/* | Arctic/*) + regional="$eu_mirrors" + others="$us_mirrors $ap_mirrors" + ;; + America/*) + regional="$us_mirrors" + others="$eu_mirrors $ap_mirrors" + ;; + Asia/* | Australia/* | Pacific/*) + regional="$ap_mirrors" + others="$eu_mirrors $us_mirrors" + ;; + *) + regional="" + others="$eu_mirrors $us_mirrors $ap_mirrors" + ;; + esac + local mirrors + mirrors="$(printf '%s\n' $regional | shuf) ftp.debian.org $(printf '%s\n' $others | shuf)" + echo 'Acquire::By-Hash "no";' >/etc/apt/apt.conf.d/99no-by-hash local apt_ok=false + local fail_count=0 for mirror in $mirrors; do + timeout 2 bash -c "echo >/dev/tcp/$mirror/80" 2>/dev/null || { + msg_info "Mirror skip: ${mirror} (unreachable)" + continue + } + msg_info "Trying mirror: ${mirror}" for src in /etc/apt/sources.list.d/debian.sources /etc/apt/sources.list; do [[ -f "$src" ]] && sed -i "s|URIs: http[s]*://[^/]*/|URIs: https://${mirror}/|g; s|deb http[s]*://[^/]*/|deb https://${mirror}/|g" "$src" done rm -rf /var/lib/apt/lists/* - if $STD apt-get update; then + local apt_out + apt_out=$(apt-get update 2>&1) + if echo "$apt_out" | grep -qi "hashsum\|hash sum"; then + msg_warn "Mirror failed: ${mirror} (hash mismatch)" + echo "$apt_out" | grep -i "hash" | head -3 | sed 's/^/ /' + elif echo "$apt_out" | grep -q "^E:"; then + msg_warn "Mirror failed: ${mirror}" + else + msg_ok "Using mirror: ${mirror}" apt_ok=true break fi + fail_count=$((fail_count + 1)) + if [[ $fail_count -ge 3 ]]; then + msg_warn "Multiple mirrors failed (possible CDN synchronization issue)." + msg_info "Find Debian mirrors at: https://www.debian.org/mirror/list" + while true; do + read -rp " Enter a Debian mirror hostname (or 'skip' to abort): " custom_mirror