#!/bin/sh program_version=@VERSION@ sysconfdir=@sysconfdir@ abuildrepo=/var/lib/buildlab/result sharedir=${ABUILD_SHAREDIR:-@sharedir@} BUILD_BASE="build-base" SUDO=${SUDO:-"sudo"} FAKEROOT=${FAKEROOT:-"fakeroot"} APK=${APK:-apk} # read config ABUILD_CONF=${ABUILD_CONF:-"$sysconfdir/abuild.conf"} [ -f "$ABUILD_CONF" ] && . "$ABUILD_CONF" default_colors() { NORMAL="\033[1;0m" STRONG="\033[1;1m" RED="\033[1;31m" GREEN="\033[1;32m" YELLOW="\033[1;33m" BLUE="\033[1;34m" } default_colors is_local() { case "$1" in http://*|ftp://*|https://*|saveas-*://*) return 1;; esac return 0 } msg() { local prompt="$GREEN>>>${NORMAL}" [ -z "$quiet" ] && printf "${prompt} $@\n" >&2 } error() { local prompt="$RED>>>${NORMAL}" printf "${prompt} $@\n" >&2 } die() { error "$@" exit 1 } runpart() { local part=$1 msg "Running part $part" $part || die "$part failed" } 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 } do_chroot_action() { local path="$1" local command="$2" msg "Doing chroot action '$command' in '$path'..." do_chroot_open "$path" || return 1 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 do_chroot_close } update_chroot() { local path="$1" apk --root $path --repositories "$path"/etc/apk/repositories update apk --root $path --repositories "$path"/etc/apk/repositories upgrade -a } prepare_chroot() { local path="$1" local version="$2" local mirror="$3" local arch="$4" local enablecache="$5" msg "Setting up repositories for mirror $mirror with version $version at $path..." mkdir -p "$path"/etc/apk echo "http://$mirror/alpine/$version/main" >> "$path"/etc/apk/repositories echo "http://$mirror/alpine/$version/testing" >> "$path"/etc/apk/repositories if [ ! -z "$enablecache" ]; then mkdir -p "$path"/var/cache/apk ln -s /var/cache/apk "$path"/etc/apk/cache fi 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 mkdir -p "$path"/etc cp /etc/resolv.conf "$path"/etc/resolv.conf msg "Updating package lists..." apk --arch $buildarch --root $path --repositories "$path"/etc/apk/repositories update msg "Installing alpine-base..." apk --arch $buildarch --root $path --repositories "$path"/etc/apk/repositories add --initdb alpine-base msg "Installing abuild..." apk --arch $buildarch --root $path --repositories "$path"/etc/apk/repositories add --initdb abuild msg "Installing build-base..." apk --arch $buildarch --root $path --repositories "$path"/etc/apk/repositories add --initdb build-base msg "Adding abuild user..." do_chroot_action "$path" adduser -D -G abuild abuild echo "abuild ALL=NOPASSWD: ALL" >> "$path"/etc/sudoers chmod 440 "$path"/etc/sudoers msg "Generating buildlab signing keys..." do_chroot_action "$path" su abuild -c "'abuild-keygen -ai'" msg "Setting up repository symlink..." mkdir -p "$path"/home/abuild/.cache/apks 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 for i in $triggers; do src=${i%=*} 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 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() { 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 } unset force unset recursive while getopts "chqCkp:v:m:a:b:u" opt; do case $opt in 'c') default_colors color_opt="-c";; 'h') usage;; 'q') quiet="-q";; 'C') create="-c";; 'p') buildpath="$OPTARG";; 'm') buildmirror="$OPTARG";; 'v') buildver="$OPTARG";; 'a') buildarch="$OPTARG";; 'k') enablecache=1;; 'b') buildpkg="$OPTARG";; 'u') update="-u";; esac done shift $(( $OPTIND - 1 )) if [ ! -z "$create" ]; then msg "Creating new chroot at $buildpath..." prepare_chroot $buildpath $buildver $buildmirror $buildarch $enablecache exit 0 fi if [ ! -z "$buildpkg" ]; then msg "Building APKBUILD $buildpkg in chroot $buildpath..." build_package $buildpath $buildpkg exit 0 fi if [ ! -z "$update" ]; then msg "Updating chroot at $buildpath..." update_chroot $buildpath exit 0 fi