--- makechrootpkg.sh.in +++ makechrootpkg.sh.ugly @@ -12,12 +12,7 @@ shopt -s nullglob -# So that usage conflicts between upstream and -par mkarchroot don't get hidden -# silently in a merge. -archroot() { - mkarchroot "$@" -} - +init_variables() { makepkg_args='-s --noconfirm -L' repack=false update_first=false @@ -28,13 +23,14 @@ temp_chroot=false chrootdir= passeddir= -declare -a install_pkgs -declare -i ret=0 +declare -ag install_pkgs +declare -ig ret=0 copy=$USER [[ -n $SUDO_USER ]] && copy=$SUDO_USER [[ -z "$copy" || $copy = root ]] && copy=copy src_owner=${SUDO_USER:-$USER} +} usage() { echo "Usage: ${0##*/} [options] -r [--] [makepkg args]" @@ -69,6 +65,7 @@ exit 1 } +parse_options_init() { while getopts 'hcudr:I:l:nT' arg; do case "$arg" in h) usage ;; @@ -129,8 +126,20 @@ # Note this is the same FD number as in mkarchroot lock_open_write 9 "$copydir" \ "Waiting for existing lock on chroot copy to be released: [$copy]" +} + +# Usage: chroot_sync $CHROOTDIR/$CHROOT [$CHROOTCOPY|$copydir] +chroot_sync() { + local chrootdir=$1 + local copy=$2 + local copydir='' + if [[ ${copy:0:1} = / ]]; then + copydir=$copy + else + copydir="$chrootdir/$copy" + fi + local chroottype=$(stat -f -c %T "$chrootdir") -if [[ ! -d $copydir ]] || $clean_first; then # Get a read lock on the root chroot to make # sure we don't clone a half-updated chroot lock_open_read 8 "$chrootdir/root" \ @@ -152,9 +161,16 @@ # Drop the read lock again lock_close 8 -fi +} + +# Usage: chroot_install_pkgs $copydir $pkgs... +chroot_install_pkgs() { + local copydir=$1 + shift + declare -i ret=0 + declare -a install_pkgs=("$@") + local pkgname -if [[ -n "${install_pkgs[*]}" ]]; then for install_pkg in "${install_pkgs[@]}"; do pkgname="${install_pkg##*/}" cp "$install_pkg" "$copydir/$pkgname" @@ -165,10 +181,10 @@ rm "$copydir/$pkgname" done - # If there is no PKGBUILD we have done - [[ -f PKGBUILD ]] || exit $ret -fi + return $ret +} +func1() { $update_first && archroot -u "$copydir" mkdir -p "$copydir/build" @@ -230,14 +246,24 @@ # Set target CARCH as it might be used within the PKGBUILD to select correct sources eval $(grep '^CARCH=' "$copydir/etc/makepkg.conf") export CARCH +} +# Usage: chroot_copy_in $copydir +# Environment: +# - In the dirctory of a PKGBUILD +# - $SRCDEST is set +chroot_copy_in() { +local copydir=$1 # Copy PKGBUILD and sources -cp PKGBUILD "$copydir/build/" +for recipe in PKGBUILD SRCBUILD; do +if [[ -f $recipe ]]; then +cp $recipe "$copydir/build/" ( - source PKGBUILD - for file in "${source[@]}"; do + source $recipe + for file in "${source[@]}" "${mksource[@]}"; do file="${file%%::*}" file="${file##*://*/}" + file="${file##*://}" if [[ -f $file ]]; then cp "$file" "$copydir/srcdest/" elif [[ -f $SRCDEST/$file ]]; then @@ -251,18 +277,30 @@ # evaluate any bash variables used eval file=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "$file")\" [[ -f $file ]] && cp "$file" "$copydir/build/" - done < <(sed -n "s/^[[:space:]]*$i=//p" PKGBUILD) + done < <(sed -n "s/^[[:space:]]*$i=//p" $recipe) done ) +fi +done chown -R nobody "$copydir"/{build,pkgdest,srcdest} +} +# Usage: chroot_let_nobody_use_pacman $copydir +chroot_let_nobody_use_pacman() { +local copydir=$1 cat > "$copydir/etc/sudoers.d/nobody-pacman" <"$copydir/chrootbuild" </dev/null repo-add repo.db.tar.gz "${pkgfile##*/}" popd >/dev/null - fi + done +} +# Usage: chroot_copy_out_pkgs $copydir $user +# Environment: +# - $PKGDEST is set +chroot_copy_out_pkgs() { + local copydir=$1 + local src_owner=$2 + for pkgfile in "$copydir"/pkgdest/*.pkg.tar*; do chown "$src_owner" "$pkgfile" mv "$pkgfile" "$PKGDEST" + if [[ $PKGDEST != . ]]; then + ln -sf "$PKGDEST/${pkgfile##*/}" . + fi done +} - for l in "$copydir"/build/*-{build,check,namcap,package,package_*}.log; do +# Usage: chroot_copy_out_pkgs $copydir $user +chroot_copy_out_logs() { + local copydir=$1 + local src_owner=$2 + for l in "$copydir"/build/*.log; do chown "$src_owner" "$l" [[ -f $l ]] && mv "$l" . done -else - # Just in case. We returned 1, make sure we fail - ret=1 -fi +} +# Usage: chroot_copy_out_srcs $copydir $user +# Environment: +# - $SRCDEST is set +chroot_copy_out_srcs() { +local copydir=$1 +local src_owner=$2 for f in "$copydir"/srcdest/*; do chown "$src_owner" "$f" mv "$f" "$SRCDEST" done +} -if $temp_chroot; then - stat_busy "Removing temporary directoy [$copy]" +# Usage: chroot_delete $copydir +chroot_delete() { + local chroottype=$(stat -f -c %T "$copydir") + stat_busy "Removing chroot copy [$copy]" if [[ "$chroottype" == btrfs ]]; then btrfs subvolume delete "$copydir" >/dev/null || die "Unable to delete subvolume $copydir" @@ -326,8 +389,39 @@ # remove lock file rm --force "$copydir.lock" stat_done -elif (( ret != 0 )); then - die "Build failed, check $copydir/build" -else - true -fi +} + +main() { + init_variables + parse_options_init "$@" + if [[ ! -d $copydir ]] || $clean_first; then + chroot_sync "$chrootdir" "$copy" + fi + if [[ -n "${install_pkgs[*]}" ]]; then + chroot_install_pkgs "$copydir" "${install_pkgs[@]}" + ret=$? + # If there is no PKGBUILD we have done + [[ -f PKGBUILD ]] || exit $ret + fi + func1 + chroot_copy_in "$copydir" + chroot_let_nobody_use_pacman "$copydir" + chroot_build "$copydir" "$makepkg_args" "$run_namcap" + func2 + if chroot_build; then + chroot_add_to_local_repo "$copydir" "$copydir"/pkgdest/*.pkg.tar* + chroot_copy_out_pkgs "$copydir" "$src_owner" + chroot_copy_out_logs "$copydir" "$src_owner" + else + # Just in case. We returned 1, make sure we fail + ret=1 + fi + chroot_copy_out_srcs "$copydir" "$src_owner" + if $temp_chroot; then + chroot_delete "$copydir" + elif (( ret != 0 )); then + die "Build failed, check $copydir/build" + else + true + fi +}