summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common.mk11
-rw-r--r--src/chroot-tools/.gitignore4
-rw-r--r--src/chroot-tools/Makefile48
-rw-r--r--src/chroot-tools/hooks-chcleanup.sh15
-rw-r--r--src/chroot-tools/hooks-check.sh38
-rw-r--r--src/chroot-tools/hooks-distcc.sh86
-rwxr-xr-xsrc/chroot-tools/librechroot128
-rwxr-xr-xsrc/chroot-tools/libremakepkg410
-rw-r--r--src/chroot-tools/makechrootpkg.sh.patch450
-rw-r--r--src/devtools/Makefile9
10 files changed, 634 insertions, 565 deletions
diff --git a/common.mk b/common.mk
index 89ab001..68b5d56 100644
--- a/common.mk
+++ b/common.mk
@@ -10,13 +10,6 @@ pkglibexecdir ?= $(libexecdir)/libretools
# This is used when using sources grabbed from devtools
edit = sed -e 's|m4_include(lib/\(.*\))|. $$(librelib \1)|'
-# 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
-
# Usage <INPUT $(pofmt) >OUTPUT
# Normalize a .po(t) file
pofmt = msguniq -Fi
@@ -89,6 +82,10 @@ build: PHONY $(build_files)
ronn --roff $(RONNFLAGS) < '$<' > '$@'
%.html: %.ronn
ronn --html $(RONNFLAGS) < '$<' > '$@'
+%: %.in
+ @echo "GEN $@"
+ @$(edit) <"$<" >"$@" || { rm -f -- '$@'; false; }
+ @chmod 755 "$@" || { rm -f -- '$@'; false; }
%.pot: %
{ $(xgettext-main); $(xgettext-prose); } | $(pofmt) > '$@'
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
+}
diff --git a/src/devtools/Makefile b/src/devtools/Makefile
index 6cae230..3fc5d70 100644
--- a/src/devtools/Makefile
+++ b/src/devtools/Makefile
@@ -3,15 +3,6 @@ copy_files = $(addsuffix .in,$(progs))
install_files = $(DESTDIR)$(bindir)/find-libprovides
include ../../common.mk
-# Build ##############################################################
-
-%: %.in Makefile
- @echo "GEN $@"
- @$(edit) <"$<" >"$@" || { rm -f -- '$@'; false; }
- @chmod 755 "$@" || { rm -f -- '$@'; false; }
-
-# Install ############################################################
-
$(DESTDIR)$(bindir)/find-libprovides:
install -d $(@D)
ln -sf find-libdeps $@