Skip to content

Instantly share code, notes, and snippets.

@ThinGuy
Last active October 11, 2017 10:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ThinGuy/4236baff0bc21ac6733e267c6c670d7b to your computer and use it in GitHub Desktop.
Save ThinGuy/4236baff0bc21ac6733e267c6c670d7b to your computer and use it in GitHub Desktop.
Functions for getting Known Ubuntu Mirrors, group mirrors hosted by Ubuntu, and show local Country mirror if applicable
# get-known mirrors grabs all officially registered ubuntu mirrors from launchpad.net
# Creates the following variables:
# KNOWN_MIRRORS - All mirrors
# HOST_MIRRORS - Mirrors ran by Ubuntu team @ Canonical
# CN_MIRROR - Country specific Hosted Mirror where Country determined by your IP addres
get-known-mirrors() {
unset KNOWN_MIRRORS
local THIS_COUNTRY="$(curl -sSL --connect-timeout 15 --max-time 20 https://whatismycountry.com/|/bin/grep -oP '(?<=>Your Country is )[^<]+')"
export KNOWN_MIRRORS=$(curl -sSL --connect-timeout 15 --max-time 20 https://launchpad.net/ubuntu/+archivemirrors|awk -F'["><]' '/application-summary/,/<\/table>/ { if(/th colspan="2">/){COUNTRY=$5;next} if(/http/||/ftp/||/rsync/){SITE=$3} if(/Mbps/||/Gbps/){SPEED=$3} if(/distromirrorstatus/){STATE=$5;gsub(/1 Gbps/,"1000",SPEED);gsub(/2 Gbps/,"2000",SPEED);gsub(/10 Gbps/,"10000",SPEED);gsub(/20 Gbps/,"20000",SPEED);gsub(/4 Gbps/,"4000",SPEED);gsub(/ Mbps/,"",SPEED);gsub(/behind/,"",STATE);gsub(/Up to date/,"0",STATE);gsub(/One hour/,"1",STATE);gsub(/Two hours/,"2",STATE);gsub(/Six hours/,"6",STATE);gsub(/One day/,"24",STATE);gsub(/One week/,"168",STATE);gsub(/Two days/,"48",STATE);gsub(/Two weeks/,"336",STATE);gsub(/Last update unknown/,"999",STATE);gsub(/ $/,"",STATE);!SITE && SPEED = "";print COUNTRY"|"SITE"|"SPEED"|"STATE}}'|sort -u)
if [[ -n "${KNOWN_MIRRORS}" ]];then
export HOSTED_MIRRORS=$(echo "${KNOWN_MIRRORS}"|/bin/grep -E '[a-z]+://[a-z0-9]+.archive.ubuntu.com/ubuntu')
if [[ -n ${THIS_COUNTRY} && $(echo "${HOSTED_MIRRORS}"|awk -F\| '/'"${THIS_COUNTRY}"'/{print $2}') ]];then
export CN_MIRROR=$(echo "${HOSTED_MIRRORS}"|awk -F\| '/'"${THIS_COUNTRY}"'/{print $2}')
else
CN_MIRROR=archive.ubuntu.com
fi
else
printf "ERROR: Could not get list of mirrors\n"
KNOWN_MIRRORS=
HOSTED_MIRRORS=
export CN_MIRROR=archive.ubuntu.com
fi
}
#echo the discovered country mirror
show-cn-mirror() {
[[ -n ${CN_MIRROR} ]] || get-known-mirrors
[[ -n ${CN_MIRROR} ]] && { echo "${CN_MIRROR}"; } || { printf "ERROR: Could not get list of mirrors\n"; }
}
#show list of all known mirrors with a header
show-known-mirrors() {
[[ -n ${KNOWN_MIRRORS} ]] || get-known-mirrors
[[ -n ${KNOWN_MIRRORS} ]] && { (printf '\e[1mCountry|URL|Speed (Mbps)|Behind (Hours)\e[0m\n';echo "${KNOWN_MIRRORS}" )|column -ts'|'|sed -E 's/Country|URL|Speed|Behind/'$(printf "\e[1m")'&'$(printf "\e[0m")'/g'; } || { printf "ERROR: Could not get list of mirrors\n"; }
}
#show list of all hosted mirrors with a header
show-hosted-mirrors() {
[[ -n ${HOSTED_MIRRORS} ]] || get-known-mirrors
[[ -n ${HOSTED_MIRRORS} ]] && { (printf 'Country|URL|Speed (Mbps)|Behind (Hours)\n';echo "${HOSTED_MIRRORS}" )|column -ts'|'|sed -E 's/Country|URL|Speed|Behind/'$(printf "\e[1m")'&'$(printf "\e[0m")'/g'; } || { printf "ERROR: Could not get list of mirrors\n"; }
}
# Search official Ubuntu Archive Mirrors based Country, Protocol, Speed, and Age, then display best choice
# requires netselect from debian archive to display best choice
# note: netselect does not work from behind a proxy
mirror-browser() {
if [[ $(dpkg 2>/dev/null -l ttf-ubuntu-font-family|/bin/grep -oE '^ii') ]];then
export ULOGO="\UFEFF\UE0FF\UFEFF"
else
export ULOGO=
fi
#Regular Red
export RR='\e[0;0;38;2;255;0;0m'
#Regular Green
export RG='\e[0m\e[0;0;38;2;0;255;0m'
#Regular Orange
RO='\e[0;0;38;2;225;95;0m'
#Reset Text
RT='\e[0m'
printf '\n\e[0;1;38;2;1;1;0m\e[48;2;255;255;255m Ubuntu'${ULOGO}' \e[0;1;38;2;255;255;255m\e[48;2;225;95;0m Mirror Search-O-Matic\U00AE \e[0m\n'
echo
install-netselect() {
#Install debian netselect
NS_URL="http://http.us.debian.org/debian/pool/main/n/netselect/"
NS_FILE=$(curl --connect-timeout 10 --retry 5 --retry-delay 1 --retry-max-time 60 --max-time 20 -s ${NS_URL} -l|sort -r|grep -m1 -Po '(?<=href=")[^"]*.[0-9]+[0-9]_amd64.deb')
wget "${NS_URL}${NS_FILE}" -qO /tmp/${NS_FILE} && sudo dpkg -i /tmp/${NS_FILE} > /tmp/${FUNCNAME}.log 2>&1; sudo rm /tmp/${NS_FILE}
}
sstatus() {
RETCODE=$(echo $?)
if [[ $RETCODE -eq 0 ]];then
{ printf '\e['$(($COLUMNS-5))'G'${RG}' \u2714\u2003'${RT}'\n';return $RETCODE; }
elif [[ $RETCODE -eq 1 ]];then
{ printf '\e['$(($COLUMNS-5))'G'${RR}'\u2006\u2716\u2003'${RT}'\n';return $RETCODE; }
fi
}
[[ -n ${KNOWN_MIRRORS} ]] || get-known-mirrors
[[ -n ${KNOWN_MIRRORS} ]] || { printf "ERROR: Could not get list of mirrors\n";return 1; }
printf "Search for Official Ubuntu${ULOGO} Archive Mirrors\n"
printf "\e[K\e[2G\e[1m1\e[0m) Scroll through choices using Up${RO}\U21E7\U2008\e[0mDown${RO}\U21E9\U2008\e[0marrow keys\n"
printf "\e[2G\e[1m2\e[0m) Press Enter${RO}\U21B5\U2008\e[0m to select\e[0m\n\n"
unset SEARCH_CNT SEARCH_RESULTS CNTRY_STR PROTO_STR SPEED_STR AGE_STR
unset MIRROR_CLIST MIRROR_PLIST MIRROR_SLIST MIRROR_ALIST
while IFS= read -r n;do MIRROR_CLIST+=( "$n" );done < <(echo "any";echo "${KNOWN_MIRRORS}"|awk -F\| '1==1{print $1}'|sort -u)
while IFS= read -r n;do MIRROR_PLIST+=( "$n" );done < <(echo "any";echo "${KNOWN_MIRRORS}"|awk -F\| '1==1{gsub(/:.*$/,"");print $2}'|sort -u)
while IFS= read -r n;do MIRROR_SLIST+=( "$n" );done < <(echo "any";echo "${KNOWN_MIRRORS}"|awk -F\| '1==1{print $3}'|sort -un)
while IFS= read -r n;do MIRROR_ALIST+=( "$n" );done < <(echo "any";echo "${KNOWN_MIRRORS}"|awk -F\| '1==1{print $4}'|sort -un)
i=0
printf '\n'
while true;do
[[ $i -lt 0 ]] && i=0
[[ ${MIRROR_CLIST[$i]} ]] || i=$(($i-1))
[[ $((${i}%2)) -eq 0 ]] && C=36 || C=33
printf "\e[2G\e[0mSelect a country:\e[0m \e[1;${C}m${MIRROR_CLIST[$i]}\e[0m\e[K"
read -sn 1 TOGGLE
case "$TOGGLE" in
"B")
i=$(($i+1))
[[ $((${i}%2)) -eq 0 ]] && C=36 || C=33
;;
"A")
i=$(($i-1))
[[ $((${i}%2)) -eq 0 ]] && C=36 || C=33
;;
[a-z])
if [[ $(echo "${MIRROR_CLIST[@],,}"|grep -m 1 -oE '\ '${TOGGLE}'[^ ]+') ]];then
LSTART=$(for s in ${!MIRROR_CLIST[@]};do [[ ${MIRROR_CLIST[$s],,} =~ ^${TOGGLE,,} ]] && { echo $s;break; };done)
LNEXT=$(echo {a..z}|/bin/grep -oP '(?<='${TOGGLE,,}' )[^ ]+')
LEND=$(for e in ${!MIRROR_CLIST[@]};do [[ ${MIRROR_CLIST[$e],,} =~ ^${LNEXT,,} ]] && { echo $e;break; };done)
[[ $i -lt $LSTART ]] && i=${LSTART}
[[ $i -ge $LSTART ]] && i=$(($i+1))
[[ $i -ge $LEND ]] && i=${LSTART}
else
i=0
fi
[[ $((${i}%2)) -eq 0 ]] && C=36 || C=33
;;
"")
#read -i "y" -erp "$(printf "\n\e[2GSelect ${MIRROR_CLIST[$i]}? [y/n]: ")" CONFIRM
#if [[ ${CONFIRM,,} = y ]];then
printf '\r\e[K'
local M_CNTRY="${MIRROR_CLIST[$i]}"
[[ "${M_CNTRY,,}" = "any" ]] && CNTRY_STR= || CNTRY_STR=' == "'${M_CNTRY}'"'
break
#else
# printf '\re[K\e[1A\e[2G'
#fi
;;
esac
done
printf "\e[2GSelected Country:\e[26G\e[1m${M_CNTRY}\e[0m\n\n"
unset RESULTS RESULTS_CNT
local RESULTS="$(echo "$KNOWN_MIRRORS"|awk -F'|' '$1'"${CNTRY_STR}"' && $2'"${PROTO_STR}"' && $3'"${SPEED_STR}"' && $4'"${AGE_STR}"' {print $0}')"
local RESULTS_CNT=$(echo "$RESULTS"|wc -l)
if [[ $RESULTS_CNT -eq 1 ]];then
printf "Sole result for ${M_CNTRY}-based Official Ubuntu${ULOGOC} Mirror\n"
(printf 'URL|Speed (Mbps)|Behind (Hours)\n';echo "${RESULTS}"|awk -F'|' '{print $2"|"$3"|"$4"|"}')|column -ts'|'|sed -E 's/Country|URL|Speed|Behind/'$(printf "\e[1m")'&'$(printf "\e[0m")'/g'
printf '\n'
export SINGLE_RESULT_MIRROR=$(echo "${RESULTS}"|awk -F'|' '{print $2}')
return 0
fi
i=0
while true;do
[[ $i -lt 0 ]] && i=0
[[ ${MIRROR_PLIST[$i]} ]] || i=$(($i-1))
[[ $((${i}%2)) -eq 0 ]] && C=36 || C=33
printf "\e[2G\e[0mSelect a Protocol: \e[0m \e[1;${C}m${MIRROR_PLIST[$i]}\e[0m\e[K"
read -sn 1 TOGGLE
case "$TOGGLE" in
"B")
i=$(($i+1))
[[ $((${i}%2)) -eq 0 ]] && C=36 || C=33
;;
"A")
i=$(($i-1))
[[ $((${i}%2)) -eq 0 ]] && C=36 || C=33
;;
"")
#read -i "y" -erp "$(printf "\n\e[2GSelect ${MIRROR_PLIST[$i]}? [y/n]: ")" CONFIRM
#if [[ ${CONFIRM,,} = y ]];then
printf "\r\e[K\e[1A"
local M_PROTO="${MIRROR_PLIST[$i]}"
[[ "${M_PROTO,,}" = "any" ]] && PROTO_STR= || PROTO_STR=' ~ "^'${M_PROTO}'"'
break
#else
# printf '\r\e[K\e[1A\e[2G'
#fi
;;
esac
done
printf "\e[2GSelected Protocol:\e[26G\e[1m${M_PROTO}\e[0m\n\n"
unset RESULTS RESULTS_CNT
local RESULTS="$(echo "$KNOWN_MIRRORS"|awk -F'|' '$1'"${CNTRY_STR}"' && $2'"${PROTO_STR}"' && $3'"${SPEED_STR}"' && $4'"${AGE_STR}"' {print $0}')"
local RESULTS_CNT=$(echo "$RESULTS"|wc -l)
if [[ $RESULTS_CNT -eq 1 ]];then
if [[ ${M_CNTRY} = any ]];then
printf "Sole result for Official Ubuntu${ULOGOC} Mirror matching above criteria\n"
(printf 'Country|URL|Speed (Mbps)|Behind (Hours)\n';echo "${RESULTS}")|column -ts'|'|sed -E 's/Country|URL|Speed|Behind/'$(printf "\e[1m")'&'$(printf "\e[0m")'/g'
printf '\n'
export SINGLE_RESULT_MIRROR=$(echo "${RESULTS}"|awk -F'|' '{print $2}')
return 0
else
printf "Sole result for ${M_CNTRY}-based Official Ubuntu${ULOGOC} Mirror matching above criteria\n"
(printf 'URL|Speed (Mbps)|Behind (Hours)\n';echo "${RESULTS}"|awk -F'|' '{print $2"|"$3"|"$4"|"}')|column -ts'|'|sed -E 's/Country|URL|Speed|Behind/'$(printf "\e[1m")'&'$(printf "\e[0m")'/g'
printf '\n'
export SINGLE_RESULT_MIRROR=$(echo "${RESULTS}"|awk -F'|' '{print $2}')
return 0
fi
fi
i=0
while true;do
[[ $i -lt 0 ]] && i=0
[[ ${MIRROR_SLIST[$i]} ]] || i=$(($i-1))
[[ $((${i}%2)) -eq 0 ]] && C=36 || C=33
printf "\e[2G\e[0mSelect Minimum Speed (Mbps): \e[0m \e[1;${C}m${MIRROR_SLIST[$i]}\e[0m\e[K"
read -sn 1 TOGGLE
case "$TOGGLE" in
"B")
i=$(($i+1))
[[ $((${i}%2)) -eq 0 ]] && C=36 || C=33
;;
"A")
i=$(($i-1))
[[ $((${i}%2)) -eq 0 ]] && C=36 || C=33
;;
"")
#read -i "y" -erp "$(printf "\n\e[2GSelect ${MIRROR_SLIST[$i]}? [y/n]: ")" CONFIRM
#if [[ ${CONFIRM,,} = y ]];then
printf "\r\e[K\e[1A"
local M_SPEED="${MIRROR_SLIST[$i]}"
[[ "${M_SPEED,,}" = "any" ]] && SPEED_STR= || SPEED_STR='>= '${M_SPEED}''
break
#else
# printf '\e[K\e[1A\e[2G'
#fi
;;
esac
done
printf "\e[2GSelected Speed:\e[26G\e[1m${M_SPEED}\e[0m\n\n"
unset RESULTS RESULTS_CNT
local RESULTS="$(echo "$KNOWN_MIRRORS"|awk -F'|' '$1'"${CNTRY_STR}"' && $2'"${PROTO_STR}"' && $3'"${SPEED_STR}"' && $4'"${AGE_STR}"' {print $0}')"
local RESULTS_CNT=$(echo "$RESULTS"|wc -l)
if [[ $RESULTS_CNT -eq 1 ]];then
if [[ ${M_CNTRY} = any ]];then
printf "Sole result for Official Ubuntu${ULOGOC} Mirror matching above criteria\n"
(printf 'Country|URL|Speed (Mbps)|Behind (Hours)\n';echo "${RESULTS}")|column -ts'|'|sed -E 's/Country|URL|Speed|Behind/'$(printf "\e[1m")'&'$(printf "\e[0m")'/g'
printf '\n'
export SINGLE_RESULT_MIRROR=$(echo "${RESULTS}"|awk -F'|' '{print $2}')
return 0
else
printf "Sole result for ${M_CNTRY}-based Official Ubuntu${ULOGOC} Mirror matching above criteria\n"
(printf 'URL|Speed (Mbps)|Behind (Hours)\n';echo "${RESULTS}"|awk -F'|' '{print $2"|"$3"|"$4"|"}')|column -ts'|'|sed -E 's/Country|URL|Speed|Behind/'$(printf "\e[1m")'&'$(printf "\e[0m")'/g'
printf '\n'
export SINGLE_RESULT_MIRROR=$(echo "${RESULTS}"|awk -F'|' '{print $2}')
return 0
fi
fi
i=0
while true;do
[[ $i -lt 0 ]] && i=0
[[ ${MIRROR_ALIST[$i]} ]] || i=$(($i-1))
[[ $((${i}%2)) -eq 0 ]] && C=36 || C=33
printf "\e[2G\e[0mSelect maximum hours behind: \e[0m \e[1;${C}m${MIRROR_ALIST[$i]}\e[0m\e[K"
read -sn 1 TOGGLE
case "$TOGGLE" in
"B")
i=$(($i+1))
[[ $((${i}%2)) -eq 0 ]] && C=36 || C=33
;;
"A")
i=$(($i-1))
[[ $((${i}%2)) -eq 0 ]] && C=36 || C=33
;;
"")
#read -i "y" -erp "$(printf "\n\e[2GSelect ${MIRROR_ALIST[$i]}? [y/n]: ")" CONFIRM
#if [[ ${CONFIRM,,} = y ]];then
printf "\r\e[K\e[1A"
local M_AGE="${MIRROR_ALIST[$i]}"
[[ "${M_AGE,,}" = "any" ]] && AGE_STR= || AGE_STR='<= '${M_AGE}''
break
#else
# printf '\e[K\e[1A\e[2G'
#fi
;;
esac
done
printf "\e[2GSelected Hours Behind:\e[26G\e[1m${M_AGE}\e[0m\n\n"
unset RESULTS RESULTS_CNT
local RESULTS="$(echo "$KNOWN_MIRRORS"|awk -F'|' '$1'"${CNTRY_STR}"' && $2'"${PROTO_STR}"' && $3'"${SPEED_STR}"' && $4'"${AGE_STR}"' {print $0}')"
local RESULTS_CNT=$(echo "$RESULTS"|wc -l)
[[ $RESULTS_CNT -eq 0 ]] && printf "\e[2GCould not find any mirrors matching above criteria.\n\e[2GTry using \"any\" to broaden your search."
if [[ $RESULTS_CNT -eq 1 ]];then
if [[ ${M_CNTRY} = any ]];then
printf "Sole result for Official Ubuntu${ULOGOC} Mirror matching above criteria\n"
(printf 'Country|URL|Speed (Mbps)|Behind (Hours)\n';echo "${RESULTS}")|column -ts'|'|sed -E 's/Country|URL|Speed|Behind/'$(printf "\e[1m")'&'$(printf "\e[0m")'/g'
printf '\n'
export SINGLE_RESULT_MIRROR=$(echo "${RESULTS}"|awk -F'|' '{print $2}')
return 0
else
printf "Sole result for ${M_CNTRY}-based Official Ubuntu${ULOGOC} Mirror matching above criteria\n"
(printf 'URL|Speed (Mbps)|Behind (Hours)\n';echo "${RESULTS}"|awk -F'|' '{print $2"|"$3"|"$4"|"}')|column -ts'|'|sed -E 's/Country|URL|Speed|Behind/'$(printf "\e[1m")'&'$(printf "\e[0m")'/g'
printf '\n'
export SINGLE_RESULT_MIRROR=$(echo "${RESULTS}"|awk -F'|' '{print $2}')
return 0
fi
else
if [[ ${M_CNTRY} = any ]];then
printf "Results for ${RESULTS_CNT} Official Ubuntu${ULOGOC} Mirrors\n"
(printf 'Country|URL|Speed (Mbps)|Behind (Hours)\n';echo "${RESULTS}")|column -ts'|'|sed -E 's/Country|URL|Speed|Behind/'$(printf "\e[1m")'&'$(printf "\e[0m")'/g'|sed -e's/^.* [0,1,2,6]$/'$(printf "\e[0;32m&\e[0m")''$(printf "\e[0;32m*\e[0m")'/g'
else
printf "Results for ${RESULTS_CNT} ${M_CNTRY}-based Official Ubuntu${ULOGOC} Mirrors\n"
(printf 'URL|Speed (Mbps)|Behind (Hours)\n';echo "${RESULTS}"|awk -F'|' '{print $2"|"$3"|"$4"|"}')|column -ts'|'|sed -E 's/Country|URL|Speed|Behind/'$(printf "\e[1m")'&'$(printf "\e[0m")'/g'|sed -e's/^.* [0,1,2,6]$/'$(printf "\e[0;32m&\e[0m")''$(printf "\e[0;32m*\e[0m")'/g'
fi
fi
[[ -n $(set -o posix;set|/bin/grep -ioE '^[Aa-Zz]*_PROXY') ]] && export PRXY_IN_USE=${TRUE} || export PRXY_IN_USE=${FALSE}
if [[ $PRXY_IN_USE = ${FALSE} ]];then
command -v netselect > /dev/null 2>&1 || install-netselect
command -v netselect > /dev/null 2>&1 || return 0
unset MLIST MSTATS
if [[ ${RESULTS_CNT} -ge 10 ]];then
printf "\n\e[2GGetting Top 10 Netselect Scores..."
local MLIST=$(sudo netselect -D 2>/dev/null -s10 $(echo "$RESULTS"|awk -F'|' '{print $2}')|awk '{print $2}')
else
printf "\n\e[2GGetting Netselect scores for ${RESULTS_CNT} mirrors..."
local MLIST=$(sudo netselect -D -s${RESULTS_CNT} 2>/dev/null $(echo "$RESULTS"|awk -F'|' '{print $2}')|awk '{print $2}')
fi
local MSTATS=$(sudo netselect -D -vv $(echo "$MLIST") 2>&1|awk '/^http/||/^ftp/||/^rsync/'|sort -n);sstatus;echo
(printf 'Score\tURL\tLatency\tHops\tPct\tPkts\n';(echo "$MSTATS"|sed -E -e 's/[a-z]\/\ |ms|hops|ok|[0-9]+\)|10\)|]/&\t/g' -e 's/ |^ | $//g' -e 's/ms|hops|ok//g'|awk -F'\t' '{gsub(/\[|\]/,"");print $6 "\t" $1 "\t" $2 "\t" $3 "\t" $4 "\t" $5}'|sort -n))|column -ts $'\t'|sed -E 's/Score|URL|Latency|Hops|Pct|Pkts/'$(printf "\e[1m")'&'$(printf "\e[0m")'/g'
fi
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment