diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 15:21:59 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 15:21:59 +0000 |
commit | 59010db2e74061a361a54ba7d3a7e0710e01ee46 (patch) | |
tree | d91ba2aceedf86ec13e6030dc582f074676bb171 /debian/tests | |
parent | Adding upstream version 1.0.128+nmu2+deb12u1. (diff) | |
download | debootstrap-59010db2e74061a361a54ba7d3a7e0710e01ee46.tar.xz debootstrap-59010db2e74061a361a54ba7d3a7e0710e01ee46.zip |
Adding debian version 1.0.128+nmu2+deb12u1.debian/1.0.128+nmu2+deb12u1debian
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'debian/tests')
-rw-r--r-- | debian/tests/control | 19 | ||||
-rwxr-xr-x | debian/tests/debian-testing | 325 | ||||
-rwxr-xr-x | debian/tests/fake/pbuilder-0.228.4-1 | 31 | ||||
-rwxr-xr-x | debian/tests/fake/pbuilder-proposed | 54 | ||||
-rwxr-xr-x | debian/tests/fake/schroot-1.6.10-3 | 47 | ||||
-rwxr-xr-x | debian/tests/fake/schroot-proposed | 68 | ||||
-rw-r--r-- | debian/tests/mitm.py | 92 | ||||
-rwxr-xr-x | debian/tests/unsorted-packages-files | 33 |
8 files changed, 669 insertions, 0 deletions
diff --git a/debian/tests/control b/debian/tests/control new file mode 100644 index 0000000..6ad74e1 --- /dev/null +++ b/debian/tests/control @@ -0,0 +1,19 @@ +Tests: debian-testing +Depends: + debootstrap, + libdistro-info-perl, + libdpkg-perl, + libipc-run-perl, + perl, + systemd [linux-any], + systemd-container [linux-any], + ca-certificates, +Restrictions: allow-stderr, needs-root + +Tests: unsorted-packages-files +Depends: + debootstrap, + python3-debian, + python3-flask, + python3-requests, +Restrictions: allow-stderr diff --git a/debian/tests/debian-testing b/debian/tests/debian-testing new file mode 100755 index 0000000..89703cb --- /dev/null +++ b/debian/tests/debian-testing @@ -0,0 +1,325 @@ +#!/usr/bin/perl +# Verify that debootstrap'ing Debian testing produces a usable chroot, +# and in particular that using it with early 2017 versions of schroot and +# pbuilder results in working pseudo-terminals (#817236) +# +# Copyright © 2017 Simon McVittie +# SPDX-License-Identifier: MIT +# (see debian/copyright) + +use strict; +use warnings; + +use Cwd qw(getcwd); +use Debian::DistroInfo; +use Dpkg::Version; +use IPC::Run qw(run); +use Test::More; + +my $srcdir = getcwd; + +sub verbose_run { + my $argv = shift; + diag("Running: @{$argv}"); + return run($argv, @_); +} + +sub capture { + my $output; + my $argv = shift; + ok(verbose_run($argv, '>', \$output), "@{$argv}"); + chomp $output; + return $output; +} + +my $check_non_docker_env; +if (run([qw(grep docker.*cgroup /proc/1/mountinfo)], '&>', '/dev/null')) { + diag("it seems docker environment"); + $check_non_docker_env = 0; +} +else { + diag("okay, it's not docker environment"); + $check_non_docker_env = 1; +} + +my @maybe_unshare_mount_ns; + +if (verbose_run(['unshare', '-m', 'true'])) { + diag('can unshare mount namespace'); + @maybe_unshare_mount_ns = ('unshare', '-m'); +} +else { + diag('cannot unshare mount namespace, are we in a container?'); +} + +sub check_fake_schroot { + my %params = @_; + my $reference = $params{reference}; + my $version = $params{version} || '1.6.10-3'; + my $extra_argv = $params{extra_argv} || []; + + # Use unshare -m to make sure the /dev mount gets cleaned up on exit, even + # on failures + my $response = capture([@maybe_unshare_mount_ns, + "$srcdir/debian/tests/fake/schroot-$version", @{$extra_argv}, + $params{chroot}, + qw(runuser -u nobody --), + qw(script -q -c), 'cat /etc/debian_version', '/dev/null']); + $response =~ s/\r//g; + is($response, $reference, 'script(1) should work under (fake) schroot'); +} + +sub check_fake_pbuilder { + my %params = @_; + my $reference = $params{reference}; + my $version = $params{version} || '0.228.4-1'; + + my $response = capture([@maybe_unshare_mount_ns, + "$srcdir/debian/tests/fake/pbuilder-$version", $params{chroot}, + qw(runuser -u nobody --), + qw(script -q -c), 'cat /etc/debian_version', '/dev/null']); + $response =~ s/\r//g; + is($response, $reference, + 'script(1) should work under (fake) pbuilder'); +} + +sub check_chroot { + my %params = @_; + my $chroot = $params{chroot}; + my $response; + + ok(-f "$chroot/etc/debian_version", + 'chroot should have /etc/debian_version'); + ok(-x "$chroot/usr/bin/env", + 'chroot should have /usr/bin/env which is Essential'); + ok(-x "$chroot/usr/bin/hello", 'chroot should have /usr/bin/hello due to --include'); + ok(-d "$chroot/usr/share/doc", 'chroot should have /usr/share/doc'); + + ok(-c "$chroot/dev/full", '/dev/full should be a character device'); + is(capture(['/usr/bin/stat', '--printf=%t %T %a', "$chroot/dev/full"]), + '1 7 666', '/dev/full should be device 1,7 with 0666 permissions'); + ok(-c "$chroot/dev/null"); + is(capture(['/usr/bin/stat', '--printf=%t %T %a', "$chroot/dev/null"]), + '1 3 666', '/dev/null should be device 1,3 with 0666 permissions'); + + my $did_mknod_ptmx; + + if (-l "$chroot/dev/ptmx") { + # Necessary if debootstrap is run inside some containers, see + # https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=817236#77 + diag("/dev/ptmx is a symbolic link"); + like(readlink("$chroot/dev/ptmx"), qr{(?:/dev/)?pts/ptmx}, + 'if /dev/ptmx is a symlink it should be to /dev/pts/ptmx'); + $did_mknod_ptmx = 0; + } + else { + diag("/dev/ptmx is not a symbolic link"); + ok(-c "$chroot/dev/ptmx", + 'if /dev/pts is not a symlink it should be a character device'); + is(capture(['/usr/bin/stat', '--printf=%t %T %a', + "$chroot/dev/ptmx"]), '5 2 666', + 'if /dev/pts is a device node it should be 5,2 with 0666 permissions'); + $did_mknod_ptmx = 1; + } + + if ($params{can_mknod_ptmx}) { + ok($did_mknod_ptmx, 'able to mknod ptmx so should have done so'); + } + + my $reference = capture(['cat', "$chroot/etc/debian_version"]); + + is(capture([qw(chroot chroot.d runuser -u nobody -- + cat /etc/debian_version)]), + $reference); + + # The schroot behaviour proposed to fix #856877 and #983423 works, + # even inside (privileged) lxc. + check_fake_schroot(%params, reference => $reference, version => 'proposed'); + check_fake_schroot(%params, reference => $reference, version => 'proposed', + extra_argv => ['--sbuild']); + + # As of 1.6.10-3, or equivalently 1.6.10-11, the default profile + # certainly doesn't work in lxc >= 3 or in Docker: + # https://bugs.debian.org/983423 + # It probably won't work in other container managers either, for + # similar reasons. + if (defined $params{container}) { + TODO: { + local $TODO = "schroot default profile doesn't work in lxc >= 3 or Docker"; + check_fake_schroot(%params, reference => $reference, + version => '1.6.10-3'); + } + } + else { + check_fake_schroot(%params, reference => $reference, + version => '1.6.10-3'); + } + + # schroot 1.6.10-3's sbuild profile does work in lxc, but only on newer + # kernels: https://bugs.debian.org/856877 + if (Dpkg::Version->new($params{kernel}) < Dpkg::Version->new('4.7') && + defined $params{container} && $params{container} eq 'lxc') { + TODO: { + local $TODO = "schroot --sbuild doesn't work in lxc on older ". + "kernels"; + check_fake_schroot(%params, reference => $reference, + extra_argv => ['--sbuild']); + } + } + elsif (! $params{can_mknod_ptmx}) { + TODO: { + local $TODO = "schroot --sbuild doesn't work when /dev/ptmx is ". + "a symlink to /dev/pts/ptmx"; + check_fake_schroot(%params, reference => $reference, + extra_argv => ['--sbuild']); + } + } + else { + check_fake_schroot(%params, reference => $reference, + extra_argv => ['--sbuild']); + } + + # pbuilder >= 0.228.6 works fine + check_fake_pbuilder(%params, reference => $reference, + version => 'proposed'); + + # Older pbuilder doesn't work if we are in a container where we can't + # create the /dev/ptmx device node: https://bugs.debian.org/841935 + if (! $params{can_mknod_ptmx}) { + TODO: { + local $TODO = "schroot --sbuild doesn't work when /dev/ptmx is ". + "a symlink to /dev/pts/ptmx"; + check_fake_pbuilder(%params, reference => $reference); + } + } + else { + check_fake_pbuilder(%params, reference => $reference); + } +} + +# Specify https mirror to check https mirror specific problem +# https://bugs.debian.org/896071 +my $mirror = 'https://deb.debian.org/debian'; +my $tmp = $ENV{AUTOPKGTEST_TMP} || $ENV{AUTOPKGTEST_TMP}; +die "no autopkgtest temporary directory specified" unless $tmp; +chdir $tmp or die "chdir $tmp: $!"; + +$ENV{LC_ALL} = 'C.UTF-8'; + +# Try to inherit a Debian mirror from the host +foreach my $file ('/etc/apt/sources.list', + glob('/etc/apt/sources.list.d/*.list')) { + open(my $fh, '<', $file); + while (<$fh>) { + if (m{^deb\s+(http://[-a-zA-Z0-9.:]+/debian)\s}) { + $mirror = $1; + last; + } + } + close $fh; +} + +if (run(['ischroot'], '>&2')) { + diag("In a chroot according to ischroot(1)"); +} +else { + diag("Not in a chroot according to ischroot(1)"); +} + +my $virtualization; +if ($^O ne 'linux') { + diag("Cannot use systemd-detect-virt on non-Linux"); +} +elsif (run(['systemd-detect-virt', '--vm'], '>', \$virtualization)) { + chomp $virtualization; + diag("Virtualization: $virtualization"); +} +else { + $virtualization = undef; + diag("Virtualization: (not in a virtual machine)"); +} + +my $in_container = 0; +my $container; +if ($^O ne 'linux') { + diag("Cannot use systemd-detect-virt on non-Linux"); +} +elsif (run(['systemd-detect-virt', '--container'], '>', \$container)) { + $in_container = 1; + chomp $container; + diag("Container: $container"); +} +else { + $container = undef; + diag("Container: (not in a container)"); +} + +my $kernel = capture([qw(uname -r)]); +chomp $kernel; + +open(my $fh, '<', '/proc/self/mountinfo'); +while (<$fh>) { + chomp; + diag("mountinfo: $_"); +} +close $fh; + +my $can_mknod_ptmx; +if (run([qw(mknod -m000 ptmx c 5 2)], '&>', '/dev/null')) { + diag("mknod ptmx succeeded"); + $can_mknod_ptmx = 1; +} +else { + diag("mknod ptmx failed, are we in a container?"); + $can_mknod_ptmx = 0; +} + +my $distro_info = DebianDistroInfo->new; +my $testing = $distro_info->testing; + +# Should specify multiple components for checking (see Bug#898738) +if (!verbose_run(['debootstrap', + '--include=debootstrap,debian-archive-keyring,gnupg,hello', + '--variant=minbase', + '--components=main,contrib,non-free', + $testing, 'chroot.d', $mirror], '>&2')) { + BAIL_OUT("debootstrap failed: $?"); +} + +if ($check_non_docker_env) { + check_chroot(chroot => 'chroot.d', can_mknod_ptmx => $can_mknod_ptmx, + kernel => $kernel, container => $container); +} + +if ($^O ne 'linux') { + diag("Cannot use systemd-nspawn on non-Linux"); +} +elsif ($in_container) { + diag('in a container according to systemd --container, not trying to '. + 'use systemd-nspawn'); +} +elsif (! -d '/run/systemd/system') { + diag('systemd not booted, not trying to use systemd-nspawn'); +} +else { + if (!verbose_run(['systemd-nspawn', '-D', 'chroot.d', + "--bind=$ENV{AUTOPKGTEST_TMP}:/mnt", + '--bind-ro=/usr/sbin/debootstrap', + '--bind-ro=/usr/share/debootstrap', + '--', + 'debootstrap', '--include=hello', '--variant=minbase', + $testing, '/mnt/from-nspawn.d', $mirror], '>&2')) { + BAIL_OUT("debootstrap wrapped in systemd-nspawn failed: $?"); + } + + check_chroot(chroot => "$ENV{AUTOPKGTEST_TMP}/from-nspawn.d", can_mknod_ptmx => 0, + kernel => $kernel, container => "nspawn"); +} + +if (!run([qw(rm -fr --one-file-system chroot.d)], '>&2')) { + BAIL_OUT('Unable to remove chroot.d'); +} + +done_testing; + +# vim:set sw=4 sts=4 et: diff --git a/debian/tests/fake/pbuilder-0.228.4-1 b/debian/tests/fake/pbuilder-0.228.4-1 new file mode 100755 index 0000000..308ed34 --- /dev/null +++ b/debian/tests/fake/pbuilder-0.228.4-1 @@ -0,0 +1,31 @@ +#!/bin/sh +# fake/pbuilder-0.228.4-1 -- emulate how pbuilder/0.228.4-1 would chroot. +# It mounts /dev/pts, without explicitly requesting a new instance or a +# usable /dev/pts/ptmx. +# (There is of course a lot more that it does, but these are the parts that +# affect pty users like script(1).) +# +# Copyright © 2017 Simon McVittie +# SPDX-License-Identifier: MIT +# (see debian/copyright) + +set -e + +chroot="$1" +shift +if test -z "$chroot" || test -z "$1"; then + echo "Usage: $0 CHROOT COMMAND...">&2 + exit 2 +fi + +mkdir -p "$chroot/dev/pts" +mount -t devpts none "$chroot/dev/pts" -onoexec,nosuid,gid=5,mode=620 + +ls -l "$chroot/dev/ptmx" | sed -e 's/^/# fake-pbuilder: /' >&2 +ls -l "$chroot/dev/pts/ptmx" | sed -e 's/^/# fake-pbuilder: /' >&2 + +e=0 +chroot "$chroot" "$@" || e=$? + +umount "$chroot/dev/pts" +exit "$e" diff --git a/debian/tests/fake/pbuilder-proposed b/debian/tests/fake/pbuilder-proposed new file mode 100755 index 0000000..8aeca63 --- /dev/null +++ b/debian/tests/fake/pbuilder-proposed @@ -0,0 +1,54 @@ +#!/bin/sh +# fake/pbuilder-proposed -- emulate how pbuilder is proposed to chroot in +# future. +# +# Copyright © 2017 Simon McVittie +# SPDX-License-Identifier: MIT +# (see debian/copyright) + +set -e + +BUILDPLACE="$1" +shift +if test -z "$BUILDPLACE" || test -z "$1"; then + echo "Usage: $0 CHROOT COMMAND...">&2 + exit 2 +fi + +devpts_options="noexec,nosuid,gid=5,mode=620" + +mkdir -p "$BUILDPLACE/dev/pts" +if ! mount -t devpts none "$BUILDPLACE/dev/pts" -o "$devpts_options,newinstance,ptmxmode=666"; then + mount -t devpts none "$BUILDPLACE/dev/pts" -o "$devpts_options" +fi + +mounted_ptmx=no + +if [ -e "$BUILDPLACE/dev/pts/ptmx" ] && \ + ! [ -L "$BUILDPLACE/dev/ptmx" ]; then + chmod 666 "$BUILDPLACE/dev/pts/ptmx" + mount --bind "$BUILDPLACE/dev/pts/ptmx" "$BUILDPLACE/dev/ptmx" + mounted_ptmx=yes +fi + +mounted_console=no + +if stdin_tty="$(tty)"; then + if [ ! -e "$BUILDPLACE/dev/console" ]; then + mknod -m700 "$BUILDPLACE/dev/console" c 5 1 + fi + + mount --bind "$stdin_tty" "$BUILDPLACE/dev/console" + mounted_console=yes +fi + +ls -l "$BUILDPLACE/dev/ptmx" | sed -e 's/^/# fake-pbuilder: /' >&2 +ls -l "$BUILDPLACE/dev/pts/ptmx" | sed -e 's/^/# fake-pbuilder: /' >&2 + +e=0 +chroot "$BUILDPLACE" "$@" || e=$? + +[ "$mounted_console" = no ] || umount "$BUILDPLACE/dev/console" +[ "$mounted_ptmx" = no ] || umount "$BUILDPLACE/dev/ptmx" +umount "$BUILDPLACE/dev/pts" +exit "$e" diff --git a/debian/tests/fake/schroot-1.6.10-3 b/debian/tests/fake/schroot-1.6.10-3 new file mode 100755 index 0000000..d6e0bbe --- /dev/null +++ b/debian/tests/fake/schroot-1.6.10-3 @@ -0,0 +1,47 @@ +#!/bin/sh +# fake/schroot-1.6.10-3 -- emulate how schroot/1.6.10-3 would chroot. +# It bind-mounts /dev/pts and maybe /dev from the host system. +# (There is of course a lot more that it does, but these are the parts that +# affect pty users like script(1).) +# +# Copyright © 2017 Simon McVittie +# SPDX-License-Identifier: MIT +# (see debian/copyright) + +set -e + +# /etc/schroot/default/fstab +bind_dev=yes + +while true; do + case "$1" in + (--sbuild) + shift + # /etc/schroot/sbuild/fstab + bind_dev=no + ;; + (*) + break + esac +done + +chroot="$1" +shift +if test -z "$chroot" || test -z "$1"; then + echo "Usage: $0 CHROOT COMMAND...">&2 + exit 2 +fi + +[ "$bind_dev" = no ] || mount --bind /dev "$chroot/dev" +mount --bind /dev/pts "$chroot/dev/pts" + +ls -l "$chroot/dev/ptmx" | sed -e 's/^/# fake-schroot: /' >&2 +ls -l "$chroot/dev/pts/ptmx" | sed -e 's/^/# fake-schroot: /' >&2 + +e=0 +chroot "$chroot" "$@" || e=$? + +umount "$chroot/dev/pts" +[ "$bind_dev" = no ] || umount "$chroot/dev" + +exit "$e" diff --git a/debian/tests/fake/schroot-proposed b/debian/tests/fake/schroot-proposed new file mode 100755 index 0000000..b15e741 --- /dev/null +++ b/debian/tests/fake/schroot-proposed @@ -0,0 +1,68 @@ +#!/bin/sh +# fake/schroot-proposed -- emulate proposed mount behaviour for schroot +# +# Copyright © 2017 Simon McVittie +# SPDX-License-Identifier: MIT +# (see debian/copyright) + +set -e + +# /etc/schroot/default/fstab +bind_dev=yes + +while true; do + case "$1" in + (--sbuild) + shift + # /etc/schroot/sbuild/fstab + bind_dev=no + ;; + (*) + break + esac +done + +CHROOT_PATH="$1" +shift +if test -z "$CHROOT_PATH" || test -z "$1"; then + echo "Usage: $0 CHROOT COMMAND...">&2 + exit 2 +fi + +[ "$bind_dev" = no ] || mount --bind /dev "$CHROOT_PATH/dev" +mount -t devpts -o rw,newinstance,ptmxmode=666,mode=620,gid=5 /dev/pts "$CHROOT_PATH/dev/pts" + +ls -l "$CHROOT_PATH/dev/ptmx" | sed -e 's/^/# fake-schroot: /' >&2 +ls -l "$CHROOT_PATH/dev/pts/ptmx" | sed -e 's/^/# fake-schroot: /' >&2 + +mounted_ptmx=no + +if [ -e "$CHROOT_PATH/dev/pts/ptmx" ] && \ + ! [ -L "$CHROOT_PATH/dev/ptmx" ]; then + mount --bind "$CHROOT_PATH/dev/pts/ptmx" "$CHROOT_PATH/dev/ptmx" + mounted_ptmx=yes +fi + +mounted_console=no + +if stdin_tty="$(tty)"; then + if [ ! -e "$CHROOT_PATH/dev/console" ]; then + mknod -m700 "$CHROOT_PATH/dev/console" c 5 1 + fi + + mount --bind "$stdin_tty" "$CHROOT_PATH/dev/console" + mounted_console=yes +fi + +ls -l "$CHROOT_PATH/dev/ptmx" | sed -e 's/^/# fake-schroot: /' >&2 +ls -l "$CHROOT_PATH/dev/pts/ptmx" | sed -e 's/^/# fake-schroot: /' >&2 + +e=0 +chroot "$CHROOT_PATH" "$@" || e=$? + +[ "$mounted_console" = no ] || umount "$CHROOT_PATH/dev/console" +[ "$mounted_ptmx" = no ] || umount "$CHROOT_PATH/dev/ptmx" +umount "$CHROOT_PATH/dev/pts" +[ "$bind_dev" = no ] || umount "$CHROOT_PATH/dev" + +exit "$e" diff --git a/debian/tests/mitm.py b/debian/tests/mitm.py new file mode 100644 index 0000000..cd2cd75 --- /dev/null +++ b/debian/tests/mitm.py @@ -0,0 +1,92 @@ +"""Flask app which MITM's an archive to generate out-of-order apt lists. + +Specifically, it prepends an additional Packages file stanza for a non-existent +lower version of apt: a fixed version of debootstrap will find the second +(correct) apt stanza and succeed; a broken version of debootstrap will find +only the first (non-existent) apt stanza and fail. +""" +import functools +import gzip +import hashlib +import os + +import requests +from debian.deb822 import Packages +from flask import Flask, redirect + +app = Flask(__name__) + +ARCH = os.environ.get("FLASK_ARCH", "amd64") +DIST = os.environ.get("FLASK_DIST", "bookworm") +DISTRO = os.environ.get("FLASK_DISTRO", "debian") +MIRROR = os.environ.get("FLASK_MIRROR", "http://deb.debian.org") + + +if DISTRO == "debian": + hash_funcs = [hashlib.md5, hashlib.sha256] +else: + # Ubuntu includes SHA1 still + hash_funcs = [hashlib.md5, hashlib.sha1, hashlib.sha256] + + +def _munge_release_file(url: str) -> bytes: + """Given a Release file URL, rewrite it for our modified Packages content.""" + original = requests.get(MIRROR + "/" + url).content + packages_content = _packages_content( + f"{DISTRO}/dists/{DIST}/main/binary-{ARCH}/Packages" + ) + size = bytes(str(len(packages_content)), "ascii") + sums = [ + bytes(hash_func(packages_content).hexdigest(), "ascii") + for hash_func in hash_funcs + ] + new_lines = [] + filename = f"main/binary-{ARCH}/Packages".encode("ascii") + for line in original.splitlines(): + if not line.endswith(filename): + new_lines.append(line) + continue + new_lines.append(b" ".join([b"", sums.pop(0), size, filename])) + return b"\n".join(new_lines) + + +@functools.lru_cache +def _packages_content(url: str) -> bytes: + """Given a Packages URL, fetch it and prepend a broken apt stanza.""" + resp = requests.get(MIRROR + "/" + url + ".gz") + upstream_content = gzip.decompress(resp.content) + + # Find the first `apt` stanza + for stanza in Packages.iter_paragraphs(upstream_content): + if stanza["Package"] == "apt": + break + + # Generate the broken stanza + new_version = stanza["Version"] + "~test" + stanza["Filename"] = stanza["Filename"].replace(stanza["Version"], new_version) + stanza["Version"] = new_version + + # Prepend the stanza to the upstream content + return bytes(stanza) + b"\n" + upstream_content + + +@app.route("/<path:url>", methods=["GET", "POST"]) +def root(url): + """Handler for all requests.""" + if ( + url == f"{DISTRO}/dists/{DIST}/InRelease" + or "by-hash" in url + or "Packages.xz" in url + or "Packages.gz" in url + ): + # 404 these URLs to force clients to fetch by path and without compression, to + # make MITM easier + return "", 404 + if url == f"{DISTRO}/dists/{DIST}/Release": + # If Release is being fetched, return our modified version + return _munge_release_file(url) + if url == f"{DISTRO}/dists/{DIST}/main/binary-{ARCH}/Packages": + # If Packages is being fetched, return our modified version + return _packages_content(url) + # For anything we don't need to modify, redirect clients to upstream mirror + return redirect(f"{MIRROR}/{url}") diff --git a/debian/tests/unsorted-packages-files b/debian/tests/unsorted-packages-files new file mode 100755 index 0000000..f039690 --- /dev/null +++ b/debian/tests/unsorted-packages-files @@ -0,0 +1,33 @@ +#!/bin/sh + +# This test runs the mitm.py Flask app which debootstrap is then pointed at. +# mitm.py will return a Packages file which has an additional `apt` stanza +# prepended, with the Version and Filename adjusted to point at a lower, +# non-existent version. Versions of debootstrap which process _all_ Packages +# files entries will find the original stanza later in the file (and +# succesfully fetch the corresponding package file): versions that don't will +# find the prepended stanza and fail (with a 404 of the nonexistent package +# file). + +export FLASK_ARCH="$(dpkg --print-architecture)" +export FLASK_DIST=testing +export FLASK_DISTRO=debian +export FLASK_MIRROR=http://deb.debian.org +export PATH=$PATH:/usr/sbin + +# Launch our MitM "mirror" server, ensure that request logging is sent to stdout +PYTHONDONTWRITEBYTECODE=true FLASK_APP=debian/tests/mitm.py flask run 2>&1 & +flask_pid=$! + +# Give Flask time to come up +sleep 2 + +tempdir=$(mktemp -d) +# Run debootstrap against our MitM "mirror", ignoring the inevitable GPG errors +debootstrap --download-only --variant minbase --no-check-gpg ${FLASK_DIST} $tempdir http://127.0.0.1:5000/${FLASK_DISTRO}/ +rc=$? + +rm -rf $tempdir +kill $flask_pid + +exit $rc |