Compare commits

...

10 Commits

Author SHA1 Message Date
Monson Shao
6b7792202f arch-nspawn: obsolete nosetarch option
setarch is mainly used for building i686 packages on x86_64, while it
disturbs building ARM packages on x86_64, so the nosetarch option (-s)
was introduced. But there is a better way that we could always precheck
the setarch support list, and do it only when available.

This could fix the partial implement of setarch refered on #41 .
2020-04-10 05:02:54 +08:00
Levente Polyak
5b1123e11f offload-build: retrieve the PKGBUILD in case makepkg changes it via pkgver
Building a package may change the PKGBUILD during update_pkgver. Let's
retrieve the PKGBUILD after building to ensure we have the very same
file as the one we used to build the package. Otherwise this may lead to
the inability to distribute the package during commitpkg in case the
expected and the actual hashsum mismatch.
2020-03-09 23:27:03 +01:00
Levente Polyak
a0f79fcce0 makerepropkg: prioritize downloading .zst packages over legacy format
First try a .zst location before falling back to legacy variants. This
should slightly speed up downloading of dependencies, especially over
time as .zst packages are or will be the dominant format.

Signed-off-by: Levente Polyak <anthraxx@archlinux.org>
2020-03-09 23:27:03 +01:00
Eli Schwartz
94b0413e13 arch-nspawn: fix up host_mirrors cachedir handling
This was incorrectly implemented in commit
0067176529, which added the host_mirrors
root directory as a cachedir, when we actually want to use the pool/*
subdirectories (the same ones installed on the build server's
/etc/pacman.conf).

Signed-off-by: Eli Schwartz <eschwartz@archlinux.org>
Signed-off-by: Levente Polyak <anthraxx@archlinux.org>
2020-02-27 14:50:27 +01:00
Eli Schwartz
e963b6da9e makechrootpkg: use the chroot database to find checkpkg packages
We don't want to check against the current version known to the host
system, because that will be incorrect in a wide variety of situations,
including:
- the build host hasn't done a full system upgrade yet
- we're building against staging, and want to see the delta between
  different staging versions
- we're building against extra, but the host runs testing which carries
  changes we don't want to visualize right now
- the chroot has a configured database not available to the host, and
  the package is only available there

Essentially, it's rarely 100% correct to run checkpkg on the host, but
we already have a database we *know* is correct, and that is the one we
just built the package against. So let's use that.

This also fixes a bug in the current logic, where in order to try
downloading fresh databases, we work in a non-cached temporary working
database to download the package files, but then let checkpkg default to
comparing packages in the system database. Since we are explicitly
trying to compare against packages that differ from the host's pacman
database, we need to pass the package files as options to checkpkg,
using the additional modes added in commit c14338c0fe

Signed-off-by: Eli Schwartz <eschwartz@archlinux.org>
Signed-off-by: Levente Polyak <anthraxx@archlinux.org>
2020-02-27 14:50:19 +01:00
Eli Schwartz
b2cbb8628e checkpkg: fix support for http:// url comparisons
Broken in commit c14338c0fe.

Signed-off-by: Eli Schwartz <eschwartz@archlinux.org>
Signed-off-by: Levente Polyak <anthraxx@archlinux.org>
2020-02-27 14:50:14 +01:00
Eli Schwartz
6d273f79c3 zsh-completion: update for new makerepropkg options
Thanks to anthraxx for the guidance.

Original-patch-by: Levente Polyak <anthraxx@archlinux.org>
Signed-off-by: Eli Schwartz <eschwartz@archlinux.org>
Signed-off-by: Levente Polyak <anthraxx@archlinux.org>
2020-02-27 14:50:05 +01:00
Eli Schwartz
51842a1676 makerepropkg: support checking multiple split packages
By specifying multiple package files, we assume they are all from the
same PKGBUILD, and try to check them all against the produced artifacts.
Since the buildinfo should be comparable for all of them, we simply use
the first one passed on the command line.

Signed-off-by: Eli Schwartz <eschwartz@archlinux.org>
Signed-off-by: Levente Polyak <anthraxx@archlinux.org>
2020-02-27 14:49:54 +01:00
Eli Schwartz
53fe5c67a1 makerepropkg: add support to check unreproducible packages using diffoscope
Signed-off-by: Eli Schwartz <eschwartz@archlinux.org>
Signed-off-by: Levente Polyak <anthraxx@archlinux.org>
2020-02-27 14:49:48 +01:00
Eli Schwartz
21d9984acc makerepropkg: fix wonky indent
Signed-off-by: Eli Schwartz <eschwartz@archlinux.org>
Signed-off-by: Levente Polyak <anthraxx@archlinux.org>
2020-02-27 14:49:33 +01:00
10 changed files with 80 additions and 60 deletions

View File

@@ -31,7 +31,6 @@ usage() {
echo ' -M <file> Location of a makepkg config file' echo ' -M <file> Location of a makepkg config file'
echo ' -c <dir> Set pacman cache' echo ' -c <dir> Set pacman cache'
echo ' -f <file> Copy file from the host to the chroot' echo ' -f <file> Copy file from the host to the chroot'
echo ' -s Do not run setarch'
echo ' -h This message' echo ' -h This message'
exit 1 exit 1
} }
@@ -42,7 +41,6 @@ while getopts 'hC:M:c:f:s' arg; do
M) makepkg_conf="$OPTARG" ;; M) makepkg_conf="$OPTARG" ;;
c) cache_dirs+=("$OPTARG") ;; c) cache_dirs+=("$OPTARG") ;;
f) files+=("$OPTARG") ;; f) files+=("$OPTARG") ;;
s) nosetarch=1 ;;
h|?) usage ;; h|?) usage ;;
*) error "invalid argument '%s'" "$arg"; usage ;; *) error "invalid argument '%s'" "$arg"; usage ;;
esac esac
@@ -69,7 +67,9 @@ host_mirrors=($($pacconf_cmd --repo extra Server 2> /dev/null | sed -r 's#(.*/)e
for host_mirror in "${host_mirrors[@]}"; do for host_mirror in "${host_mirrors[@]}"; do
if [[ $host_mirror == *file://* ]]; then if [[ $host_mirror == *file://* ]]; then
host_mirror=$(echo "$host_mirror" | sed -r 's#file://(/.*)/\$repo/os/\$arch#\1#g') host_mirror=$(echo "$host_mirror" | sed -r 's#file://(/.*)/\$repo/os/\$arch#\1#g')
in_array "$host_mirror" "${cache_dirs[@]}" || cache_dirs+=("$host_mirror") for m in "$host_mirror"/pool/*/; do
in_array "$m" "${cache_dirs[@]}" || cache_dirs+=("$m")
done
fi fi
done done
@@ -122,8 +122,7 @@ fi
copy_hostconf copy_hostconf
eval "$(grep -a '^CARCH=' "$working_dir/etc/makepkg.conf")" eval "$(grep -a '^CARCH=' "$working_dir/etc/makepkg.conf")"
setarch --list | grep -qx "$CARCH" || unset CARCH
[[ -z $nosetarch ]] || unset CARCH
exec ${CARCH:+setarch "$CARCH"} systemd-nspawn -q \ exec ${CARCH:+setarch "$CARCH"} systemd-nspawn -q \
-D "$working_dir" \ -D "$working_dir" \

View File

@@ -69,7 +69,10 @@ if ${clean_first} || [[ ! -d "${chroots}/${repo}-${arch}" ]]; then
rm -rf --one-file-system "${chroots}/${repo}-${arch}" rm -rf --one-file-system "${chroots}/${repo}-${arch}"
(umask 0022; mkdir -p "${chroots}/${repo}-${arch}") (umask 0022; mkdir -p "${chroots}/${repo}-${arch}")
setarch "${arch}" mkarchroot \
setarch --list | grep -qx "$arch" && setarch_cmd="setarch $arch"
${setarch_cmd} mkarchroot \
-C "${pacman_config}" \ -C "${pacman_config}" \
-M "${makepkg_config}" \ -M "${makepkg_config}" \
"${chroots}/${repo}-${arch}/root" \ "${chroots}/${repo}-${arch}/root" \

View File

@@ -95,8 +95,10 @@ for _pkgname in "${pkgname[@]}"; do
if (( $# )); then if (( $# )); then
case $1 in case $1 in
*://*)
pkgurl=$1 ;;
/*|*/*) /*|*/*)
pkgurl=file://$(readlink -m "$1") ;; pkgurl=$(readlink -m "$1") ;;
*.pkg.tar*) *.pkg.tar*)
pkgurl=$1 ;; pkgurl=$1 ;;
'') '')

View File

@@ -7,12 +7,12 @@ makerepropkg - Rebuild a package to see if it is reproducible
Synopsis Synopsis
-------- --------
makerepropkg [OPTIONS] <package_file> makerepropkg [OPTIONS] <package_file>...
Description Description
----------- -----------
Given the path to a built pacman package, attempt to rebuild it using the Given the path to a built pacman package(s), attempt to rebuild it using the
PKGBUILD in the current directory. The package will be built in an environment PKGBUILD in the current directory. The package will be built in an environment
as closely matching the environment of the initial package as possible, by as closely matching the environment of the initial package as possible, by
building up a chroot to match the information exposed in the package's building up a chroot to match the information exposed in the package's
@@ -20,12 +20,19 @@ linkman:BUILDINFO[5] manifest. On success, the resulting package will be
compared to the input package, and makerepropkg will report whether the compared to the input package, and makerepropkg will report whether the
artifacts are identical. artifacts are identical.
When given multiple packages, additional package files are assumed to be split
packages and will be treated as additional artifacts to compare during the
verification step.
This implements a verifier for pacman/libalpm packages in accordance with the This implements a verifier for pacman/libalpm packages in accordance with the
link:https://reproducible-builds.org/[Reproducible Builds] project. link:https://reproducible-builds.org/[Reproducible Builds] project.
Options Options
------- -------
*-d*::
If packages are not reproducible, compare them using diffoscope.
*-c*:: *-c*::
Set the pacman cache directory. Set the pacman cache directory.

View File

@@ -35,9 +35,6 @@ Options
*-f* <file>:: *-f* <file>::
Copy file from the host to the chroot. Copy file from the host to the chroot.
*-s*::
Do not run setarch.
*-h*:: *-h*::
Output command line options. Output command line options.

View File

@@ -366,11 +366,7 @@ if arch-nspawn "$copydir" \
"${bindmounts_ro[@]}" "${bindmounts_rw[@]}" \ "${bindmounts_ro[@]}" "${bindmounts_rw[@]}" \
/chrootbuild "${makepkg_args[@]}" /chrootbuild "${makepkg_args[@]}"
then then
pkgnames=() mapfile -t pkgnames < <(sudo -u "$makepkg_user" bash -c 'source PKGBUILD; printf "%s\n" "${pkgname[@]}"')
for pkgfile in "$copydir"/pkgdest/*; do
pkgfile=${pkgfile##*/};
pkgnames+=("${pkgfile%-*-*-*}");
done
move_products move_products
else else
(( ret += 1 )) (( ret += 1 ))
@@ -388,29 +384,29 @@ else
if (( run_checkpkg )); then if (( run_checkpkg )); then
msg "Running checkpkg" msg "Running checkpkg"
# sync off-site databases for up-to-date queries mapfile -t remotepkgs < <(pacman --config "$copydir"/etc/pacman.conf \
trap 'rm -rf $dbpath; cleanup' EXIT INT TERM QUIT --dbpath "$copydir"/var/lib/pacman \
dbpath=$(mktemp -d --tmpdir makechrootpkg-database.XXXXXXXXXX) -Sddp "${pkgnames[@]}")
mkdir -p "$dbpath"
pacman -Sy --dbpath "$dbpath" --logfile /dev/null
# query current package locations if ! wait $!; then
remotepkgs=($(pacman -Sddp --dbpath "$dbpath" --logfile /dev/null "${pkgnames[@]}"))
if (( $? )); then
warning "Skipped checkpkg due to missing repo packages" warning "Skipped checkpkg due to missing repo packages"
exit 0 exit 0
fi fi
# download package files if any non-local location exists # download package files if any non-local location exists
for remotepkg in "${remotepkgs[@]}"; do for remotepkg in "${remotepkgs[@]}"; do
[[ $remotepkg == file://* ]] && continue if [[ $remotepkg != file://* ]]; then
msg2 "Downloading current versions" msg2 "Downloading current versions"
pacman --noconfirm -Swdd --dbpath "$dbpath" --logfile /dev/null "${pkgnames[@]}" arch-nspawn "$copydir" pacman --noconfirm -Swdd "${pkgnames[@]}"
break mapfile -t remotepkgs < <(pacman --config "$copydir"/etc/pacman.conf \
--dbpath "$copydir"/var/lib/pacman \
-Sddp "${pkgnames[@]}")
break
fi
done done
msg2 "Checking packages" msg2 "Checking packages"
sudo -u "$makepkg_user" checkpkg --rmdir --warn sudo -u "$makepkg_user" checkpkg --rmdir --warn "${remotepkgs[@]/#file:\/\//}"
fi fi
true true
fi fi

View File

@@ -29,6 +29,7 @@ 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 chroot=testenv
diffoscope=0
parse_buildinfo() { parse_buildinfo() {
local line var val local line var val
@@ -59,7 +60,7 @@ get_pkgfile() {
local pkgname=${pkgfilebase%-*-*-*} local pkgname=${pkgfilebase%-*-*-*}
local pkgfile ext local pkgfile ext
for ext in .xz .zst ''; do for ext in .zst .xz ''; do
pkgfile=${pkgfilebase}.pkg.tar${ext} pkgfile=${pkgfilebase}.pkg.tar${ext}
for c in "${cache_dirs[@]}"; do for c in "${cache_dirs[@]}"; do
@@ -94,19 +95,21 @@ package, including the .PKGINFO as well as the buildinfo.
For more details see https://reproducible-builds.org/ For more details see https://reproducible-builds.org/
OPTIONS OPTIONS
-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
-h Show this usage message -h Show this usage message
__EOF__ __EOF__
} }
while getopts 'M:c:h' arg; do while getopts 'dM:c:h' arg; do
case "$arg" in case "$arg" in
M) archroot_args+=(-M "$OPTARG") ;; d) diffoscope=1 ;;
c) cache_dirs+=("$OPTARG") ;; M) archroot_args+=(-M "$OPTARG") ;;
h) usage; exit 0 ;; c) cache_dirs+=("$OPTARG") ;;
*|?) usage; exit 1 ;; h) usage; exit 0 ;;
esac *|?) usage; exit 1 ;;
esac
done done
shift $((OPTIND - 1)) shift $((OPTIND - 1))
@@ -114,10 +117,13 @@ check_root
if [[ -n $1 ]]; then if [[ -n $1 ]]; then
pkgfile="$1" pkgfile="$1"
if ! bsdtar -tqf "${pkgfile}" .BUILDINFO >/dev/null 2>&1; then splitpkgs=("$@")
error "file is not a valid pacman package: '%s'" "${pkgfile}" for f in "${splitpkgs[@]}"; do
exit 1 if ! bsdtar -tqf "${f}" .BUILDINFO >/dev/null 2>&1; then
fi error "file is not a valid pacman package: '%s'" "${f}"
exit 1
fi
done
else else
error "no package file specified. Try '${BASH_SOURCE[0]##*/} -h' for more information. " error "no package file specified. Try '${BASH_SOURCE[0]##*/} -h' for more information. "
exit 1 exit 1
@@ -173,18 +179,26 @@ arch-nspawn "${buildroot}/${chroot}" \
--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=$?
if (( $? == 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 ${buildroot}/${chroot}/pkgdest"
msg "comparing artifacts..." msg "comparing artifacts..."
if cmp -s "${pkgfile}" "${buildroot}/${chroot}/pkgdest/${pkgfile##*/}"; then
msg2 "Package successfully reproduced!" for pkgfile in "${splitpkgs[@]}"; do
exit 0 comparefiles=("${pkgfile}" "${buildroot}/${chroot}/pkgdest/${pkgfile##*/}")
else if cmp -s "${comparefiles[@]}"; then
warning "Package is not reproducible. :(" msg2 "Package '%s' successfully reproduced!" "${pkgfile}"
sha256sum "${pkgfile}" "${buildroot}/${chroot}/pkgdest/${pkgfile##*/}" else
fi ret=1
warning "Package '%s' is not reproducible. :(" "${pkgfile}"
sha256sum "${comparefiles[@]}"
if (( diffoscope )); then
diffoscope "${comparefiles[@]}"
fi
fi
done
fi fi
# the package either failed to build, or was unreproducible # return failure from chrootbuild, or the reproducibility status
exit 1 exit ${ret}

View File

@@ -31,7 +31,6 @@ usage() {
echo ' -M <file> Location of a makepkg config file' echo ' -M <file> Location of a makepkg config file'
echo ' -c <dir> Set pacman cache' echo ' -c <dir> Set pacman cache'
echo ' -f <file> Copy file from the host to the chroot' echo ' -f <file> Copy file from the host to the chroot'
echo ' -s Do not run setarch'
echo ' -h This message' echo ' -h This message'
exit 1 exit 1
} }
@@ -43,7 +42,6 @@ while getopts 'hUC:M:c:f:s' arg; do
M) makepkg_conf="$OPTARG" ;; M) makepkg_conf="$OPTARG" ;;
c) cache_dirs+=("$OPTARG") ;; c) cache_dirs+=("$OPTARG") ;;
f) files+=("$OPTARG") ;; f) files+=("$OPTARG") ;;
s) nosetarch=1 ;;
h|?) usage ;; h|?) usage ;;
*) error "invalid argument '%s'" "$arg"; usage ;; *) error "invalid argument '%s'" "$arg"; usage ;;
esac esac

View File

@@ -81,12 +81,13 @@ fi
archbuild_cmd=("${repo}${archbuild_arch:+-$archbuild_arch}-build" "$@") archbuild_cmd=("${repo}${archbuild_arch:+-$archbuild_arch}-build" "$@")
trap 'rm -rf $SRCPKGDEST' EXIT INT TERM QUIT trap 'rm -rf $TEMPDIR' EXIT INT TERM QUIT
# Use a source-only tarball as an intermediate to transfer files. This # Use a source-only tarball as an intermediate to transfer files. This
# guarantees the checksums are okay, and guarantees that all needed files are # guarantees the checksums are okay, and guarantees that all needed files are
# transferred, including local sources, install scripts, and changelogs. # transferred, including local sources, install scripts, and changelogs.
export SRCPKGDEST=$(mktemp -d) export TEMPDIR=$(mktemp -d --tmpdir offload-build.XXXXXXXXXX)
export SRCPKGDEST=${TEMPDIR}
makepkg --source || die "unable to make source package" makepkg --source || die "unable to make source package"
# Temporary cosmetic workaround makepkg if SRCDEST is set somewhere else # Temporary cosmetic workaround makepkg if SRCDEST is set somewhere else
@@ -114,14 +115,17 @@ mapfile -t files < <(
if [[ -f /usr/share/devtools/makepkg-'"${repo}"'-'"${arch}"'.conf ]]; then if [[ -f /usr/share/devtools/makepkg-'"${repo}"'-'"${arch}"'.conf ]]; then
makepkg_config="/usr/share/devtools/makepkg-'"${repo}"'-'"${arch}"'.conf" makepkg_config="/usr/share/devtools/makepkg-'"${repo}"'-'"${arch}"'.conf"
fi && fi &&
makepkg --config <(cat "${makepkg_user_config}" "${makepkg_config}" 2>/dev/null) --packagelist makepkg --config <(cat "${makepkg_user_config}" "${makepkg_config}" 2>/dev/null) --packagelist &&
printf "%s\n" "${temp}/PKGBUILD"
') ')
if (( ${#files[@]} )); then if (( ${#files[@]} )); then
printf '%s\n' '' '-> copying files...' printf '%s\n' '' '-> copying files...'
load_makepkg_config load_makepkg_config
scp "${files[@]/#/$server:}" "${PKGDEST:-${PWD}}/" scp "${files[@]/#/$server:}" "${TEMPDIR}/"
mv "${TEMPDIR}"/*.pkg.tar* "${PKGDEST:-${PWD}}/"
mv "${TEMPDIR}/PKGBUILD" "${PWD}/"
else else
exit 1 exit 1
fi fi

View File

@@ -21,7 +21,6 @@ _arch_nspawn_args=(
'-M[Location of a makepkg config file]:makepkg_config:_files -g "*.conf(.)"' '-M[Location of a makepkg config file]:makepkg_config:_files -g "*.conf(.)"'
'-c[Set pacman cache]:pacman_cache:_files -/' '-c[Set pacman cache]:pacman_cache:_files -/'
'-f[Copy file from the host to the chroot]:copy_file:_files' '-f[Copy file from the host to the chroot]:copy_file:_files'
'-s[Do not run setarch]'
'-h[Display usage]' '-h[Display usage]'
'1:chroot_dir:_files -/' '1:chroot_dir:_files -/'
) )
@@ -94,10 +93,11 @@ _offload_build_args=(
) )
_makerepropkg_args=( _makerepropkg_args=(
'-d[Run diffoscope if the package is unreproducible]'
'-c[Set pacman cache]:pacman_cache:_files -/' '-c[Set pacman cache]:pacman_cache:_files -/'
'-M[Location of a makepkg config file]:makepkg_config:_files -g "*.conf(.)"' '-M[Location of a makepkg config file]:makepkg_config:_files -g "*.conf(.)"'
'-h[Display usage]' '-h[Display usage]'
'1:working_dir:_files -g "*.pkg.tar.*(.)"' '*:working_dir:_files -g "*.pkg.tar.*(.)"'
) )
_devtools_completions_all_packages() { _devtools_completions_all_packages() {