22a4bf8cfe
* Weight-based mirror selection: do not give each mirror same usage ratio as hosts have different properties. * Rotate mirrors after 6h: pkg now checks usability of all mirrors before selecting one, this takes time but we may want to reduce delays before the actual `apt` operation will be started. * Update apt cache after 20min: reduce amount of necessary package list queries. We even can go with 1h, but since we prefer origin repository over mirrors as download source, 20 minutes should be fine.
149 lines
4.4 KiB
Bash
Executable File
149 lines
4.4 KiB
Bash
Executable File
#!/bin/bash
|
|
set -e -u
|
|
|
|
show_help() {
|
|
local cache_size
|
|
cache_size=$(du -sh /data/data/com.termux/cache/apt/archives 2>/dev/null | cut -f1)
|
|
|
|
echo 'Usage: pkg command [arguments]'
|
|
echo
|
|
echo 'A tool for managing packages. Commands:'
|
|
echo
|
|
echo ' autoclean - Remove all outdated packages from .deb package'
|
|
echo ' cache.'
|
|
echo
|
|
echo ' clean - Remove all packages from .deb package cache.'
|
|
[ -n "$cache_size" ] && echo " Using ${cache_size} now."
|
|
echo
|
|
echo ' files <packages> - Show all files installed by packages.'
|
|
echo
|
|
echo ' install <packages> - Install specified packages.'
|
|
echo
|
|
echo ' list-all - List all packages available in repositories.'
|
|
echo
|
|
echo ' list-installed - List installed packages.'
|
|
echo
|
|
echo ' reinstall <packages> - Reinstall specified installed packages at the'
|
|
echo ' latest version.'
|
|
echo
|
|
echo ' search <query> - Search package by query, for example by name or'
|
|
echo ' description part.'
|
|
echo
|
|
echo ' show <packages> - Show basic metadata, such as dependencies.'
|
|
echo
|
|
echo ' uninstall <packages> - Uninstall specified packages. Configuration files'
|
|
echo ' will be left intact.'
|
|
echo
|
|
echo ' upgrade - Upgrade all installed packages to the latest'
|
|
echo ' version.'
|
|
echo
|
|
exit 1
|
|
}
|
|
|
|
select_mirror() {
|
|
local main_repo="https://termux.org/packages"
|
|
|
|
declare -A mirrors
|
|
mirrors[50]="https://dl.bintray.com/termux/termux-packages-24"
|
|
mirrors[23]="https://termux.mentality.rip/termux-packages-24"
|
|
mirrors[15]="https://main.termux-mirror.ml"
|
|
mirrors[12]="https://grimler.se/termux-packages-24"
|
|
|
|
local current_mirror
|
|
current_mirror=$(grep -P "^\s*deb\s+" @TERMUX_PREFIX@/etc/apt/sources.list | grep -oP 'https?://[a-z0-9/._-]+')
|
|
|
|
# Do not update mirror if:
|
|
# * Uses .cn domain - specific to Chinese users.
|
|
# * If $TERMUX_PKG_NO_MIRROR_SELECT was set.
|
|
if [ -n "${TERMUX_PKG_NO_MIRROR_SELECT-}" ] || grep -qP '.+\.cn/' <(echo "${current_mirror-x}"); then
|
|
return
|
|
fi
|
|
|
|
# Mirrors are rotated if 6 hours timeout has been passed or mirror is no longer accessible.
|
|
if [ -n "$(find /data/data/com.termux/cache/apt/pkgcache.bin -mmin -360 2>/dev/null)" ]; then
|
|
if [ -n "${current_mirror}" ] && curl --user-agent 'Termux-PKG/1.0 mirror-checker' --head --fail --location "${current_mirror}/dists/stable/Release" >/dev/null 2>&1; then
|
|
echo "Reusing mirror: ${current_mirror}"
|
|
return
|
|
fi
|
|
fi
|
|
|
|
# Test mirror availability, remove unaccessible mirrors from list.
|
|
echo "Testing the available mirrors:"
|
|
local w total_mirror_weight=0
|
|
for w in "${!mirrors[@]}"; do
|
|
echo -n "[*] ${mirrors[$w]}: "
|
|
if curl --user-agent 'Termux-PKG/1.0 mirror-checker' --head --fail --location "${mirrors[$w]}/dists/stable/Release" >/dev/null 2>&1; then
|
|
echo "ok"
|
|
total_mirror_weight=$((total_mirror_weight + w))
|
|
else
|
|
echo "bad"
|
|
unset "mirror[$w]"
|
|
fi
|
|
done
|
|
unset w
|
|
|
|
# Weight-based mirror selection.
|
|
local selected_mirror=""
|
|
if ((total_mirror_weight > 0)); then
|
|
local w random_weight calc_weight=0
|
|
random_weight=$((RANDOM % total_mirror_weight + 1))
|
|
for w in $(echo "${!mirrors[@]}" | tr ' ' '\n' | sort -n); do
|
|
calc_weight=$((calc_weight + w))
|
|
|
|
if ((calc_weight >= random_weight)); then
|
|
echo "Picking mirror: ${mirrors[$w]}"
|
|
selected_mirror="${mirrors[$w]}"
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
|
|
if [ -n "${selected_mirror}" ]; then
|
|
echo "deb ${selected_mirror}/ stable main" > @TERMUX_PREFIX@/etc/apt/sources.list
|
|
else
|
|
echo "Using fallback mirror: ${main_repo}"
|
|
echo "deb ${main_repo}/ stable main" > @TERMUX_PREFIX@/etc/apt/sources.list
|
|
fi
|
|
}
|
|
|
|
update_apt_cache() {
|
|
if [ -z "$(find /data/data/com.termux/cache/apt/pkgcache.bin -mmin -20 2>/dev/null)" ]; then
|
|
apt update
|
|
fi
|
|
}
|
|
|
|
if [ $# = 0 ]; then
|
|
show_help
|
|
fi
|
|
|
|
CMD="$1"
|
|
shift 1
|
|
|
|
case "$CMD" in
|
|
f*) dpkg -L "$@";;
|
|
h*) show_help;;
|
|
add|i*)
|
|
select_mirror
|
|
update_apt_cache
|
|
apt install "$@"
|
|
;;
|
|
autoc*) apt autoclean;;
|
|
cl*) apt clean;;
|
|
list-a*) apt list "$@";;
|
|
list-i*) apt list --installed "$@";;
|
|
rei*) apt install --reinstall "$@";;
|
|
se*)
|
|
select_mirror
|
|
update_apt_cache
|
|
apt search "$@"
|
|
;;
|
|
sh*) apt show "$@";;
|
|
un*|rem*|rm|del*) apt remove "$@";;
|
|
up*)
|
|
select_mirror
|
|
apt update
|
|
apt full-upgrade "$@"
|
|
;;
|
|
*) echo "Unknown command: '$CMD' (run 'pkg help' for usage information)"; exit 1;;
|
|
esac
|