buildlab.in 6.52 KB
Newer Older
1 2
#!/bin/sh

3
program_version=@VERSION@
4 5 6 7 8 9 10 11 12
sysconfdir=@sysconfdir@
abuildrepo=/var/lib/buildlab/result
datadir=@datadir@

BUILD_BASE="build-base"
SUDO=${SUDO:-"sudo"}
FAKEROOT=${FAKEROOT:-"fakeroot"}
APK=${APK:-apk}

13 14 15 16
# read config
ABUILD_CONF=${ABUILD_CONF:-"$sysconfdir/abuild.conf"}
[ -f "$ABUILD_CONF" ] && . "$ABUILD_CONF"

17
default_colors() {
18 19 20 21 22 23
	NORMAL="\033[1;0m"
	STRONG="\033[1;1m"
	RED="\033[1;31m"
	GREEN="\033[1;32m"
	YELLOW="\033[1;33m"
	BLUE="\033[1;34m"
24 25 26 27 28
}

default_colors

is_local() {
29 30 31 32 33
	case "$1" in
		http://*|ftp://*|https://*|saveas-*://*)
			return 1;;
	esac
	return 0
34 35 36 37
}

msg() {
	local prompt="$GREEN>>>${NORMAL}"
38
	[ -z "$quiet" ] && printf "${prompt} $@\n" >&2
39 40 41 42
}

error() {
	local prompt="$RED>>>${NORMAL}"
43
	printf "${prompt} $@\n" >&2
44 45 46 47 48 49 50 51
}

die() {
	error "$@"
	exit 1
}

runpart() {
52
	local part=$1
53
	msg "Running part $part"
54
	$part || die "$part failed"
55 56
}

57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
is_vserver() {
	egrep -q '^VxID:[[:space:]]*[0-9]+' /proc/self/status
}

do_chroot_open() {
	local path="$1"
	if is_vserver; then
		# vserver does not allow us mount or create devices
		# but we can create hard links as long as chroot is
		# on same filesystem as real root
		rmdir "$path"/proc "$path"/sys "$path"/dev 2>/dev/null
		ln /dev "$path"/dev
		ln /proc "$path"/proc
		ln /sys "$path"/sys

	else
		mkdir -p "$path"/dev "$path"/proc "$path"/sys
		mount -o bind /dev "$path"/dev || return 1
		mount -o bind /proc "$path"/proc
		mount -o bind /sys "$path"/sys
	fi
}

do_chroot_close() {
	local path="$1"
	if is_vserver; then
		rmdir  "$path"/dev "$path"/proc "$path"/sys
	else
		umount "$path"/dev "$path"/proc "$path"/sys
	fi
}
William Pitcock's avatar
William Pitcock committed
88

89 90 91 92 93 94
do_chroot_action() {
	local path="$1"
	local command="$2"

	msg "Doing chroot action '$command' in '$path'..."

95
	do_chroot_open "$path" || return 1
96 97 98 99 100 101 102
	shift;

	# XXX: we have to do this because busybox clobbers us, bleah.
	echo $* > "$path"/.chroot-action.sh
	chroot "$path" /bin/sh /.chroot-action.sh
	rm "$path"/.chroot-action.sh

103
	do_chroot_close
104 105
}

106 107 108 109 110 111 112
update_chroot() {
	local path="$1"

	apk --root $path --repositories "$path"/etc/apk/repositories update
	apk --root $path --repositories "$path"/etc/apk/repositories upgrade -a
}

113 114 115 116 117
prepare_chroot() {
	local path="$1"
	local version="$2"
	local mirror="$3"
	local arch="$4"
118
	local enablecache="$5"
119 120 121 122

	msg "Setting up repositories for mirror $mirror with version $version at $path..."

	mkdir -p "$path"/etc/apk
123 124
	echo "http://$mirror/alpine/$version/main" >> "$path"/etc/apk/repositories
	echo "http://$mirror/alpine/$version/testing" >> "$path"/etc/apk/repositories
125

126 127 128 129 130
	if [ ! -z "$enablecache" ]; then
		mkdir -p "$path"/var/cache/apk
		ln -s /var/cache/apk "$path"/etc/apk/cache
	fi

131 132 133 134 135
	echo "alpine-base" > "$path"/etc/apk/world
	mkdir -p "$path"/lib/apk/db
	mkdir -p "$path"/var/lock
	mkdir -p "$path"/var/cache/apk
	mkdir -p "$path"/tmp
136 137 138 139 140 141

	mkdir -p "$path"/etc
	cp /etc/resolv.conf "$path"/etc/resolv.conf

	msg "Updating package lists..."

142
	apk --arch $buildarch --root $path --repositories "$path"/etc/apk/repositories update
143 144 145

	msg "Installing alpine-base..."

146
	apk --arch $buildarch --root $path --repositories "$path"/etc/apk/repositories add --initdb alpine-base
147 148 149

	msg "Installing abuild..."

150
	apk --arch $buildarch --root $path --repositories "$path"/etc/apk/repositories add --initdb abuild
151 152 153

	msg "Installing build-base..."

154
	apk --arch $buildarch --root $path --repositories "$path"/etc/apk/repositories add --initdb build-base
155 156 157 158 159

	msg "Adding abuild user..."

	do_chroot_action "$path" adduser -D -G abuild abuild
	echo "abuild ALL=NOPASSWD: ALL" >> "$path"/etc/sudoers
160
	chmod 440 "$path"/etc/sudoers
161 162 163

	msg "Generating buildlab signing keys..."
	do_chroot_action "$path" su abuild -c "'abuild-keygen -ai'"
164

165
	msg "Setting up repository symlink..."
166
	mkdir -p "$path"/home/abuild/.cache/apks
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
	do_chroot_action "$path" chown abuild:abuild /home/abuild/${src}
	do_chroot_action "$path" ln -sf .cache/apks /home/abuild/repo

	msg "Build chroot is ready!"
}

build_package() {
	local path="$1"
	local apkbuild="$2"
	srcdir="$(dirname $apkbuild)"

	msg "Parsing $apkbuild..."
	. "$apkbuild"

	msg "Copying local sources..."

	mkdir -p "$path"/home/abuild/src
	chmod 666 "$path"/home/abuild/src

	for src in $source $install; do
		is_local $src || continue

		msg "${srcdir}/${src} -> ${path}/home/abuild/src/${src} ..."
		cp ${srcdir}/${src} "${path}"/home/abuild/${src}
		do_chroot_action "$path" chown abuild:abuild /home/abuild/${src}
	done

194
	for i in $triggers; do
195
		src=${i%=*}
196 197 198 199 200 201 202
		is_local $src || continue

		msg "${srcdir}/${src} -> ${path}/home/abuild/src/${src} ..."
		cp ${srcdir}/${src} "${path}"/home/abuild/${src}
		do_chroot_action "$path" chown abuild:abuild /home/abuild/${src}
	done

203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
	cp $apkbuild "$path"/home/abuild
	do_chroot_action "$path" chown abuild:abuild /home/abuild/$(basename $apkbuild)

	msg "Invoking abuild..."
	do_chroot_action "$path" su abuild -c "'cd /home/abuild; abuild -r'"

	msg "Copying back results to ${abuildrepo}..."
	mkdir -p ${abuildrepo}
	for papk in "${path}"/home/abuild/*.apk; do
		apk=$(basename $papk)
		msg "$papk -> ${abuildrepo}/${apk}"
		cp $papk ${abuildrepo}/${apk}
	done

	msg "Cleaning up..."
	rm -rf "$path"/home/abuild/src
	rm -rf "$path"/home/abuild/pkg
	rm -f "$path"/home/abuild/APKBUILD
}

usage() {
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252
	cat <<-EOF
		buildlab $program_version

		Common options:

		 -q  Quiet operation
		 -p  Path to buildroot

		Creating build roots (buildlab -C):

		 -m  APK repository mirror
		 -v  APK distribution version
		 -a  APK repository architecture
		 -k  Enable APK caching

		Updating build roots (buildlab -u):

		 No special options.

		Building packages (buildlab -b):

		 -b  APKBUILD file

		Examples:

		 sudo ./buildlab -C -p /home/nenolod/buildroot -m dl-3.alpinelinux.org -v edge -a x86_64
		 sudo ./buildlab -b /home/nenolod/aports/main/gnome-panel/APKBUILD -p /home/nenolod/buildroot
		 sudo ./buildlab -u -p /home/nenolod/buildroot
	EOF
253 254 255 256
}

unset force
unset recursive
257
while getopts "chqCkp:v:m:a:b:u" opt; do
258 259 260
	case $opt in
		'c') default_colors
		     color_opt="-c";;
261 262
		'h') usage;;
		'q') quiet="-q";;
263 264 265 266
		'C') create="-c";;
		'p') buildpath="$OPTARG";;
		'm') buildmirror="$OPTARG";;
		'v') buildver="$OPTARG";;
267 268
		'a') buildarch="$OPTARG";;
		'k') enablecache=1;;
269
		'b') buildpkg="$OPTARG";;
270
		'u') update="-u";;
271
	esac
272 273 274 275 276
done
shift $(( $OPTIND - 1 ))

if [ ! -z "$create" ]; then
	msg "Creating new chroot at $buildpath..."
277
	prepare_chroot $buildpath $buildver $buildmirror $buildarch $enablecache
278 279 280 281 282 283 284 285
	exit 0
fi

if [ ! -z "$buildpkg" ]; then
	msg "Building APKBUILD $buildpkg in chroot $buildpath..."
	build_package $buildpath $buildpkg
	exit 0
fi
286 287 288 289 290 291

if [ ! -z "$update" ]; then
	msg "Updating chroot at $buildpath..."
	update_chroot $buildpath
	exit 0
fi