makerepropkg: support parallel runs in dedicated namespaces

This adds proper namespace locking as well to fix screwing up the
running makerepropkg process.
This commit is contained in:
Levente Polyak 2021-11-11 23:39:29 +01:00
parent dacde204c9
commit cc6cf65ef9
No known key found for this signature in database
GPG Key ID: FC1B547C8D8172C8
2 changed files with 26 additions and 12 deletions

View File

@ -48,6 +48,11 @@ Options
*-M* <file>:: *-M* <file>::
Location of a makepkg config file. Location of a makepkg config file.
*-l* <chroot>::
The directory name to use as the chroot namespace
Useful for maintaining multiple copies
Default: $USER
*-h*:: *-h*::
Show this usage message Show this usage message

View File

@ -17,9 +17,12 @@ declare -a buildenv buildopts installed installpkgs
archiveurl='https://archive.archlinux.org/packages' archiveurl='https://archive.archlinux.org/packages'
buildroot=/var/lib/archbuild/reproducible buildroot=/var/lib/archbuild/reproducible
chroot=testenv
diffoscope=0 diffoscope=0
chroot=$USER
[[ -n ${SUDO_USER:-} ]] && chroot=$SUDO_USER
[[ -z "$chroot" || $chroot = root ]] && chroot=copy
parse_buildinfo() { parse_buildinfo() {
local line var val local line var val
@ -108,15 +111,19 @@ OPTIONS
-d Run diffoscope if the package is unreproducible -d Run diffoscope if the package is unreproducible
-c <dir> Set pacman cache -c <dir> Set pacman cache
-M <file> Location of a makepkg config file -M <file> Location of a makepkg config file
-l <chroot> The directory name to use as the chroot namespace
Useful for maintaining multiple copies
Default: $chroot
-h Show this usage message -h Show this usage message
__EOF__ __EOF__
} }
while getopts 'dM:c:h' arg; do while getopts 'dM:c:l:h' arg; do
case "$arg" in case "$arg" in
d) diffoscope=1 ;; d) diffoscope=1 ;;
M) archroot_args+=(-M "$OPTARG") ;; M) archroot_args+=(-M "$OPTARG") ;;
c) cache_dirs+=("$OPTARG") ;; c) cache_dirs+=("$OPTARG") ;;
l) chroot="$OPTARG" ;;
h) usage; exit 0 ;; h) usage; exit 0 ;;
*|?) usage; exit 1 ;; *|?) usage; exit 1 ;;
esac esac
@ -184,12 +191,14 @@ BUILDTOOLVER="${buildinfo[buildtoolver]}"
PKGEXT=${splitpkgs[0]#${splitpkgs[0]%.pkg.tar*}} PKGEXT=${splitpkgs[0]#${splitpkgs[0]%.pkg.tar*}}
# nuke and restore reproducible testenv # nuke and restore reproducible testenv
for copy in "${buildroot}"/*/; do namespace="$buildroot/$chroot"
lock 9 "${namespace}.lock" "Locking chroot namespace '%s'" "${namespace}"
for copy in "${namespace}"/*/; do
[[ -d ${copy} ]] || continue [[ -d ${copy} ]] || continue
subvolume_delete_recursive "${copy}" subvolume_delete_recursive "${copy}"
done done
rm -rf --one-file-system "${buildroot}" rm -rf --one-file-system "${namespace}"
(umask 0022; mkdir -p "${buildroot}") (umask 0022; mkdir -p "${namespace}")
for fname in "${installed[@]}"; do for fname in "${installed[@]}"; do
if ! allpkgfiles+=("$(get_pkgfile "${fname}")"); then if ! allpkgfiles+=("$(get_pkgfile "${fname}")"); then
@ -216,10 +225,10 @@ else
warning "Unknown buildtool (${BUILDTOOL}-${BUILDTOOLVER}), using fallback" warning "Unknown buildtool (${BUILDTOOL}-${BUILDTOOLVER}), using fallback"
makepkg_conf=@pkgdatadir@/makepkg-x86_64.conf makepkg_conf=@pkgdatadir@/makepkg-x86_64.conf
fi fi
printf '%s\n' "${allpkgfiles[@]}" | mkarchroot -M "${makepkg_conf}" -U "${archroot_args[@]}" "${buildroot}"/root - || exit 1 printf '%s\n' "${allpkgfiles[@]}" | mkarchroot -M "${makepkg_conf}" -U "${archroot_args[@]}" "${namespace}/root" - || exit 1
# use makechrootpkg to prep the build directory # use makechrootpkg to prep the build directory
makechrootpkg -r "${buildroot}" -l "${chroot}" -- --packagelist || exit 1 makechrootpkg -r "${namespace}" -l build -- --packagelist || exit 1
# set detected makepkg.conf options # set detected makepkg.conf options
{ {
@ -228,22 +237,22 @@ makechrootpkg -r "${buildroot}" -l "${chroot}" -- --packagelist || exit 1
done done
printf 'OPTIONS=(%s)\n' "${buildopts[*]@Q}" printf 'OPTIONS=(%s)\n' "${buildopts[*]@Q}"
printf 'BUILDENV=(%s)\n' "${buildenv[*]@Q}" printf 'BUILDENV=(%s)\n' "${buildenv[*]@Q}"
} >> "${buildroot}/${chroot}"/etc/makepkg.conf } >> "${namespace}/build"/etc/makepkg.conf
install -d -o "${SUDO_UID:-$UID}" -g "$(id -g "${SUDO_UID:-$UID}")" "${buildroot}/${chroot}/${BUILDDIR}" install -d -o "${SUDO_UID:-$UID}" -g "$(id -g "${SUDO_UID:-$UID}")" "${namespace}/build/${BUILDDIR}"
# kick off the build # kick off the build
arch-nspawn "${buildroot}/${chroot}" \ arch-nspawn "${namespace}/build" \
--bind="${PWD}:/startdir" \ --bind="${PWD}:/startdir" \
--bind="${SRCDEST}:/srcdest" \ --bind="${SRCDEST}:/srcdest" \
/chrootbuild -C --noconfirm --log --holdver --skipinteg /chrootbuild -C --noconfirm --log --holdver --skipinteg
ret=$? ret=$?
if (( ${ret} == 0 )); then if (( ${ret} == 0 )); then
msg2 "built succeeded! built packages can be found in ${buildroot}/${chroot}/pkgdest" msg2 "built succeeded! built packages can be found in ${namespace}/build/pkgdest"
msg "comparing artifacts..." msg "comparing artifacts..."
for pkgfile in "${splitpkgs[@]}"; do for pkgfile in "${splitpkgs[@]}"; do
comparefiles=("${pkgfile}" "${buildroot}/${chroot}/pkgdest/${pkgfile##*/}") comparefiles=("${pkgfile}" "${namespace}/build/pkgdest/${pkgfile##*/}")
if cmp -s "${comparefiles[@]}"; then if cmp -s "${comparefiles[@]}"; then
msg2 "Package '%s' successfully reproduced!" "${pkgfile}" msg2 "Package '%s' successfully reproduced!" "${pkgfile}"
else else