setup-apkrepos.in 4.71 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 [-fhr] [REPO...]
141 142 143 144

Setup apk repositories

options:
145
 -f  Detect and add fastest mirror
146 147 148 149 150 151 152
 -h  Show this help
 -r  Add a random mirror and do not prompt
__EOF__
	exit 1

}

153
while getopts "fhr" opt; do
154
        case $opt in
155
                f) JUSTADDFASTEST=1;;
156 157 158 159
                h) usage;;
                r) JUSTADDRANDOM=1;;
        esac
done
160
shift $(($OPTIND - 1))
161

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

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

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

180 181
get_alpine_release
default_answer=f
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
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

198 199 200 201 202
if [ -n "$JUSTADDFASTEST" ]; then
	show_mirror_list > /dev/null
	add_fastest_mirror && changed=true
fi

203 204 205 206 207 208 209 210 211 212 213 214 215 216
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
217
done
Matt Smith's avatar
Matt Smith committed
218

219
if $changed; then
220
	echo -n "Updating repository indexes... "
221
	apk update --quiet $apk_root_opt && echo "done."
222
fi
223 224 225

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