#! /bin/sh set -e PATH=/bin:/usr/bin:/usr/sbin:/usr/local/package/bin:/usr/local/bin umask 022 die() { echo "$@" exit 1 } die_usage() { die "usage: $0 example-1.2.3-0 [--purge] [--bind directory]" } ere_quote() { sed 's/[]\.|$(){}?+*^]/\\&/g' <<< "$*" } log_cmd() { echo "$@" "$@" } eval set -- $(getopt --options "" --longoptions purge,bind: -- "$@") while true; do case "$1" in --bind) opt_bind=1;bind_dir=$2;shift 2;; --purge) opt_purge=1;shift;; --) shift;break;; *) die "internal error: unknown option $!" esac done test $# -eq 1 || die_usage PKG="$1" PKG="${PKG%.build.sh}" grep -q -E "^$(ere_quote "$PKG")\b" /etc/mxpkg || die "$PKG not found in mxpkg" test -e "$PKG.build.sh" || die "$PKG.build.sh: file does not exist" test $UID -eq 0 || die "$0: please run with sudo" if [ ! -d "/package/pkg/$PKG" ]; then log_cmd mkdir -p "/package/pkg/$PKG" log_cmd chown build:build "/pkg/$PKG" fi if [ "$(stat -c %U "/pkg/$PKG")" != "build" ] && [ -z "$opt_purge" ] ; then echo "/pkg/$PKG is no longer owned by build user" echo "rerun with --purge if you want to build from scratch" exit 1 fi if [ -n "$opt_purge" ]; then # make double sure PKG is not empty even if bugs are introduced in code above test -z "$PKG" && die "internal error: PKG is empty" log_cmd find "/pkg/$PKG" -mindepth 1 -delete test "$(stat -c %U "/pkg/$PKG")" = "build" || log_cmd chown build:build "/pkg/$PKG" if [ -n "$opt_bind" -a -d "$bind_dir/pkg_bindmnt" ]; then log_cmd find "$bind_dir/pkg_bindmnt" -mindepth 1 -delete fi fi chmod a+rx "$PKG.build.sh" if [ -n "$opt_bind" ]; then mkdir -p "$bind_dir/pkg_bindmnt" chown build:build "$bind_dir/pkg_bindmnt" # check that '/pkg/$PKG' differs from intended location (i.e. isn't mounted already) if [ $(stat --format=%D:%i "$bind_dir/pkg_bindmnt") != $(stat --format=%D:%i /pkg/$PKG) ]; then log_cmd mount --bind "$bind_dir/pkg_bindmnt" /pkg/$PKG # prevent automount from unmounting exec 3</pkg/$PKG/. test $(stat --format=%D:%i "$bind_dir/pkg_bindmnt") = $(stat --format=%D:%i /pkg/$PKG) || die "unable to mount and lock '$bind_dir/pkg_bindmnt' on /pkg/$PKG" else die "'$bind_dir/pkg_bindmnt' is already mounted on /pkg/$PKG (try 'umount /pkg/$PKG')" fi fi echo "sudo -u build script -q -e -c \"./$PKG.build.sh\" /package/pkg/$PKG/$PKG.build.log" ( sudo -u build script -q -e -c "./$PKG.build.sh" /package/pkg/$PKG/$PKG.build.log sudo -u build cp "$PKG.build.sh" "/package/pkg/$PKG/$PKG.build.sh" ) # make double sure PKG is not empty even if bugs are introduced in code above test -z "$PKG" && die "internal error: PKG is empty" log_cmd chown -R bin:bin "/pkg/$PKG" if [ -n "$opt_bind" ]; then test -z "$PKG" && die "internal error: PKG variable is empty" test $(ls "/pkg/$PKG" | wc -l) = 0 && die "/pkg/$PKG contains no files" # withdraw our 'foot in the door' exec 3<&- log_cmd umount /pkg/$PKG # enforce single filesystem as source, and ignore .* log_cmd cp -ax $bind_dir/pkg_bindmnt/* /package/pkg/$PKG log_cmd chown bin:bin "/package/pkg/$PKG" fi