#!/bin/sh PROGRAM=setup-apkrepos PREFIX=@PREFIX@ : ${LIBDIR=$PREFIX/lib} . "$LIBDIR/libalpine.sh" : ${MIRRORS_URL:=https://mirrors.alpinelinux.org/mirrors.txt} if [ "$ROOT" != "/" ]; then apk_root_opt="--root $ROOT" fi get_hostname_from_url() { local n="${1#*://}" echo ${n%%/*} } get_mirror_count() { set -- $MIRRORS echo $# } ask_setup_method() { cat <<-__EOF__ r) Add random from the above list f) Detect and add fastest mirror from above list e) Edit ${ROOT}etc/apk/repositories with text editor __EOF__ ask "Enter mirror number (1-$(get_mirror_count)) or URL to add (or r/f/e/done)" "$1" } add_random_mirror() { local i=0 local count=$(get_mirror_count) if [ ${count:-0} -eq 0 ]; then echo "Warning! no mirror found" >&2 return 1 fi local random_mirror_index="$(awk -v count=$count 'BEGIN {srand(); printf("%.0f", rand() * count)}')" printf %s "Picking random mirror... " for mirror in $MIRRORS; do if [ $i -eq $random_mirror_index ]; then break fi i=$(( $i + 1 )) done add_mirror $mirror } time_cmd() { local start="$(cut -d ' ' -f1 /proc/uptime)" $@ >&2 || return awk -v start=$start -v end=$(cut -d ' ' -f1 /proc/uptime) \ 'BEGIN {print end - start; exit}' } find_fastest_mirror() { local url= local arch="$(apk --print-arch)" for url in $MIRRORS; do # warm up the dns cache $MOCK nslookup $(get_hostname_from_url $url) >/dev/null 2>&1 local time="$(time_cmd wget --spider -q -T 5 -t 1 \ ${url%/}/edge/main/$arch/APKINDEX.tar.gz)" if [ -n "$time" ]; then echo "$time $url" fi done | tee /dev/stderr | sort -nk1,1 | head -n1 | cut -d' ' -f2 } add_fastest_mirror() { echo "Finding fastest mirror... " local fastest="$(find_fastest_mirror)" if [ -z "$fastest" ]; then echo "Warning! No mirror found" >&2 return 1 fi add_mirror "$fastest" } # show mirrors show_mirror_list() { local mirror i=0 [ -z "$MIRRORS" ] && return echo "" echo "Available mirrors:" for mirror in $MIRRORS; do i=$(($i + 1)) echo "$i) $(get_hostname_from_url $mirror)" done echo "" } add_from_list() { local mirror_index="$1" if [ $mirror_index -lt 1 ] || [ $mirror_index -gt $(get_mirror_count) ]; then return 1 fi set $MIRRORS eval "mirror=\${$mirror_index}" add_mirror "$mirror" } get_alpine_release() { # use the main version already configured, or get the version from /etc/alpine-release local version="$(grep -Eom1 '[^/]+/main/?$' "${ROOT}"etc/apk/repositories 2>/dev/null | grep -Eo '^[^/]+' \ || cat "${ROOT}"etc/alpine-release 2>/dev/null)" case "$version" in *_git*|*_alpha*) release="edge";; [0-9]*.[0-9]*.[0-9]*) # release in x.y.z format, cut last digit release=v${version%.[0-9]*};; *) # fallback to edge release="edge";; esac } add_mirror() { local mirror="$1" mkdir -p "${APKREPOS_PATH%/*}" echo "${mirror%/}/${release}/main" >> $APKREPOS_PATH echo "${community_prefix}${mirror%/}/${release}/community" >> $APKREPOS_PATH case "$release" in v[0-9]*) echo "#${mirror%/}/edge/main" >> $APKREPOS_PATH; echo "#${mirror%/}/edge/community" >> $APKREPOS_PATH;; esac echo "#${mirror%/}/edge/testing" >> $APKREPOS_PATH echo "" >> $APKREPOS_PATH echo "Added mirror $(get_hostname_from_url $mirror)" } add_from_url() { mkdir -p "${APKREPOS_PATH%/*}" echo "$1" >> $APKREPOS_PATH echo "" >> $APKREPOS_PATH } edit_repositories() { local md5="$(md5sum $APKREPOS_PATH 2>/dev/null)" mkdir -p "${APKREPOS_PATH%/*}" ${EDITOR:-vi} "$APKREPOS_PATH" # return true if file changed test "$(md5sum $APKREPOS_PATH 2>/dev/null)" != "$md5" } usage() { cat <<-__EOF__ usage: setup-apkrepos [-ch] [-f|-r|-1|REPO...] Setup apk repositories options: -c Enable the community repo -f Detect and add fastest mirror -h Show this help -r Add a random mirror and do not prompt -1 Add first mirror on the list (normally a CDN) __EOF__ exit $1 } community_prefix="#" add_fastest=false add_first=false add_random=false while getopts "c1fhr" opt; do case $opt in c) community_prefix="";; f) add_fastest=true if $add_first || $add_random; then usage "1" >&2 fi ;; 1) add_first=true if $add_fastest || $add_random; then usage "1" >&2 fi ;; h) usage 0;; r) add_random=true if $add_first || $add_fastest; then usage "1" >&2 fi ;; '?') usage "1" >&2;; esac done shift $(($OPTIND - 1)) if [ -z "$MIRRORS" ]; then MIRRORS=$(wget -qO- $MIRRORS_URL) fi APKREPOS_PATH="${ROOT}"etc/apk/repositories if [ -r "$APKREPOS_PATH" ]; then APKREPOS=$(cat "$APKREPOS_PATH") fi get_alpine_release changed=false if [ $# -gt 0 ]; then # replace the apk repos with the specified ones rm -f "$APKREPOS_PATH" mkdir -p "${APKREPOS_PATH%/*}" for i; do echo "$i" >> "$APKREPOS_PATH" && changed=true done fi if $add_first; then set -- $MIRRORS if [ $# -eq 0 ]; then echo "Warning! No mirror found" >&2 exit 1 fi add_mirror "$1" || exit changed=true fi if $add_random; then add_random_mirror || exit changed=true fi if $add_fastest; then add_fastest_mirror || exit changed=true fi if $add_first || $add_random || $add_fastest; then interactive=false else interactive=true fi while $interactive && ! $changed; do if [ -z "$MIRRORS" ]; then MIRRORS=$(wget -qO- $MIRRORS_URL) fi show_mirror_list | more ask_setup_method ${APKREPO_DEFAULT_ANSWER:-1} case "$resp" in "done") break;; [0-9]*) add_from_list "$resp" && changed=true;; /*|http://*|ftp://*|https://*) add_from_url "$resp" \ && changed=true;; r) add_random_mirror && changed=true;; f) add_fastest_mirror && changed=true;; e) edit_repositories && changed=true;; esac done if $changed; then printf %s "Updating repository indexes... " apk update --quiet $apk_root_opt && echo "done." fi