diff -Nru sbuild-0.80.0ubuntu1/bin/create-chroot sbuild-0.81.2ubuntu5/bin/create-chroot --- sbuild-0.80.0ubuntu1/bin/create-chroot 2020-08-01 12:07:53.000000000 +0000 +++ sbuild-0.81.2ubuntu5/bin/create-chroot 1970-01-01 00:00:00.000000000 +0000 @@ -1,485 +0,0 @@ -#!/bin/bash - -# GPLv2. -# (C) 2009 Philipp Kern -# (C) 2009 Marc Brockschmidt -# (C) 2010-1 Andreas Barth - -set -e - -if [ "$USER" != "buildd" ] -then - echo "You need to run this as user buildd!" >&2 - exit 1 -fi - -usage() { - message=$1 - if [ ! -z "$message" ] - then - echo "E: $message" >&2 - fi - echo "Usage: $0 [http://some.debian.mirror/debian] [--arch=arch] suite [vgname lvsize]" >&2 - echo "Valid suites: oldstable, stable, testing, unstable, experimental," >&2 - echo " oldstable-security, stable-security, testing-security," >&2 - echo " oldstable-backports, stable-backports," >&2 - echo " oldstable-edu, stable-edu, testing-edu" >&2 - echo "If vgname is given, the script will setup schroot" >&2 - echo "to use snapshots based on a source lv." >&2 - exit 1 -} - -error() { - message=$1 - echo "E: ${message}" >&2 - exit 1 -} - -if [ -f /etc/schroot/conf.buildd ] ; then - set +e - . /etc/schroot/conf.buildd - set -e -fi - -if echo "$1" | egrep -q '^(ht|f)tp://'; then - MIRROR="$1" - shift -else - MIRROR="${debian_mirror}" - [ -z ${MIRROR} ] && error "no mirror specified (neither on command line nor in /etc/schroot/conf.buildd)" -fi - - -ARCH="$(dpkg --print-architecture)" -if echo "$1" | egrep -q '^--arch='; then - ARCH=${1:7} - shift -fi - -SUITE="$1" -VGNAME="$2" -LVSIZE="$3" -# This might need an adjustment if you are creating chroots different -# from the host architecture. (Not tested.) - -if [ -z "$MIRROR" ] -then - usage "No mirror specified!" -fi - -if [ -z "$SUITE" ] -then - usage "No suite specified!" -fi - -if ! [ -z "$VGNAME" ] && [ -z "$LVSIZE" ] -then - usage "You need to specifiy a source lv size!" -fi - -BASE="$SUITE" -OLDSTABLE="squeeze" -STABLE="wheezy" -TESTING="jessie" -case "$SUITE" in - oldstable) BASE=$OLDSTABLE ;; - oldstable-security) BASE=$OLDSTABLE; VARIANT="security" ;; - oldstable-backports) BASE=$OLDSTABLE; VARIANT="backports" ;; - oldstable-edu) BASE=$OLDSTABLE; VARIANT="edu" ;; - stable) BASE=$STABLE ;; - stable-security) BASE=$STABLE; VARIANT="security" ;; - stable-backports) BASE=$STABLE; VARIANT="backports" ;; - stable-edu) BASE=$STABLE; VARIANT="edu" ;; - testing) BASE=$TESTING ;; - testing-security) BASE=$TESTING; VARIANT="security" ;; - testing-edu) BASE=$TESTING; VARIANT="edu" ;; - unstable) BASE="sid" ;; - experimental) BASE="sid"; VARIANT="experimental";; - *) usage "Invalid suite specified (must be symbolic, e.g. 'stable')!" ;; -esac - -echo "I: Building environment for $SUITE" -echo "I: Mirror: $MIRROR" -echo "I: Base suite: $BASE" -if [ ! -z "$VARIANT" ] -then - echo "I: Variant: $VARIANT" - IDENTIFIER="$BASE-$VARIANT" -else - IDENTIFIER="$BASE" -fi - -TARGET=~buildd/chroots/$IDENTIFIER -echo "I: Chroot target: $TARGET" - -check_prerequisites() { - echo "I: Checking prerequisites..." - [ -d /etc/schroot/chroot.d ] || \ - error "/etc/schroot/chroot.d not found, schroot not installed?" - [ ! -d $TARGET ] || error "Target $TARGET already exists." - ! schroot -l | grep ^${IDENTIFIER}-${ARCH}-sbuild$ -q || error "schroot target ${IDENTIFIER}-${ARCH}-sbuild exists" - if [ "${SUITE}" = experimental ]; then - ! schroot -l | grep ^${SUITE}-${ARCH}-sbuild$ -q || error "schroot target ${SUITE}-${ARCH}-sbuild exists" - fi - [ ! -f "/etc/schroot/chroot.d/buildd-${IDENTIFIER}-${ARCH}" ] || error "schroot file /etc/schroot/chroot.d/buildd-${IDENTIFIER}-${ARCH} already exists" - if [ -z "$VGNAME" ]; then - mkdir -p ~buildd/chroots - fi - mkdir -p ~buildd/build-trees -} - -do_debootstrap() { - ensure_target_mounted - echo "I: Running debootstrap..." - echo - sudo debootstrap \ - --arch=$ARCH \ - --variant=buildd \ - --include=fakeroot,build-essential,debfoster,apt \ - $BASE \ - $TARGET \ - $MIRROR - echo - echo "I: Creating a policy-rc.d to prevent daemon startups..." - TEMPFILE="$(mktemp)" - cat > "${TEMPFILE}" <&2 -exit 101 -EOT - sudo mv "${TEMPFILE}" "${TARGET}/usr/sbin/policy-rc.d" - sudo chown root: "${TARGET}/usr/sbin/policy-rc.d" - sudo chmod 0755 "${TARGET}/usr/sbin/policy-rc.d" - # With wheezy and up /dev/shm is a symlink to /run/shm; because all - # suites share the same setup scripts, this needs to be reverted. - echo "I: Switching /dev/shm to a real directory..." - if [ -L "${TARGET}/dev/shm" ] - then - sudo rm "${TARGET}/dev/shm" - sudo mkdir "${TARGET}/dev/shm" - sudo chmod a+w,o+t "${TARGET}/dev/shm" - fi - ensure_target_unmounted -} - -setup_schroot() { - echo "I: Setting up schroot configuration..." - TEMPFILE="$(mktemp)" - cat > "${TEMPFILE}" <> "${TEMPFILE}" - fi - if [ -z "$VGNAME" ]; then - echo "type=directory" >> "${TEMPFILE}" - echo "directory=${TARGET}" >> "${TEMPFILE}" - SCHROOT="schroot -c ${IDENTIFIER}-${ARCH}-sbuild -u root -d /root --" - else - cat >>"${TEMPFILE}" <>"${TEMPFILE}" - fi - sudo mv "${TEMPFILE}" "/etc/schroot/chroot.d/buildd-${IDENTIFIER}${EXTRA}-${ARCH}" - sudo chown root: "/etc/schroot/chroot.d/buildd-${IDENTIFIER}${EXTRA}-${ARCH}" - sudo chmod 0644 "/etc/schroot/chroot.d/buildd-${IDENTIFIER}${EXTRA}-${ARCH}" -} - -setup_schroot_variant() { - echo VARIANT: $EXTRA - if ! [ -f "/etc/schroot/chroot.d/buildd-${IDENTIFIER}${EXTRA}-${ARCH}" ] && - ! schroot -l | grep ^${IDENTIFIER}${EXTRA}-${ARCH}-sbuild$ -q && - ( [ -z "${SUITEEXTRA}" ] || ! schroot -l | grep ^${SUITEEXTRA}-${ARCH}-sbuild$ -q ) ; then - setup_schroot - fi -} - -setup_sources() { - echo "I: Setting up sources..." - TEMPFILE="$(mktemp)" - cat > "${TEMPFILE}" <> "${TEMPFILE}" <> "${TEMPFILE}" <> "${TEMPFILE}" <> "${TEMPFILE}" <> "${TEMPFILE}" <> "${TEMPFILE}" < "${TEMPFILE}" < "${TEMPFILE}" < "${TEMPFILE}" < "${TEMPFILE}" <> "$file" - fi -} - -setup_debfoster() { - echo "I: Setting up debfoster's keepers file..." - TEMPFILE="$(mktemp)" - cat > "$TEMPFILE" < /etc/schroot/conf.buildd" -fi - -do_debootstrap -setup_schroot -if ! [ -z "$VGNAME" ] && [ -z "$VARIANT" ]; then - variants="security backports" - if [ "$ARCH" == "i386" -o "$ARCH" == "amd64" -o "$ARCH" == "powerpc" ]; then - variants="${variants} edu" - fi - if [ "$BASE" == "sid" ]; then variants="experimental"; fi - for EXTRA in $variants; do - EXTRA=-${EXTRA} - SUITEEXTRA="" - if [ "$BASE" = "sid" ]; then SUITEEXTRA="experimental"; fi - - setup_schroot_variant - done -fi -setup_sources -adjust_debconf -adjust_dpkg -setup_sbuild -old_sbuild_compat -setup_debfoster - -do_dist_upgrade - -echo -echo "I: The last step is coming up, you can also abort on the apt prompt" -echo "I: caused by debfoster!" -echo -do_debfoster - diff -Nru sbuild-0.80.0ubuntu1/bin/Makefile.am sbuild-0.81.2ubuntu5/bin/Makefile.am --- sbuild-0.80.0ubuntu1/bin/Makefile.am 2020-08-01 12:07:53.000000000 +0000 +++ sbuild-0.81.2ubuntu5/bin/Makefile.am 2021-03-18 07:38:02.000000000 +0000 @@ -34,6 +34,10 @@ sbuild-upgrade \ sbuild-distupgrade \ sbuild-clean \ + sbuild-qemu \ + sbuild-qemu-create \ + sbuild-qemu-create-modscript \ + sbuild-qemu-update \ sbuild-shell \ sbuild-hold \ sbuild-unhold \ @@ -49,7 +53,6 @@ sbuild-destroychroot sbuilddata_SCRIPTS = \ - create-chroot \ dobuildlog doc_DATA = \ diff -Nru sbuild-0.80.0ubuntu1/bin/sbuild sbuild-0.81.2ubuntu5/bin/sbuild --- sbuild-0.80.0ubuntu1/bin/sbuild 2020-08-04 14:28:23.000000000 +0000 +++ sbuild-0.81.2ubuntu5/bin/sbuild 2021-03-18 07:38:02.000000000 +0000 @@ -60,7 +60,9 @@ die "A maintainer name, uploader name or key ID must be specified in .sbuildrc,\nor use -m, -e or -k, when performing a binNMU or appending a version suffix\n"; } -umask(002); +# default umask for Debian +# see dpkg source: scripts/Dpkg/Vendor/Debian.pm +umask(0022); # Job state my $job = undef; diff -Nru sbuild-0.80.0ubuntu1/bin/sbuild-destroychroot sbuild-0.81.2ubuntu5/bin/sbuild-destroychroot --- sbuild-0.80.0ubuntu1/bin/sbuild-destroychroot 2020-08-01 12:07:53.000000000 +0000 +++ sbuild-0.81.2ubuntu5/bin/sbuild-destroychroot 2021-03-18 07:38:02.000000000 +0000 @@ -163,6 +163,12 @@ print "\n"; print " rm --recursive --one-file-system $chroot_path\n"; print "\n"; + if (-e "$Sbuild::Sysconfig::paths{'SBUILD_SYSCONF_DIR'}/chroot/$chroot") { + print "Delete the chroot link, for example by running:\n"; + print "\n"; + print " rm $Sbuild::Sysconfig::paths{'SBUILD_SYSCONF_DIR'}/chroot/$chroot\n"; + print "\n"; + } } else { print "Delete the tarball, for example by running:\n"; print "\n"; diff -Nru sbuild-0.80.0ubuntu1/bin/sbuild-qemu sbuild-0.81.2ubuntu5/bin/sbuild-qemu --- sbuild-0.80.0ubuntu1/bin/sbuild-qemu 1970-01-01 00:00:00.000000000 +0000 +++ sbuild-0.81.2ubuntu5/bin/sbuild-qemu 2021-03-18 07:38:02.000000000 +0000 @@ -0,0 +1,166 @@ +#!/usr/bin/python3 +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright © 2020 Christian Kastner +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see +# . +# +####################################################################### + + +import argparse +import os +import platform +import psutil +import sys + + +MACHINE_TO_DEB_ARCH = { + 'x86_64': 'amd64', + 'i386': 'i386' +} +DEB_ARCH_TO_QEMU = { + 'amd64': 'qemu-system-x86_64', + 'i386': 'qemu-system-i386', +} + + +MACHINE = platform.machine() +try: + ARCH = MACHINE_TO_DEB_ARCH[MACHINE] +except KeyError as e: + print(f"Unsupported machine type {MACHINE}", file=sys.stderr) + sys.exit(1) +# Defaults +MEM = 2048 +CPUS = psutil.cpu_count(logical=False) +DIST = 'unstable' +_DEFAULT_IMAGEDIR = os.path.join(os.path.expanduser('~'), '.cache', 'sbuild') +IMAGEDIR = os.environ.get('IMAGEDIR', _DEFAULT_IMAGEDIR) + + +def main(): + # init options + parser = argparse.ArgumentParser( + description="Build Debian packages using sbuild(1) and QEMU images", + epilog="All other options are passed on through to sbuild(1). " + "The image will be started in -snapshot mode, so no changes " + "are saved, and multiple processes can use the same image " + "concurrently.", + ) + parser.add_argument( + '--arch', + action='store', + default=ARCH, + help="Architecture to use. Default is the host architecture. " + "Currently supported architectures are: " + f"{', '.join(DEB_ARCH_TO_QEMU.keys())}.", + ) + parser.add_argument( + '-d', '--dist', + action='store', + default=DIST, + help=f"Distribution (for the .changes file). Default is '{DIST}'.", + ) + parser.add_argument( + '--image', + action='store', + help="VM image to use for building. If not specified, will look for " + "an image with the name DIST-autopkgtest-ARCH.img. Will first " + "look in the current directory, and if no such file exists " + "there, then the directory $IMAGEDIR is tried. A suitable image " + "can be created with qemu-sbuild-create(1).", + ) + parser.add_argument( + '--autopkgtest-debug', + action='store_true', + help="Enable debug output for the autopkgtest-virt-qemu(1) driver.", + ) + parser.add_argument( + '--ram', + metavar='MiB', + action='store', + default=MEM, + help=f"VM memory size in MB. Default: {MEM}", + ) + parser.add_argument( + '--cpus', + metavar='CPUs', + action='store', + default=CPUS, + help="VM CPU count. Default: Number of physical cores on the host.", + ) + parser.add_argument( + '--overlay-dir', + action='store', + help="Directory for the temporary image overlay instead of " + "autopkgtest's default of /tmp (or $TMPDIR).", + ) + parser.add_argument( + '--noexec', + action='store_true', + help="Don't actually do anything. Just print the sbuild(1) command " + "string that would be executed, and then exit.", + ) + parsed_args, unparsed_args = parser.parse_known_args() + + if parsed_args.image: + if os.path.exists(os.path.abspath(parsed_args.image)): + image = parsed_args.image + else: + image = os.path.join(IMAGEDIR, parsed_args.image) + else: + guessed_name = f'{parsed_args.dist}-autopkgtest-{ARCH}.img' + if os.path.exists(os.path.abspath(guessed_name)): + images = os.path.abspath(guessed_name) + else: + image = os.path.join( + IMAGEDIR, + f'{parsed_args.dist}-autopkgtest-{ARCH}.img', + ) + qemu = DEB_ARCH_TO_QEMU[ARCH] + + args = [ + 'sbuild', + '--arch', parsed_args.arch, + '--dist', parsed_args.dist, + '--purge-build=never', + '--purge-deps=never', + '--chroot-mode=autopkgtest', + '--autopkgtest-virt-server=qemu', + '--autopkgtest-virt-server-opt', '--overlay-dir=/tmp', + '--autopkgtest-virt-server-opt', f'--qemu-command={qemu}', + '--autopkgtest-virt-server-opt', f'--ram-size={parsed_args.ram}', + '--autopkgtest-virt-server-opt', f'--cpus={parsed_args.cpus}', + '--autopkgtest-virt-server-opt', image, + # Worarkound -- dose can hang stuff in a qemu VM + '--bd-uninstallable-explainer', 'apt', + ] + if parsed_args.autopkgtest_debug: + args += ['--autopkgtest-virt-server-opt', '--debug'] + if parsed_args.overlay_dir: + d = parsed_args.overlay_dir + args += ['--autopkgtest-virt-server-opt', f'--overlay_dir={d}'] + + # Pass on the remaining arguments to sbuild + args += unparsed_args + + print(' '.join(str(a) for a in args)) + if not parsed_args.noexec: + os.execvp(args[0], args) + + +if __name__ == '__main__': + main() diff -Nru sbuild-0.80.0ubuntu1/bin/sbuild-qemu-create sbuild-0.81.2ubuntu5/bin/sbuild-qemu-create --- sbuild-0.80.0ubuntu1/bin/sbuild-qemu-create 1970-01-01 00:00:00.000000000 +0000 +++ sbuild-0.81.2ubuntu5/bin/sbuild-qemu-create 2021-03-18 07:38:02.000000000 +0000 @@ -0,0 +1,218 @@ +#!/usr/bin/python3 +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright © 2020 Christian Kastner +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see +# . +# +####################################################################### + + +import argparse +import os +import platform +import sys +import textwrap + + +SUPPORTED_ARCHS = { + 'x86_64': 'amd64', + 'i386': 'i386' +} + + +MACHINE = platform.machine() +try: + ARCH = SUPPORTED_ARCHS[MACHINE] +except KeyError as e: + print(f"Unsupported machine type {MACHINE}", file=sys.stderr) + sys.exit(1) +OUT_FILE = '-autopkgtest-.img' +MOD_SCRIPT = '/usr/share/sbuild/sbuild-qemu-create-modscript' + + +def gen_sourceslist(mirror, dist, components, with_bpo=False): + """Generate a sources.list file for the VM. + + If distribution ends with '-backports', then its base distribution will + automatically be added. + + If distribution is 'experimental', then the 'unstable' distribution will + automatically be added. + """ + sl = textwrap.dedent( + f"""\ + deb {mirror} {dist} {' '.join(components)} + deb-src {mirror} {dist} {' '.join(components)} + """) + if dist == 'experimental': + sl += textwrap.dedent( + f""" + deb {mirror} unstable {' '.join(components)} + deb-src {mirror} unstable {' '.join(components)} + """) + elif dist.endswith('-backports'): + sl += textwrap.dedent( + f""" + deb {mirror} {dist[:-10]} {' '.join(components)} + deb-src {mirror} {dist[:-10]} {' '.join(components)} + """) + return sl + + +def main(): + parser = argparse.ArgumentParser( + description="Builds images for use with qemu-sbuild and autopkgtest.", + epilog="Note that qemu-sbuild-create is just a simple wrapper around " + "autopkgtest-build-qemu(1) that automates a few additional " + "steps commonly performed with package-building images.", + ) + parser.add_argument( + '--arch', + action='store', + default=ARCH, + help="Architecture to use. Default is the host architecture. " + "Currently supported architectures are: " + f"{', '.join(SUPPORTED_ARCHS.values())}.", + ) + parser.add_argument( + '--install-packages', + action='store', + help="Comma-separated list of additional packages to install in the " + "image using 'apt-get install'.", + ) + parser.add_argument( + '--extra-deb', + action='append', + help="Package file (.deb) from the local filesystem to install. Can " + "be specified more than once.", + ) + parser.add_argument( + '--components', + action='store', + default='main', + help="Comma-separated list of components to use with sources.list " + "entries. Default: main.", + ) + # Not yet merged into autopkgtest, see #973457 + # parser.add_argument('--variant', action='store') + parser.add_argument( + '--skel', + type=str, + action='store', + help="Skeleton directory to use for /root.", + ) + parser.add_argument( + '--size', + type=str, + action='store', + default='10G', + help="VM size to use. Note that the images are in qcow2 format, so " + "they won't consume that space right away. Default: 10G.", + ) + parser.add_argument( + '-o', '--out-file', + action='store', + default=OUT_FILE, + help="Output filename. If not supplied, then " + "DIST-autopkgtest-ARCH.img will be used.", + ) + parser.add_argument( + '--noexec', + action='store_true', + help="Don't actually do anything. Just print the autopkgtest-build-" + "qemu(1) command string that would be executed, and then exit.", + ) + parser.add_argument( + 'distribution', + action='store', + help="The distribution to debootstrap.", + ) + parser.add_argument( + 'mirror', + action='store', + help="The mirror to use for the installation. Note that the mirror " + "will also be used for the sources.list file in the VM. See " + "MIRROR below.", + ) + parsed = parser.parse_args() + + # Internal args + if parsed.arch not in SUPPORTED_ARCHS.values(): + print( + f"Unsupported architecture: {parsed.arch}", + file=sys.stderr, + ) + sys.exit(1) + if parsed.out_file == OUT_FILE: + # Default unchanged - peplace template with instantiated name + out_file = f"{parsed.distribution}-autopkgtest-{parsed.arch}.img" + else: + out_file = parsed.out_file + components = parsed.components.split(',') + + # Args that *may* be consumed by modscript (if supplied) + if parsed.skel: + os.environ['QSC_SKEL'] = parsed.skel + print('export QSC_SKEL=' + os.environ['QSC_SKEL']) + if parsed.extra_deb: + extra_debs = ' '.join(parsed.extra_deb) + os.environ['QSC_EXTRA_DEBS'] = extra_debs + print('export QSC_EXTRA_DEBS=' + extra_debs) + if parsed.install_packages: + install_packages = parsed.install_packages.replace(',', ' ') + os.environ['QSC_INSTALL_PACKAGES'] = install_packages + print('export QSC_INSTALL_PACKAGES=' + install_packages) + + # Args consumed by autopkgtest-build-qemu + os.environ['AUTOPKGTEST_APT_SOURCES'] = gen_sourceslist( + parsed.mirror, + parsed.distribution, + components, + ) + print('sources.list (via export AUTOPKGTEST_APT_SOURCES)\n------------') + print(os.environ['AUTOPKGTEST_APT_SOURCES']) + + args = [ + 'autopkgtest-build-qemu', + '--architecture', parsed.arch, + '--mirror', parsed.mirror, + '--size', parsed.size, + '--script', MOD_SCRIPT, + ] + #if parsed.variant: + # args += ['--variant', parsed.variant] + dist = parsed.distribution + if dist.endswith('-backports'): + dist = dist[:-10] + elif dist == 'experimental': + dist = 'unstable' + args += [ + dist, + out_file, + ] + + if os.getuid() != 0: + print('Must be root to use this.', file=sys.stderr) + sys.exit(1) + os.umask(22) + + print(' '.join(str(a) for a in args)) + if not parsed.noexec: + os.execvp(args[0], args) + + +if __name__ == '__main__': + main() diff -Nru sbuild-0.80.0ubuntu1/bin/sbuild-qemu-create-modscript sbuild-0.81.2ubuntu5/bin/sbuild-qemu-create-modscript --- sbuild-0.80.0ubuntu1/bin/sbuild-qemu-create-modscript 1970-01-01 00:00:00.000000000 +0000 +++ sbuild-0.81.2ubuntu5/bin/sbuild-qemu-create-modscript 2021-03-18 07:38:02.000000000 +0000 @@ -0,0 +1,80 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright © 2020 Christian Kastner +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see +# . +# +####################################################################### + + +set -e +umask 0022 + + +VMROOT="$1" +if [ -z "$VMROOT" ] +then + echo "$0 expects the mounted root of the VM as first argument." >&2 + exit 1 +elif ! mountpoint -q "$VMROOT" +then + echo "$VMROOT is not a mountpoint." >&2 + exit 1 +fi + + +echo "### Customizing base image ###" + +if [ -n "$QSC_SKEL" ] +then + echo "Copying contents of $QSC_SKEL" + if [ ! -d "$QSC_SKEL" ] + then + echo "$QSC_SKEL is not a directory." >&2 + exit 1 + fi + cp -pr $QSC_SKEL/. $VMROOT/root +fi + +if [ -n "$QSC_INSTALL_PACKAGES" ] +then + echo "Installing additional packages" + chroot $VMROOT apt-get install --quiet --assume-yes $QSC_INSTALL_PACKAGES +fi + +if [ -n "$QSC_EXTRA_DEBS" ] +then + echo "Installing extra .debs" + VMTMP=`mktemp -d -p $VMROOT` + cp -t $VMTMP $QSC_EXTRA_DEBS + chroot $VMROOT dpkg --recursive -i `basename $VMTMP` + chroot $VMROOT apt-get update + rm -rf $VMTMP +fi + +# Mount point for a shared folder, if the VM is launched with one +echo "Adding 9p to initramfs" +echo -e "9p\n9pnet\n9pnet_virtio" >> $VMROOT/etc/initramfs-tools/modules +chroot $VMROOT update-initramfs -u +echo "Adding shared folder to fstab" +mkdir -m 755 $VMROOT/shared +echo "qlaunch /shared 9p trans=virtio,version=9p2000.L,auto,nofail 0 0" >> $VMROOT/etc/fstab + +echo "Updating GRUB menu" +echo "GRUB_TIMEOUT=1" >> $VMROOT/etc/default/grub +chroot $VMROOT update-grub + +echo "### Customization of base image complete. ###" diff -Nru sbuild-0.80.0ubuntu1/bin/sbuild-qemu-update sbuild-0.81.2ubuntu5/bin/sbuild-qemu-update --- sbuild-0.80.0ubuntu1/bin/sbuild-qemu-update 1970-01-01 00:00:00.000000000 +0000 +++ sbuild-0.81.2ubuntu5/bin/sbuild-qemu-update 2021-03-18 07:38:02.000000000 +0000 @@ -0,0 +1,161 @@ +#!/usr/bin/python3 +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright © 2020 Christian Kastner +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see +# . +# +####################################################################### + + +import argparse +import datetime +import os +import subprocess +import sys + +import pexpect + + +DEB_ARCH_TO_QEMU = { + 'amd64': 'qemu-system-x86_64', + 'i386': 'qemu-system-i386', +} + + +_DEFAULT_IMAGEDIR = os.path.join(os.path.expanduser('~'), '.cache', 'sbuild') +IMAGEDIR = os.environ.get('IMAGEDIR', _DEFAULT_IMAGEDIR) + + +def make_snapshot(image): + iso_stamp = datetime.datetime.now().strftime('%Y-%m-%d_%H%M%S') + run = subprocess.run( + ['qemu-img', 'snapshot', '-l', image], + capture_output=True + ) + tags = [t.split()[1].decode('utf-8') for t in run.stdout.splitlines()[2:]] + + if iso_stamp in tags: + print( + f"Error: snapshot for {iso_stamp} already exists.", + file=sys.stderr + ) + return False + + run = subprocess.run(['qemu-img', 'snapshot', '-c', iso_stamp, image]) + return True if run.returncode == 0 else False + + +def main(): + # init options + parser = argparse.ArgumentParser( + description="sbuild-update analog for QEMU images.", + ) + parser.add_argument( + '--snapshot', + action='store_true', + help="Create a snapshot of the image before updating it. Useful for " + "reproducibility purposes.", + ) + parser.add_argument( + '--arch', + action='store', + help="Architecture to use (instead of attempting to auto-guess based " + "on the image name).", + ) + parser.add_argument( + '--noexec', + action='store_true', + help="Don't actually do anything. Just print the command string that " + "would be executed, and then exit.", + ) + parser.add_argument( + 'image', + action='store', + help="Image. Will first be interpreted as a path. If no suitable " + "image exists at that location, then $IMAGEDIR\ is tried.", + ) + + parsed_args = parser.parse_args() + + if os.path.exists(parsed_args.image): + image = parsed_args.image + elif os.path.exists(os.path.join(IMAGEDIR, parsed_args.image)): + image = os.path.join(IMAGEDIR, parsed_args.image) + else: + print("Image does not exist", file=sys.stderr) + sys.exit(1) + + if parsed_args.arch: + try: + qemu = DEB_ARCH_TO_QEMU[parsed_args.arch] + except KeyError as e: + print( + f"Unsupported architecture {parsed_args.arch}", + file=sys.stderr, + ) + sys.exit(1) + else: + # This assumes that images are named foo-bar-ARCH.img + components = os.path.basename(parsed_args.image)[:-4].split('-') + if 'amd64' in components: + qemu = DEB_ARCH_TO_QEMU['amd64'] + elif 'i386' in components: + qemu = DEB_ARCH_TO_QEMU['i386'] + else: + print( + f"Could not guess architecture, please use --arch", + file=sys.stderr, + ) + sys.exit(1) + + args = [ + qemu, + '-enable-kvm', + '-object', 'rng-random,filename=/dev/urandom,id=rng0', + '-device', 'virtio-rng-pci,rng=rng0,id=rng-device0', + '-m', '2048', + '-nographic', + ] + args.append(image) + + print(' '.join(str(a) for a in args)) + if not parsed_args.noexec: + if parsed_args.snapshot and not make_snapshot(image): + return + child = pexpect.spawn(' '.join(args), encoding='utf-8') + child.timeout = 240 + child.expect('host login: ') + child.sendline('root') + child.logfile = sys.stdout + child.expect('root@host:~# ') + child.sendline('DEBIAN_FRONTEND=noninteractive apt-get --quiet update') + child.expect('root@host:~# ') + child.sendline('DEBIAN_FRONTEND=noninteractive apt-get --quiet --assume-yes dist-upgrade') + child.expect('root@host:~# ') + child.sendline('DEBIAN_FRONTEND=noninteractive apt-get --quiet --assume-yes clean') + child.expect('root@host:~# ') + child.sendline('DEBIAN_FRONTEND=noninteractive apt-get --quiet --assume-yes autoremove') + child.expect('root@host:~# ') + child.sendline('sync') + child.expect('root@host:~# ') + # Don't recall what issue this solves, but it solves it + child.sendline('sleep 1') + child.expect('root@host:~# ') + child.sendline('shutdown -h now') + + +if __name__ == '__main__': + main() diff -Nru sbuild-0.80.0ubuntu1/ChangeLog.in sbuild-0.81.2ubuntu5/ChangeLog.in --- sbuild-0.80.0ubuntu1/ChangeLog.in 2020-08-01 12:07:53.000000000 +0000 +++ sbuild-0.81.2ubuntu5/ChangeLog.in 2021-03-18 07:38:02.000000000 +0000 @@ -7,6 +7,11 @@ README file also contains more specific notes regarding building and configuration. + * Major changes in 0.80.0: + + 1) sbuild became a Debian native package -- consult debian/changelog or + /usr/share/doc/sbuild/changelog.Debian.gz instead + * Major changes in 0.79.1: 1) buildd: add --dpkg-file-suffix option diff -Nru sbuild-0.80.0ubuntu1/configure.ac sbuild-0.81.2ubuntu5/configure.ac --- sbuild-0.80.0ubuntu1/configure.ac 2020-08-01 12:07:53.000000000 +0000 +++ sbuild-0.81.2ubuntu5/configure.ac 2021-03-18 07:38:02.000000000 +0000 @@ -29,8 +29,8 @@ [sbuild_m4_chomp(m4_esyscmd([$1]))]) AC_PREREQ(2.59) dnl Quoting the first argument results in a bizarrely corrupted package tarname -AC_INIT(sbuild_m4_esyscmd_s([sed -ne '/^Package:/{s/Package:[[:space:]][[:space:]]*//p;q}' VERSION]), - sbuild_m4_esyscmd_s([sed -ne '/^Version:/{s/Version:[[:space:]][[:space:]]*//p;q}' VERSION]), +AC_INIT(sbuild_m4_esyscmd_s([dpkg-parsechangelog --show-field Source]), + sbuild_m4_esyscmd_s([dpkg-parsechangelog --show-field Version]), [buildd-tools-devel@lists.alioth.debian.org]) dnl For safety, check we are in the right directory by dnl checking for a known unique file. @@ -62,8 +62,8 @@ dnl Initialise automake stuff. AM_INIT_AUTOMAKE([1.10 gnu check-news tar-pax foreign]) m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])]) -RELEASE_DATE='sbuild_m4_esyscmd_s([sed -ne '/^Release-Date:/{s/Release-Date:[[:space:]][[:space:]]*//p;q}' VERSION])' -RELEASE_DATE_S='sbuild_m4_esyscmd_s(date --date='sbuild_m4_esyscmd_s([sed -ne '/^Release-Date:/{s/Release-Date:[[:space:]][[:space:]]*//p;q}' VERSION])' '+%s')' +RELEASE_DATE='sbuild_m4_esyscmd_s(date --utc --date=@'sbuild_m4_esyscmd_s([dpkg-parsechangelog --show-field Timestamp])' '+%d %B %Y')' +RELEASE_DATE_S='sbuild_m4_esyscmd_s(date --utc --date=@'sbuild_m4_esyscmd_s([dpkg-parsechangelog --show-field Timestamp])' '+%s')' AC_DEFINE_UNQUOTED([RELEASE_DATE], ["$RELEASE_DATE_S"], [Package release date.]) AC_SUBST([RELEASE_DATE]) diff -Nru sbuild-0.80.0ubuntu1/debian/changelog sbuild-0.81.2ubuntu5/debian/changelog --- sbuild-0.80.0ubuntu1/debian/changelog 2020-08-04 14:28:23.000000000 +0000 +++ sbuild-0.81.2ubuntu5/debian/changelog 2021-03-18 07:38:02.000000000 +0000 @@ -1,3 +1,97 @@ +sbuild (0.81.2ubuntu5) hirsute; urgency=medium + + * debian/tests/control: Skip unshare-qemuwrapper test where linux-image-amd64 + is missing. It is missing in Ubuntu making the test fail. + * debian/tests/unshare: Run the test, but skip it if user namespaces are not + supported + * debian/tests/unshare-qemuwrapper: Drop delta + * debian/tests/unshare*: Test with current release + + -- Balint Reczey Thu, 18 Mar 2021 08:38:02 +0100 + +sbuild (0.81.2ubuntu4) hirsute; urgency=medium + + * debian/tests/unshare-qemuwrapper: Don't use linux-image-amd64 package in + bootrstrapping test on Ubuntu + + -- Balint Reczey Mon, 01 Mar 2021 12:02:26 +0100 + +sbuild (0.81.2ubuntu3) hirsute; urgency=medium + + * debian/tests/control: Don't depend on linux-image-amd64 package + It does not exist on Ubuntu. + + -- Balint Reczey Thu, 25 Feb 2021 18:50:14 +0100 + +sbuild (0.81.2ubuntu2) hirsute; urgency=medium + + * No change rebuild with fixed ownership. + + -- Dimitri John Ledkov Tue, 16 Feb 2021 17:05:37 +0000 + +sbuild (0.81.2ubuntu1) hirsute; urgency=medium + + * Merge with Debian; remaining changes: + - no-pkg-mangle-deps.patch: Set NO_PKG_MANGLE=1 when building dummy + packages, as pkgbinarymangler's dpkg-deb expects to be run from a source + package. + - abs-path-revert.patch: Revert upstream commit that breaks lp-buildd by + causing symlinks to files not ending in .dsc to no longer be buildable. + - d/t/control: add isolation-machine to the test flags + + -- Matthias Klose Mon, 08 Feb 2021 11:55:35 +0100 + +sbuild (0.81.2) unstable; urgency=medium + + * Package sbuild-qemu should be arch:all, not arch:amd64. + Resolves a FTBFS. + + -- Christian Kastner Sun, 31 Jan 2021 15:34:54 +0100 + +sbuild (0.81.1) unstable; urgency=medium + + * lib/Sbuild/ChrootUnshare.pm: also ignore /dev/console when unpacking + rootfs becauke mknod is forbidden in unshare mode + * lib/Sbuild/Build.pm: add comment about #977674 + * bin/sbuild: use umask 0022 as default for Debian -- see dpkg source: + scripts/Dpkg/Vendor/Debian.pm + * lib/Sbuild/Build.pm: run dpkg-buildpackage with --sanitize-env if dpkg + 1.20.0 is available + * add new unshare autopkgtest with qemu wrapper + + -- Johannes 'josch' Schauer Sun, 31 Jan 2021 10:41:30 +0100 + +sbuild (0.81.0) unstable; urgency=medium + + [ Johannes 'josch' Schauer ] + * make 'none' explicitly disable the bd-uninstallable-explainer. + Thanks helmut & vagrantc + + [ Jochen Sprickerhof ] + * Cleanup link in /etc/sbuild if it exists + + [ Christian Kastner ] + * Add package sbuild-qemu, replaces qemu-sbuild-utils + - The utilities have been renamed from qemu-sbuild-* to sbuild-qemu-* to + for consistency + * Add myself to Uploaders + * Set Rules-Requires-Root: no + * Bump Standards-Version to 4.5.1 + + [ Bruno Kleinert ] + * Removed obsolete script /usr/share/sbuild/create-chroot to fix 'bullseye: + /updates -> -security'. Neither sbuild itself, nor any reverse dependency + appear to depend on that script, so removed it. (Closes: #972747) + + -- Johannes 'josch' Schauer Sun, 24 Jan 2021 23:13:34 +0100 + +sbuild (0.80.1) unstable; urgency=medium + + * Fix build system to rely on debian/changelog instead of VERSION file + * use mkdir -p when creating build_path (thanks Niels Thykier) + + -- Johannes 'josch' Schauer Sat, 05 Dec 2020 17:46:22 +0100 + sbuild (0.80.0ubuntu1) groovy; urgency=medium * Resynchronize on Debian, remaining changes diff -Nru sbuild-0.80.0ubuntu1/debian/control sbuild-0.81.2ubuntu5/debian/control --- sbuild-0.80.0ubuntu1/debian/control 2020-08-04 14:28:23.000000000 +0000 +++ sbuild-0.81.2ubuntu5/debian/control 2021-03-18 07:38:02.000000000 +0000 @@ -7,15 +7,19 @@ Michael Banck , Francesco Paolo Lovergine , Wookey , - Michael Stapelberg + Michael Stapelberg , + Christian Kastner , Build-Depends: debhelper-compat (= 12) -Build-Depends-Indep: groff-base, +Build-Depends-Indep: dh-python, + groff-base, libdpkg-perl (>= 1.20), libexception-class-perl, libfilesys-df-perl, libmime-lite-perl, - libyaml-tiny-perl -Standards-Version: 4.3.0 + libyaml-tiny-perl, + python3-all, +Standards-Version: 4.5.1 +Rules-Requires-Root: no Vcs-Browser: https://salsa.debian.org/debian/sbuild/tree/debian/unstable Vcs-Git: https://salsa.debian.org/debian/sbuild.git -b debian/unstable @@ -118,3 +122,27 @@ using the wanna-build database to identify which packages need to be built. Note that the wanna-build database is not packaged, and requires installing separately. + +Package: sbuild-qemu +Architecture: all +Depends: autopkgtest, + python3-pexpect, + python3-psutil, + qemu-system-x86, + qemu-utils, + sbuild, + ${misc:Depends}, + ${python3:Depends}, +Recommends: vmdb2 (>= 0.22), +Breaks: qemu-sbuild-utils (<< 0.2.1~) +Replaces: qemu-sbuild-utils (<< 0.2.1~) +Description: Utilities for using sbuild with QEMU images + These utilities facilitate the use of sbuild together with QEMU images using + sbuild's --chroot-mode=autopkgtest. Currently, amd64 and i386 guest + architectures are supported, with more in the works. + . + The following utilities are provided: + . + * sbuild-qemu-create Create an image suitable for building packages + * sbuild-qemu-update Run apt-get update within the image + * sbuild-qemu Use sbuild with the image to build a package diff -Nru sbuild-0.80.0ubuntu1/debian/copyright sbuild-0.81.2ubuntu5/debian/copyright --- sbuild-0.80.0ubuntu1/debian/copyright 2020-08-01 12:07:53.000000000 +0000 +++ sbuild-0.81.2ubuntu5/debian/copyright 2021-03-18 07:38:02.000000000 +0000 @@ -26,6 +26,7 @@ © 2003-2004 Francesco Paolo Lovergine © 2005 Michael Banck © 2005-2008 Roger Leigh + © 2020 Christian Kastner License: GPL-2+ Files: Makefile.am diff -Nru sbuild-0.80.0ubuntu1/debian/patches/series sbuild-0.81.2ubuntu5/debian/patches/series --- sbuild-0.80.0ubuntu1/debian/patches/series 2020-08-04 14:28:23.000000000 +0000 +++ sbuild-0.81.2ubuntu5/debian/patches/series 2021-03-18 07:38:02.000000000 +0000 @@ -1,3 +1,2 @@ no-pkg-mangle-deps.patch abs-path-revert.patch - diff -Nru sbuild-0.80.0ubuntu1/debian/rules sbuild-0.81.2ubuntu5/debian/rules --- sbuild-0.80.0ubuntu1/debian/rules 2020-08-01 12:07:53.000000000 +0000 +++ sbuild-0.81.2ubuntu5/debian/rules 2021-03-18 07:38:02.000000000 +0000 @@ -1,7 +1,8 @@ #!/usr/bin/make -f %: - dh $@ + # dh_python3 is needed for sbuild-qemu + dh $@ --with=python3 override_dh_installinit: dh_installinit --no-start --no-stop-on-upgrade diff -Nru sbuild-0.80.0ubuntu1/debian/sbuild-qemu.install sbuild-0.81.2ubuntu5/debian/sbuild-qemu.install --- sbuild-0.80.0ubuntu1/debian/sbuild-qemu.install 1970-01-01 00:00:00.000000000 +0000 +++ sbuild-0.81.2ubuntu5/debian/sbuild-qemu.install 2021-03-18 07:38:02.000000000 +0000 @@ -0,0 +1,4 @@ +usr/bin/sbuild-qemu +usr/bin/sbuild-qemu-create +usr/bin/sbuild-qemu-create-modscript usr/share/sbuild/ +usr/bin/sbuild-qemu-update diff -Nru sbuild-0.80.0ubuntu1/debian/sbuild-qemu.manpages sbuild-0.81.2ubuntu5/debian/sbuild-qemu.manpages --- sbuild-0.80.0ubuntu1/debian/sbuild-qemu.manpages 1970-01-01 00:00:00.000000000 +0000 +++ sbuild-0.81.2ubuntu5/debian/sbuild-qemu.manpages 2021-03-18 07:38:02.000000000 +0000 @@ -0,0 +1,3 @@ +usr/share/man/man1/sbuild-qemu.1 +usr/share/man/man1/sbuild-qemu-create.1 +usr/share/man/man1/sbuild-qemu-update.1 diff -Nru sbuild-0.80.0ubuntu1/debian/sbuild-qemu.README sbuild-0.81.2ubuntu5/debian/sbuild-qemu.README --- sbuild-0.80.0ubuntu1/debian/sbuild-qemu.README 1970-01-01 00:00:00.000000000 +0000 +++ sbuild-0.81.2ubuntu5/debian/sbuild-qemu.README 2021-03-18 07:38:02.000000000 +0000 @@ -0,0 +1,10 @@ +README for sbuild-qemu +====================== + +Acceleration +------------ + +By adding the build user to the 'kvm' group, qemu-sbuild can operate with +near-native performance on systems where KVM is supported. + + $ sudo gpasswd -a kvm diff -Nru sbuild-0.80.0ubuntu1/debian/tests/control sbuild-0.81.2ubuntu5/debian/tests/control --- sbuild-0.80.0ubuntu1/debian/tests/control 2020-08-04 14:28:23.000000000 +0000 +++ sbuild-0.81.2ubuntu5/debian/tests/control 2021-03-18 07:38:02.000000000 +0000 @@ -1,3 +1,13 @@ Tests: build-procenv Depends: @, debootstrap, distro-info, lsb-release, apt (>= 1.1~exp2), apt-utils Restrictions: needs-root, isolation-machine + +Tests: unshare-qemuwrapper +Architecture: amd64 +Depends: mmdebstrap, qemu-system-x86, libguestfs-tools, linux-image-amd64, sleepenh, openssh-client, grep-dctrl, lsb-release +Restrictions: allow-stderr needs-root skip-not-installable + +Tests: unshare +Architecture: amd64 +Depends: gnupg, sbuild, mmdebstrap, build-essential, uidmap, fakeroot, diffoscope, lsb-release +Restrictions: allow-stderr skippable diff -Nru sbuild-0.80.0ubuntu1/debian/tests/unshare sbuild-0.81.2ubuntu5/debian/tests/unshare --- sbuild-0.80.0ubuntu1/debian/tests/unshare 1970-01-01 00:00:00.000000000 +0000 +++ sbuild-0.81.2ubuntu5/debian/tests/unshare 2021-03-18 07:38:02.000000000 +0000 @@ -0,0 +1,279 @@ +#!/bin/sh +# +# This script tests whether sbuild can work with a very minimal chroot (only +# build-essential and apt), whether unshare mode works and whether signing +# works. +# +# After bugs #977674 and #981021 are fixed, also test --source-only-changes + +set -eu + +if [ -z ${AUTOPKGTEST_TMP+x} ]; then + echo "AUTOPKGTEST_TMP is unset" >&2; + exit 1 +fi + +if ! grep -q '^1$' /proc/sys/kernel/unprivileged_userns_clone 2> /dev/null; then + echo "User namespace support is not enabled" >&2; + exit 77 +fi + +nativearch=$(dpkg --print-architecture) +release=$(lsb_release -c -s) +if [ "$release" = "sid" ]; then + release="unstable" +fi + +mkdir -p "${AUTOPKGTEST_TMP}/gpghome" +chmod 700 "${AUTOPKGTEST_TMP}/gpghome" +export GNUPGHOME="${AUTOPKGTEST_TMP}/gpghome" + +verify_orig() { +cat << END | base64 -d > "${AUTOPKGTEST_TMP}/expected" +/Td6WFoAAATm1rRGAgAhARYAAAB0L+Wj4Cf/BBZdADoZSs4dfiUjFYSOxzYxnd+/m6AlVEVOGf2j +nT6NK0F9XZ7LLydbY3I//WjMOM2RFpGUqZ8R8Q8lLmydB5SLN5ZQSPW3OJjHlzxVQmv2v3KUyPxo +V5uvr2rp1j0gfmjB4O+m6SMxUWGmCOp3mrA13iUy99dt9OK9tRQagXItob106li/2LWmOsXR3/5M +8m/JLF/6KIaYolPsvzut8mTFmik8s22eXjugZufC7CQwXJ7KVb8/LPYgLzHo8tKwkrieBonYFwD+ +R17Q1wsK/wbdQCw78oh4JrairZPz0NY1WsY/6GXQZOeo0Wl3dgG0PmrQtgPH133asZz5XgrtfDwU +KqaSBmKWIGrht7IqByDr5Bf+XyzpU9vwiE30hIVmvzCQDnNIrcaO5wZJQgujJreb4k1BKKmZJ4dT +B46ae4yTd8zLLGH7YwFWk145SHCQJOBakSuVGjej3zElgoNsTwYTAK5J3wQX/BEszByCX+5AKUP3 +v4ZGs1oyM65MyvWjQNqYmMYK2juki3pvUV+d+XhR7S3wrmLuq5P2PHAU6chrOs+n9HewOOE//L6O +gq5jJFLEtMRzAXUSpKERHuwdzt0MfiKSWDfeqRUy5Pfoh+pNrpYdA/jsiH37EhzSR3evlu92fwVP +gTO+5GV7wgpDvI24RMwTK5oXtcJHShfeBe61HUHF/BIDx1hbuV2SjMoYVT8Q3A09bdpEjI7tqyfM +evjoP8WJ3fGJfj02LBCQF2Rzp7rOSWjjFfpTaepgIBfuU9BBJ6VecWgsidQ/kJSyL2+ZQ9EFTUET +YU4/yQ7G+GDJFNij3h0vSuhc2zblAmUvfWNpzZUWORDZhJCIGQnczbbEhzuCILGsnq/8Rw48mMun +jKxq2HbQrl50uPSnYu94sgaSq9ev3ZXA/ORE9wxzK74nBnurW8KGcUbZyLv0JdBF99d8QdCD50u/ +8JuSVlMB7RBQkH6azuMlObRnPmi1dnUKUwAK3HSSSlxyELIGRgj4dm6BHhtFdTsKDziaNUeE5Cna +lj7rmf50f/N9LR6HX/+8vtEk7J+R4uLoSlAYi1UUHICfsGeItmOWneGZZ1mEsmhVIRw0YMg1qrgo +Ngl1nOQuSoqplYrbmxdCw4oduvYB3OgXfcLOcUAc+1WDN5Dmqh6gwxKX8HOm0I38EwPVc9qD0hxR +Y38ZubJeYl1QScQZndB7mlN5FBaMZTDJfuPbnwykozxXl76gPtZLO2CFcTnL2kvT/40ydjxwXGpA +hGY9jQZg/RJY+A49vQTPzt87LF8IOdmecD4cNYHyLIOZ8rTlNVWMZ+M7JSu8UhWWGG9jrQ0IVIi9 +HHF+p/1uF4uIAuk/Y8D2ZKB+C3sTI/A47u58/zG6hpHuZbkUJ2qVEIqSBVZhSEuJoaAAAAAAwt/l +WjS+6mMAAbIIgFAAAOm1wiWxxGf7AgAAAAAEWVo= +END + diffoscope "${AUTOPKGTEST_TMP}/expected" "${AUTOPKGTEST_TMP}/test-pkg_1.0.tar.xz" + rm "${AUTOPKGTEST_TMP}/expected" +} + +verify_deb() { +cat << END | base64 -d > "${AUTOPKGTEST_TMP}/expected" +ITxhcmNoPgpkZWJpYW4tYmluYXJ5ICAgMTQ2NzMxMDUxMiAgMCAgICAgMCAgICAgMTAwNjQ0ICA0 +ICAgICAgICAgYAoyLjAKY29udHJvbC50YXIueHogIDE0NjczMTA1MTIgIDAgICAgIDAgICAgIDEw +MDY0NCAgNDYwICAgICAgIGAK/Td6WFoAAATm1rRGBMCLA4BQIQEWAAAAAAAAABDCPtjgJ/8Bg10A +Fwu8HH0BlcAdSj55FcLMJqNUbvT+gy5sC9KUdfhWlMfx+HFB6yCe/fISQhBljyagwzHK2z0fjzyl +9Q5RM24IJQO/ldGzSmZVQWpU6KVdaPbRDHZuPdcqnL6anvCMgysm5qSPjjXVOwMVwj6jVZ5T2sCV +Fd/tSdNnW1XFUQn9644MqVzknw4SL9DaLW7i3+zDmOmKLa1uyfXLuKVwGKiN/XsSDaT3B5SeuLIF +zwuAJSCguYhU4uMPUxWJnyNUaQwmnOO3Xd+TOkvIqqSrdnOHGqbp12kRpSDYAwHfpmldwagZ/ASu +HwJhd7Lk9pL1pNzWZazJ9RoCkHx449h6+exGzkVLLw7R+Exmp1O27wZC9/RuDyQE0JOY4Y1jGp1A +fH5U9xynjVoRrP5/hETw+GrGZoDShN8D/Z7rG5ICtTEqnspW6LWJLCDwndpz6OplHPZTDKckJYp7 +U6sXoF5ISdBIUEAc7XBEN61AQTJnfZ6L8d4L87WDLz5bFzwsk3o7cl5PzAXsAAAwfo4j+rTojAAB +pwOAUAAA0BcJAbHEZ/sCAAAAAARZWmRhdGEudGFyLnh6ICAgICAxNDY3MzEwNTEyICAwICAgICAw +ICAgICAxMDA2NDQgIDE2OCAgICAgICBgCv03elhaAAAE5ta0RgTAZ4BQIQEWAAAAAAAAAAA01v2+ +4Cf/AF9dABcLvBx9AZXAHUo+eRXCzCajVG70/oMubAvSlHX4VpTH8fhxQesgnv3yEkIQZY8moMMx +yts9NQ8iYiRRZoI1x3LfpWOmroELBNZOWKNu6b83Vt4bhMs3qreRNcwuusQAAADYvYvhx4Mp4gAB +gwGAUAAAkAP057HEZ/sCAAAAAARZWg== +END + diffoscope "${AUTOPKGTEST_TMP}/expected" "${AUTOPKGTEST_TMP}/test-pkg_1.0_all.deb" + rm "${AUTOPKGTEST_TMP}/expected" +} + +verify() { + verify_orig="${1+no}" + verify_deb="${1+no}" + verify_src="${1+no}" + verify_bin="${1+no}" + if [ "$verify_bin" = "yes" ]; then + echo "verifying test-pkg_1.0.tar.xz" >&2 + verify_orig + fi + if [ "$verify_bin" = "yes" ]; then + echo "verifying test-pkg_1.0_all.deb" >&2 + verify_deb + fi + # we shouldn't have to manually pass the keyring because the path is an + # implementation detail of gnupg (it used to be named pubring.gpg in + # the past) but dscverify ignores GNUPGHOME, see Debian bug #981008 + if [ "$verify_bin" = "yes" ]; then + echo "verifying test-pkg_1.0.dsc" >&2 + dscverify --keyring="${AUTOPKGTEST_TMP}/gpghome/pubring.kbx" "${AUTOPKGTEST_TMP}/test-pkg_1.0.dsc" + echo "verifying test-pkg_1.0_${nativearch}.changes" >&2 + dscverify --keyring="${AUTOPKGTEST_TMP}/gpghome/pubring.kbx" "${AUTOPKGTEST_TMP}/test-pkg_1.0_${nativearch}.changes" + fi + if [ "$verify_src" = "yes" ]; then + echo "verifying test-pkg_1.0_source.changes" >&2 + dscverify --keyring="${AUTOPKGTEST_TMP}/gpghome/pubring.kbx" "${AUTOPKGTEST_TMP}/test-pkg_1.0_source.changes" + fi + # remove verified files, so that we make sure not to accidentally + # verify anything from an earlier build + rm "${AUTOPKGTEST_TMP}/test-pkg_1.0_all.deb" \ + "${AUTOPKGTEST_TMP}/test-pkg_1.0.tar.xz" \ + "${AUTOPKGTEST_TMP}/test-pkg_1.0.dsc" + rm -f "${AUTOPKGTEST_TMP}/test-pkg_1.0_${nativearch}.changes" \ + "${AUTOPKGTEST_TMP}/test-pkg_1.0_source.changes" \ + "${AUTOPKGTEST_TMP}/test-pkg_1.0_${nativearch}.buildinfo" \ + "${AUTOPKGTEST_TMP}/test-pkg_1.0_source.buildinfo" +} + + +# FIXME: generate a key without expiry date +cat << END | gpg --allow-secret-key-import --import - +-----BEGIN PGP PRIVATE KEY BLOCK----- + +xVgEYA6+IBYJKwYBBAHaRw8BAQdAM1MKmD3Qm9XwkCv40xOUt1KTLL3nQ2NYfl6B +n+LOdLMAAQCkkntzWSe/Xsij3RSijtv+SJclZ+8O4p8MzZV66OgabBFOwsARBB8W +CgCDBYJgDr4gBYkFn6YAAwsJBwkQ8I/4RUH1oMBHFAAAAAAAHgAgc2FsdEBub3Rh +dGlvbnMuc2VxdW9pYS1wZ3Aub3Jnol5Qc4phlxfxrTOrw9UQlS20xKwlATRTr8Jb +7ZBPjyoDFQoIApsBAh4BFiEEYTotuR/zjHkQhq+U8I/4RUH1oMAAAAejAP9TNbf+ +KGB7pwj7igR7xB9fag1mW4rS66m6urmHUaxv8wEApQtzmbw2gZDcdR/8k85XfzOE +iTwx3rJ6dek4INyeSQLNL3NidWlsZCBmYWtlIHVwbG9hZGVyIDxmYWtlLXVwbG9h +ZGVyQGRlYmlhbi5vcmc+wsAUBBMWCgCGBYJgDr4gBYkFn6YAAwsJBwkQ8I/4RUH1 +oMBHFAAAAAAAHgAgc2FsdEBub3RhdGlvbnMuc2VxdW9pYS1wZ3Aub3JnF63kQ2as +sxKVvMSZGTzDgQlwrZMmRnyNf8L57pvR2AUDFQoIApkBApsBAh4BFiEEYTotuR/z +jHkQhq+U8I/4RUH1oMAAAC9hAQD0DitVEsSsa88L7e53iRtxNUS4ps8K6o5Tp1aX +8NzjMQEAqD53s2ICMBhQ8J7ub3jMeuthvyImBrdN65/4+gVWxwXHWARgDr4gFgkr +BgEEAdpHDwEBB0BNjjq4aQ/7iTf/mRfi3Bi2V8hGf5BiDd7D0QkQlNptEwABAIvV +ziS+mxfuZXfBoT7tjeaiVS0cfnUhiz757pFsp8JREUjCwMgEGBYKAToFgmAOviAF +iQWfpgAJEPCP+EVB9aDARxQAAAAAAB4AIHNhbHRAbm90YXRpb25zLnNlcXVvaWEt +cGdwLm9yZ8rIdP9aihzTjSrWOpTSuGXz3YmXKV46r4FHEm3IGXTuApsCAh4BvqAE +GRYKAG8FgmAOviAJEKQXmx3WngHdRxQAAAAAAB4AIHNhbHRAbm90YXRpb25zLnNl +cXVvaWEtcGdwLm9yZ98fe0i9BRZ7Vha10pZ933EtISKJja+B0Mi+3h+CNHwvFiEE +/l9vBfi0bJJ8ahzwpBebHdaeAd0AAB+eAP9fO95YdZmmbD0PQ4IExYSbw77eQwM8 ++bRlCb3NnhIlnwD9H1cPlpZlyESBTgYbJ+HiEtIYAfb+j/UYrMLFUEusqAgWIQRh +Oi25H/OMeRCGr5Twj/hFQfWgwAAA70kBAIMo8zmQnm3dikMTIN1TMq1jL9Scb2eu +3NTkHwfszJs8AP44F9+fndFRJdHgLABrbz8q2JnBCtJTOjp+I5YcKzhbA8ddBGAO +viASCisGAQQBl1UBBQEBB0BkyOEsAvMt8QIFlQ2wdC9X5QT/PdTyHgrAT6RZ8mzW +IAMBCAkAAP9r1GpEGNkv+/S2FNjYRT3YJW04OiTJD+ubMfNHqL9ieBEBwsAJBBgW +CgB7BYJgDr4gBYkFn6YACRDwj/hFQfWgwEcUAAAAAAAeACBzYWx0QG5vdGF0aW9u +cy5zZXF1b2lhLXBncC5vcmfFtzHBSr/u6zZM60iohrfYWWunv8HzyxJV7f/9GROX +fQKbDAIeARYhBGE6Lbkf84x5EIavlPCP+EVB9aDAAAA42AEA2usL+cPAS5/sSTlP +WPFaWuVIttbR1gVdi/47Ukm2zt4BANsA9OS0U1RVOOylMeZM8O7cI9y+IFCDua9G +VZd06jMN +=v7YN +-----END PGP PRIVATE KEY BLOCK----- +END + +mkdir -p "${AUTOPKGTEST_TMP}/test-pkg-1.0/debian/source" + +cat << END > "${AUTOPKGTEST_TMP}/test-pkg-1.0/debian/control" +Source: test-pkg +Section: debug +Priority: optional +Maintainer: sbuild maintainers +Uploaders: sbuild fake uploader +Standards-Version: 4.5.1 + +Package: test-pkg +Architecture: all +Description: test package + This is a test package for debugging purposes, with a fake description + to cheat linters into believing this contains some actual valuable text + that the reader can make some sense of. +END + +cat << END > "${AUTOPKGTEST_TMP}/test-pkg-1.0/debian/changelog" +test-pkg (1.0) ${release}; urgency=low + + * Entry. Closes: #12345 + + -- sbuild fake uploader Thu, 30 Jun 2016 20:15:12 +0200 +END + +cat << END > "${AUTOPKGTEST_TMP}/test-pkg-1.0/debian/copyright" +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ + +Files: * +Copyright: + Copyright © 2021 sbuild maintainers +License: GPL-2+ + This program is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any later + version. + . + On Debian systems, the full text of the GNU General Public License version 2 + can be found in the file /usr/share/common-licenses/GPL-2. +END + +cat << END > "${AUTOPKGTEST_TMP}/test-pkg-1.0/debian/rules" +#!/usr/bin/make -f + +clean: + rm -rf debian/files debian/tmp + +build-indep: +build-arch: +build: build-indep build-arch + +binary-indep: build-indep + rm -rf debian/tmp + mkdir -p debian/tmp/DEBIAN + dpkg-gencontrol + dpkg-deb --build debian/tmp .. + +binary-arch: build-arch + +binary: binary-indep binary-arch + +.PHONY: clean build-indep build-arch build binary-indexp binary-arch binary +END +chmod +x "${AUTOPKGTEST_TMP}/test-pkg-1.0/debian/rules" + +cat << END > "${AUTOPKGTEST_TMP}/test-pkg-1.0/debian/source/format" +3.0 (native) +END + +mmdebstrap --mode=unshare --variant=apt ${release} "${AUTOPKGTEST_TMP}/chroot.tar" + +env --chdir="${AUTOPKGTEST_TMP}/test-pkg-1.0/" dpkg-buildpackage --build=full +env --chdir="${AUTOPKGTEST_TMP}/test-pkg-1.0/" dpkg-buildpackage --target=clean + +if [ "$release" = unstable ]; then + verify yes yes no yes +else + verify no no no yes +fi + +# FIXME use installed sbuild + +# Test running sbuild from the unpacked source +env --chdir="${AUTOPKGTEST_TMP}/test-pkg-1.0/" sbuild \ + --chroot="${AUTOPKGTEST_TMP}/chroot.tar" --chroot-mode=unshare \ + --keyid="sbuild fake uploader " \ + --source \ + --no-run-lintian --no-run-autopkgtest +verify no yes + +env --chdir="${AUTOPKGTEST_TMP}/test-pkg-1.0/" sbuild \ + --chroot="${AUTOPKGTEST_TMP}/chroot.tar" --chroot-mode=unshare \ + --keyid="sbuild fake uploader " \ + --no-run-lintian --no-run-autopkgtest +verify no yes + +# Test running sbuild on the dsc +env --chdir="${AUTOPKGTEST_TMP}/test-pkg-1.0/" dpkg-source --build . +env --chdir="${AUTOPKGTEST_TMP}" sbuild \ + --chroot="${AUTOPKGTEST_TMP}/chroot.tar" --chroot-mode=unshare \ + --keyid="sbuild fake uploader " \ + --source \ + --no-run-lintian --no-run-autopkgtest -d ${release} test-pkg_1.0.dsc +verify no yes + +env --chdir="${AUTOPKGTEST_TMP}/test-pkg-1.0/" dpkg-source --build . +env --chdir="${AUTOPKGTEST_TMP}" sbuild \ + --chroot="${AUTOPKGTEST_TMP}/chroot.tar" --chroot-mode=unshare \ + --keyid="sbuild fake uploader " \ + --no-run-lintian --no-run-autopkgtest -d ${release} test-pkg_1.0.dsc +verify no yes + + +rm "${AUTOPKGTEST_TMP}/test-pkg_1.0_${nativearch}"*.build +rm -r "${AUTOPKGTEST_TMP}/gpghome/" +rm "${AUTOPKGTEST_TMP}/test-pkg-1.0/debian/changelog" \ + "${AUTOPKGTEST_TMP}/test-pkg-1.0/debian/control" \ + "${AUTOPKGTEST_TMP}/test-pkg-1.0/debian/source/format" \ + "${AUTOPKGTEST_TMP}/test-pkg-1.0/debian/rules" \ + "${AUTOPKGTEST_TMP}/test-pkg-1.0/debian/copyright" +rmdir "${AUTOPKGTEST_TMP}/test-pkg-1.0/debian/source" \ + "${AUTOPKGTEST_TMP}/test-pkg-1.0/debian" \ + "${AUTOPKGTEST_TMP}/test-pkg-1.0" +rm "${AUTOPKGTEST_TMP}/chroot.tar" diff -Nru sbuild-0.80.0ubuntu1/debian/tests/unshare-qemuwrapper sbuild-0.81.2ubuntu5/debian/tests/unshare-qemuwrapper --- sbuild-0.80.0ubuntu1/debian/tests/unshare-qemuwrapper 1970-01-01 00:00:00.000000000 +0000 +++ sbuild-0.81.2ubuntu5/debian/tests/unshare-qemuwrapper 2021-03-18 07:38:02.000000000 +0000 @@ -0,0 +1,284 @@ +#!/bin/sh +# +# Copyright 2021 Johannes Schauer Marin Rodrigues +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. + +# Since Debian bug #898446 was closed, usernamespaces are enabled by default in +# Debian. Unfortunately, salsaci and debci both do not allow processes to +# unshare. To still be able to test software that requires namespace support we +# spin up a qemu virtual machine, install EXTRA_DEPS in it and then run the +# target SCRIPT as a normal user on that machine. +# +# Another advantage of using this wrapper is, that it can be run by any +# unprivileged user without building the package and spinning up autopkgtest +# first. + +set -exu + +EXTRA_DEPS=gnupg,sbuild,mmdebstrap,build-essential,uidmap,fakeroot,diffoscope,lsb-release +SCRIPT=./debian/tests/unshare + +release=$(lsb_release -c -s) + +[ -e debian/tests/control ] +SOURCES="$(pwd)" + +if [ -z ${AUTOPKGTEST_TMP+x} ]; then + # if AUTOPKGTEST_TMP is not set, then this script is probably not + # executed under autopkgtest + TMPDIR=$(mktemp --directory) + aptsources= + MODE=auto +else + # since AUTOPKGTEST_TMP is set, we assume that this script is executed + # under autopkgtest --> switch to the temporary directory + TMPDIR="$AUTOPKGTEST_TMP" + mkdir -p "$TMPDIR" + # we need to install the chroot using the same apt sources as used by + # the autopkgtest chroot so that the packages to be tested are + # available + aptsources= + if [ -e /etc/apt/sources.list ]; then + aptsources="$aptsources /etc/apt/sources.list" + fi + for f in /etc/apt/sources.list.d/*.list /etc/apt/sources.list.d/*.sources; do + [ -e "$f" ] || continue + aptsources="$aptsources $f" + done + MODE=root +fi + +# make TMPDIR world-readable or otherwise it cannot be accessed in unshare mode +chmod a+rx "$TMPDIR" +cd "$TMPDIR" + +# generate a new ssh key for us, so that we can authenticate ourselves to the +# setup system, as well as the cryptsystem (both dropbear and openssh) via +# public key instead of using passwords +if [ ! -e "$TMPDIR/id_rsa" ]; then +ssh-keygen -q -t rsa -f "$TMPDIR/id_rsa" -N "" +fi + +cat << SCRIPT > "$TMPDIR/customize.sh" +#!/bin/sh +set -exu + +rootfs="\$1" + +# setup various files in /etc +echo host > "\$rootfs/etc/hostname" +echo "127.0.0.1 localhost host" > "\$rootfs/etc/hosts" +echo "/dev/vda1 / auto errors=remount-ro 0 1" > "\$rootfs/etc/fstab" +cat /etc/resolv.conf > "\$rootfs/etc/resolv.conf" +echo 'net.ipv4.ip_forward=1' > "\$rootfs/etc/sysctl.conf" + +# give a trivial password to the root user for easy debugging in case something fails +echo root:abcdef | chroot "\$rootfs" /usr/sbin/chpasswd + +# extlinux config to boot from /dev/vda1 with predictable network interface +# naming and a serial console for logging +cat << END > "\$rootfs/extlinux.conf" +default linux +timeout 0 + +label linux +kernel /vmlinuz +append initrd=/initrd.img root=/dev/vda1 net.ifnames=0 console=ttyS0 +END + +# network interface config +# we can use eth0 because we boot with net.ifnames=0 for predictable interface +# names +cat << END > "\$rootfs/etc/network/interfaces" +auto lo +iface lo inet loopback + +auto eth0 +iface eth0 inet dhcp +END + +# copy in the public key +mkdir "\$rootfs/root/.ssh" +cp "$TMPDIR/id_rsa.pub" "\$rootfs/root/.ssh/authorized_keys" +chroot "\$rootfs" chown 0:0 /root/.ssh/authorized_keys + +chroot "\$rootfs" adduser --gecos user --disabled-password user +SCRIPT +chmod +x "$TMPDIR/customize.sh" + +# mmdebstrap will not have access to any file:// apt repositories because the +# path will be outside the chroot. To fix this, copy their contents into the +# chroot. We could also bind-mount the repos but then their contents would only +# be available during installation and not anymore at a later point +cat << 'SCRIPT' > "$TMPDIR/setup.sh" +#!/bin/sh +set -exu + +rootfs="$1" + +apt-get indextargets \ + | grep-dctrl \( -F Created-By Packages -a --regex -F Repo-URI '^file://' \) -s Repo-URI -n \ + | while read uri; do + repo=${uri#file://} # strip prefix + mkdir -p "$rootfs/$repo" + mmdebstrap --hook-helper "$rootfs" "$MMDEBSTRAP_MODE" setup env 1 sync-in "$repo" "$repo" <&$MMDEBSTRAP_HOOKSOCK >&$MMDEBSTRAP_HOOKSOCK +done +SCRIPT +chmod +x "$TMPDIR/setup.sh" + +if [ ! -e "$TMPDIR/debian-${release}-host.tar" ]; then +mmdebstrap --variant=apt --mode=$MODE --verbose \ + --setup-hook="$TMPDIR/setup.sh" \ + --include=openssh-server,systemd-sysv,ifupdown,netbase,isc-dhcp-client,udev,policykit-1,linux-image-amd64,$EXTRA_DEPS \ + --customize-hook="$TMPDIR/customize.sh" \ + ${release} "$TMPDIR/debian-${release}-host.tar" $aptsources +fi + +# use guestfish to prepare the host system +# +# - create a single 2G partition and unpack the rootfs tarball into it +# - put a syslinux MBR into the first 440 bytes of the drive +# - install extlinux and make partition bootable +# +# useful stuff to debug any errors: +# LIBGUESTFS_BACKEND_SETTINGS=force_tcg +# libguestfs-test-tool || true +# export LIBGUESTFS_DEBUG=1 LIBGUESTFS_TRACE=1 +guestfish -N "$TMPDIR/host.img"=disk:2G -- \ + part-disk /dev/sda mbr : \ + mkfs ext2 /dev/sda1 : \ + mount /dev/sda1 / : \ + tar-in "$TMPDIR/debian-${release}-host.tar" / : \ + mkdir /build : \ + copy-in "$SOURCES/." /build/ : \ + upload /usr/lib/SYSLINUX/mbr.bin /mbr.bin : \ + copy-file-to-device /mbr.bin /dev/sda size:440 : \ + rm /mbr.bin : \ + extlinux / : \ + sync : \ + umount / : \ + part-set-bootable /dev/sda 1 true : \ + shutdown + +# start the host system +# prefer using kvm but fall back to tcg if not available +# avoid entropy starvation by feeding the crypt system with random bits from /dev/urandom +# the default memory size of 128 MiB is not enough for Debian, so we go with 1G +# use a virtio network card instead of emulating a real network device +# we don't need any graphics +# this also multiplexes the console and the monitor to stdio +# creates a multiplexed stdio backend connected to the serial port and the qemu +# monitor +# redirect tcp connections on port 10022 localhost to the host system port 22 +# redirect all output to a file +# run in the background +qemu-system-x86_64 \ + -M accel=kvm:tcg \ + -no-user-config \ + -object rng-random,filename=/dev/urandom,id=rng0 -device virtio-rng-pci,rng=rng0 \ + -m 1G \ + -net nic,model=virtio \ + -nographic \ + -serial mon:stdio \ + -net user,hostfwd=tcp:127.0.0.1:10022-:22 \ + -drive file="$TMPDIR/host.img",format=raw,if=virtio \ + > "$TMPDIR/qemu.log" &1 & + +# store the pid +QEMUPID=$! + +onerror() { + # attempt poweroff + $ssh -o ConnectTimeout=$TIMEOUT root@localhost systemctl poweroff || true + # give a few seconds for poweroff + sleep 10 + kill $QEMUPID || true + # turn off verbose output + set +x + echo "script failed -- temporary files are stored in $TMPDIR:" + echo + ls -lha "$TMPDIR" + echo + echo "to test yourself, run qemu with:" + echo + echo " $ qemu-system-x86_64 -no-user-config -m 1G -net nic,model=virtio -nographic -serial mon:stdio -net user,hostfwd=tcp:127.0.0.1:10022-:22 -drive file=\"$TMPDIR/host.img\",format=raw,if=virtio" + echo + echo "and log in using:" + echo + echo " user: root" + echo " pass: abcdef" + echo + echo "or connect to it via ssh:" + echo + echo " $ $ssh root@localhost" + echo + echo "when you are done, cleanup temporary files with:" + echo + echo " $ rm -r \"$TMPDIR\"" +} + +# show the log and kill qemu in case the script exits first +trap "cat --show-nonprinting $TMPDIR/qemu.log; onerror" EXIT + +# the default ssh command does not store known hosts and even ignores host keys +# it identifies itself with the rsa key generated above +# pseudo terminal allocation is disabled or otherwise, programs executed via +# ssh might wait for input on stdin of the ssh process +ssh="ssh -oUserKnownHostsFile=/dev/null -oStrictHostKeyChecking=no -i "$TMPDIR/id_rsa" -T -p 10022" + +# we use sleepenh to make sure that we wait the right number of seconds +# independent on how long the command took beforehand +TIMESTAMP=$(sleepenh 0 || [ $? -eq 1 ]) +# the timeout in seconds +TIMEOUT=5 +# the maximum number of tries +NUM_TRIES=20 +i=0 +while true; do + rv=0 + $ssh -o ConnectTimeout=$TIMEOUT root@localhost echo success || rv=1 + # with an exit code of zero, the ssh connection was successful + # and we break out of the loop + [ $rv -eq 0 ] && break + # if the command before took less than $TIMEOUT seconds, wait the remaining time + TIMESTAMP=$(sleepenh $TIMESTAMP $TIMEOUT || [ $? -eq 1 ]); + # increment the counter and break out of the loop if we tried + # too often + i=$((i+1)) + if [ $i -ge $NUM_TRIES ]; then + break + fi +done + +# if all tries were exhausted, the process failed +if [ $i -eq $NUM_TRIES ]; then + echo "timeout reached: unable to connect to qemu via ssh" + exit 1 +fi + +trap onerror EXIT + +$ssh root@localhost env --chdir=/build/ AUTOPKGTEST_TMP=/tmp runuser -u user -- "$SCRIPT" + +# shut the system off +trap - EXIT +$ssh root@localhost systemctl poweroff || true +wait $QEMUPID + +# cleanup +for f in debian-${release}-host.tar id_rsa id_rsa.pub \ + qemu.log host.img customize.sh setup.sh; do + rm "$TMPDIR/$f" +done +if [ -z ${AUTOPKGTEST_TMP+x} ]; then + rmdir "$TMPDIR" +fi diff -Nru sbuild-0.80.0ubuntu1/HACKING sbuild-0.81.2ubuntu5/HACKING --- sbuild-0.80.0ubuntu1/HACKING 2020-08-01 12:07:53.000000000 +0000 +++ sbuild-0.81.2ubuntu5/HACKING 2021-03-18 07:38:02.000000000 +0000 @@ -47,18 +47,8 @@ Releasing ───────── -New upstream releases: - • The code must pass the testsuite (run 'sudo make check' after ./configure --enable-chroot-checks). This requires a local schroot called 'unstable' setup. These checks can take some time to run. Plain "autoreconf -fi && ./configure && make check" runs only the checks that can be done without schroot, which are very quick. - -• Add an entry for the new version into ChangeLog.in. Do not add entries to - ChangeLog.in together with the implementation of the feature because that - makes it harder to rebase these commits. - -• Adjust the VERSION file with the new sbuild version and the release date. - -• git commit -m "Bump version to XXX" ChangeLog.in VERSION diff -Nru sbuild-0.80.0ubuntu1/lib/Sbuild/Build.pm sbuild-0.81.2ubuntu5/lib/Sbuild/Build.pm --- sbuild-0.80.0ubuntu1/lib/Sbuild/Build.pm 2020-08-01 12:07:53.000000000 +0000 +++ sbuild-0.81.2ubuntu5/lib/Sbuild/Build.pm 2021-03-18 07:38:02.000000000 +0000 @@ -59,6 +59,8 @@ use Sbuild::Resolver qw(get_resolver); use Sbuild::Exception; +use version; + BEGIN { use Exporter (); our (@ISA, @EXPORT); @@ -955,7 +957,8 @@ my $could_not_explain = undef; if (defined $self->get_conf('BD_UNINSTALLABLE_EXPLAINER') - && $self->get_conf('BD_UNINSTALLABLE_EXPLAINER') ne '') { + && $self->get_conf('BD_UNINSTALLABLE_EXPLAINER') ne '' + && $self->get_conf('BD_UNINSTALLABLE_EXPLAINER') ne 'none') { if (!$self->explain_bd_uninstallable()) { $could_not_explain = 1; } @@ -2324,6 +2327,32 @@ $self->get_conf('BUILD_ENV_CMND')); push (@{$buildcmd}, 'dpkg-buildpackage'); + my $dpkgversion = version->new(0); + { + # we use pipe_command instead of read_command because we want to + # ignore non-zero exit code without printing an error message from + # dpkg versions before 1.20 which didn't have --robot + my $pipe = $session->pipe_command( + { + COMMAND => [ 'dpkg', '--robot', '--version' ], + STREAMERR => $devnull + } + ); + chomp( + my $content = do { local $/; <$pipe> } + ); + close $pipe; + if ( $? == 0 and $content =~ /^([0-9.]+)( .*)?$/ ) { + # dpkg is new enough for the --robot option + $dpkgversion = version->new($1); + } + } + # since dpkg 1.20.0 + # will reset environment and umask to their vendor specific defaults + if ($dpkgversion >= "1.20.0") { + push (@{$buildcmd}, '--sanitize-env'); + } + if ($host_arch ne $build_arch) { push (@{$buildcmd}, '-a' . $host_arch); } @@ -3327,6 +3356,15 @@ system('debsign', '--re-sign', "-k$key_id", '--', "$build_dir/$changes"); } if ($self->get_conf('SOURCE_ONLY_CHANGES')) { + # We would like to run debsign with --no-re-sign so that a file + # referenced by the normal changes file and was already signed + # there does not get changed here by re-signing. Otherwise, the + # checksum from the normal changes file might not match + # anymore. https://bugs.debian.org/977674 + # + # The problem is, that with --no-re-sign, debsign will see a + # signed buildinfo file and skip signing the dsc. + # https://bugs.debian.org/981021 my $so_changes = $build_dir . '/' . $self->get('Package_SVersion') . "_source.changes"; if (-r $so_changes) { system('debsign', '--re-sign', "-k$key_id", '--', "$so_changes"); diff -Nru sbuild-0.80.0ubuntu1/lib/Sbuild/ChrootSetup.pm sbuild-0.81.2ubuntu5/lib/Sbuild/ChrootSetup.pm --- sbuild-0.80.0ubuntu1/lib/Sbuild/ChrootSetup.pm 2020-08-01 12:07:53.000000000 +0000 +++ sbuild-0.81.2ubuntu5/lib/Sbuild/ChrootSetup.pm 2021-03-18 07:38:02.000000000 +0000 @@ -103,7 +103,7 @@ $session->run_command( { COMMAND => ['/bin/sh', '-c', - 'set -e; if [ ! -d ' . (shellescape $build_path) . ' ] ; then mkdir -m 0775 ' . (shellescape $build_path) . '; fi'], + 'set -e; if [ ! -d ' . (shellescape $build_path) . ' ] ; then mkdir -p -m 0775 ' . (shellescape $build_path) . '; fi'], USER => 'root', DIR => '/' }); if ($?) { diff -Nru sbuild-0.80.0ubuntu1/lib/Sbuild/ChrootUnshare.pm sbuild-0.81.2ubuntu5/lib/Sbuild/ChrootUnshare.pm --- sbuild-0.80.0ubuntu1/lib/Sbuild/ChrootUnshare.pm 2020-08-01 12:07:53.000000000 +0000 +++ sbuild-0.81.2ubuntu5/lib/Sbuild/ChrootUnshare.pm 2021-03-18 07:38:02.000000000 +0000 @@ -163,6 +163,7 @@ '--exclude=./dev/random', '--exclude=./dev/full', '--exclude=./dev/null', + '--exclude=./dev/console', '--exclude=./dev/zero', '--exclude=./dev/tty', '--exclude=./dev/ptmx', diff -Nru sbuild-0.80.0ubuntu1/lib/Sbuild/Conf.pm sbuild-0.81.2ubuntu5/lib/Sbuild/Conf.pm --- sbuild-0.80.0ubuntu1/lib/Sbuild/Conf.pm 2020-08-01 12:07:53.000000000 +0000 +++ sbuild-0.81.2ubuntu5/lib/Sbuild/Conf.pm 2021-03-18 07:38:02.000000000 +0000 @@ -1477,10 +1477,10 @@ die "Bad bd-uninstallable explainer \'" . $conf->get('BD_UNINSTALLABLE_EXPLAINER') . "\'" if defined $conf->get('BD_UNINSTALLABLE_EXPLAINER') && !isin($conf->get('BD_UNINSTALLABLE_EXPLAINER'), - ('apt', 'dose3', '')); + ('apt', 'dose3', '', 'none')); }, DEFAULT => 'dose3', - HELP => 'Method to use for explaining build dependency installation failures. Possible value are "dose3" (default) and "apt". Set to the empty string or undef to disable running any explainer.', + HELP => 'Method to use for explaining build dependency installation failures. Possible value are "dose3" (default), "apt" and "none". Set to "none", the empty string "" or Perl undef to disable running any explainer.', CLI_OPTIONS => ['--bd-uninstallable-explainer'] }, 'PURGE_EXTRA_PACKAGES' => { diff -Nru sbuild-0.80.0ubuntu1/Makefile.am sbuild-0.81.2ubuntu5/Makefile.am --- sbuild-0.80.0ubuntu1/Makefile.am 2020-08-01 12:07:53.000000000 +0000 +++ sbuild-0.81.2ubuntu5/Makefile.am 2021-03-18 07:38:02.000000000 +0000 @@ -38,8 +38,7 @@ Makefile-buildd \ NEWS-buildd \ README.buildd-admin \ - README.chroot-building \ - VERSION + README.chroot-building ps: $(MAKE) -C doc sbuild.ps diff -Nru sbuild-0.80.0ubuntu1/man/Makefile.am sbuild-0.81.2ubuntu5/man/Makefile.am --- sbuild-0.80.0ubuntu1/man/Makefile.am 2020-08-01 12:07:53.000000000 +0000 +++ sbuild-0.81.2ubuntu5/man/Makefile.am 2021-03-18 07:38:02.000000000 +0000 @@ -38,6 +38,9 @@ sbuild-debian-developer-setup.1 \ sbuild-destroychroot.8 \ sbuild-hold.1 \ + sbuild-qemu.1 \ + sbuild-qemu-create.1 \ + sbuild-qemu-update.1 \ sbuild-setup.7 \ sbuild-shell.1 \ sbuild-update.1 diff -Nru sbuild-0.80.0ubuntu1/man/sbuild.1.in sbuild-0.81.2ubuntu5/man/sbuild.1.in --- sbuild-0.80.0ubuntu1/man/sbuild.1.in 2020-08-01 12:07:53.000000000 +0000 +++ sbuild-0.81.2ubuntu5/man/sbuild.1.in 2021-03-18 07:38:02.000000000 +0000 @@ -107,7 +107,7 @@ .RB [ \-\-autopkgtest\-virt\-server\-opt=\fIstring\fP ] .RB [ \-\-autopkgtest\-virt\-server\-opts=\fIoptions\fP ] .RB [ \-\-purge\-extra\-packages\fP ] -.RB [ \-\-bd\-uninstallable\-explainer=\fIdose3|apt\fP ] +.RB [ \-\-bd\-uninstallable\-explainer=\fIdose3|apt|none\fP ] .RB [ PACKAGE [ .dsc ]] .SH DESCRIPTION \fBsbuild\fR rebuilds Debian binary packages from the corresponding Debian @@ -1180,11 +1180,11 @@ .BR sbuild.conf (5) for more information. .TP -.BR \-\-bd\-uninstallable\-explainer=\fIdose3|apt\fP +.BR \-\-bd\-uninstallable\-explainer=\fIdose3|apt|none\fP If the build dependencies cannot be satisfied by the chosen resolver, sbuild will run the selected method to give a better explanation why the build dependencies cannot be installed. Possible arguments for this option are dose3 -(the default) and apt. To disable this feature, pass the empty string. +(the default), apt and none. To disable this feature, pass none or the empty string. Depending on the resolver, the dose3 explainer might report a dependency situation as satisfiable even if the chosen resolver found it to be unsatisfiable. This is especially likely to happen if the apt resolver (the diff -Nru sbuild-0.80.0ubuntu1/man/sbuild-qemu.1.in sbuild-0.81.2ubuntu5/man/sbuild-qemu.1.in --- sbuild-0.80.0ubuntu1/man/sbuild-qemu.1.in 1970-01-01 00:00:00.000000000 +0000 +++ sbuild-0.81.2ubuntu5/man/sbuild-qemu.1.in 2021-03-18 07:38:02.000000000 +0000 @@ -0,0 +1,117 @@ +.\" Copyright © 2020 Christian Kastner +.\" +.\" This program is free software: you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation, either version 2 of the License, or +.\" (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, but +.\" WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +.\" General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program. If not, see +.\" . +.so defs.man +.TH SBUILD\-QEMU "1" "\*[RELEASE_DATE]" "Version \*[VERSION]" "Debian sbuild" +.SH NAME +sbuild\-qemu \- sbuild using QEMU images +.SH SYNOPSIS +.B sbuild\-qemu +.RB [ \-h ] +.RB [ \-\-arch=ARCH ] +.RB [ \-d=DIST ] +.RB [ \-\-image=IMAGE ] +.RB [ \-\-autopkgtest\-debug ] +.RB [ \-\-ram=MiB ] +.RB [ \-\-cpus=CPUs ] +.RB [ \-\-overlay\-dir=OVERLAY_DIR ] +.RB [ \-\-noexec ] +.PP +Build Debian packages with \fBsbuild\fR using QEMU images, by using sbuild's +\fB\-\-chroot\-mode=autopkgtest\fR. +.PP +All options other than the ones described below are passed on through to +\fBsbuild\fR. The image will be started in snapshot mode, so the image is +never changed. Multiple processes can use the same image concurrently. +.SH OPTIONS +.TP +\fB\-h\fR, \fB\-\-help\fR +Show this help message and exit. +.TP +\fB\-\-arch\fR=ARCH +Architecture to use. Default is the host architecture. Currently supported +architectures are: amd64, i386. +.TP +\fB\-d\fR=DIST, \fB\-\-dist\fR=DIST +Distribution (for the .changes file). Default is \fBunstable\fR. +.TP +\fB\-\-image\fR=IMAGE +VM image to use for building. If not specified, will look for an image with the +name \fBDIST\-autopkgtest\-ARCH.img\fR. Will first look in the current +directory, and if no such file exists there, then the directory +\fB$IMAGEDIR\fR is tried. A suitable image can be created with +sbuild\-qemu\-create(1). +.TP +\fB\-\-autopkgtest\-debug\fR +Enable debug output for the autopkgtest\-virt\-qemu(1) driver. +.TP +\fB\-\-ram\fR=MiB +VM memory size in MB. Default: 2048 +.TP +\fB\-\-cpus\fR=CPUs +VM CPU count. Default: Number of physical cores on the host. +.TP +\fB\-\-overlay\-dir\fR=OVERLAY_DIR +Directory for the temporary image overlay instead of autopkgtest's default of +\fI\,/tmp\/\fP (or $TMPDIR). +.TP +\fB\-\-noexec\fR +Don't actually do anything. Just print the sbuild(1) command string that would +be executed, and then exit. +.SH CONSIDERATIONS +Using a fast temporary image overlay is key to faster build times. An overlay +created on a \fItmpfs\fR would be ideal, and can speed up I/O by an order of +magnitude, compared to a slow HDD. If \fI\,/tmp\fR or \fI$TMPDIR\fR are mountpoints +for a tmpfs, then all should be fine by default. +.PP +However, tmpfs filesystems are backed by memory and swap on the host, so a build +needing substantial disk space in the VM may fail. If this happens, the +\-\-overlay\-dir option should be used to point to a host directory with more +available disk space. Note that the base image itself must have been created +with a suitable size, see the \fB\-\-size\fR option to sbuild\-qemu\-create(1). +.SH LIMITATIONS +Due to the nature of sbuild's \fB\-\-chroot\-mode=autopkgtest\fR, not all +sbuild options are supported yet. In particular, getting an interactive +shell, for example using \fB\-\-build\-failed\-command\fR is \fBNOT\fR possible. +However, there are other ways to access the build environment (see below). +.SH "VM ACCESS" +sbuild's \fB\-\-chroot\-mode=autopkgtest\fR uses autopkgtest\-virt\-qemu under +the hood, so you will find an SSH shell on port 10022 (or the first free port +after that) if, and only if, the openssh\-server package is installed in the +VM. +.PP +As a further consequence of this chroot mode, what is stated in +autopkgtest\-virt\-qemu(1) generally also holds here. +.PP +.SH EXAMPLES +\fB$ sbuild\-qemu \-d unstable \-s \-\-arch\-all FOO.dsc\fR +.PP +This will build the package \fBFOO.dsc\fR using \fBunstable\fR as the +Distribution in the generated .changes file. +.PP +Because the \fB\-\-image\fR option was not specified, an image with the name +\fBunstable\-autopkgtest\-amd64.img\fR will be looked for first in the current +directory, and then in \fB$IMAGEDIR\fI. +.PP +The \fB\-s\fR and \fB\-\-arch\-all\fR aren't known to sbuild-qemu, and +are therefore will be passed on through to sbuild for it to use. +.SH ENVIRONMENT +\fB$IMAGEDIR\fR defaults to \fI~/.cache/sbuild\fR. +.SH COPYRIGHT +Copyright \[co] 2020 Christian Kastner +.SH "SEE ALSO" +.BR sbuild (1), +.BR sbuild\-qemu\-create (1), +.BR sbuild\-qemu\-update (1). diff -Nru sbuild-0.80.0ubuntu1/man/sbuild-qemu-create.1.in sbuild-0.81.2ubuntu5/man/sbuild-qemu-create.1.in --- sbuild-0.80.0ubuntu1/man/sbuild-qemu-create.1.in 1970-01-01 00:00:00.000000000 +0000 +++ sbuild-0.81.2ubuntu5/man/sbuild-qemu-create.1.in 2021-03-18 07:38:02.000000000 +0000 @@ -0,0 +1,141 @@ +.\" Copyright © 2020 Christian Kastner +.\" +.\" This program is free software: you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation, either version 2 of the License, or +.\" (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, but +.\" WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +.\" General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program. If not, see +.\" . +.so defs.man +.TH SBUILD\-QEMU\-CREATE "1" "\*[RELEASE_DATE]" "Version \*[VERSION]" "Debian sbuild" +.SH NAME +sbuild\-qemu\-create \- QEMU image creator for sbuild +.SH SYNOPSIS +.B sbuild\-qemu\-create +.RB [ \-h ] +.RB [ \-\-arch=ARCH ] +.RB [ \-\-install\-packages=INSTALL_PACKAGES] +.RB [ \-\-extra\-deb=EXTRA_DEB] +.RB [ \-\-components=COMPONENTS ] +.RB [ \-\-skel=SKEL ] +.RB [ \-\-size=SIZE ] +.RB [ \-o=OUT_FILE ] +.RB [ \-\-noexec ] +debmirror +.PP +Build an image for use with \fBsbuild-qemu\fR and \fBautopkgtest\fR. +\fBdistribution\fR will be debootstrapped using mirror \fBdebmirror\fR. +Note that the mirror will also be used for the \fIsources.list\fR file in +the VM. See MIRROR below. +.PP +Note that sbuild\-qemu\-create is just a simple wrapper around +autopkgtest\-build\-qemu(1) that automates a few additional steps commonly +performed with package\-building images. +.SH OPTIONS +.TP +\fB\-h\fR, \fB\-\-help\fR +Show this help message and exit. +.TP +\fB\-\-arch\fR=ARCH +Architecture to use. Default is the host architecture. Currently supported +architectures are: amd64, i386. +.TP +\fB\-\-install\-packages\fR=INSTALL_PACKAGES +Comma\-separated list of additional packages to install using +\fBapt\-get install\fR from within the running image. +.TP +\fB\-\-extra\-deb\fR=EXTRA_DEB +Package file (.deb) from the local filesystem to install. Can be specified more +than once. +.TP +\fB\-\-components\fR=COMPONENTS +Comma\-separated list of components to use with \fIsources.list\fR entries. +Default: main. +.TP +\fB\-\-skel\fR=SKEL +Skeleton directory to use for \fI\,/root\/\fP. +.TP +\fB\-\-size\fR=SIZE +VM size to use. Note that the images will be created in qcow2 format, so they +won't consume that space right away. Default: 10G. +.TP +\fB\-o\fR=OUT_FILE, \fB\-\-out\-file\fR=OUT_FILE +Output filename. If not supplied, then DIST\-autopkgtest\-ARCH.img will be +used. +.TP +\fB\-\-noexec\fR +Don't actually do anything. Just print the autopkgtest\-build\-qemu(1) command +string that would be executed, and then exit. +.SH "MIRROR" +It is \fBhighly recommended\fR that you use an APT cache, like approx(8), or +apt\-cacher\-ng(8), on the \fBlocal\fR machine (so that the VM guest can +access it without much hassle) as a mirror. This will dramatically speed up the +package build process. On the author's local machine, installing the build +dependencies of even larger packages takes only a few seconds. +.SH "SPECIAL CASES" +If the distribution is \fBexperimental\fR, \fIsources.list\fR will contain +entries for both \fBexperimental\fR and \fBunstable\fR. +.PP +If the distribution ends with \fB\-backports\fR, \fIsources.list\fR will contain +entries for both the distribution and the distribution it is based upon. +.SH "SHARING FILES" +Among other things, autopkgtest\-virt\-qemu(1) has built-in support for sharing a +directory on the host with the guest, so no further configuration should be +necessary when accessing the VM using autopkgtest. +.PP +However, for cases where the VM is launched via QEMU directly, a \fI/shared\fR +mount point for a 9p filesystem has been added to the VM's \fI/etc/fstab\fR. It +is configured with the \fBnofail\fR option, so it will be ignored if nothing is +being shared. +.PP +To share a directory on the host with the VM, QEMU should be started with +the following additional options: +.PP +\fB \-virtfs path=/path/to/host/dir,local,id=shared,mount_tag=shared,security_model=none +.SH EXAMPLES +\fB$ sudo sbuild\-qemu\-create unstable http://deb.debian.org/debian\fR +.PP +This will create an image \fBunstable\-autopkgtest\-amd64.img\fR (assuming +that the host architecture is amd64) with the unstable distribution. +.PP +\fB$ sudo sbuild\-qemu\-create buster\-backports http://deb.debian.org/debian\fR +.PP +This will create an image \fBbuster\-backports\-autopkgtest\-amd64.img\fR, +with \fIsources.list\fR entries for both buster and buster-backports. +.PP +\fB$ sudo sbuild\-qemu\-create \-\-skel DIR unstable http://deb.debian.org/debian\fR +.PP +The files in \fBDIR\fR will be copied into /root (that is, root's $HOME). This +can be used, for example, to copy an \fB.ssh/authorized_keys\fR file, so that +one can connect to the running image using SSH (assuming openssh\-server is +installed). +.PP +\fB$ sudo sbuild\-qemu\-create \-\-install\-packages openssh\-server unstable http://deb.debian.org/debian\fR +.PP +This would install openssh\-server. The package will be downloaded in the +target environment using 'apt-get'. +.PP +A popular package to pre\-install this way would be \fBdebhelper\fR, as it is a +build dependency of the vast majority of Debian packages. +.PP +\fB$ sudo sbuild\-qemu\-create \-\-extra\-deb FOO.deb unstable http://deb.debian.org/debian\fR +.PP +This would install the package \fBFOO.deb\fR from the local filesystem. +Useful, for example, to install additional keyring packages. +.PP +\fB$ sudo sbuild\-qemu\-create --shared-mountpoint unstable http://deb.debian.org/debian\fR +.PP +This will create an image with an fstab entry for the directory \fI/shared\fR. +.SH COPYRIGHT +Copyright \[co] 2020 Christian Kastner +.SH "SEE ALSO" +.BR sbuild (1), +.BR sbuild\-qemu (1), +.BR sbuild\-qemu\-update (1). diff -Nru sbuild-0.80.0ubuntu1/man/sbuild-qemu-update.1.in sbuild-0.81.2ubuntu5/man/sbuild-qemu-update.1.in --- sbuild-0.80.0ubuntu1/man/sbuild-qemu-update.1.in 1970-01-01 00:00:00.000000000 +0000 +++ sbuild-0.81.2ubuntu5/man/sbuild-qemu-update.1.in 2021-03-18 07:38:02.000000000 +0000 @@ -0,0 +1,62 @@ +.\" Copyright © 2020 Christian Kastner +.\" +.\" This program is free software: you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation, either version 2 of the License, or +.\" (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, but +.\" WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +.\" General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program. If not, see +.\" . +.so defs.man +.TH SBUILD\-QEMU\-UPDATE "1" "\*[RELEASE_DATE]" "Version \*[VERSION]" "Debian sbuild" +.SH NAME +sbuild\-qemu\-update \- sbuild\-update analog for QEMU images +.SH SYNOPSIS +.B sbuild\-qemu\-update +.RB [ \-h ] +.RB [ \-\-snapshot ] +.RB [ \-\-arch=ARCH ] +.RB [ \-\-noexec ] +.RB image +.SH DESCRIPTION +\fBsbuild\-qemu\-update\fR boots a QEMU VM using \fIimage\fR and then runs +\fBapt-get\fR in it, performing \fBupdate\fR, \fBdist-upgrade\fR, \fBclean\fR +and \fBautoremove\fR. It can optionally create a snapshot before updating. +.SH OPTIONS +.TP +\fB\-h\fR, \fB\-\-help\fR +Show this help message and exit. +.TP +\fB\-\-snapshot\fR +Create a snapshot of the image before updating it. Useful for +reproducibility purposes. +.TP +\fB\-\-arch\fR=ARCH +Architecture to use (instead of attempting to auto\-guess based on the image +name). +.TP +\fB\-\-noexec\fR +Don't actually do anything. Just print the command string that +would be executed, and then exit. +.SH EXAMPLES +\fB$ sbuild\-qemu\-update unstable\-autopkgtest\-amd64.img\fR +.PP +This will update the image \fBunstable\-autopkgtest\-amd64.img\fR in +the current directory. If no such file exists there, then +\fB$IMAGEDIR/unstable\-autopkgtest\-amd64.img\fR is tried. +.SH ENVIRONMENT +If \fB$IMAGEDIR\fR is unset, then \fI~/.cache/sbuild\fR is used. +.SH COPYRIGHT +.nf +Copyright \[co] 2020 Christian Kastner +.fi +.SH "SEE ALSO" +.BR sbuild (1), +.BR sbuild\-qemu (1), +.BR sbuild\-qemu\-create (1). diff -Nru sbuild-0.80.0ubuntu1/.pc/abs-path-revert.patch/bin/sbuild sbuild-0.81.2ubuntu5/.pc/abs-path-revert.patch/bin/sbuild --- sbuild-0.80.0ubuntu1/.pc/abs-path-revert.patch/bin/sbuild 2020-08-04 14:28:23.000000000 +0000 +++ sbuild-0.81.2ubuntu5/.pc/abs-path-revert.patch/bin/sbuild 1970-01-01 00:00:00.000000000 +0000 @@ -1,383 +0,0 @@ -#!/usr/bin/perl -# -# sbuild: build packages, obeying source dependencies -# Copyright © 1998-2000 Roman Hodek -# Copyright © 2005 Ryan Murray -# Copyright © 2005-2009 Roger Leigh -# Copyright © 2008 Simon McVittie -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see -# . -# -####################################################################### - -package main; - -use strict; -use warnings; - -use Cwd qw(:DEFAULT abs_path); -use File::Basename qw(basename dirname); -use POSIX; -use Data::Dumper; -use Dpkg::Control; -use Sbuild qw(isin check_group_membership $debug_level dsc_files debug); -use Sbuild::Conf qw(); -use Sbuild::Sysconfig qw(%programs); -use Sbuild::Options; -use Sbuild::Build; -use Sbuild::Exception; -use Sbuild::Utility qw(check_url download); - -sub main (); -sub create_source_package ($); -sub download_source_package ($); -sub write_jobs_file (); -sub status_trigger ($$); -sub shutdown ($); -sub dump_main_state (); - -my $conf = Sbuild::Conf::new(); -exit 1 if !defined($conf); -my $options = Sbuild::Options->new($conf, "sbuild", "1"); -exit 1 if !defined($options); -check_group_membership() if $conf->get('CHROOT_MODE') eq 'schroot'; - -if (!$conf->get('MAINTAINER_NAME') && - ($conf->get('BIN_NMU') || $conf->get('APPEND_TO_VERSION'))) { - die "A maintainer name, uploader name or key ID must be specified in .sbuildrc,\nor use -m, -e or -k, when performing a binNMU or appending a version suffix\n"; -} - -umask(002); - -# Job state -my $job = undef; - -main(); - -sub main () { - $SIG{'INT'} = \&main::shutdown; - $SIG{'TERM'} = \&main::shutdown; - $SIG{'ALRM'} = \&main::shutdown; - $SIG{'PIPE'} = \&main::shutdown; - - # If no arguments are supplied, assume we want to process the current dir. - push @ARGV, '.' unless (@ARGV); - - die "Only one build is permitted\n" - if (@ARGV != 1); - - # Create and run job - my $status = eval { - my $jobname = $ARGV[0]; - my $source_dir = 0; - - if (-e $jobname) { - $jobname = abs_path($jobname); - } - - if (-d $jobname) { - $jobname = create_source_package($jobname); - if ($jobname eq '.') { - chdir('..') or Sbuild::Exception::Build->throw( - error => "Failed to change directory", - failstage => "change-build-dir"); - $conf->_set_default('BUILD_DIR', cwd()); - } - $source_dir = 1; - } elsif (($jobname =~ m/\.dsc$/) && # Use apt to download - check_url($jobname)) { - # Valid URL - $jobname = download_source_package($jobname); - } - - - # Check after source package build (which might set dist) - my $dist = $conf->get('DISTRIBUTION'); - if (!defined($dist) || !$dist) { - print STDERR "No distribution defined\n"; - exit(1); - } - - print "Selected distribution " . $conf->get('DISTRIBUTION') . "\n" - if $conf->get('DEBUG'); - print "Selected chroot " . $conf->get('CHROOT') . "\n" - if $conf->get('DEBUG') and defined $conf->get('CHROOT'); - print "Selected host architecture " . $conf->get('HOST_ARCH') . "\n" - if $conf->get('DEBUG' && defined($conf->get('HOST_ARCH'))); - print "Selected build architecture " . $conf->get('BUILD_ARCH') . "\n" - if $conf->get('DEBUG' && defined($conf->get('BUILD_ARCH'))); - print "Selected build profiles " . $conf->get('BUILD_PROFILES') . "\n" - if $conf->get('DEBUG' && defined($conf->get('BUILD_PROFILES'))); - - $job = Sbuild::Build->new($jobname, $conf); - $job->set('Pkg Status Trigger', \&status_trigger); - write_jobs_file(); # Will now update on trigger. - - # Run job. - $job->run(); - - dump_main_state() if $conf->get('DEBUG'); - }; - - my $e; - if ($e = Exception::Class->caught('Sbuild::Exception::Build')) { - print STDERR "E: $e\n"; - print STDERR "I: " . $e->info . "\n" - if ($e->info); - if ($debug_level) { - #dump_main_state(); - #print STDERR $e->trace->as_string, "\n"; - } - } elsif (!defined($e)) { - print STDERR "E: $@\n" if $@; - } - - unlink($conf->get('JOB_FILE')) - if $conf->get('BATCH_MODE'); - - # Until buildd parses status info from sbuild output, skipped must - # be treated as a failure. - if (defined($job)) { - if ($job->get_status() eq "successful" || - ($conf->get('SBUILD_MODE') ne "buildd" && - $job->get_status() eq "skipped")) { - exit 0; - } elsif ($job->get_status() eq "attempted") { - exit 2; - } elsif ($job->get_status() eq "given-back") { - #Probably needs a give back: - exit 3; - } - # Unknown status - probably needs a give back, but needs to be - # reported to the admin as failure: - exit 1; - } - debug("Error main(): $@") if $@; - exit 1; -} - -sub create_source_package ($) { - my $dsc = shift; - - open(my $pipe, '-|', 'dpkg-parsechangelog', - '-l' . $dsc . '/debian/changelog') - or Sbuild::Exception::Build->throw( - error => "Could not parse $dsc/debian/changelog: $!", - failstage => "pack-source"); - - my $pclog = Dpkg::Control->new(type => CTRL_CHANGELOG); - if (!$pclog->parse($pipe, 'dpkg-parsechangelog')) { - Sbuild::Exception::Build->throw( - error => "Could not parse $dsc/debian/changelog: $!", - failstage => "pack-source"); - } - - $pipe->close or Sbuild::Exception::Build->throw( - error => "dpkg-parsechangelog failed (exit status $?)", - failstage => "pack-source"); - - my $package = $pclog->{'Source'}; - my $version = $pclog->{'Version'}; - - if (!defined($package) || !defined($version)) { - Sbuild::Exception::Build->throw( - error => "Missing Source or Version in $dsc/debian/changelog", - failstage => "pack-source"); - } - - my $dist = $pclog->{'Distribution'}; - my $pver = Dpkg::Version->new($version, check => 1); - unless (defined $pver) { - Sbuild::Exception::Build->throw( - error => "Bad version $version in $dsc/debian/changelog", - failstage => "pack-source"); - } - - my ($uversion, $dversion); - $uversion = $pver->version(); - $dversion = "-" . $pver->revision(); - $dversion = "" if $pver->{'no_revision'}; - - if (!defined($conf->get('DISTRIBUTION')) || - !$conf->get('DISTRIBUTION')) { - $conf->set('DISTRIBUTION', $dist); - } - - my $dir = getcwd(); - my $origdir=$dir; - my $origdsc=$dsc; - # Note: need to support cases when invoked from a subdirectory - # of the build directory, i.e. $dsc/foo -> $dsc/.. in addition - # to $dsc -> $dsc/.. as below. - # We won't attempt to build the source package from the source - # directory so the source package files will go to the parent dir. - my $dscdir = abs_path("$dsc/.."); - if (index($dir, $dsc, 0) == 0) { - $conf->set('BUILD_DIR', $dscdir); - } - - $dsc = "${dscdir}/${package}_${uversion}${dversion}.dsc"; - - $dir = $origdsc; - - chdir($dir) or Sbuild::Exception::Build->throw( - error => "Failed to change directory", - failstage => "pack-source"); - my @dpkg_source_before = ($conf->get('DPKG_SOURCE'), '--before-build'); - push @dpkg_source_before, @{$conf->get('DPKG_SOURCE_OPTIONS')} - if ($conf->get('DPKG_SOURCE_OPTIONS')); - push @dpkg_source_before, '.'; - system(@dpkg_source_before); - if ($?) { - Sbuild::Exception::Build->throw( - error => "Failed to run dpkg-source --before-build " . getcwd(), - failstage => "pack-source"); - } - if ($conf->get('CLEAN_SOURCE')) { - system($conf->get('FAKEROOT'), 'debian/rules', 'clean'); - if ($?) { - Sbuild::Exception::Build->throw( - error => "Failed to clean source directory $dir ($dsc)", - failstage => "pack-source"); - } - } - my @dpkg_source_command = ($conf->get('DPKG_SOURCE'), '-b'); - push @dpkg_source_command, @{$conf->get('DPKG_SOURCE_OPTIONS')} - if ($conf->get('DPKG_SOURCE_OPTIONS')); - push @dpkg_source_command, '.'; - system(@dpkg_source_command); - if ($?) { - Sbuild::Exception::Build->throw( - error => "Failed to package source directory " . getcwd(), - failstage => "pack-source"); - } - my @dpkg_source_after = ($conf->get('DPKG_SOURCE'), '--after-build'); - push @dpkg_source_after, @{$conf->get('DPKG_SOURCE_OPTIONS')} - if ($conf->get('DPKG_SOURCE_OPTIONS')); - push @dpkg_source_after, '.'; - system(@dpkg_source_after); - if ($?) { - Sbuild::Exception::Build->throw( - error => "Failed to run dpkg-source --after-build " . getcwd(), - failstage => "pack-source"); - } - chdir($origdir) or Sbuild::Exception::Build->throw( - error => "Failed to change directory", - failstage => "pack-source"); - - return $dsc; -} - -sub download_source_package ($) { - my $dsc = shift; - - my $srcdir = dirname($dsc); - my $dscbase = basename($dsc); - - my @fetched; - - # Work with a .dsc file. - # $file is the name of the downloaded dsc file written in a tempfile. - my $file; - $file = download($dsc, $dscbase) or - Sbuild::Exception::Build->throw( - error => "Could not download $dsc", - failstage => "download-source"); - push(@fetched, $dscbase); - - my @cwd_files = dsc_files($file); - - foreach (@cwd_files) { - my $subfile = download("$srcdir/$_", $_); - if (!$subfile) { - # Remove downloaded sources - foreach my $rm (@fetched) { - unlink($rm); - } - Sbuild::Exception::Build->throw( - error => "Could not download $srcdir/$_", - failstage => "download-source"); - } - push(@fetched, $_); - } - - return $file; -} - -# only called from main loop, but depends on job state. -sub write_jobs_file () { - if ($conf->get('BATCH_MODE')) { - - my $file = $conf->get('JOB_FILE'); - local( *F ); - - return if !open( F, ">$file" ); - if (defined($job)) { - print F $job->get('Package_OVersion') . ": " . - $job->get_status() . "\n"; - } - close( F ); - } -} - -sub status_trigger ($$) { - my $build = shift; - my $status = shift; - - write_jobs_file(); - - # Rewrite status if we need to give back or mark attempted - # following failure. Note that this must follow the above - # function calls because set_status will recursively trigger. - if ($status eq "failed" && - isin($build->get('Pkg Fail Stage'), - qw(fetch-src install-core install-essential install-deps - unpack check-unpacked-version check-space hack-binNMU - install-deps-env apt-get-clean apt-get-update - apt-get-upgrade apt-get-distupgrade))) { - $build->set_status('given-back'); - } elsif ($status eq "failed" && - isin ($build->get('Pkg Fail Stage'), - qw(build arch-check))) { - $build->set_status('attempted'); - } -} - -sub shutdown ($) { - my $signame = shift; - - $SIG{'INT'} = 'IGNORE'; - $SIG{'QUIT'} = 'IGNORE'; - $SIG{'TERM'} = 'IGNORE'; - $SIG{'ALRM'} = 'IGNORE'; - $SIG{'PIPE'} = 'IGNORE'; - - if (defined($job)) { - $job->request_abort("Received $signame signal"); - } else { - exit(1); - } - - $SIG{'INT'} = \&main::shutdown; - $SIG{'TERM'} = \&main::shutdown; - $SIG{'ALRM'} = \&main::shutdown; - $SIG{'PIPE'} = \&main::shutdown; -} - -sub dump_main_state () { - print STDERR Data::Dumper->Dump([$job], - [qw($job)] ); -} diff -Nru sbuild-0.80.0ubuntu1/.pc/applied-patches sbuild-0.81.2ubuntu5/.pc/applied-patches --- sbuild-0.80.0ubuntu1/.pc/applied-patches 2020-08-04 14:28:23.000000000 +0000 +++ sbuild-0.81.2ubuntu5/.pc/applied-patches 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -no-pkg-mangle-deps.patch -abs-path-revert.patch diff -Nru sbuild-0.80.0ubuntu1/.pc/no-pkg-mangle-deps.patch/lib/Sbuild/ResolverBase.pm sbuild-0.81.2ubuntu5/.pc/no-pkg-mangle-deps.patch/lib/Sbuild/ResolverBase.pm --- sbuild-0.80.0ubuntu1/.pc/no-pkg-mangle-deps.patch/lib/Sbuild/ResolverBase.pm 2020-08-04 14:28:23.000000000 +0000 +++ sbuild-0.81.2ubuntu5/.pc/no-pkg-mangle-deps.patch/lib/Sbuild/ResolverBase.pm 1970-01-01 00:00:00.000000000 +0000 @@ -1,1687 +0,0 @@ -# Resolver.pm: build library for sbuild -# Copyright © 2005 Ryan Murray -# Copyright © 2005-2010 Roger Leigh -# Copyright © 2008 Simon McVittie -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see -# . -# -####################################################################### - -package Sbuild::ResolverBase; - -use strict; -use warnings; -use POSIX; -use Fcntl; -use File::Temp qw(mktemp); -use File::Basename qw(basename); -use File::Copy; -use MIME::Base64; - -use Dpkg::Deps; -use Sbuild::Base; -use Sbuild qw(isin debug debug2); - -BEGIN { - use Exporter (); - our (@ISA, @EXPORT); - - @ISA = qw(Exporter Sbuild::Base); - - @EXPORT = qw(); -} - -sub new { - my $class = shift; - my $conf = shift; - my $session = shift; - my $host = shift; - - my $self = $class->SUPER::new($conf); - bless($self, $class); - - $self->set('Session', $session); - $self->set('Host', $host); - $self->set('Changes', {}); - $self->set('AptDependencies', {}); - $self->set('Split', $self->get_conf('CHROOT_SPLIT')); - # Typically set by Sbuild::Build, but not outside a build context. - $self->set('Host Arch', $self->get_conf('HOST_ARCH')); - $self->set('Build Arch', $self->get_conf('BUILD_ARCH')); - $self->set('Build Profiles', $self->get_conf('BUILD_PROFILES')); - $self->set('Multiarch Support', 1); - $self->set('Initial Foreign Arches', {}); - $self->set('Added Foreign Arches', {}); - - my $dummy_archive_list_file = - '/etc/apt/sources.list.d/sbuild-build-depends-archive.list'; - $self->set('Dummy archive list file', $dummy_archive_list_file); - - my $extra_repositories_archive_list_file = - '/etc/apt/sources.list.d/sbuild-extra-repositories.list'; - $self->set('Extra repositories archive list file', $extra_repositories_archive_list_file); - - my $extra_packages_archive_list_file = - '/etc/apt/sources.list.d/sbuild-extra-packages-archive.list'; - $self->set('Extra packages archive list file', $extra_packages_archive_list_file); - - return $self; -} - -sub setup { - my $self = shift; - - my $session = $self->get('Session'); - my $chroot_dir = $session->get('Location'); - - #Set up dpkg config - $self->setup_dpkg(); - - my $aptconf = "/var/lib/sbuild/apt.conf"; - $self->set('APT Conf', $aptconf); - - my $chroot_aptconf = $session->get('Location') . "/$aptconf"; - $self->set('Chroot APT Conf', $chroot_aptconf); - - my $tmpaptconf = $session->mktemp({ TEMPLATE => "$aptconf.XXXXXX"}); - if (!$tmpaptconf) { - $self->log_error("Can't create $chroot_aptconf.XXXXXX: $!\n"); - return 0; - } - - my $F = $session->get_write_file_handle($tmpaptconf); - if (!$F) { - $self->log_error("Cannot open pipe: $!\n"); - return 0; - } - - # Always write out apt.conf, because it may become outdated. - if ($self->get_conf('APT_ALLOW_UNAUTHENTICATED')) { - print $F qq(APT::Get::AllowUnauthenticated "true";\n); - } - print $F qq(APT::Install-Recommends "false";\n); - print $F qq(APT::AutoRemove::SuggestsImportant "false";\n); - print $F qq(APT::AutoRemove::RecommendsImportant "false";\n); - print $F qq(Acquire::Languages "none";\n); # do not download translations - - if ($self->get_conf('APT_KEEP_DOWNLOADED_PACKAGES')) { - print $F qq(APT::Keep-Downloaded-Packages "true";\n); - } else { - # remove packages from /var/cache/apt/archive/*.deb after installation - print $F qq(APT::Keep-Downloaded-Packages "false";\n); - } - - if ($self->get('Split')) { - print $F "Dir \"$chroot_dir\";\n"; - } - - close $F; - - if (!$session->rename($tmpaptconf, $aptconf)) { - $self->log_error("Can't rename $tmpaptconf to $aptconf: $!\n"); - return 0; - } - - if (!$session->chown($aptconf, $self->get_conf('BUILD_USER'), 'sbuild')) { - $self->log_error("Failed to set " . $self->get_conf('BUILD_USER') . - ":sbuild ownership on apt.conf at $aptconf\n"); - return 0; - } - if (!$session->chmod($aptconf, '0664')) { - $self->log_error("Failed to set 0664 permissions on apt.conf at $aptconf\n"); - return 0; - } - - # unsplit mode uses an absolute path inside the chroot, rather - # than on the host system. - if ($self->get('Split')) { - $self->set('APT Options', - ['-o', "Dir::State::status=$chroot_dir/var/lib/dpkg/status", - '-o', "DPkg::Options::=--root=$chroot_dir", - '-o', "DPkg::Run-Directory=$chroot_dir"]); - - $self->set('Aptitude Options', - ['-o', "Dir::State::status=$chroot_dir/var/lib/dpkg/status", - '-o', "DPkg::Options::=--root=$chroot_dir", - '-o', "DPkg::Run-Directory=$chroot_dir"]); - - # sudo uses an absolute path on the host system. - $session->get('Defaults')->{'ENV'}->{'APT_CONFIG'} = - $self->get('Chroot APT Conf'); - } else { # no split - $self->set('APT Options', []); - $self->set('Aptitude Options', []); - $session->get('Defaults')->{'ENV'}->{'APT_CONFIG'} = - $self->get('APT Conf'); - } - - # Add specified extra repositories into /etc/apt/sources.list.d/. - # This has to be done this early so that the early apt - # update/upgrade/distupgrade steps also consider the extra repositories. - # If this step would be done too late, extra repositories would only be - # considered when resolving build dependencies but not for upgrading the - # base chroot. - if (scalar @{$self->get_conf('EXTRA_REPOSITORIES')} > 0) { - my $extra_repositories_archive_list_file = $self->get('Extra repositories archive list file'); - if ($session->test_regular_file($extra_repositories_archive_list_file)) { - $self->log_error("$extra_repositories_archive_list_file exists - will not write extra repositories to it\n"); - } else { - my $tmpfilename = $session->mktemp(); - - my $tmpfh = $session->get_write_file_handle($tmpfilename); - if (!$tmpfh) { - $self->log_error("Cannot open pipe: $!\n"); - return 0; - } - for my $repospec (@{$self->get_conf('EXTRA_REPOSITORIES')}) { - print $tmpfh "$repospec\n"; - } - close $tmpfh; - # List file needs to be moved with root. - if (!$session->chmod($tmpfilename, '0644')) { - $self->log("Failed to create apt list file for dummy archive.\n"); - $session->unlink($tmpfilename); - return 0; - } - if (!$session->rename($tmpfilename, $extra_repositories_archive_list_file)) { - $self->log("Failed to create apt list file for dummy archive.\n"); - $session->unlink($tmpfilename); - return 0; - } - } - } - - # Create an internal repository for packages given via --extra-package - # If this step would be done too late, extra packages would only be - # considered when resolving build dependencies but not for upgrading the - # base chroot. - if (scalar @{$self->get_conf('EXTRA_PACKAGES')} > 0) { - my $extra_packages_archive_list_file = $self->get('Extra packages archive list file'); - if ($session->test_regular_file($extra_packages_archive_list_file)) { - $self->log_error("$extra_packages_archive_list_file exists - will not write extra packages archive list to it\n"); - } else { - #Prepare a path to place the extra packages - if (! defined $self->get('Extra packages path')) { - my $tmpdir = $session->mktemp({ TEMPLATE => $self->get('Build Dir') . '/resolver-XXXXXX', DIRECTORY => 1}); - if (!$tmpdir) { - $self->log_error("mktemp -d " . $self->get('Build Dir') . '/resolver-XXXXXX failed\n'); - return 0; - } - $self->set('Extra packages path', $tmpdir); - } - if (!$session->chown($self->get('Extra packages path'), $self->get_conf('BUILD_USER'), 'sbuild')) { - $self->log_error("Failed to set " . $self->get_conf('BUILD_USER') . - ":sbuild ownership on extra packages dir\n"); - return 0; - } - if (!$session->chmod($self->get('Extra packages path'), '0770')) { - $self->log_error("Failed to set 0770 permissions on extra packages dir\n"); - return 0; - } - my $extra_packages_dir = $self->get('Extra packages path'); - my $extra_packages_archive_dir = $extra_packages_dir . '/apt_archive'; - my $extra_packages_release_file = $extra_packages_archive_dir . '/Release'; - - $self->set('Extra packages archive directory', $extra_packages_archive_dir); - $self->set('Extra packages release file', $extra_packages_release_file); - my $extra_packages_archive_list_file = $self->get('Extra packages archive list file'); - - if (!$session->test_directory($extra_packages_dir)) { - $self->log_warning('Could not create build-depends extra packages dir ' . $extra_packages_dir . ': ' . $!); - return 0; - } - if (!($session->test_directory($extra_packages_archive_dir) || $session->mkdir($extra_packages_archive_dir, { MODE => "00775"}))) { - $self->log_warning('Could not create build-depends extra packages archive dir ' . $extra_packages_archive_dir . ': ' . $!); - return 0; - } - - # Copy over all the extra binary packages from the host into the - # chroot - for my $deb (@{$self->get_conf('EXTRA_PACKAGES')}) { - if (-f $deb) { - my $base_deb = basename($deb); - if ($session->test_regular_file("$extra_packages_archive_dir/$base_deb")) { - $self->log_warning("$base_deb already exists in $extra_packages_archive_dir inside the chroot. Skipping...\n"); - next; - } - $session->copy_to_chroot($deb, $extra_packages_archive_dir); - } elsif (-d $deb) { - opendir(D, $deb); - while (my $f = readdir(D)) { - next if (! -f "$deb/$f"); - next if ("$deb/$f" !~ /\.deb$/); - if ($session->test_regular_file("$extra_packages_archive_dir/$f")) { - $self->log_warning("$f already exists in $extra_packages_archive_dir inside the chroot. Skipping...\n"); - next; - } - $session->copy_to_chroot("$deb/$f", $extra_packages_archive_dir); - } - closedir(D); - } else { - $self->log_warning("$deb is neither a regular file nor a directory. Skipping...\n"); - } - } - - # Do code to run apt-ftparchive - if (!$self->run_apt_ftparchive($self->get('Extra packages archive directory'))) { - $self->log("Failed to run apt-ftparchive.\n"); - return 0; - } - - # Write a list file for the extra packages archive if one not create yet. - if (!$session->test_regular_file($extra_packages_archive_list_file)) { - my $tmpfilename = $session->mktemp(); - - if (!$tmpfilename) { - $self->log_error("Can't create tempfile\n"); - return 0; - } - - my $tmpfh = $session->get_write_file_handle($tmpfilename); - if (!$tmpfh) { - $self->log_error("Cannot open pipe: $!\n"); - return 0; - } - - # We always trust the extra packages apt repositories. - print $tmpfh 'deb [trusted=yes] file://' . $extra_packages_archive_dir . " ./\n"; - print $tmpfh 'deb-src [trusted=yes] file://' . $extra_packages_archive_dir . " ./\n"; - - close($tmpfh); - # List file needs to be moved with root. - if (!$session->chmod($tmpfilename, '0644')) { - $self->log("Failed to create apt list file for extra packages archive.\n"); - $session->unlink($tmpfilename); - return 0; - } - if (!$session->rename($tmpfilename, $extra_packages_archive_list_file)) { - $self->log("Failed to create apt list file for extra packages archive.\n"); - $session->unlink($tmpfilename); - return 0; - } - } - - } - } - - # Now, we'll add in any provided OpenPGP keys into the archive, so that - # builds can (optionally) trust an external key for the duration of the - # build. - # - # Keys have to be in a format that apt expects to land in - # /etc/apt/trusted.gpg.d as they are just copied to there. We could also - # support more formats by first importing them using gpg and then - # exporting them but that would require gpg to be installed inside the - # chroot. - if (@{$self->get_conf('EXTRA_REPOSITORY_KEYS')}) { - my $host = $self->get('Host'); - # remember whether running gpg worked or not - my $has_gpg = 1; - for my $repokey (@{$self->get_conf('EXTRA_REPOSITORY_KEYS')}) { - debug("Adding archive key: $repokey\n"); - if (!-f $repokey) { - $self->log("Failed to add archive key '${repokey}' - it doesn't exist!\n"); - return 0; - } - # key might be armored but apt requires keys in binary format - # We first try to run gpg from the host to convert the key into - # binary format (this works even when the key already is in binary - # format). - my $tmpfilename = mktemp("/tmp/tmp.XXXXXXXXXX"); - if ($has_gpg == 1) { - $host->run_command({ - COMMAND => ['gpg', '--yes', '--batch', '--output', $tmpfilename, '--dearmor', $repokey], - USER => $self->get_conf('BUILD_USER'), - }); - if ($?) { - # don't try to use gpg again in later loop iterations - $has_gpg = 0; - } - } - # If that doesn't work, then we manually convert the key - # as it is just base64 encoded data with a header and footer. - # - # The decoding of armored gpg keys can even be done from a shell - # script by using: - # - # awk '/^$/{ x = 1; } /^[^=-]/{ if (x) { print $0; } ; }' | base64 -d - # - # As explained by dkg here: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=831409#67 - if ($has_gpg == 0) { - # Test if we actually have an armored key. Otherwise, no - # conversion is needed. - open my $fh, '<', $repokey; - read $fh, my $first_line, 36; - if ($first_line eq "-----BEGIN PGP PUBLIC KEY BLOCK-----") { - # Read the remaining part of the line until the newline. - # We do it like this because the line might contain - # additional whitespace characters or \r\n newlines. - <$fh>; - open my $out, '>', $tmpfilename; - # the file is an armored gpg key, so we convert it to the - # binary format - my $header = 1; - while( my $line = <$fh>) { - chomp $line; - # an empty line marks the end of the header - if ($line eq "") { - $header = 0; - next; - } - if ($header == 1) { - next; - } - # the footer might contain lines starting with an - # equal sign or minuses - if ($line =~ /^[=-]/) { - last; - } - print $out (decode_base64($line)); - } - close $out; - } - close $fh; - } - # we could use incrementing integers to number the extra - # repository keys but mktemp will also make sure that the new name - # doesn't exist yet and avoids the complexity of an additional - # variable - my $keyfilename = $session->mktemp({TEMPLATE => "/etc/apt/trusted.gpg.d/sbuild-extra-repository-XXXXXXXXXX.gpg"}); - if (!$keyfilename) { - $self->log_error("Can't create tempfile for external repository key\n"); - $session->unlink($keyfilename); - unlink $tmpfilename; - return 0; - } - if (!$session->copy_to_chroot($tmpfilename, $keyfilename)) { - $self->log_error("Failed to copy external repository key $repokey into chroot $keyfilename\n"); - $session->unlink($keyfilename); - unlink $tmpfilename; - return 0; - } - unlink $tmpfilename; - if (!$session->chmod($keyfilename, '0644')) { - $self->log_error("Failed to chmod $keyfilename inside the chroot\n"); - $session->unlink($keyfilename); - return 0; - } - } - - } - - # We have to do this early so that we can setup log filtering for the RESOLVERDIR - # We only set it up, if 'Build Dir' was set. It is not when the resolver - # is used by sbuild-createchroot, for example. - #Prepare a path to build a dummy package containing our deps: - if (! defined $self->get('Dummy package path') && defined $self->get('Build Dir')) { - my $tmpdir = $session->mktemp({ TEMPLATE => $self->get('Build Dir') . '/resolver-XXXXXX', DIRECTORY => 1}); - if (!$tmpdir) { - $self->log_error("mktemp -d " . $self->get('Build Dir') . '/resolver-XXXXXX failed\n'); - return 0; - } - $self->set('Dummy package path', $tmpdir); - } - - return 1; -} - -sub get_foreign_architectures { - my $self = shift; - - my $session = $self->get('Session'); - - $session->run_command({ COMMAND => ['dpkg', '--assert-multi-arch'], - USER => 'root'}); - if ($?) - { - $self->set('Multiarch Support', 0); - $self->log_error("dpkg does not support multi-arch\n"); - return {}; - } - - my $foreignarchs = $session->read_command({ COMMAND => ['dpkg', '--print-foreign-architectures'], USER => 'root' }); - - if (!defined($foreignarchs)) { - $self->set('Multiarch Support', 0); - $self->log_error("dpkg does not support multi-arch\n"); - return {}; - } - - if (!$foreignarchs) - { - debug("There are no foreign architectures configured\n"); - return {}; - } - - my %set; - foreach my $arch (split /\s+/, $foreignarchs) { - chomp $arch; - next unless $arch; - $set{$arch} = 1; - } - - return \%set; -} - -sub add_foreign_architecture { - - my $self = shift; - my $arch = shift; - - # just skip if dpkg is to old for multiarch - if (! $self->get('Multiarch Support')) { - debug("not adding $arch because of no multiarch support\n"); - return 1; - }; - - # if we already have this architecture, we're done - if ($self->get('Initial Foreign Arches')->{$arch}) { - debug("not adding $arch because it is an initial arch\n"); - return 1; - } - if ($self->get('Added Foreign Arches')->{$arch}) { - debug("not adding $arch because it has already been aded"); - return 1; - } - - my $session = $self->get('Session'); - - # FIXME - allow for more than one foreign arch - $session->run_command( - # This is the Ubuntu dpkg 1.16.0~ubuntuN interface; - # we ought to check (or configure) which to use with - # check_dpkg_version: - # { COMMAND => ['sh', '-c', 'echo "foreign-architecture ' . $self->get('Host Arch') . '" > /etc/dpkg/dpkg.cfg.d/sbuild'], - # USER => 'root' }); - # This is the Debian dpkg >= 1.16.2 interface: - { COMMAND => ['dpkg', '--add-architecture', $arch], - USER => 'root' }); - if ($?) - { - $self->log_error("Failed to set dpkg foreign-architecture config\n"); - return 0; - } - debug("Added foreign arch: $arch\n") if $arch; - - $self->get('Added Foreign Arches')->{$arch} = 1; - return 1; -} - -sub cleanup_foreign_architectures { - my $self = shift; - - # just skip if dpkg is to old for multiarch - if (! $self->get('Multiarch Support')) { return 1 }; - - my $added_foreign_arches = $self->get('Added Foreign Arches'); - - my $session = $self->get('Session'); - - if (defined ($session->get('Session Purged')) && $session->get('Session Purged') == 1) { - debug("Not removing foreign architectures: cloned chroot in use\n"); - return; - } - - foreach my $arch (keys %{$added_foreign_arches}) { - $self->log("Removing foreign architecture $arch\n"); - $session->run_command({ COMMAND => ['dpkg', '--remove-architecture', $arch], - USER => 'root', - DIR => '/'}); - if ($?) - { - $self->log_error("Failed to remove dpkg foreign-architecture $arch\n"); - return; - } - } -} - -sub setup_dpkg { - my $self = shift; - - my $session = $self->get('Session'); - - # Record initial foreign arch state so it can be restored - $self->set('Initial Foreign Arches', $self->get_foreign_architectures()); - - if ($self->get('Host Arch') ne $self->get('Build Arch')) { - $self->add_foreign_architecture($self->get('Host Arch')) - } -} - -sub cleanup { - my $self = shift; - - #cleanup dpkg cross-config - # rm /etc/dpkg/dpkg.cfg.d/sbuild - $self->cleanup_apt_archive(); - $self->cleanup_foreign_architectures(); -} - -sub update { - my $self = shift; - - $self->run_apt_command( - { COMMAND => [$self->get_conf('APT_GET'), 'update'], - ENV => {'DEBIAN_FRONTEND' => 'noninteractive'}, - USER => 'root', - DIR => '/' }); - return $?; -} - -sub update_archive { - my $self = shift; - - if (!$self->get_conf('APT_UPDATE_ARCHIVE_ONLY')) { - # Update with apt-get; causes complete archive update - $self->run_apt_command( - { COMMAND => [$self->get_conf('APT_GET'), 'update'], - ENV => {'DEBIAN_FRONTEND' => 'noninteractive'}, - USER => 'root', - DIR => '/' }); - } else { - my $session = $self->get('Session'); - # Create an empty sources.list.d directory that we can set as - # Dir::Etc::sourceparts to suppress the real one. /dev/null - # works in recent versions of apt, but not older ones (we want - # 448eaf8 in apt 0.8.0 and af13d14 in apt 0.9.3). Since this - # runs against the target chroot's apt, be conservative. - my $dummy_sources_list_d = $self->get('Dummy package path') . '/sources.list.d'; - if (!($session->test_directory($dummy_sources_list_d) || $session->mkdir($dummy_sources_list_d, { MODE => "00700"}))) { - $self->log_warning('Could not create build-depends dummy sources.list directory ' . $dummy_sources_list_d . ': ' . $!); - return 0; - } - - # Run apt-get update pointed at our dummy archive list file, and - # the empty sources.list.d directory, so that we only update - # this one source. Since apt doesn't have all the sources - # available to it in this run, any caches it generates are - # invalid, so we then need to run gencaches with all sources - # available to it. (Note that the tempting optimization to run - # apt-get update -o pkgCacheFile::Generate=0 is broken before - # 872ed75 in apt 0.9.1.) - for my $list_file ($self->get('Dummy archive list file'), - $self->get('Extra packages archive list file'), - $self->get('Extra repositories archive list file')) { - if (!$session->test_regular_file_readable($list_file)) { - next; - } - $self->run_apt_command( - { COMMAND => [$self->get_conf('APT_GET'), 'update', - '-o', 'Dir::Etc::sourcelist=' . $list_file, - '-o', 'Dir::Etc::sourceparts=' . $dummy_sources_list_d, - '--no-list-cleanup'], - ENV => {'DEBIAN_FRONTEND' => 'noninteractive'}, - USER => 'root', - DIR => '/' }); - if ($? != 0) { - return 0; - } - } - - $self->run_apt_command( - { COMMAND => [$self->get_conf('APT_CACHE'), 'gencaches'], - ENV => {'DEBIAN_FRONTEND' => 'noninteractive'}, - USER => 'root', - DIR => '/' }); - } - - if ($? != 0) { - return 0; - } - - return 1; -} - -sub upgrade { - my $self = shift; - - $self->run_apt_command( - { COMMAND => [$self->get_conf('APT_GET'), '-uy', '-o', 'Dpkg::Options::=--force-confold', 'upgrade'], - ENV => {'DEBIAN_FRONTEND' => 'noninteractive'}, - USER => 'root', - DIR => '/' }); - return $?; -} - -sub distupgrade { - my $self = shift; - - $self->run_apt_command( - { COMMAND => [$self->get_conf('APT_GET'), '-uy', '-o', 'Dpkg::Options::=--force-confold', 'dist-upgrade'], - ENV => {'DEBIAN_FRONTEND' => 'noninteractive'}, - USER => 'root', - DIR => '/' }); - return $?; -} - -sub clean { - my $self = shift; - - $self->run_apt_command( - { COMMAND => [$self->get_conf('APT_GET'), '-y', 'clean'], - ENV => {'DEBIAN_FRONTEND' => 'noninteractive'}, - USER => 'root', - DIR => '/' }); - return $?; -} - -sub autoclean { - my $self = shift; - - $self->run_apt_command( - { COMMAND => [$self->get_conf('APT_GET'), '-y', 'autoclean'], - ENV => {'DEBIAN_FRONTEND' => 'noninteractive'}, - USER => 'root', - DIR => '/' }); - return $?; -} - -sub autoremove { - my $self = shift; - - $self->run_apt_command( - { COMMAND => [$self->get_conf('APT_GET'), '-y', 'autoremove'], - ENV => {'DEBIAN_FRONTEND' => 'noninteractive'}, - USER => 'root', - DIR => '/' }); - return $?; -} - -sub add_dependencies { - my $self = shift; - my $pkg = shift; - my $build_depends = shift; - my $build_depends_arch = shift; - my $build_depends_indep = shift; - my $build_conflicts = shift; - my $build_conflicts_arch = shift; - my $build_conflicts_indep = shift; - - debug("Build-Depends: $build_depends\n") if $build_depends; - debug("Build-Depends-Arch: $build_depends_arch\n") if $build_depends_arch; - debug("Build-Depends-Indep: $build_depends_indep\n") if $build_depends_indep; - debug("Build-Conflicts: $build_conflicts\n") if $build_conflicts; - debug("Build-Conflicts-Arch: $build_conflicts_arch\n") if $build_conflicts_arch; - debug("Build-Conflicts-Indep: $build_conflicts_indep\n") if $build_conflicts_indep; - - my $deps = { - 'Build Depends' => $build_depends, - 'Build Depends Arch' => $build_depends_arch, - 'Build Depends Indep' => $build_depends_indep, - 'Build Conflicts' => $build_conflicts, - 'Build Conflicts Arch' => $build_conflicts_arch, - 'Build Conflicts Indep' => $build_conflicts_indep - }; - - $self->get('AptDependencies')->{$pkg} = $deps; -} - -sub uninstall_deps { - my $self = shift; - - my( @pkgs, @instd, @rmvd ); - - @pkgs = keys %{$self->get('Changes')->{'removed'}}; - debug("Reinstalling removed packages: @pkgs\n"); - $self->log("Failed to reinstall removed packages!\n") - if !$self->run_apt("-y", \@instd, \@rmvd, 'install', @pkgs); - debug("Installed were: @instd\n"); - debug("Removed were: @rmvd\n"); - $self->unset_removed(@instd); - $self->unset_installed(@rmvd); - - @pkgs = keys %{$self->get('Changes')->{'installed'}}; - debug("Removing installed packages: @pkgs\n"); - $self->log("Failed to remove installed packages!\n") - if !$self->run_apt("-y", \@instd, \@rmvd, 'remove', @pkgs); - $self->unset_removed(@instd); - $self->unset_installed(@rmvd); -} - -sub set_installed { - my $self = shift; - - foreach (@_) { - $self->get('Changes')->{'installed'}->{$_} = 1; - } - debug("Added to installed list: @_\n"); -} - -sub set_removed { - my $self = shift; - foreach (@_) { - $self->get('Changes')->{'removed'}->{$_} = 1; - if (exists $self->get('Changes')->{'installed'}->{$_}) { - delete $self->get('Changes')->{'installed'}->{$_}; - $self->get('Changes')->{'auto-removed'}->{$_} = 1; - debug("Note: $_ was installed\n"); - } - } - debug("Added to removed list: @_\n"); -} - -sub unset_installed { - my $self = shift; - foreach (@_) { - delete $self->get('Changes')->{'installed'}->{$_}; - } - debug("Removed from installed list: @_\n"); -} - -sub unset_removed { - my $self = shift; - foreach (@_) { - delete $self->get('Changes')->{'removed'}->{$_}; - if (exists $self->get('Changes')->{'auto-removed'}->{$_}) { - delete $self->get('Changes')->{'auto-removed'}->{$_}; - $self->get('Changes')->{'installed'}->{$_} = 1; - debug("Note: revived $_ to installed list\n"); - } - } - debug("Removed from removed list: @_\n"); -} - -sub dump_build_environment { - my $self = shift; - - my $status = $self->get_dpkg_status(); - - my $arch = $self->get('Arch'); - my ($sysname, $nodename, $release, $version, $machine) = POSIX::uname(); - $self->log_subsection("Build environment"); - $self->log("Kernel: $sysname $release $version $arch ($machine)\n"); - - $self->log("Toolchain package versions:"); - foreach my $name (sort keys %{$status}) { - foreach my $regex (@{$self->get_conf('TOOLCHAIN_REGEX')}) { - if ($name =~ m,^$regex, && defined($status->{$name}->{'Version'})) { - $self->log(' ' . $name . '_' . $status->{$name}->{'Version'}); - } - } - } - $self->log("\n"); - - $self->log("Package versions:"); - foreach my $name (sort keys %{$status}) { - if (defined($status->{$name}->{'Version'})) { - $self->log(' ' . $name . '_' . $status->{$name}->{'Version'}); - } - } - $self->log("\n"); - - return $status->{'dpkg-dev'}->{'Version'}; -} - -sub run_apt { - my $self = shift; - my $mode = shift; - my $inst_ret = shift; - my $rem_ret = shift; - my $action = shift; - my @packages = @_; - my( $msgs, $status, $pkgs, $rpkgs ); - - $msgs = ""; - # redirection of stdin from /dev/null so that conffile question - # are treated as if RETURN was pressed. - # dpkg since 1.4.1.18 issues an error on the conffile question if - # it reads EOF -- hardwire the new --force-confold option to avoid - # the questions. - my @apt_command = ($self->get_conf('APT_GET'), '--purge', - '-o', 'DPkg::Options::=--force-confold', - '-o', 'DPkg::Options::=--refuse-remove-essential', - '-o', 'APT::Install-Recommends=false', - '-o', 'Dpkg::Use-Pty=false', - '-q'); - push @apt_command, '--allow-unauthenticated' if - ($self->get_conf('APT_ALLOW_UNAUTHENTICATED')); - push @apt_command, "$mode", $action, @packages; - my $pipe = - $self->pipe_apt_command( - { COMMAND => \@apt_command, - ENV => {'DEBIAN_FRONTEND' => 'noninteractive'}, - USER => 'root', - PRIORITY => 0, - DIR => '/' }); - if (!$pipe) { - $self->log("Can't open pipe to apt-get: $!\n"); - return 0; - } - - while(<$pipe>) { - $msgs .= $_; - $self->log($_) if $mode ne "-s" || debug($_); - } - close($pipe); - $status = $?; - - $pkgs = $rpkgs = ""; - if ($msgs =~ /NEW packages will be installed:\n((^[ ].*\n)*)/mi) { - ($pkgs = $1) =~ s/^[ ]*((.|\n)*)\s*$/$1/m; - $pkgs =~ s/\*//g; - } - if ($msgs =~ /packages will be REMOVED:\n((^[ ].*\n)*)/mi) { - ($rpkgs = $1) =~ s/^[ ]*((.|\n)*)\s*$/$1/m; - $rpkgs =~ s/\*//g; - } - @$inst_ret = split( /\s+/, $pkgs ); - @$rem_ret = split( /\s+/, $rpkgs ); - - $self->log("apt-get failed.\n") if $status && $mode ne "-s"; - return $mode eq "-s" || $status == 0; -} - -sub run_xapt { - my $self = shift; - my $mode = shift; - my $inst_ret = shift; - my $rem_ret = shift; - my $action = shift; - my @packages = @_; - my( $msgs, $status, $pkgs, $rpkgs ); - - $msgs = ""; - # redirection of stdin from /dev/null so that conffile question - # are treated as if RETURN was pressed. - # dpkg since 1.4.1.18 issues an error on the conffile question if - # it reads EOF -- hardwire the new --force-confold option to avoid - # the questions. - my @xapt_command = ($self->get_conf('XAPT')); - my $pipe = - $self->pipe_xapt_command( - { COMMAND => \@xapt_command, - ENV => {'DEBIAN_FRONTEND' => 'noninteractive'}, - USER => 'root', - PRIORITY => 0, - DIR => '/' }); - if (!$pipe) { - $self->log("Can't open pipe to xapt: $!\n"); - return 0; - } - - while(<$pipe>) { - $msgs .= $_; - $self->log($_) if $mode ne "-s" || debug($_); - } - close($pipe); - $status = $?; - - $pkgs = $rpkgs = ""; - if ($msgs =~ /NEW packages will be installed:\n((^[ ].*\n)*)/mi) { - ($pkgs = $1) =~ s/^[ ]*((.|\n)*)\s*$/$1/m; - $pkgs =~ s/\*//g; - } - if ($msgs =~ /packages will be REMOVED:\n((^[ ].*\n)*)/mi) { - ($rpkgs = $1) =~ s/^[ ]*((.|\n)*)\s*$/$1/m; - $rpkgs =~ s/\*//g; - } - @$inst_ret = split( /\s+/, $pkgs ); - @$rem_ret = split( /\s+/, $rpkgs ); - - $self->log("xapt failed.\n") if $status && $mode ne "-s"; - return $mode eq "-s" || $status == 0; -} - -sub format_deps { - my $self = shift; - - return join( ", ", - map { join( "|", - map { ($_->{'Neg'} ? "!" : "") . - $_->{'Package'} . - ($_->{'Rel'} ? " ($_->{'Rel'} $_->{'Version'})":"")} - scalar($_), @{$_->{'Alternatives'}}) } @_ ); -} - -sub get_dpkg_status { - my $self = shift; - my @interest = @_; - my %result; - - debug("Requesting dpkg status for packages: @interest\n"); - my $STATUS = $self->get('Session')->get_read_file_handle('/var/lib/dpkg/status'); - if (!$STATUS) { - $self->log("Can't open /var/lib/dpkg/status inside chroot: $!\n"); - return (); - } - local( $/ ) = ""; - while( <$STATUS> ) { - my( $pkg, $status, $version, $provides ); - /^Package:\s*(.*)\s*$/mi and $pkg = $1; - /^Status:\s*(.*)\s*$/mi and $status = $1; - /^Version:\s*(.*)\s*$/mi and $version = $1; - /^Provides:\s*(.*)\s*$/mi and $provides = $1; - if (!$pkg) { - $self->log_error("parse error in /var/lib/dpkg/status: no Package: field\n"); - next; - } - if (defined($version)) { - debug("$pkg ($version) status: $status\n") if $self->get_conf('DEBUG') >= 2; - } else { - debug("$pkg status: $status\n") if $self->get_conf('DEBUG') >= 2; - } - if (!$status) { - $self->log_error("parse error in /var/lib/dpkg/status: no Status: field for package $pkg\n"); - next; - } - if ($status !~ /\sinstalled$/) { - $result{$pkg}->{'Installed'} = 0 - if !(exists($result{$pkg}) && - $result{$pkg}->{'Version'} eq '~*=PROVIDED=*='); - next; - } - if (!defined $version || $version eq "") { - $self->log_error("parse error in /var/lib/dpkg/status: no Version: field for package $pkg\n"); - next; - } - $result{$pkg} = { Installed => 1, Version => $version } - if (isin( $pkg, @interest ) || !@interest); - if ($provides) { - foreach (split( /\s*,\s*/, $provides )) { - $result{$_} = { Installed => 1, Version => '~*=PROVIDED=*=' } - if isin( $_, @interest ) and (not exists($result{$_}) or - ($result{$_}->{'Installed'} == 0)); - } - } - } - close( $STATUS ); - return \%result; -} - -# Create an apt archive. Add to it if one exists. -sub setup_apt_archive { - my $self = shift; - my $dummy_pkg_name = shift; - my @pkgs = @_; - - my $session = $self->get('Session'); - - - if (!$session->chown($self->get('Dummy package path'), $self->get_conf('BUILD_USER'), 'sbuild')) { - $self->log_error("Failed to set " . $self->get_conf('BUILD_USER') . - ":sbuild ownership on dummy package dir\n"); - return 0; - } - if (!$session->chmod($self->get('Dummy package path'), '0770')) { - $self->log_error("Failed to set 0770 permissions on dummy package dir\n"); - return 0; - } - my $dummy_dir = $self->get('Dummy package path'); - my $dummy_gpghome = $dummy_dir . '/gpg'; - my $dummy_archive_dir = $dummy_dir . '/apt_archive'; - my $dummy_release_file = $dummy_archive_dir . '/Release'; - my $dummy_archive_seckey = $dummy_archive_dir . '/sbuild-key.sec'; - my $dummy_archive_pubkey = $dummy_archive_dir . '/sbuild-key.pub'; - - $self->set('Dummy archive directory', $dummy_archive_dir); - $self->set('Dummy Release file', $dummy_release_file); - my $dummy_archive_list_file = $self->get('Dummy archive list file'); - - if (!$session->test_directory($dummy_dir)) { - $self->log_warning('Could not create build-depends dummy dir ' . $dummy_dir . ': ' . $!); - return 0; - } - if (!($session->test_directory($dummy_gpghome) || $session->mkdir($dummy_gpghome, { MODE => "00700"}))) { - $self->log_warning('Could not create build-depends dummy gpg home dir ' . $dummy_gpghome . ': ' . $!); - return 0; - } - if (!$session->chown($dummy_gpghome, $self->get_conf('BUILD_USER'), 'sbuild')) { - $self->log_error('Failed to set ' . $self->get_conf('BUILD_USER') . - ':sbuild ownership on $dummy_gpghome\n'); - return 0; - } - if (!($session->test_directory($dummy_archive_dir) || $session->mkdir($dummy_archive_dir, { MODE => "00775"}))) { - $self->log_warning('Could not create build-depends dummy archive dir ' . $dummy_archive_dir . ': ' . $!); - return 0; - } - - my $dummy_pkg_dir = $dummy_dir . '/' . $dummy_pkg_name; - my $dummy_deb = $dummy_archive_dir . '/' . $dummy_pkg_name . '.deb'; - my $dummy_dsc = $dummy_archive_dir . '/' . $dummy_pkg_name . '.dsc'; - - if (!($session->mkdir("$dummy_pkg_dir", { MODE => "00775"}))) { - $self->log_warning('Could not create build-depends dummy dir ' . $dummy_pkg_dir . $!); - return 0; - } - - if (!($session->mkdir("$dummy_pkg_dir/DEBIAN", { MODE => "00775"}))) { - $self->log_warning('Could not create build-depends dummy dir ' . $dummy_pkg_dir . '/DEBIAN: ' . $!); - return 0; - } - - my $DUMMY_CONTROL = $session->get_write_file_handle("$dummy_pkg_dir/DEBIAN/control"); - if (!$DUMMY_CONTROL) { - $self->log_warning('Could not open ' . $dummy_pkg_dir . '/DEBIAN/control for writing: ' . $!); - return 0; - } - - my $arch = $self->get('Host Arch'); - print $DUMMY_CONTROL <<"EOF"; -Package: $dummy_pkg_name -Version: 0.invalid.0 -Architecture: $arch -EOF - - my @positive; - my @negative; - my @positive_arch; - my @negative_arch; - my @positive_indep; - my @negative_indep; - - for my $pkg (@pkgs) { - my $deps = $self->get('AptDependencies')->{$pkg}; - - push(@positive, $deps->{'Build Depends'}) - if (defined($deps->{'Build Depends'}) && - $deps->{'Build Depends'} ne ""); - push(@negative, $deps->{'Build Conflicts'}) - if (defined($deps->{'Build Conflicts'}) && - $deps->{'Build Conflicts'} ne ""); - if ($self->get_conf('BUILD_ARCH_ANY')) { - push(@positive_arch, $deps->{'Build Depends Arch'}) - if (defined($deps->{'Build Depends Arch'}) && - $deps->{'Build Depends Arch'} ne ""); - push(@negative_arch, $deps->{'Build Conflicts Arch'}) - if (defined($deps->{'Build Conflicts Arch'}) && - $deps->{'Build Conflicts Arch'} ne ""); - } - if ($self->get_conf('BUILD_ARCH_ALL')) { - push(@positive_indep, $deps->{'Build Depends Indep'}) - if (defined($deps->{'Build Depends Indep'}) && - $deps->{'Build Depends Indep'} ne ""); - push(@negative_indep, $deps->{'Build Conflicts Indep'}) - if (defined($deps->{'Build Conflicts Indep'}) && - $deps->{'Build Conflicts Indep'} ne ""); - } - } - - my $positive_build_deps = join(", ", @positive, - @positive_arch, @positive_indep); - my $positive = deps_parse($positive_build_deps, - reduce_arch => 1, - host_arch => $self->get('Host Arch'), - build_arch => $self->get('Build Arch'), - build_dep => 1, - reduce_profiles => 1, - build_profiles => [ split / /, $self->get('Build Profiles') ]); - if( !defined $positive ) { - my $msg = "Error! deps_parse() couldn't parse the positive Build-Depends '$positive_build_deps'"; - $self->log_error("$msg\n"); - return 0; - } - - my $negative_build_deps = join(", ", @negative, - @negative_arch, @negative_indep); - my $negative = deps_parse($negative_build_deps, - reduce_arch => 1, - host_arch => $self->get('Host Arch'), - build_arch => $self->get('Build Arch'), - build_dep => 1, - union => 1, - reduce_profiles => 1, - build_profiles => [ split / /, $self->get('Build Profiles') ]); - if( !defined $negative ) { - my $msg = "Error! deps_parse() couldn't parse the negative Build-Depends '$negative_build_deps'"; - $self->log_error("$msg\n"); - return 0; - } - - - # sbuild turns build dependencies into the dependencies of a dummy binary - # package. Since binary package dependencies do not support :native the - # architecture qualifier, these have to either be removed during native - # compilation or replaced by the build (native) architecture during cross - # building - my $handle_native_archqual = sub { - my ($dep) = @_; - if ($dep->{archqual} && $dep->{archqual} eq "native") { - if ($self->get('Host Arch') eq $self->get('Build Arch')) { - $dep->{archqual} = undef; - } else { - $dep->{archqual} = $self->get('Build Arch'); - } - } - return 1; - }; - deps_iterate($positive, $handle_native_archqual); - deps_iterate($negative, $handle_native_archqual); - - $self->log("Merged Build-Depends: $positive\n") if $positive; - $self->log("Merged Build-Conflicts: $negative\n") if $negative; - - # Filter out all but the first alternative except in special - # cases. - if (!$self->get_conf('RESOLVE_ALTERNATIVES')) { - my $positive_filtered = Dpkg::Deps::AND->new(); - foreach my $item ($positive->get_deps()) { - my $alt_filtered = Dpkg::Deps::OR->new(); - my @alternatives = $item->get_deps(); - my $first = shift @alternatives; - $alt_filtered->add($first) if defined $first; - # Allow foo (rel x) | foo (rel y) as the only acceptable - # form of alternative. i.e. where the package is the - # same, but different relations are needed, since these - # are effectively a single logical dependency. - foreach my $alt (@alternatives) { - if ($first->{'package'} eq $alt->{'package'}) { - $alt_filtered->add($alt); - } else { - last; - } - } - $positive_filtered->add($alt_filtered); - } - $positive = $positive_filtered; - } - - if ($positive ne "") { - print $DUMMY_CONTROL 'Depends: ' . $positive . "\n"; - } - if ($negative ne "") { - print $DUMMY_CONTROL 'Conflicts: ' . $negative . "\n"; - } - - $self->log("Filtered Build-Depends: $positive\n") if $positive; - $self->log("Filtered Build-Conflicts: $negative\n") if $negative; - - print $DUMMY_CONTROL <<"EOF"; -Maintainer: Debian buildd-tools Developers -Description: Dummy package to satisfy dependencies with apt - created by sbuild - This package was created automatically by sbuild and should never appear on - a real system. You can safely remove it. -EOF - close ($DUMMY_CONTROL); - - foreach my $path ($dummy_pkg_dir . '/DEBIAN/control', - $dummy_pkg_dir . '/DEBIAN', - $dummy_pkg_dir, - $dummy_archive_dir) { - if (!$session->chown($path, $self->get_conf('BUILD_USER'), 'sbuild')) { - $self->log_error("Failed to set " . $self->get_conf('BUILD_USER') - . ":sbuild ownership on $path\n"); - return 0; - } - } - - #Now build the package: - $session->run_command( - { COMMAND => ['dpkg-deb', '--build', $dummy_pkg_dir, $dummy_deb], - USER => $self->get_conf('BUILD_USER'), - PRIORITY => 0}); - if ($?) { - $self->log("Dummy package creation failed\n"); - return 0; - } - - # Write the dummy dsc file. - my $dummy_dsc_fh = $session->get_write_file_handle($dummy_dsc); - if (!$dummy_dsc_fh) { - $self->log_warning('Could not open ' . $dummy_dsc . ' for writing: ' . $!); - return 0; - } - - print $dummy_dsc_fh <<"EOF"; -Format: 1.0 -Source: $dummy_pkg_name -Binary: $dummy_pkg_name -Architecture: any -Version: 0.invalid.0 -Maintainer: Debian buildd-tools Developers -EOF - if (scalar(@positive)) { - print $dummy_dsc_fh 'Build-Depends: ' . join(", ", @positive) . "\n"; - } - if (scalar(@negative)) { - print $dummy_dsc_fh 'Build-Conflicts: ' . join(", ", @negative) . "\n"; - } - if (scalar(@positive_arch)) { - print $dummy_dsc_fh 'Build-Depends-Arch: ' . join(", ", @positive_arch) . "\n"; - } - if (scalar(@negative_arch)) { - print $dummy_dsc_fh 'Build-Conflicts-Arch: ' . join(", ", @negative_arch) . "\n"; - } - if (scalar(@positive_indep)) { - print $dummy_dsc_fh 'Build-Depends-Indep: ' . join(", ", @positive_indep) . "\n"; - } - if (scalar(@negative_indep)) { - print $dummy_dsc_fh 'Build-Conflicts-Indep: ' . join(", ", @negative_indep) . "\n"; - } - print $dummy_dsc_fh "\n"; - close $dummy_dsc_fh; - - # Do code to run apt-ftparchive - if (!$self->run_apt_ftparchive($self->get('Dummy archive directory'))) { - $self->log("Failed to run apt-ftparchive.\n"); - return 0; - } - - # Write a list file for the dummy archive if one not create yet. - if (!$session->test_regular_file($dummy_archive_list_file)) { - my $tmpfilename = $session->mktemp(); - - if (!$tmpfilename) { - $self->log_error("Can't create tempfile\n"); - return 0; - } - - my $tmpfh = $session->get_write_file_handle($tmpfilename); - if (!$tmpfh) { - $self->log_error("Cannot open pipe: $!\n"); - return 0; - } - - # We always trust the dummy apt repositories by setting trusted=yes. - # - # We use copy:// instead of file:// as URI because the latter will make - # apt use symlinks in /var/lib/apt/lists. These symlinks will become - # broken after the dummy archive is removed. This in turn confuses - # launchpad-buildd which directly tries to access - # /var/lib/apt/lists/*_Packages and cannot use `apt-get indextargets` as - # that apt feature is too new for it. - print $tmpfh 'deb [trusted=yes] copy://' . $dummy_archive_dir . " ./\n"; - print $tmpfh 'deb-src [trusted=yes] copy://' . $dummy_archive_dir . " ./\n"; - - close($tmpfh); - # List file needs to be moved with root. - if (!$session->chmod($tmpfilename, '0644')) { - $self->log("Failed to create apt list file for dummy archive.\n"); - $session->unlink($tmpfilename); - return 0; - } - if (!$session->rename($tmpfilename, $dummy_archive_list_file)) { - $self->log("Failed to create apt list file for dummy archive.\n"); - $session->unlink($tmpfilename); - return 0; - } - } - - return 1; -} - -# Remove the apt archive. -sub cleanup_apt_archive { - my $self = shift; - - my $session = $self->get('Session'); - - if (defined $self->get('Dummy package path')) { - $session->unlink($self->get('Dummy package path'), { RECURSIVE => 1, FORCE => 1 }); - } - - if (defined $self->get('Extra packages path')) { - $session->unlink($self->get('Extra packages path'), { RECURSIVE => 1, FORCE => 1 }); - } - - $session->unlink($self->get('Dummy archive list file'), { FORCE => 1 }); - - $session->unlink($self->get('Extra repositories archive list file'), { FORCE => 1 }); - - $session->unlink($self->get('Extra packages archive list file'), { FORCE => 1 }); - - $self->set('Extra packages path', undef); - $self->set('Extra packages archive directory', undef); - $self->set('Extra packages release file', undef); - $self->set('Dummy archive directory', undef); - $self->set('Dummy Release file', undef); -} - -# Function that runs apt-ftparchive -sub run_apt_ftparchive { - my $self = shift; - my $dummy_archive_dir = shift; - - my $session = $self->get('Session'); - - # We create the Packages, Sources and Release file inside the chroot. - # We cannot use IO::Compress::Gzip, Digest::MD5, or Digest::SHA because - # they are not available inside a chroot with only Essential:yes and apt - # installed. - # We cannot use apt-ftparchive as this is not available inside the chroot. - # Apt-ftparchive outside the chroot might not have access to the files - # inside the chroot (for example when using qemu or ssh backends). - # The only alternative would've been to set up the archive outside the - # chroot using apt-ftparchive and to then copy Packages, Sources and - # Release into the chroot. - # We do not do this to avoid copying files from and to the chroot. - # At the same time doing it like this has the advantage to have less - # dependencies of sbuild itself (no apt-ftparchive needed). - # The disadvantage of doing it this way is that we now have to maintain - # our own code creating the Release file which might break in the future. - my $packagessourcescmd = <<'SCRIPTEND'; -use strict; -use warnings; - -use POSIX qw(strftime); -use POSIX qw(locale_h); - -# Execute a command without /bin/sh but plain execvp while redirecting its -# standard output to a file given as the first argument. -# Using "print $fh `my_command`" has the disadvantage that "my_command" might -# be executed through /bin/sh (depending on the characters used) or that the -# output of "my_command" is very long. - -sub hash_file($$) -{ - my ($filename, $util) = @_; - my $output = `$util $filename`; - my ($hash, undef) = split /\s+/, $output; - return $hash; -} - -{ - opendir(my $dh, '.') or die "Can't opendir('.'): $!"; - open my $out, '>', 'Packages'; - while (my $entry = readdir $dh) { - next if $entry !~ /\.deb$/; - open my $in, '-|', 'dpkg-deb', '-I', $entry, 'control' or die "cannot fork dpkg-deb"; - while (my $line = <$in>) { - print $out $line; - } - close $in; - my $size = -s $entry; - my $md5 = hash_file($entry, 'md5sum'); - my $sha1 = hash_file($entry, 'sha1sum'); - my $sha256 = hash_file($entry, 'sha256sum'); - print $out "Size: $size\n"; - print $out "MD5sum: $md5\n"; - print $out "SHA1: $sha1\n"; - print $out "SHA256: $sha256\n"; - print $out "Filename: ./$entry\n"; - print $out "\n"; - } - close $out; - closedir($dh); -} -{ - opendir(my $dh, '.') or die "Can't opendir('.'): $!"; - open my $out, '>', 'Sources'; - while (my $entry = readdir $dh) { - next if $entry !~ /\.dsc$/; - my $size = -s $entry; - my $md5 = hash_file($entry, 'md5sum'); - my $sha1 = hash_file($entry, 'sha1sum'); - my $sha256 = hash_file($entry, 'sha256sum'); - my ($sha1_printed, $sha256_printed, $files_printed) = (0, 0, 0); - open my $in, '<', $entry or die "cannot open $entry"; - while (my $line = <$in>) { - next if $line eq "\n"; - $line =~ s/^Source:/Package:/; - print $out $line; - if ($line eq "Checksums-Sha1:\n") { - print $out " $sha1 $size $entry\n"; - $sha1_printed = 1; - } elsif ($line eq "Checksums-Sha256:\n") { - print $out " $sha256 $size $entry\n"; - $sha256_printed = 1; - } elsif ($line eq "Files:\n") { - print $out " $md5 $size $entry\n"; - $files_printed = 1; - } - } - close $in; - if ($sha1_printed == 0) { - print $out "Checksums-Sha1:\n"; - print $out " $sha1 $size $entry\n"; - } - if ($sha256_printed == 0) { - print $out "Checksums-Sha256:\n"; - print $out " $sha256 $size $entry\n"; - } - if ($files_printed == 0) { - print $out "Files:\n"; - print $out " $md5 $size $entry\n"; - } - print $out "Directory: .\n"; - print $out "\n"; - } - close $out; - closedir($dh); -} - -system('gzip -c --force Packages > Packages.gz') == 0 or die "gzip failed: $?\n"; -system('gzip -c --force Sources > Sources.gz' ) == 0 or die "gzip failed: $?\n"; - -my $packages_md5 = hash_file('Packages', 'md5sum'); -my $sources_md5 = hash_file('Sources', 'md5sum'); -my $packagesgz_md5 = hash_file('Packages.gz', 'md5sum'); -my $sourcesgz_md5 = hash_file('Sources.gz', 'md5sum'); - -my $packages_sha1 = hash_file('Packages', 'sha1sum'); -my $sources_sha1 = hash_file('Sources', 'sha1sum'); -my $packagesgz_sha1 = hash_file('Packages.gz', 'sha1sum'); -my $sourcesgz_sha1 = hash_file('Sources.gz', 'sha1sum'); - -my $packages_sha256 = hash_file('Packages', 'sha256sum'); -my $sources_sha256 = hash_file('Sources', 'sha256sum'); -my $packagesgz_sha256 = hash_file('Packages.gz', 'sha256sum'); -my $sourcesgz_sha256 = hash_file('Sources.gz', 'sha256sum'); - -my $packages_size = -s 'Packages'; -my $sources_size = -s 'Sources'; -my $packagesgz_size = -s 'Packages.gz'; -my $sourcesgz_size = -s 'Sources.gz'; - -# The timestamp format of release files is documented here: -# https://wiki.debian.org/RepositoryFormat#Date.2CValid-Until -# It is specified to be the same format as described in Debian Policy §4.4 -# https://www.debian.org/doc/debian-policy/ch-source.html#s-dpkgchangelog -# or the same as in debian/changelog or the Date field in .changes files. -# or the same format as `date -R` -# To adhere to the specified format, the C or C.UTF-8 locale must be used. -my $old_locale = setlocale(LC_TIME); -setlocale(LC_TIME, "C.UTF-8"); -my $datestring = strftime "%a, %d %b %Y %H:%M:%S +0000", gmtime(); -setlocale(LC_TIME, $old_locale); - -open(my $releasefh, '>', 'Release') or die "cannot open Release for writing: $!"; - -print $releasefh <<"END"; -Codename: invalid -Date: $datestring -Description: Sbuild Build Dependency Temporary Archive -Label: sbuild-build-depends-archive -Origin: sbuild-build-depends-archive -Suite: invalid -MD5Sum: - $packages_md5 $packages_size Packages - $sources_md5 $sources_size Sources - $packagesgz_md5 $packagesgz_size Packages.gz - $sourcesgz_md5 $sourcesgz_size Sources.gz -SHA1: - $packages_sha1 $packages_size Packages - $sources_sha1 $sources_size Sources - $packagesgz_sha1 $packagesgz_size Packages.gz - $sourcesgz_sha1 $sourcesgz_size Sources.gz -SHA256: - $packages_sha256 $packages_size Packages - $sources_sha256 $sources_size Sources - $packagesgz_sha256 $packagesgz_size Packages.gz - $sourcesgz_sha256 $sourcesgz_size Sources.gz -END - -close $releasefh; - -SCRIPTEND - - # Instead of using $(perl -e) and passing $packagessourcescmd as a command - # line argument, feed perl from standard input because otherwise the - # command line will be too long for certain backends (like the autopkgtest - # qemu backend). - my $pipe = $session->pipe_command( - { COMMAND => ['perl'], - USER => "root", - DIR => $dummy_archive_dir, - PIPE => 'out', - }); - if (!$pipe) { - $self->log_error("cannot open pipe\n"); - return 0; - } - print $pipe $packagessourcescmd; - close $pipe; - if ($? ne 0) { - $self->log_error("cannot create dummy archive\n"); - return 0; - } - - return 1; -} - -sub get_apt_command_internal { - my $self = shift; - my $options = shift; - - my $command = $options->{'COMMAND'}; - my $apt_options = $self->get('APT Options'); - - debug2("APT Options: ", join(" ", @$apt_options), "\n") - if defined($apt_options); - - my @aptcommand = (); - if (defined($apt_options)) { - push(@aptcommand, @{$command}[0]); - push(@aptcommand, @$apt_options); - if ($#$command > 0) { - push(@aptcommand, @{$command}[1 .. $#$command]); - } - } else { - @aptcommand = @$command; - } - - debug2("APT Command: ", join(" ", @aptcommand), "\n"); - - $options->{'INTCOMMAND'} = \@aptcommand; -} - -sub run_apt_command { - my $self = shift; - my $options = shift; - - my $session = $self->get('Session'); - my $host = $self->get('Host'); - - # Set modfied command - $self->get_apt_command_internal($options); - - if ($self->get('Split')) { - return $host->run_command_internal($options); - } else { - return $session->run_command_internal($options); - } -} - -sub pipe_apt_command { - my $self = shift; - my $options = shift; - - my $session = $self->get('Session'); - my $host = $self->get('Host'); - - # Set modfied command - $self->get_apt_command_internal($options); - - if ($self->get('Split')) { - return $host->pipe_command_internal($options); - } else { - return $session->pipe_command_internal($options); - } -} - -sub pipe_xapt_command { - my $self = shift; - my $options = shift; - - my $session = $self->get('Session'); - my $host = $self->get('Host'); - - # Set modfied command - $self->get_apt_command_internal($options); - - if ($self->get('Split')) { - return $host->pipe_command_internal($options); - } else { - return $session->pipe_command_internal($options); - } -} - -sub get_aptitude_command_internal { - my $self = shift; - my $options = shift; - - my $command = $options->{'COMMAND'}; - my $apt_options = $self->get('Aptitude Options'); - - debug2("Aptitude Options: ", join(" ", @$apt_options), "\n") - if defined($apt_options); - - my @aptcommand = (); - if (defined($apt_options)) { - push(@aptcommand, @{$command}[0]); - push(@aptcommand, @$apt_options); - if ($#$command > 0) { - push(@aptcommand, @{$command}[1 .. $#$command]); - } - } else { - @aptcommand = @$command; - } - - debug2("APT Command: ", join(" ", @aptcommand), "\n"); - - $options->{'INTCOMMAND'} = \@aptcommand; -} - -sub run_aptitude_command { - my $self = shift; - my $options = shift; - - my $session = $self->get('Session'); - my $host = $self->get('Host'); - - # Set modfied command - $self->get_aptitude_command_internal($options); - - if ($self->get('Split')) { - return $host->run_command_internal($options); - } else { - return $session->run_command_internal($options); - } -} - -sub pipe_aptitude_command { - my $self = shift; - my $options = shift; - - my $session = $self->get('Session'); - my $host = $self->get('Host'); - - # Set modfied command - $self->get_aptitude_command_internal($options); - - if ($self->get('Split')) { - return $host->pipe_command_internal($options); - } else { - return $session->pipe_command_internal($options); - } -} - -sub get_sbuild_dummy_pkg_name { - my $self = shift; - my $name = shift; - - return 'sbuild-build-depends-' . $name. '-dummy'; -} - -1; diff -Nru sbuild-0.80.0ubuntu1/.pc/.quilt_patches sbuild-0.81.2ubuntu5/.pc/.quilt_patches --- sbuild-0.80.0ubuntu1/.pc/.quilt_patches 2020-08-04 14:28:23.000000000 +0000 +++ sbuild-0.81.2ubuntu5/.pc/.quilt_patches 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -debian/patches diff -Nru sbuild-0.80.0ubuntu1/.pc/.quilt_series sbuild-0.81.2ubuntu5/.pc/.quilt_series --- sbuild-0.80.0ubuntu1/.pc/.quilt_series 2020-08-04 14:28:23.000000000 +0000 +++ sbuild-0.81.2ubuntu5/.pc/.quilt_series 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -series diff -Nru sbuild-0.80.0ubuntu1/.pc/.version sbuild-0.81.2ubuntu5/.pc/.version --- sbuild-0.80.0ubuntu1/.pc/.version 2020-08-04 14:28:23.000000000 +0000 +++ sbuild-0.81.2ubuntu5/.pc/.version 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -2 diff -Nru sbuild-0.80.0ubuntu1/VERSION sbuild-0.81.2ubuntu5/VERSION --- sbuild-0.80.0ubuntu1/VERSION 2020-08-01 12:07:53.000000000 +0000 +++ sbuild-0.81.2ubuntu5/VERSION 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -Package: sbuild -Version: 0.79.1 -Release-Date: 22 April 2020