setup-apkrepos.in 4.53 KB
Newer Older
1 2 3 4 5 6 7
#!/bin/sh

PROGRAM=setup-apkrepos
PREFIX=

. $PREFIX/lib/libalpine.sh

8 9 10
if [ "$ROOT" != "/" ]; then
	apk_root_opt="--root $ROOT"
fi
Matt Smith's avatar
Matt Smith committed
11

Natanael Copa's avatar
Natanael Copa committed
12 13 14 15 16
get_hostname_from_url() {
	local n=${1#*://}
	echo ${n%%/*}
}

Matt Smith's avatar
Matt Smith committed
17
prompt_setup_method() {
18 19
	echo "r) Add random from the above list"
	echo "f) Detect and add fastest mirror from above list"
20
	echo "e) Edit "${ROOT}"etc/apk/repositores with text editor"
21 22
	echo ""
	echo -n "Enter mirror number (1-$mirror_count) or URL to add (or r/f/e/done) [$1]: "
Matt Smith's avatar
Matt Smith committed
23 24
}

25
add_random_mirror() {
Matt Smith's avatar
Matt Smith committed
26
	local i=0
27
	local random_mirror_index=$(( $RANDOM % $mirror_count ))
28

Matt Smith's avatar
Matt Smith committed
29 30 31 32 33
	echo -n "Picking random mirror... "
	for mirror in $MIRRORS; do
		if [ $i -eq $random_mirror_index ]; then
			break
		fi
34
		i=$(( $i + 1 ))
Matt Smith's avatar
Matt Smith committed
35
	done
36
	add_mirror $mirror
Matt Smith's avatar
Matt Smith committed
37 38
}

39 40 41 42 43 44
time_cmd() {
	local start=$(cut -d ' ' -f1 /proc/uptime)
	$@ >&2
	awk -v start=$start -v end=$(cut -d ' ' -f1 /proc/uptime) \
		'BEGIN {print end - start; exit}'
}
Matt Smith's avatar
Matt Smith committed
45

46 47 48 49
find_fastest_mirror() {
	export http_proxy=
	local url=
	for url in $MIRRORS; do
50
		echo $(time_cmd apk update --quiet $apk_root_opt \
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
				--repository $url/edge/main \
				--repositories-file /dev/null) $url
	done | awk ' {
		if (!current) {
			current=$1
			url=$2
		} else {
			if ($1 < current) {
				current=$1
				url=$2
			}
		}
		printf("%6.2f %s\n", $1, $2) > "/dev/stderr"
	}
	END { print url }'
}

add_fastest_mirror() {
	echo "Finding fastest mirror... "
	local fastest=$(find_fastest_mirror)
	add_mirror "$fastest"
Matt Smith's avatar
Matt Smith committed
72 73
}

74
# show mirrors and store how many in global mirror_count
75
show_mirror_list() {
76 77 78
	local mirror i=0
	mirror_count=0
	[ -z "$MIRRORS" ] && return
79
	echo ""
80
	echo "Available mirrors:"
81 82
	for mirror in $MIRRORS; do
		i=$(($i + 1))
83
		echo "$i) $(get_hostname_from_url $mirror)"
84
	done
85 86
	echo ""
	mirror_count=$i
87 88
}

89 90 91 92 93
add_from_list() {
	local mirror_index=$1
	if [ $mirror_index -lt 1 ] || [ $mirror_index -gt $mirror_count ]; then
		return 1
	fi
Matt Smith's avatar
Matt Smith committed
94
	set $MIRRORS
Natanael Copa's avatar
Natanael Copa committed
95
	eval "mirror=\$$mirror_index"
96
	add_mirror "$mirror"
Matt Smith's avatar
Matt Smith committed
97 98 99
}

get_alpine_release() {
100
	local version=$(cat "${ROOT}"etc/alpine-release 2>/dev/null)
101
	case "$version" in
102
		*_git*|*_alpha*) release="edge";;
103 104
		[0-9]*.[0-9]*.[0-9]*)
			# release in x.y.z format, cut last digit
105 106 107
			release=v${version%.[0-9]*};;
		*)	# fallback to edge
			release="edge";;
108
	esac
Matt Smith's avatar
Matt Smith committed
109
}
110

111 112
add_mirror() {
	local mirror="$1"
113
	mkdir -p "${APKREPOS_PATH%/*}"
114
	echo "${mirror%/}/${release}/main" >> $APKREPOS_PATH
115 116 117 118 119
	case "$release" in
	v[0-9]*)
		echo "#${mirror%/}/edge/main" >> $APKREPOS_PATH;;
	esac
	echo "#${mirror%/}/edge/testing" >> $APKREPOS_PATH
120 121 122
	echo "" >> $APKREPOS_PATH
	echo "Added mirror $(get_hostname_from_url $mirror)"
}
Matt Smith's avatar
Matt Smith committed
123

124
add_from_url() {
125
	mkdir -p "${APKREPOS_PATH%/*}"
126 127
	echo "$1" >> $APKREPOS_PATH
	echo "" >> $APKREPOS_PATH
Matt Smith's avatar
Matt Smith committed
128 129
}

130
edit_repositories() {
131 132
	local md5=$(md5sum $APKREPOS_PATH 2>/dev/null)
	mkdir -p "${APKREPOS_PATH%/*}"
133 134
	${EDITOR:-vi} "$APKREPOS_PATH"
	# return true if file changed
135
	test "$(md5sum $APKREPOS_PATH 2>/dev/null)" != "$md5"
136
}
Matt Smith's avatar
Matt Smith committed
137

138 139
usage() {
	cat <<__EOF__
140
usage: setup-apkrepos [-hr] [REPO...]
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157

Setup apk repositories

options:
 -h  Show this help
 -r  Add a random mirror and do not prompt
__EOF__
	exit 1

}

while getopts "hr" opt; do
        case $opt in
                h) usage;;
                r) JUSTADDRANDOM=1;;
        esac
done
158
shift $(($OPTIND - 1))
159

Matt Smith's avatar
Matt Smith committed
160
# main
161 162
# install alpine-mirrors if its not already there
to_uninstall=
163
if ! apk info --quiet --installed alpine-mirrors; then
164
	apk add --force --quiet --virtual .setup-apkrepos alpine-mirrors
165
	to_uninstall=.setup-apkrepos
166 167 168 169 170 171 172
fi

MIRRORS_PATH=/usr/share/alpine-mirrors/MIRRORS.txt
if [ -z "$MIRRORS" ] && [ -r "$MIRRORS_PATH" ]; then
	MIRRORS=`cat $MIRRORS_PATH`
fi

173
APKREPOS_PATH="${ROOT}"etc/apk/repositories
174 175 176 177
if [ -r "$APKREPOS_PATH" ]; then
	APKREPOS=`cat "$APKREPOS_PATH"`
fi

178 179
get_alpine_release
default_answer=f
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
changed=false

if [ $# -gt 0 ]; then
	# replace the apk repos with the specified ones
	rm -f "$APKREPOS_PATH"
	for i; do
		echo "$i" >> "$APKREPOS_PATH"
	done
	changed=true
fi

if [ -n "$JUSTADDRANDOM" ]; then
	show_mirror_list > /dev/null
	add_random_mirror && changed=true
fi

while ! $changed; do
	show_mirror_list
	prompt_setup_method $default_answer

	default_read answer $default_answer
	case "$answer" in
		"done") break;;
		[0-9]*) add_from_list $answer && changed=true;;
		/*|http://*|ftp://*|https://*) add_from_url "$answer" \
			&& changed=true;;
		r) add_random_mirror && changed=true;;
		f) add_fastest_mirror && changed=true;;
		e) edit_repositories && changed=true;;
	esac
210
done
Matt Smith's avatar
Matt Smith committed
211

212
if $changed; then
213
	echo -n "Updating repository indexes... "
214
	apk update --quiet $apk_root_opt && echo "done."
215
fi
216 217 218

# clean up
if [ -n "$to_uninstall" ]; then
Natanael Copa's avatar
Natanael Copa committed
219
	apk del --quiet $to_uninstall
220
fi