diff options
Diffstat (limited to 'src/chroot-tools')
-rw-r--r-- | src/chroot-tools/.gitignore | 4 | ||||
-rw-r--r-- | src/chroot-tools/Makefile | 48 | ||||
-rw-r--r-- | src/chroot-tools/hooks-chcleanup.sh | 15 | ||||
-rw-r--r-- | src/chroot-tools/hooks-check.sh | 38 | ||||
-rw-r--r-- | src/chroot-tools/hooks-distcc.sh | 86 | ||||
-rwxr-xr-x | src/chroot-tools/librechroot | 128 | ||||
-rwxr-xr-x | src/chroot-tools/libremakepkg | 410 | ||||
-rw-r--r-- | src/chroot-tools/makechrootpkg.sh.patch | 450 |
8 files changed, 630 insertions, 549 deletions
diff --git a/src/chroot-tools/.gitignore b/src/chroot-tools/.gitignore index fbb07f7..80e1000 100644 --- a/src/chroot-tools/.gitignore +++ b/src/chroot-tools/.gitignore @@ -1,3 +1,5 @@ makechrootpkg.sh* !makechrootpkg.sh.patch -archroot*
\ No newline at end of file + +arch-nspawn* +mkarchroot* diff --git a/src/chroot-tools/Makefile b/src/chroot-tools/Makefile index 258caea..0540636 100644 --- a/src/chroot-tools/Makefile +++ b/src/chroot-tools/Makefile @@ -1,31 +1,39 @@ -# The makechrootpkg flow is: -# $(devtoolsdir)/*.in -> *.sh.in + *.sh.patch -> *.sh.ugly -> *.sh - -copy_files = makechrootpkg.sh.in archroot.in -libs = makechrootpkg.sh -progs = archroot +# These files are coming from devtools +copy_files = makechrootpkg.sh.in mkarchroot.in arch-nspawn.in +# These are programs that we will use internally, but shouldn't be in PATH +libexecs = mkarchroot arch-nspawn distcc-tool chcleanup +no-progs = $(libexecs) +# These are the shell libraries we will use +libs = makechrootpkg.sh $(wildcard hooks-*.sh) + +pkglibexecdir = $(libexecdir)/libretools/chroot clean_files = makechrootpkg.sh.ugly* *~ include ../../common.mk -# Copy ############################################################### +# Usage: $(call indent,FILENAME) +# Command to auto-indent a file. +indent = emacs --batch $1 \ + --eval '(setq sh-basic-offset 8)' \ + --eval '(indent-region (point-min) (point-max) nil)' \ + -f save-buffer &>/dev/null -makechrootpkg.sh.in: %.sh.in: $(devtoolsdir)/%.in - cp $< $@ +# makechrootpkg.sh is special, we patch it and do fancy stuff +# The flow is: +# $(devtoolsdir)/*.in -> *.sh.in + *.sh.patch -> *.sh.ugly -> *.sh -archroot.in: $(devtoolsdir)/mkarchroot.in +makechrootpkg.sh.in: %.sh.in: $(devtoolsdir)/%.in cp $< $@ - -# Build ############################################################## - makechrootpkg.sh.ugly: %.ugly: %.in %.patch Makefile - @echo "GEN $@" - @cp $*.in $@ - @patch $@ $*.patch || { rm -f -- '$@'; false; } - + cp $*.in $@ + @echo 'PATCH $@ $*.patch'; patch $@ $*.patch || { rm -f -- '$@'; false; } makechrootpkg.sh: %: %.ugly Makefile - @echo "GEN $@" - @$(edit) <"$<" >"$@" || { rm -f -- '$@'; false; } - $(call indent,$@) || { rm -f -- '$@'; false; } + @echo 'EDIT < $< > $@'; $(edit) <'$<' >'$@' || { rm -f -- '$@'; false; } + @echo 'INDENT $@'; $(call indent,$@) || { rm -f -- '$@'; false; } + +mkarchroot: mkarchroot.in Makefile + @echo '< $< M4_EDIT | SED > $@' + @<'$<' $(edit) | sed 's|arch-nspawn|$$(librelib chroot/&)|' >'$@' || { rm -f -- '$@'; false; } + @echo 'CHMOD $<'; chmod 755 "$@" || { rm -f -- '$@'; false; } archroot: %: %.in Makefile @echo "GEN $@" diff --git a/src/chroot-tools/hooks-chcleanup.sh b/src/chroot-tools/hooks-chcleanup.sh new file mode 100644 index 0000000..6a95dfb --- /dev/null +++ b/src/chroot-tools/hooks-chcleanup.sh @@ -0,0 +1,15 @@ +#!/bin/bash -euE + +hooks_pre_build+=("clean_chroot") + +clean_chroot() ( + set +x + local copydir=$1 + if $INCHROOT; then + cd /build + sudo -u nobody "$(librelib chroot/chcleanup)" + else + librechroot -l "$copydir" clean-pkgs + fi + r=$?; echo clean_chroot returning $r; return $r +) diff --git a/src/chroot-tools/hooks-check.sh b/src/chroot-tools/hooks-check.sh new file mode 100644 index 0000000..dee7c04 --- /dev/null +++ b/src/chroot-tools/hooks-check.sh @@ -0,0 +1,38 @@ +#!/bin/bash -euE + +hook_check_pkgbuild+=("check_pkgbuild_dependencies") +check_pkgbuild_dependencies() { + local s=0 + sudo -EH -u "$LIBREUSER" pkgbuild-check-nonfree -f || s=$? + case $s in + 0) :;; + 15) error "This PKGBUILD links to known unfree packages"; return 1;; + *) warning "pkgbuild-check-nonfree failed to run";; + esac +} + +hook_check_pkgbuild+=("check_pkgbuild_license") +check_pkgbuild_license() { + local s=0 + sudo -EH -u "$LIBREUSER" pkgbuild-check-licenses -f || s=$? + for i in 1 2 4; do + if [[ $i -eq $(($s & $i)) ]]; then + case $i in + 1) warning "pkgbuild-check-licenses encountered an error";; + 2) warning "This PKGBUILD has an uncommon license";; + 4) error "This PKGBUILD has a known nonfree license"; ret=1;; + esac + fi + done +} + +#hook_check_pkgbuild+=("check_pkgbuild_namcap") +check_pkgbuild_namcap() { + sudo -EH -u "$LIBREUSER" namcap PKGBUILD +} + +#hook_check_pkg+=("check_pkg") +check_pkg() { + # TODO + : +} diff --git a/src/chroot-tools/hooks-distcc.sh b/src/chroot-tools/hooks-distcc.sh new file mode 100644 index 0000000..bbbc3e9 --- /dev/null +++ b/src/chroot-tools/hooks-distcc.sh @@ -0,0 +1,86 @@ +#!/bin/bash -euE + +hook_pre_build+=("distcc_start") +hook_post_build+=("distcc_stop") + +_distcc_check() { + local copydir=$1 + local home=$2 + + local files=( + "$copydir/bin/distcc-tool" + "$copydir/run/distcc-tool.pid" + "$home/.makepkg.conf" + "$home/.ssh/config" + ) + + local file_err=false + for files in "${files[@]}"; do + if [[ -f $file ]]; then + file_err=true + error "Auto-generated file already exists, remove it: %s" "$file" + fi + done + if $file_err; then + exit 1 + fi +} + +distcc_start() { + local copydir=$1 + + # Because /{,usr/}{,s}bin are all symlinked together for + # fileystem 2013.05-2 and up, I can take shortcuts when checking for + # existance of programs. + if $NONET && [[ -f "$copydir/bin/socat" && -f "$copydir/bin/distcc" ]]; then + local home + if $INCHROOT; then + home=$LIBREHOME + else + home="$copydir/build" + fi + + _distcc_check + + local _distcc_tool=$(librelib chroot/distcc-tool) + install -m755 "$_distcc_tool" "$copydir/bin/distcc-tool" + + mkdir -p "$home/.ssh" + + printf '%s\n' \ + '/bin/distcc-tool idaemon "$DISTCC_HOSTS" &' \ + 'DISTCC_HOSTS="$(/bin/distcc-tool rewrite "$DISTCC_HOSTS")"' \ + > "$home/.makepkg.conf" + + printf '%s\n' \ + 'Host *' \ + ' ProxyCommand /bin/distcc-tool client %h %p' \ + > "$home/.ssh/config" + + "$_distcc_tool" odaemon "$copydir" & + echo $! > "$copydir/run/distcc-tool.pid" + fi +} + +distcc_stop() { + local copydir=$1 + + local home + if $INCHROOT; then + home=$LIBREHOME + else + home="$copydir/build" + fi + + if [[ -f "$copydir/run/distcc-tool.pid" ]]; then + + odaemon=$(cat "$copydir/distcc-tool.pid") + kill -- "$odaemon" + + rm -f -- \ + "$home/.makepkg.conf" \ + "$home/.ssh/config" \ + "$copydir/bin/distcc-tool" \ + "$copydir/run/distcc-tool.pid" + fi +} diff --git a/src/chroot-tools/librechroot b/src/chroot-tools/librechroot index e82b18c..e5ca1f7 100755 --- a/src/chroot-tools/librechroot +++ b/src/chroot-tools/librechroot @@ -25,18 +25,26 @@ # - the commands=() array # - the case statement in main() -. $(librelib conf.sh) +. $(librelib conf) load_files chroot . libremessages -. $(librelib makechrootpkg) + +shopt -s nullglob +umask 0022 + +readonly _arch_nspawn=$(librelib chroot/arch-nspawn) +readonly _mkarchroot=$(librelib chroot/mkarchroot) +readonly _makechrootpkg=$(librelib chroot/makechrootpkg.sh) # Because the makechrootpkg.sh library functions don't work with -euE -normshell() ( +_makechrootpkg() ( set +euE + . "$_makechrootpkg" "$@" ) +# Usage: make_empty_repo $copydir make_empty_repo() { local copydir=$1 mkdir -p "${copydir}/repo" @@ -44,8 +52,21 @@ make_empty_repo() { ln -s "repo.db.tar.gz" "${copydir}/repo/repo.db" } +# Usage: chroot_add_to_local_repo $copydir $pkgfiles... +chroot_add_to_local_repo() { + local copydir=$1; shift + mkdir -p "$copydir/repo" + local pkgfile + for pkgfile in "$@"; do + cp "$pkgfile" "$copydir/repo" + pushd "$copydir/repo" >/dev/null + repo-add repo.db.tar.gz "${pkgfile##*/}" + popd >/dev/null + done +} + usage() { - calculate_directories + eval "$(calculate_directories)" print "Usage: %s [OPTIONS] COMMAND [ARGS...]" "${0##*/}" print 'Interacts with an archroot (arch chroot).' echo @@ -99,6 +120,8 @@ usage() { flag '-N' 'Disable networking in the chroot' flag "-C <$(_ FILE)>" 'Copy this file to `$copydir/etc/pacman.conf`' flag "-M <$(_ FILE)>" 'Copy this file to `$copydir/etc/makepkg.conf`' + flag "-w <$(_ 'PATH[:PATH]')>" 'Bind mount a file or directory, read/write' + flag "-r <$(_ 'PATH[:PATH]')>" 'Bind mount a file or directory, read-only' echo print 'Commands:' print ' Create/copy/delete:' @@ -120,7 +143,7 @@ usage() { flag 'clean-repo' 'Clean /repo in the chroot copy' flag 'help' 'Show this message' } -commands=( +readonly commands=( noop make sync delete install-file install-name update clean-pkgs run enter clean-repo help @@ -130,6 +153,7 @@ commands=( calculate_directories() { # Don't assume that CHROOTDIR or CHROOT are set, # but assume that COPY is set. + local rootdir copydir if [[ -n ${CHROOTDIR:-} ]] && [[ -n ${CHROOT:-} ]]; then rootdir="${CHROOTDIR}/${CHROOT}/root" @@ -144,6 +168,18 @@ calculate_directories() { else copydir='' fi + + declare -p rootdir + declare -p copydir +} + +arch_nspawn_flags=() +sysd_nspawn_flags=() +arch-nspawn() { + local copydir=$1; shift + set +u # if an array is empty, it counts as unbound + "$_arch_nspawn" "${arch_nspawn_flags[@]}" "$copydir" "${sysd_nspawn_flags[@]}" -- "$@" + set -u } # Globals: $CHROOTDIR, $CHROOT, $COPY, $rootdir and $copydir @@ -152,19 +188,14 @@ main() { [[ $COPY != root ]] || COPY=copy local mode=enter - local archroot_args=() - while getopts 'n:l:NC:M:' arg; do - case $arg in + while getopts 'n:l:NC:M:w:r:' opt; do + case $opt in n) CHROOT=$OPTARG;; l) COPY=$OPTARG;; - N) - # We do this so that it carries through to - # chroot_* functions - archroot() { - $(which archroot) -N "$@" - } - ;; - C|M) archroot_args+=(-$arg "$OPTARG");; + N) sysd_nspawn_flags+=(--private-network);; + C|M) arch_nspawn_flags+=(-$opt "$OPTARG");; + w) sysd_nspawn_flags+=("--bind=$OPTARG");; + r) sysd_nspawn_flags+=("--bind-ro=$OPTARG");; *) usage >/dev/stderr; return 1;; esac done @@ -188,7 +219,12 @@ main() { fi check_vars chroot CHROOTDIR CHROOT - calculate_directories + eval "$(calculate_directories)" + + readonly LIBREUSER LIBREHOME + readonly CHROOTDIR CHROOT COPY + readonly rootdir copydir + readonly mode ######################################################################## @@ -200,29 +236,27 @@ main() { umask 0022 # Keep this lock as long as we are running - # Note that '9' is the same FD number as in (mk)archroot - lock_open_write 9 "$copydir" \ + # Note that '9' is the same FD number as in mkarchroot et al. + lock 9 "$copydir.lock" \ "Waiting for existing lock on chroot copy to be released: [%s]" "$COPY" if [[ ! -d $rootdir ]]; then msg "Creating 'root' copy for chroot [%s]" "$CHROOT" - set +u # if archroot_args is empty, it counts as unbound - archroot "${archroot_args[@]}" -m "$rootdir" base-devel + set +u # if an array is empty, it counts as unbound + "$_mkarchroot" "${arch_nspawn_flags[@]}" "$rootdir" base-devel set -u make_empty_repo "$rootdir" fi if [[ ! -d $copydir ]] || [[ $mode == sync ]]; then msg "Syncing copy [%s] with root copy" "$COPY" - normshell chroot_sync "$CHROOTDIR/$CHROOT" "$COPY" + _makechrootpkg sync_chroot "$CHROOTDIR/$CHROOT" "$COPY" fi mkdir -p "$copydir/etc/libretools.d" { - if [[ -n ${CHROOTEXTRAPKG[@]:-} ]]; then - printf 'CHROOTEXTRAPKG=(' - printf "'%s' " "${CHROOTEXTRAPKG[@]}" - printf ')\n' + if [[ -n ${CHROOTEXTRAPKG[*]:-} ]]; then + declare -p CHROOTEXTRAPKG | sed -r 's/declare( -.)* //' else printf 'CHROOTEXTRAPKG=()\n' fi @@ -234,9 +268,8 @@ main() { # - overwrite \`/etc/pacman.d/mirrorlist'" # - set \`CacheDir' in \`/etc/pacman.conf'" # - apply -C or -M flags - set +u # if archroot_args is empty, it counts as unbound - archroot "${archroot_args[@]}" -r "$copydir" true - set -u + arch-nspawn "$copydir" true + arch_nspawn_flags=() # XXX dirty hack, don't apply -C or -M again fi ######################################################################## @@ -246,30 +279,41 @@ main() { noop|make|sync) :;; delete) if [[ -d $copydir ]]; then - normshell chroot_delete "$copydir" + _makechrootpkg delete_chroot "$copydir" "$COPY" fi ;; # Dealing with packages install-file) - normshell chroot_install_pkgs "$copydir" "$@" - normshell chroot_add_to_local_repo "$copydir" "$@" + _makechrootpkg install_packages "$copydir" "$@" + chroot_add_to_local_repo "$copydir" "$@" + ;; + install-name) + arch-nspawn "$copydir" pacman -Sy "$@" + ;; + update) + arch-nspawn "$copydir" pacman -Syu --noconfirm ;; - install-name) archroot -r "$copydir" pacman -Sy "$@";; - update) archroot -u "$copydir";; clean-pkgs) - trap "rm -f '$copydir'/clean '$copydir'/chrootexec" EXIT - cp -a "$(which chcleanup)" "$copydir/clean" - echo '#!/bin/bash' > "$copydir/chrootexec" - echo 'mkdir -p /build' >> "$copydir/chrootexec" - echo 'cd /build; /clean' >> "$copydir/chrootexec" + trap "rm -f '$copydir'/bin/chcleanup '$copydir'/chrootexec" EXIT + install -m755 "$(librelib chroot/chcleanup)" "$copydir/bin/chcleanup" + printf '%s\n' \ + '#!/bin/bash' \ + 'mkdir -p /build' \ + 'cd /build' \ + '/bin/chcleanup' \ + > "$copydir/chrootexec" chmod 755 "$copydir/chrootexec" - archroot -r "$copydir" /chrootexec + arch-nspawn "$copydir" /chrootexec ;; # Other - run) archroot -r "$copydir" "$@";; - enter) archroot -r "$copydir" bash;; + run) + arch-nspawn "$copydir" "$@" + ;; + enter) + arch-nspawn "$copydir" bash + ;; clean-repo) rm -rf "${copydir}"/repo/* make_empty_repo "$copydir" diff --git a/src/chroot-tools/libremakepkg b/src/chroot-tools/libremakepkg index a1d30d4..22e7a7f 100755 --- a/src/chroot-tools/libremakepkg +++ b/src/chroot-tools/libremakepkg @@ -20,251 +20,94 @@ # You should have received a copy of the GNU General Public License # along with Parabola. If not, see <http://www.gnu.org/licenses/>. -. $(librelib conf.sh) -load_files chroot - -. libremessages -makechrootpkg=$(librelib makechrootpkg) +. $(librelib conf) +. $(librelib messages) +. $(librelib chroot/makechrootpkg.sh) shopt -s nullglob umask 0022 -# Boring/mundane functions ##################################################### - -# End inmediately but print a useful message -trap_exit() { - error "$*" - $INCHROOT || chroot_copy_out "$copydir" "$LIBREUSER" - exit 1 -} - -# Usage run [-N] $copydir "$cmd" -# Runs cmd properly, whether in a chroot already or not. -# -# Note that $cmd is a quoted string, not a list of arguments. -# $copydir=/ if INCHROOT=true -# -# Environment -# - $INCHROOT is set -run() ( - local HASNET=true - [[ $1 == -N ]] && { HASNET=false; shift; } - local copydir=$1; shift - local cmd="$*" +# Global variables: +readonly INCHROOT=$([[ -f /.arch-chroot ]] && echo true || echo false) +NONET=true # can be changed with the -N flag +# {SRC,LOG,PKG}DEST set at runtime by makepkg.conf +# MAKEFLAGS, PACKAGER set at runtime by makepkg.conf +# LIBREUSER, LIBREHOME are set by conf.sh - if $HASNET; then - trap "rm -f -- '$copydir/chrootexec'" EXIT - else - distcc_start "$copydir" - trap "rm -f -- '$copydir/chrootexec'; distcc_stop '$copydir'" EXIT - fi +# Hooks ######################################################################## - cat >"$copydir/chrootexec" <<EOF -#!/bin/bash -. /etc/profile -${INCHROOT} || export HOME=/build -${INCHROOT} || cd /build +hook_pre_build=(:) +hook_post_build=(:) +hook_check_pkgbuild=(:) +hook_check_pkg=(:) +. $(librelib chroot/hooks-chcleanup.sh) +. $(librelib chroot/hooks-check.sh) +. $(librelib chroot/hooks-distcc.sh) -${cmd} -EOF - chmod 755 "$copydir/chrootexec" - - local flags='' - if $INCHROOT; then - $HASNET || flags='-n' - unshare $flags -- /chrootexec - else - $HASNET || flags='-N' - librechroot $flags -l "$copydir" run /chrootexec - fi -) +# Boring/mundane functions ##################################################### -distcc_start() { +# Usage: exit_copy $copydir $src_owner +# End immediately, but copy log files out +exit_copy() { local copydir=$1 - # Because /{,usr/}{,s}bin are all symlinked together for - # fileystem 2013.05-2 and up, I can take shortcuts when checking for - # existance of programs. - if [[ -f "$copydir/bin/socat" && -f "$copydir/bin/distcc" ]]; then - local home=$LIBREHOME - $INCHROOT || home="$copydir/build" - - cp -a "$(which distcc-tool)" "$copydir/distcc-tool" - - mkdir -p "$home/.ssh" - - printf '%s\n' \ - '/distcc-tool idaemon "$DISTCC_HOSTS" &' \ - 'DISTCC_HOSTS="$(/distcc-tool rewrite "$DISTCC_HOSTS")"' \ - > "$home/.makepkg.conf" - - printf '%s\n' \ - 'Host *' \ - ' ProxyCommand /distcc-tool client %h %p' \ - > "$home/.ssh/config" - - distcc-tool odaemon "$copydir" & - echo $! > "$copydir/distcc-tool.pid" + local src_owner=$2 + if ! $INCHROOT; then + msg "Copying log and package files out of the chroot..." + move_products "$copydir" "$src_owner" fi } -distcc_stop() { - local copydir=$1 - local home=$LIBREHOME - $INCHROOT || home="$copydir/build" - if [[ -f "$copydir/distcc-tool.pid" ]]; then - - odaemon=$(cat "$copydir/distcc-tool.pid") - kill -- $odaemon - - rm -f -- \ - "$copydir/distcc-tool" \ - "$home/.makepkg.conf" \ - "$home/.ssh/config" \ - "$copydir/distcc-tool.pid" +# Usage; run_hook $hookname $args... +run_hook() { + local hookname=$1; shift + local hookvar="hook_${hookname}[@]" + local fails=() + msg "Running hook: %s" "$hookname" + for hook in "${!hookvar}"; do + msg2 'hook: %s' "$hook" + "$hook" "$@" || { error "result: %s" $?; fails+=("$hook"); } + done + if [[ ${#fails[@]} -gt 0 ]]; then + error "Failure(s) in %s: %s" "$hookname" "${fails[*]}" + return 1 fi + return 0 } # Usage: add_to_local_repo $copydir $pkgfiles... -add_to_local_repo() ( - set +euE - . $makechrootpkg - chroot_add_to_local_repo "$@" -) - -# Usage: chroot_copy_in $copydir -# Environment: -# - In the dirctory of a PKGBUILD -# - $SRCDEST is set -chroot_copy_in() ( - set +euE - . $makechrootpkg - chroot_copy_in "$@" -) - -# Usage: chroot_copy_out $copydir $owner -# Environment: -# - $SRCDEST is set -# - $PKGDEST is set -chroot_copy_out() ( - set +euE - . $makechrootpkg - chroot_copy_out_pkgs "$@" - chroot_copy_out_logs "$@" - chroot_copy_out_srcs "$@" -) - -# Usage: chroot_let_nobody_use_pacman $copydir -chroot_let_nobody_use_pacman() ( - set +euE - . $makechrootpkg - chroot_let_nobody_use_pacman "$@" -) - -# Usage: chroot_init $copydir $repack -# Environment -# - $LIBREHOME is set -chroot_init() { - local copydir=$1 - local repack=$2 - - librechroot -l "$copydir" make # make sure the chroot exists - mkdir -p "$copydir"/{build,pkgdest,srcdest} - - # Remove anything in there UNLESS -R (repack) was passed - $repack || rm -rf "$copydir"/build/* - - if [[ -r "$LIBREHOME/.gnupg/pubring.gpg" ]]; then - install -D "$LIBREHOME/.gnupg/pubring.gpg" "$copydir/build/.gnupg/pubring.gpg" - fi - rm -f "$copydir/build/.makepkg.conf" - - MAKEPKG_CONF="$copydir/etc/makepkg.conf" set_conf_makepkg PKGDEST /pkgdest - MAKEPKG_CONF="$copydir/etc/makepkg.conf" set_conf_makepkg SRCDEST /srcdest - local PACKAGER="$(get_conf_makepkg PACKAGER '')" - if [[ -n $PACKAGER ]]; then - MAKEPKG_CONF="$copydir/etc/makepkg.conf" set_conf_makepkg PACKAGER "$PACKAGER" - fi - unset PACKAGER - - if ! grep -q '^\[repo\]' "$copydir/etc/pacman.conf"; then - cat >> "$copydir/etc/pacman.conf" <<EOF -[repo] -SigLevel = Optional TrustAll -Server = file:///repo -EOF - fi - - chroot_let_nobody_use_pacman "$copydir" +add_to_local_repo() { + local copydir=$1; shift + mkdir -p "$copydir/repo" + local pkgfile + for pkgfile in "$@"; do + cp "$pkgfile" "$copydir/repo" + pushd "$copydir/repo" >/dev/null + repo-add repo.db.tar.gz "${pkgfile##*/}" + popd >/dev/null + done } -# Core functions ############################################################### +build() ( + local copydir=$1; shift + local cmd=(/chrootbuild "$@") -# Usage: extract -# Extracts the sources (`makepkg -o`) -# Environment: -# - $INCHROOT is set -# - $copydir is set -# - $LIBREUSER is set -extract() ( - local user=$LIBREUSER - $INCHROOT || user=nobody + run_hook pre_build "$copydir" + trap "run_hook post_build '$copydir'" EXIT - local clean + local netflag='' if $INCHROOT; then - clean=chcleanup + ! $NONET || netflag='-n' + unshare $netflag -- "${cmd[@]}" else - trap "rm -f '$copydir/clean'" EXIT - cp -a "$(which chcleanup)" "${copydir}/clean" - clean=/clean + ! $NONET || netflag='-N' + librechroot $netflag \ + -r "$PWD:/startdir_host" \ + -r "$SRCDEST:/srcdest_host" \ + -l "$copydir" \ + run "${cmd[@]}" fi - - run "$copydir" "${clean} && sudo -u ${user} -- makepkg ${makepkg_args} -o" ) -# Usage: build -# Builds the package (`makepkg -e`) -# Environment: -# - $INCHROOT is set -# - $copydir is set -# - $LIBREUSER is set -build() { - local user=$LIBREUSER - $INCHROOT || user=nobody - - if $NONET; then - run -N "$copydir" "sudo -u ${user} -- makepkg ${makepkg_args} -e" - else - run "$copydir" "sudo -u ${user} -- makepkg ${makepkg_args} -e" - fi -} - -# Functions that check for issues with the build ############################### - -check_pkgbuild() { - msg "Checking PKGBUILD for issues" - # TODO - if ! pkgbuild-check-nonfree -f; then - if [[ $? -eq 15 ]]; then - # other errors mean fail, not nonfree - error "PKGBUILD contains non-free issues" - exit 15 - else - warning "PKGBUILD couldn't be check aganist non-free issues" - fi - fi -} - -check_src() { - msg "Checking src directory for issues" - # TODO -} - -check_pkg() { - msg "Checking final package for issues" - # TODO -} - - # The main program ############################################################# usage() { @@ -291,59 +134,65 @@ usage() { echo print 'Options:' flag "-n <$(_ CHROOT)>" 'Name of the chroot to use' - flag "-l <$(_ COPY)>" 'Name of, or absolute path to, the copy to use' - flag '-N' \ - "Don't disable networking during build() and package(). PLEASE don't use this unless you have a special reason, its use is a violation of Parabola policy." + flag "-l <$(_ COPY)>" 'Name of, or absolute path to, the chroot copy to use' + flag '-N' "Don't disable networking during build() and + package(). PLEASE don't use this unless you + have a special reason, its use is a violation + of Parabola policy." flag '-R' 'Repackage contents of the package without rebuilding' flag '-h' 'Show this message' } -# Globals: $CHROOTDIR, $CHROOT, $COPY and $copydir -# Globals: $makepkg_args, $INCHROOT -main() { - # Parse command line ################################################### - - COPY=$LIBREUSER - [[ $COPY != root ]] || COPY=copy +# Convenience method for use in option parsing +err_chflag() { + local flag=$1 + error 'The -%s flag does not make sense inside of a chroot' "$flag" + return 1 +} - makepkg_args='-s --noconfirm -L ' +main() { + # Initial variable values ############################################## + local copy=$([[ $LIBREUSER == root ]] && echo copy || echo "$LIBREUSER") + local makepkg_args=(-s --noconfirm -L) local repack=false + local chroot='' - INCHROOT=false - if [[ -f /.arch-chroot ]]; then - INCHROOT=true - fi - - NONET=true - while getopts 'n:l:NRh' arg ; do - case "${arg}" in - n) CHROOT=$OPTARG;; - l) COPY=$OPTARG;; + # Parse command line options ########################################### + while getopts 'n:l:NRh' flag ; do + case "${flag}" in + n) if $INCHROOT; then err_chflag "$flag"; else chroot=$OPTARG; fi;; + l) if $INCHROOT; then err_chflag "$flag"; else copy=$OPTARG; fi;; N) NONET=false;; - R) repack=true; makepkg_args+=" -R";; + R) repack=true; makepkg_args+=(-R);; h) usage; return 0;; - *) usage; return 1;; + *) usage >&2; return 1;; esac done shift $(($OPTIND - 1)) # Pass all arguments after -- right to makepkg - makepkg_args+=" $*" + makepkg_args+=("$@") + # Resolve the chroot path ############################################## + local copydir if $INCHROOT; then copydir='/' else + load_files chroot check_vars chroot CHROOTDIR CHROOT - if [[ ${COPY:0:1} = / ]]; then - copydir=$COPY + [[ -z ${chroot} ]] || CHROOT=$chroot + if [[ ${copy:0:1} = / ]]; then + copydir=$copy else - copydir="${CHROOTDIR}/${CHROOT}/${COPY}" + copydir="${CHROOTDIR}/${CHROOT}/${copy}" fi + unset CHROOTDIR CHROOTEXTRAPKG fi + unset chroot - # Init ################################################################# + # Quick sanity check ################################################### if (( EUID )); then - error "This script must be run as root" + error "This program must be run as root" exit 1 fi @@ -353,36 +202,47 @@ main() { exit 1 fi - # Trap signals from makepkg - trap 'trap_exit "(libremakepkg): TERM signal caught. Exiting..."' TERM HUP QUIT - trap 'trap_exit "(libremakepkg): Aborted by user! Exiting..."' INT - trap 'trap_exit "(libremakepkg): An error has occurred. Exiting..."' ERR - - SRCDEST="$(get_conf_makepkg SRCDEST .)" - PKGDEST="$(get_conf_makepkg PKGDEST .)" - - # OK, we're starting now ############################################### - - $INCHROOT || lock_open_write 9 "$copydir" \ - "Waiting for existing lock on chroot copy to be released: [%s]" "$COPY" + # Load makepkg configuration ########################################### + # Note that all of these are globals + SRCDEST="$(get_conf_makepkg SRCDEST "$PWD")" + PKGDEST="$(get_conf_makepkg PKGDEST "$PWD")" + LOGDEST="$(get_conf_makepkg LOGDEST "$PWD")" + mkdir -p "$SRCDEST" "$PKGDEST" "$LOGDEST" + MAKEFLAGS="$(get_conf_makepkg MAKEFLAGS '')" + PACKAGER="$(get_conf_makepkg PACKAGER '')" - # Set target CARCH as it might be used within the PKGBUILD to select - # correct sources - MAKEPKG_CONF=$copydir/etc/makepkg.conf - export CARCH="$(get_conf_makepkg CARCH)" - unset MAKEPKG_CONF + # OK, we are starting now ############################################## - $INCHROOT || chroot_init "$copydir" "$repack" - - check_pkgbuild - $INCHROOT || chroot_copy_in "$copydir" - $repack || extract - check_src - build - check_pkg + if $INCHROOT; then + lock 9 "/build/.lock" \ + "Waiting for existing lock on build directory to be released" + else + # Obtain a lock on the chroot + lock 9 "$copydir.lock" \ + "Waiting for existing lock on chroot copy to be released: [%s]" "$copy" + # Create the chroot if it does not exist + librechroot -n "$CHROOT" -l "$copy" make + fi + # Set target CARCH + # note that we waited until after locking/creating the chroot to do this + export CARCH="$(MAKEPKG_CONF=$copydir/etc/makepkg.conf get_conf_makepkg CARCH)" + + # Pre-build + run_hook check_pkgbuild + download_sources "$copydir" "$LIBREUSER" + prepare_chroot "$copydir" "$LIBREHOME" "$repack" false + clean_chroot "$copydir" + + # Build + trap "exit_copy '$copydir' '$LIBREUSER'" EXIT + warning 'Entering build...' + build "$copydir" "${makepkg_args[@]}" + # Post-build + warning 'Entering hook check_pkg...' + run_hook check_pkg + warning 'Entering add_to_local_repo ...' add_to_local_repo "$copydir" "$copydir"/pkgdest/*.pkg.tar* - $INCHROOT || chroot_copy_out "$copydir" "$LIBREUSER" } main "$@" diff --git a/src/chroot-tools/makechrootpkg.sh.patch b/src/chroot-tools/makechrootpkg.sh.patch index 505b96a..f5b8ed7 100644 --- a/src/chroot-tools/makechrootpkg.sh.patch +++ b/src/chroot-tools/makechrootpkg.sh.patch @@ -1,52 +1,81 @@ ---- makechrootpkg.sh.in -+++ makechrootpkg.sh.ugly -@@ -12,12 +12,7 @@ +--- makechrootpkg.sh.in 2013-09-08 23:01:20.000000000 -0400 ++++ makechrootpkg.sh.ugly 2013-09-09 15:43:06.000000000 -0400 +@@ -12,6 +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' + _makepkg_args=(-s --noconfirm -L --holdver) + makepkg_args=("${_makepkg_args[@]}") 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 +@@ -26,9 +27,10 @@ + declare -i ret=0 copy=$USER - [[ -n $SUDO_USER ]] && copy=$SUDO_USER +-[[ -n $SUDO_USER ]] && copy=$SUDO_USER ++[[ -n ${SUDO_USER:-} ]] && copy=$SUDO_USER [[ -z "$copy" || $copy = root ]] && copy=copy src_owner=${SUDO_USER:-$USER} +} usage() { echo "Usage: ${0##*/} [options] -r <chrootdir> [--] [makepkg args]" -@@ -69,6 +65,7 @@ +@@ -62,6 +64,7 @@ exit 1 } +parse_options_init() { - while getopts 'hcudr:I:l:nT' arg; do + while getopts 'hcur: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]" +@@ -86,9 +89,6 @@ + [[ ! -d $chrootdir ]] && die "No chroot dir defined, or invalid path '%s'" "$passeddir" + [[ ! -d $chrootdir/root ]] && die "Missing chroot dir root directory. Try using: mkarchroot %s/root base-devel" "$chrootdir" + +-# Detect chrootdir filesystem type +-chroottype=$(stat -f -c %T "$chrootdir") +- + if [[ ${copy:0:1} = / ]]; then + copydir=$copy + else +@@ -103,30 +103,47 @@ + repack=true + fi + +-if [[ -n $SUDO_USER ]]; then ++if [[ -n ${SUDO_USER:-} ]]; then + USER_HOME=$(eval echo ~$SUDO_USER) + else + USER_HOME=$HOME + fi +} -+ -+# Usage: chroot_sync $CHROOTDIR/$CHROOT [$CHROOTCOPY|$copydir] -+chroot_sync() { + + # {{{ functions ++# Usage: load_vars $makepkg_conf ++# Globals: ++# - SRCDEST ++# - LOGDEST ++# - PKGDEST ++# - MAKEFLAGS ++# - PACKAGER + load_vars() { + local makepkg_conf="$1" var + + [[ -f $makepkg_conf ]] || return 1 + + for var in {SRC,PKG,LOG}DEST MAKEFLAGS PACKAGER; do +- [[ -z ${!var} ]] && eval $(grep "^${var}=" "$makepkg_conf") ++ [[ -z ${!var:-} ]] && eval $(grep "^${var}=" "$makepkg_conf") + done + + return 0 + } + +-create_chroot() { +- # Lock the chroot we want to use. We'll keep this lock until we exit. +- lock 9 "$copydir.lock" "Locking chroot copy [%s]" "$copy" ++# Usage: sync_chroot $CHROOTDIR/$CHROOT <$CHROOTCOPY|$copydir> ++sync_chroot() { + local chrootdir=$1 + local copy=$2 + local copydir='' @@ -55,221 +84,220 @@ + else + copydir="$chrootdir/$copy" + fi ++ ++ # Detect chrootdir filesystem type + 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 @@ +- 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 + slock 8 "$chrootdir/root.lock" "Locking clean chroot" +@@ -147,10 +164,15 @@ - # Drop the read lock again - lock_close 8 --fi -+} + # Drop the read lock again + lock_close 8 +- fi + } + +-clean_temporary() { ++# Usage: delete_chroot $copydir [$copy] ++delete_chroot() { ++ local copydir=$1 ++ local copy=${2:-$copydir} ++ # Detect chrootdir filesystem type ++ local chroottype=$(stat -f -c %T "$copydir") + -+# Usage: chroot_install_pkgs $copydir $pkgs... -+chroot_install_pkgs() { + stat_busy "Removing temporary copy [%s]" "$copy" + if [[ "$chroottype" == btrfs ]]; then + btrfs subvolume delete "$copydir" >/dev/null || +@@ -166,9 +188,14 @@ + stat_done + } + ++# Usage: install_packages $copydir $pkgs... + install_packages() { + local copydir=$1 -+ shift ++ local install_pkgs=("${@:2}") + declare -i ret=0 -+ declare -a install_pkgs=("$@") -+ local pkgname + local pkgname --if [[ -n "${install_pkgs[*]}" ]]; then ++ local install_pkg for install_pkg in "${install_pkgs[@]}"; do pkgname="${install_pkg##*/}" cp "$install_pkg" "$copydir/$pkgname" -@@ -165,10 +181,10 @@ +@@ -179,11 +206,19 @@ rm "$copydir/$pkgname" done -- # If there is no PKGBUILD we have done +- # If there is no PKGBUILD we are done - [[ -f PKGBUILD ]] || exit $ret --fi + return $ret -+} + } -+func1() { - $update_first && archroot -u "$copydir" ++# Usage: prepare_chroot $copydir $HOME $repack $run_namcap ++# Globals: ++# - MAKEFLAGS ++# - PACKAGER + prepare_chroot() { ++ local copydir=$1 ++ local USER_HOME=$2 ++ local repack=$3 ++ local run_namcap=$4 ++ + $repack || rm -rf "$copydir/build" - 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 -+} + mkdir -p "$copydir/build" +@@ -217,12 +252,12 @@ -+# 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,logdest,srcdest,startdir} - chown -R nobody "$copydir"/{build,pkgdest,srcdest} -+} +- if [[ -n $MAKEFLAGS ]]; then ++ if [[ -n ${MAKEFLAGS:-} ]]; then + sed -i '/^MAKEFLAGS=/d' "$copydir/etc/makepkg.conf" + echo "MAKEFLAGS='${MAKEFLAGS}'" >> "$copydir/etc/makepkg.conf" + fi -+# Usage: chroot_let_nobody_use_pacman $copydir -+chroot_let_nobody_use_pacman() { -+local copydir=$1 - cat > "$copydir/etc/sudoers.d/nobody-pacman" <<EOF - Defaults env_keep += "HOME" - nobody ALL = NOPASSWD: /usr/bin/pacman - EOF - chmod 440 "$copydir/etc/sudoers.d/nobody-pacman" -+} +- if [[ -n $PACKAGER ]]; then ++ if [[ -n ${PACKAGER:-} ]]; then + sed -i '/^PACKAGER=/d' "$copydir/etc/makepkg.conf" + echo "PACKAGER='${PACKAGER}'" >> "$copydir/etc/makepkg.conf" + fi +@@ -235,6 +270,14 @@ + chmod 440 "$copydir/etc/sudoers.d/nobody-pacman" + fi -+# Usage: chroot_build $copydir $makepkg_args $run_namcap -+chroot_build() { -+local copydir=$1 -+local makepkg_args=$2 -+local run_namcap=$3 - # This is a little gross, but this way the script is recreated every time in the - # working copy - cat >"$copydir/chrootbuild" <<EOF -@@ -284,37 +322,62 @@ - exit 0 - EOF - chmod +x "$copydir/chrootbuild" -+archroot -r "$copydir" "/chrootbuild" -+} ++ if ! grep -q '^\[repo\]' "$copydir/etc/pacman.conf"; then ++ cat >> "$copydir/etc/pacman.conf" <<EOF ++[repo] ++SigLevel = Optional TrustAll ++Server = file:///repo ++EOF ++ fi ++ + # This is a little gross, but this way the script is recreated every time in the + # working copy + printf $'#!/bin/bash\n%s\n_chrootbuild %q "$@"' "$(declare -f _chrootbuild)" \ +@@ -242,13 +285,19 @@ + chmod +x "$copydir/chrootbuild" + } --if archroot -r "$copydir" "/chrootbuild"; then -+# Usage: chroot_add_to_local_repo $copydir $pkgfiles... -+chroot_add_to_local_repo() { -+ local copydir=$1; shift - mkdir -p "$copydir/repo" -- for pkgfile in "$copydir"/pkgdest/*.pkg.tar.?z; do -- if $add_to_db; then -+ for pkgfile in "$@"; do - cp "$pkgfile" "$copydir/repo" - pushd "$copydir/repo" >/dev/null - repo-add repo.db.tar.gz "${pkgfile##*/}" - popd >/dev/null -- fi -+ done -+} ++# Usage: download_sources $copydir $src_owner ++# Globals: ++# - SRCDEST + download_sources() { ++ local copydir=$1 ++ local src_owner=$2 ++ + local builddir="$(mktemp -d)" + chmod 1777 "$builddir" + + # Ensure sources are downloaded +- if [[ -n $SUDO_USER ]]; then +- sudo -u $SUDO_USER env SRCDEST="$SRCDEST" BUILDDIR="$builddir" \ ++ if [[ $USER != $src_owner ]]; then ++ sudo -u $src_owner env SRCDEST="$SRCDEST" BUILDDIR="$builddir" \ + makepkg --config="$copydir/etc/makepkg.conf" --verifysource -o + else + ( export SRCDEST BUILDDIR="$builddir" +@@ -258,7 +307,7 @@ + (( $? != 0 )) && die "Could not download sources." + + # Clean up garbage from verifysource +- rm -rf $builddir ++ rm -rf "$builddir" + } + + _chrootbuild() { +@@ -295,6 +344,7 @@ -+# Usage: chroot_copy_out_pkgs $copydir $user -+# Environment: -+# - $PKGDEST is set -+chroot_copy_out_pkgs() { + # Safety check + if [[ ! -w PKGBUILD ]]; then ++ # XXX: internationalize this message + echo "Can't write to PKGBUILD!" + exit 1 + fi +@@ -312,12 +362,24 @@ + exit 0 + } + ++# Usage: move_products $copydir $owner ++# Globals: ++# - PKGDEST ++# - LOGDEST + move_products() { + local copydir=$1 + local src_owner=$2 -+ for pkgfile in "$copydir"/pkgdest/*.pkg.tar*; do ++ ++ local pkgfile + for pkgfile in "$copydir"/pkgdest/*; do chown "$src_owner" "$pkgfile" mv "$pkgfile" "$PKGDEST" -+ if [[ $PKGDEST != . ]]; then ++ if [[ $PKGDEST != $PWD ]]; 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 ++ local l + for l in "$copydir"/logdest/*; do chown "$src_owner" "$l" - [[ -f $l ]] && mv "$l" . - done --else -- # Just in case. We returned 1, make sure we fail -- ret=1 --fi -+} + mv "$l" "$LOGDEST" +@@ -325,6 +387,10 @@ + } + # }}} -+# 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 -+} ++main() { ++init_variables ++parse_options_init ++ + umask 0022 --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 [$copydir]" - 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 -+} + load_vars /etc/makepkg.conf +@@ -335,27 +401,37 @@ + [[ -d $SRCDEST ]] || SRCDEST=$PWD + [[ -d $LOGDEST ]] || LOGDEST=$PWD + +-create_chroot ++# Lock the chroot we want to use. We'll keep this lock until we exit. ++lock 9 "$copydir.lock" "Locking chroot copy [%s]" "$copy" + -+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 ++if [[ ! -d $copydir ]] || $clean_first; then ++ sync_chroot "$chrootdir" "$copy" ++fi + + $update_first && arch-nspawn "$copydir" pacman -Syu --noconfirm + +-[[ -n ${install_pkgs[*]} ]] && install_packages ++if [[ -n ${install_pkgs[*]:-} ]]; then ++ install_packages "$copydir" "${install_pkgs[@]}" ++ ret=$? ++ # If there is no PKGBUILD we have done ++ [[ -f PKGBUILD ]] || exit $ret ++fi + +-prepare_chroot ++prepare_chroot "$copydir" "$USER_HOME" "$repack" + +-download_sources ++download_sources "$copydir" "$src_owner" + + if arch-nspawn "$copydir" \ + --bind-ro="$PWD:/startdir_host" \ + --bind-ro="$SRCDEST:/srcdest_host" \ + /chrootbuild "${makepkg_args[@]}" + then +- move_products ++ move_products "$copydir" "$src_owner" + else + (( ret += 1 )) + fi + +-$temp_chroot && clean_temporary ++$temp_chroot && delete_chroot "$copydir" "$copy" + + if (( ret != 0 )); then + if $temp_chroot; then +@@ -366,3 +442,4 @@ + else + true + fi +} |