diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 09:34:11 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 09:34:11 +0000 |
commit | 7ad64c4ba5ccab524960c8f1d468d7a47f7f72a9 (patch) | |
tree | 8594f58c909db66c01c175a5bad8bead9d3e4d52 /debian/tests/debian-testing | |
parent | Adding upstream version 1.0.123+deb11u2. (diff) | |
download | debootstrap-debian.tar.xz debootstrap-debian.zip |
Adding debian version 1.0.123+deb11u2.debian/1.0.123+deb11u2debian
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rwxr-xr-x | debian/tests/debian-testing | 325 |
1 files changed, 325 insertions, 0 deletions
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: |