Improve apt mirror selection and fallback
Refactor mirror logic in misc/build.func and misc/install.func to prefer regional Debian mirrors (detected from /etc/timezone), shuffle mirror lists, and include additional AP region hosts. Add quick TCP reachability checks, limit consecutive mirror failures, and surface clearer status messages. On repeated failures, prompt interactively for a custom mirror (with validation) and handle pct exec exit codes to present more informative errors and retry behavior.
This commit is contained in:
@@ -4604,48 +4604,73 @@ EOF'
|
|||||||
msg_warn "apt-get update failed, trying alternate mirrors..."
|
msg_warn "apt-get update failed, trying alternate mirrors..."
|
||||||
pct exec "$CTID" -- bash -c '
|
pct exec "$CTID" -- bash -c '
|
||||||
APT_BASE="sudo curl mc gnupg2 jq"
|
APT_BASE="sudo curl mc gnupg2 jq"
|
||||||
MIRRORS="
|
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"
|
||||||
ftp.debian.org
|
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"
|
||||||
ftp.us.debian.org
|
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"
|
||||||
ftp.de.debian.org
|
|
||||||
ftp.fr.debian.org
|
TZ=$(cat /etc/timezone 2>/dev/null || echo "UTC")
|
||||||
ftp.nl.debian.org
|
case "$TZ" in
|
||||||
ftp.uk.debian.org
|
Europe/*|Arctic/*) REGIONAL="$EU_MIRRORS"; OTHERS="$US_MIRRORS $AP_MIRRORS" ;;
|
||||||
ftp.ch.debian.org
|
America/*) REGIONAL="$US_MIRRORS"; OTHERS="$EU_MIRRORS $AP_MIRRORS" ;;
|
||||||
ftp.se.debian.org
|
Asia/*|Australia/*|Pacific/*) REGIONAL="$AP_MIRRORS"; OTHERS="$EU_MIRRORS $US_MIRRORS" ;;
|
||||||
ftp.it.debian.org
|
*) REGIONAL=""; OTHERS="$EU_MIRRORS $US_MIRRORS $AP_MIRRORS" ;;
|
||||||
ftp.au.debian.org
|
esac
|
||||||
ftp.jp.debian.org
|
MIRRORS="$(printf "%s\n" $REGIONAL | shuf) ftp.debian.org $(printf "%s\n" $OTHERS | shuf)"
|
||||||
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
|
|
||||||
"
|
|
||||||
echo "Acquire::By-Hash \"no\";" >/etc/apt/apt.conf.d/99no-by-hash
|
echo "Acquire::By-Hash \"no\";" >/etc/apt/apt.conf.d/99no-by-hash
|
||||||
|
FAIL_COUNT=0
|
||||||
for mirror in $MIRRORS; do
|
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
|
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"
|
[ -f "$src" ] && sed -i "s|URIs: http[s]*://[^/]*/|URIs: https://${mirror}/|g; s|deb http[s]*://[^/]*/|deb https://${mirror}/|g" "$src"
|
||||||
done
|
done
|
||||||
rm -rf /var/lib/apt/lists/*
|
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
|
exit 0
|
||||||
|
else
|
||||||
|
echo " [fail] $mirror"
|
||||||
fi
|
fi
|
||||||
|
FAIL_COUNT=$((FAIL_COUNT + 1))
|
||||||
|
[ "$FAIL_COUNT" -ge 3 ] && exit 2
|
||||||
done
|
done
|
||||||
exit 1
|
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/tty
|
||||||
|
[[ -z "$custom_mirror" ]] && continue
|
||||||
|
[[ "$custom_mirror" == "skip" ]] && break
|
||||||
|
[[ ! "$custom_mirror" =~ ^[a-zA-Z0-9._-]+$ ]] && {
|
||||||
|
msg_warn "Invalid hostname format."
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
pct exec "$CTID" -- bash -c "
|
||||||
|
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://${custom_mirror}/|g; s|deb http[s]*://[^/]*/|deb https://${custom_mirror}/|g\" \"\$src\"
|
||||||
|
done
|
||||||
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
apt-get update >/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"
|
msg_error "apt-get base packages installation failed"
|
||||||
exit 1
|
exit 1
|
||||||
}
|
fi
|
||||||
|
elif [[ $mirror_exit -ne 0 ]]; then
|
||||||
|
msg_error "apt-get base packages installation failed"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -202,42 +202,80 @@ pkg_update() {
|
|||||||
apt)
|
apt)
|
||||||
if ! $STD apt-get update; then
|
if ! $STD apt-get update; then
|
||||||
msg_warn "apt-get update failed, trying alternate mirrors..."
|
msg_warn "apt-get update failed, trying alternate mirrors..."
|
||||||
local mirrors="
|
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"
|
||||||
ftp.debian.org
|
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"
|
||||||
ftp.us.debian.org
|
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"
|
||||||
ftp.de.debian.org
|
|
||||||
ftp.fr.debian.org
|
local tz regional others
|
||||||
ftp.nl.debian.org
|
tz=$(cat /etc/timezone 2>/dev/null || echo "UTC")
|
||||||
ftp.uk.debian.org
|
case "$tz" in
|
||||||
ftp.ch.debian.org
|
Europe/* | Arctic/*)
|
||||||
ftp.se.debian.org
|
regional="$eu_mirrors"
|
||||||
ftp.it.debian.org
|
others="$us_mirrors $ap_mirrors"
|
||||||
ftp.au.debian.org
|
;;
|
||||||
ftp.jp.debian.org
|
America/*)
|
||||||
ftp.ca.debian.org
|
regional="$us_mirrors"
|
||||||
debian.csail.mit.edu
|
others="$eu_mirrors $ap_mirrors"
|
||||||
mirrors.ocf.berkeley.edu
|
;;
|
||||||
mirrors.wikimedia.org
|
Asia/* | Australia/* | Pacific/*)
|
||||||
debian.osuosl.org
|
regional="$ap_mirrors"
|
||||||
mirror.cogentco.com
|
others="$eu_mirrors $us_mirrors"
|
||||||
ftp.fau.de
|
;;
|
||||||
ftp.halifax.rwth-aachen.de
|
*)
|
||||||
debian.mirror.lrz.de
|
regional=""
|
||||||
mirror.init7.net
|
others="$eu_mirrors $us_mirrors $ap_mirrors"
|
||||||
debian.ethz.ch
|
;;
|
||||||
mirrors.dotsrc.org
|
esac
|
||||||
debian.mirrors.ovh.net
|
local mirrors
|
||||||
mirror.aarnet.edu.au
|
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
|
echo 'Acquire::By-Hash "no";' >/etc/apt/apt.conf.d/99no-by-hash
|
||||||
local apt_ok=false
|
local apt_ok=false
|
||||||
|
local fail_count=0
|
||||||
for mirror in $mirrors; do
|
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
|
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"
|
[[ -f "$src" ]] && sed -i "s|URIs: http[s]*://[^/]*/|URIs: https://${mirror}/|g; s|deb http[s]*://[^/]*/|deb https://${mirror}/|g" "$src"
|
||||||
done
|
done
|
||||||
rm -rf /var/lib/apt/lists/*
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
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 </dev/tty
|
||||||
|
[[ -z "$custom_mirror" ]] && continue
|
||||||
|
[[ "$custom_mirror" == "skip" ]] && break
|
||||||
|
[[ ! "$custom_mirror" =~ ^[a-zA-Z0-9._-]+$ ]] && {
|
||||||
|
msg_warn "Invalid hostname format."
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
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://${custom_mirror}/|g; s|deb http[s]*://[^/]*/|deb https://${custom_mirror}/|g" "$src"
|
||||||
|
done
|
||||||
|
rm -rf /var/lib/apt/lists/*
|
||||||
if $STD apt-get update; then
|
if $STD apt-get update; then
|
||||||
apt_ok=true
|
apt_ok=true
|
||||||
|
break 2
|
||||||
|
fi
|
||||||
|
msg_warn "Mirror '${custom_mirror}' also failed. Try another or type 'skip'."
|
||||||
|
done
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|||||||
Reference in New Issue
Block a user