Compare commits

..

21 commits

Author SHA1 Message Date
2f768b07dc
coverage.sh: check for pod2man errors 2024-01-23 16:32:50 +01:00
4ca0556cd2
mmdebstrap-autopkgtest-build-qemu: usability and man page improvements
- explicitly instruct to add --boot=efi to autopkgtest-virt-qemu
 - add example how to run autopkgtest with --boot=efi
 - document image location requirements giving unshare restrictions
 - check if foreign arch is configured
 - instruct how to add a foreign architecture
 - check that the unshared user is able to access the image location
 - suggest to install qemu-system-* packages if they are missing
 - suggest to install packages containing EDK II OVMF UEFI firmware
2024-01-23 16:28:58 +01:00
d9f9c64ac2
do not fail during cleanup if /etc/apt/apt.conf.d/00mmdebstrap got removed, only warn 2024-01-23 16:28:58 +01:00
dd94ee3b84
read files passed as --aptopt and --dpkgopt outside the unshared namespace to avoid permission issues 2024-01-23 16:28:58 +01:00
99d2579e0b
document that the required and minbase variants do not explicitly install apt 2024-01-23 16:28:58 +01:00
610058d105
document how SUITE influences the selection of essential packages 2024-01-23 16:28:57 +01:00
2ff8f6142d
document how to run chrootless mode wrapped inside mmdebstrap 2024-01-23 16:28:57 +01:00
417d958a14
document how to remove a directory created with unshare mode 2024-01-09 10:29:53 +01:00
8674e11c71
allow for /etc/resolv.conf and /etc/hostname to already exist inside the chroot without warning about it 2024-01-09 09:47:35 +01:00
daa886264b
reword the first few paragraphs
Thanks: Raphaël Hertzog
2024-01-08 23:02:55 +01:00
d157ba2b9a
only print short --help output if wrong args are passed 2024-01-08 23:01:53 +01:00
884a04b18a
make_mirror.sh: disable networking 2024-01-08 22:56:55 +01:00
014a9c30a5
tests/check-against-debootstrap-dist: systemd 255 dropped split-/usr support 2024-01-08 22:54:43 +01:00
90fe7941bb
tests/check-against-debootstrap-dist: debootstrap installs prio:required packages in oldstable and stable for the buildd profile 2024-01-08 22:53:36 +01:00
428ee78121
disallow running chrootless as root without fakeroot unless --skip=check/chrootless is used 2024-01-08 22:37:13 +01:00
ae6dcc001d
tests/install-busybox-based-sub-essential-system: busybox 1:1.36.1-6 moved to /usr 2024-01-08 22:36:07 +01:00
b4ba78897b
make_mirror.sh: add newline at the end of /etc/hosts so that appending writes to the next line and not the current 2024-01-08 22:30:33 +01:00
69954515e7
tests/chrootless-fakeroot: also fix permissions and extended attributes for /etc/credstore 2024-01-08 22:27:35 +01:00
136cbdf0f1
run_qemu.sh: replace storing the pid and kill it a trap by using 'setpriv --pdeathsig TERM' 2024-01-08 22:25:07 +01:00
87edb1c2d1
coverage.sh: also run shellcheck on mmdebstrap-autopkgtest-build-qemu 2024-01-08 16:50:08 +01:00
0de9e19ca4
make_mirror.sh: explicitly install passwd since systemd 254.4-1 doesn't pull it in anymore 2024-01-08 14:37:00 +01:00
10 changed files with 220 additions and 105 deletions

View file

@ -20,6 +20,8 @@ if [ -e ./mmdebstrap ]; then
fi
perlcritic --severity 4 --verbose 8 ./mmdebstrap
pod2man ./mmdebstrap >/dev/null
fi
for f in tarfilter coverage.py caching_proxy.py; do
@ -27,7 +29,7 @@ for f in tarfilter coverage.py caching_proxy.py; do
black --check "./$f"
done
shellcheck --exclude=SC2016 coverage.sh make_mirror.sh run_null.sh run_qemu.sh gpgvnoexpkeysig hooks/*/*.sh
shellcheck --exclude=SC2016 coverage.sh make_mirror.sh run_null.sh run_qemu.sh gpgvnoexpkeysig mmdebstrap-autopkgtest-build-qemu hooks/*/*.sh
mirrordir="./shared/cache/debian"

View file

@ -449,7 +449,7 @@ if [ "$HAVE_QEMU" = "yes" ]; then
tmpdir="$(mktemp -d)"
trap 'kill "$PROXYPID" || :;cleanuptmpdir; cleanup_newcachedir' EXIT INT TERM
pkgs=perl-doc,systemd-sysv,perl,arch-test,fakechroot,fakeroot,mount,uidmap,qemu-user-static,qemu-user,dpkg-dev,mini-httpd,libdevel-cover-perl,libtemplate-perl,debootstrap,procps,apt-cudf,aspcud,python3,libcap2-bin,gpg,debootstrap,distro-info-data,iproute2,ubuntu-keyring,apt-utils,squashfs-tools-ng,genext2fs,linux-image-generic
pkgs=perl-doc,systemd-sysv,perl,arch-test,fakechroot,fakeroot,mount,uidmap,qemu-user-static,qemu-user,dpkg-dev,mini-httpd,libdevel-cover-perl,libtemplate-perl,debootstrap,procps,apt-cudf,aspcud,python3,libcap2-bin,gpg,debootstrap,distro-info-data,iproute2,ubuntu-keyring,apt-utils,squashfs-tools-ng,genext2fs,linux-image-generic,passwd
if [ ! -e ./mmdebstrap ]; then
pkgs="$pkgs,mmdebstrap"
fi
@ -493,6 +493,8 @@ mount -t 9p -o trans=virtio,access=any,msize=128k mmdebstrap /mnt
# need to restart mini-httpd because we mounted different content into www-root
systemctl restart mini-httpd
ip link set enp0s1 down || :
handler () {
while IFS= read -r line || [ -n "$line" ]; do
printf "%s %s: %s\n" "$(date -u -d "0 $(date +%s.%3N) seconds - $2 seconds" +"%T.%3N")" "$1" "$line"
@ -530,7 +532,8 @@ END
fi
# set PATH to pick up the correct mmdebstrap variant
env PATH="$(dirname "$(realpath --canonicalize-existing "$CMD")"):$PATH" \
debvm-create --skip=usrmerge --size="$DISK_SIZE" --release="$DEFAULT_DIST" \
debvm-create --skip=usrmerge,systemdnetwork \
--size="$DISK_SIZE" --release="$DEFAULT_DIST" \
--output="$newcachedir/debian-$DEFAULT_DIST.ext4" -- \
--architectures="$arches" --include="$pkgs" \
--setup-hook='echo "Acquire::http::Proxy \"http://127.0.0.1:8080/\";" > "$1/etc/apt/apt.conf.d/00proxy"' \
@ -541,7 +544,7 @@ END
--customize-hook='touch "$1/mmdebstrap-testenv"' \
--customize-hook='copy-in "'"$tmpdir"'/mmdebstrap.service" /etc/systemd/system/' \
--customize-hook='copy-in "'"$tmpdir"'/worker.sh" /' \
--customize-hook='printf 127.0.0.1 localhost > "$1/etc/hosts"' \
--customize-hook='echo 127.0.0.1 localhost > "$1/etc/hosts"' \
--customize-hook='printf "START=1\nDAEMON_OPTS=\"-h 127.0.0.1 -p 80 -u nobody -dd /mnt/cache -i /var/run/mini-httpd.pid -T UTF-8\"\n" > "$1/etc/default/mini-httpd"' \
"$mirror"

View file

@ -1953,7 +1953,7 @@ sub run_setup() {
# since we do not know the dpkg version inside the chroot at this
# point, we can only omit it in chrootless mode
if ($options->{mode} ne 'chrootless'
or scalar @{ $options->{dpkgopts} } > 0) {
or length $options->{dpkgopts} > 0) {
push @directories, '/etc/dpkg/dpkg.cfg.d/';
}
# if dpkg and apt operate from the outside we need some more
@ -2083,26 +2083,11 @@ sub run_setup() {
close $fh;
}
if (scalar @{ $options->{aptopts} } > 0
if (length $options->{aptopts} > 0
and (!-e "$options->{root}/etc/apt/apt.conf.d/99mmdebstrap")) {
open my $fh, '>', "$options->{root}/etc/apt/apt.conf.d/99mmdebstrap"
or error "cannot open /etc/apt/apt.conf.d/99mmdebstrap: $!";
foreach my $opt (@{ $options->{aptopts} }) {
if (-r $opt) {
# flush handle because copy() uses syswrite() which bypasses
# buffered IO
$fh->flush();
copy $opt, $fh or error "cannot copy $opt: $!";
} else {
print $fh $opt;
if ($opt !~ /;$/) {
print $fh ';';
}
if ($opt !~ /\n$/) {
print $fh "\n";
}
}
}
print $fh $options->{aptopts};
close $fh;
if ($verbosity_level >= 3) {
debug "content of /etc/apt/apt.conf.d/99mmdebstrap:";
@ -2110,7 +2095,7 @@ sub run_setup() {
}
}
if (scalar @{ $options->{dpkgopts} } > 0
if (length $options->{dpkgopts} > 0
and (!-e "$options->{root}/etc/dpkg/dpkg.cfg.d/99mmdebstrap")) {
# FIXME: in chrootless mode, dpkg will only read the configuration
# from the host -- see #808203
@ -2120,19 +2105,7 @@ sub run_setup() {
}
open my $fh, '>', "$options->{root}/etc/dpkg/dpkg.cfg.d/99mmdebstrap"
or error "cannot open /etc/dpkg/dpkg.cfg.d/99mmdebstrap: $!";
foreach my $opt (@{ $options->{dpkgopts} }) {
if (-r $opt) {
# flush handle because copy() uses syswrite() which bypasses
# buffered IO
$fh->flush();
copy $opt, $fh or error "cannot copy $opt: $!";
} else {
print $fh $opt;
if ($opt !~ /\n$/) {
print $fh "\n";
}
}
}
print $fh $options->{dpkgopts};
close $fh;
if ($verbosity_level >= 3) {
debug "content of /etc/dpkg/dpkg.cfg.d/99mmdebstrap:";
@ -2234,6 +2207,8 @@ sub run_setup() {
chmod $mode, "$options->{root}/$file"
or error "cannot chmod $file: $!";
}
} elsif (-e $file && -e "$options->{root}/$file") {
info "rootfs alreday contains $file";
} else {
warning("Host system does not have a $file to copy into the"
. " rootfs.");
@ -3137,7 +3112,7 @@ sub run_cleanup() {
} else {
# clean up temporary configuration file
unlink "$options->{root}/etc/apt/apt.conf.d/00mmdebstrap"
or error "failed to unlink /etc/apt/apt.conf.d/00mmdebstrap: $!";
or warning "failed to unlink /etc/apt/apt.conf.d/00mmdebstrap: $!";
if (defined $ENV{APT_CONFIG} && -e $ENV{APT_CONFIG}) {
unlink $ENV{APT_CONFIG}
@ -4518,8 +4493,8 @@ sub main() {
architectures => [$hostarch],
mode => 'auto',
format => 'auto',
dpkgopts => [],
aptopts => [],
dpkgopts => '',
aptopts => '',
apttrusted => $apttrusted,
apttrustedparts => $apttrustedparts,
noop => [],
@ -4586,8 +4561,43 @@ sub main() {
},
'architectures=s@' => \$options->{architectures},
'mode=s' => \$options->{mode},
'dpkgopt=s@' => \$options->{dpkgopts},
'aptopt=s@' => \$options->{aptopts},
'dpkgopt=s' => sub {
my ($opt_name, $opt_value) = @_;
if (-r $opt_value) {
open my $fh, '<', $opt_value
or error "failed to open $opt_value: $!";
$options->{dpkgopts} .= do { local $/; <$fh> };
if ($options->{dpkgopts} !~ /\n$/) {
print $fh "\n";
}
close $fh;
} else {
$options->{dpkgopts} .= $opt_value;
if ($opt_value !~ /\n$/) {
$options->{dpkgopts} .= "\n";
}
}
},
'aptopt=s' => sub {
my ($opt_name, $opt_value) = @_;
if (-r $opt_value) {
open my $fh, '<', $opt_value
or error "failed to open $opt_value: $!";
$options->{aptopts} .= do { local $/; <$fh> };
if ($options->{aptopts} !~ /\n$/) {
print $fh "\n";
}
close $fh;
} else {
$options->{aptopts} .= $opt_value;
if ($opt_value !~ /;$/) {
$options->{aptopts} .= ';';
}
if ($opt_value !~ /\n$/) {
$options->{aptopts} .= "\n";
}
}
},
'keyring=s' => sub {
my ($opt_name, $opt_value) = @_;
if ($opt_value =~ /"/) {
@ -4722,7 +4732,7 @@ sub main() {
}
push @{ $options->{skip} }, $skip;
}
}) or pod2usage(-exitval => 2, -verbose => 1);
}) or pod2usage(-exitval => 2, -verbose => 0);
if (defined($logfile)) {
open(STDERR, '>', $logfile) or error "cannot open $logfile: $!";
@ -4939,9 +4949,17 @@ sub main() {
test_unshare_userns(1);
}
} elsif ($options->{mode} eq 'chrootless') {
if ($EFFECTIVE_USER_ID == 0) {
warning "running chrootless mode as root might damage the host "
. "system";
if (any { $_ eq 'check/chrootless' } @{ $options->{skip} }) {
info "skipping check/chrootless as requested";
} else {
my $ischroot = 0 == system 'ischroot';
if ( $EFFECTIVE_USER_ID == 0
&& !exists $ENV{FAKEROOTKEY}
&& !$ischroot) {
error
"running chrootless mode as root without fakeroot might "
. "damage the host system if not run inside a chroot";
}
}
} else {
error "unknown mode: $options->{mode}";
@ -6392,45 +6410,52 @@ B<mmdebstrap> creates a Debian chroot of I<SUITE> into I<TARGET> from one or
more I<MIRROR>s. It is meant as an alternative to the debootstrap tool (see
section B<DEBOOTSTRAP>). In contrast to debootstrap it uses apt to resolve
dependencies and is thus able to use more than one mirror and resolve more
complex dependencies. See section B<OPERATION> for an overview of how
B<mmdebstrap> works internally.
complex dependency relationships. See section B<OPERATION> for an overview of
how B<mmdebstrap> works internally.
If no I<MIRROR> option is provided and I<SUITE> is not a stable release name,
L<http://deb.debian.org/debian> is used. If I<SUITE> is a stable release name
and no I<MIRROR> is specified, then mirrors for updates and security are
automatically added. If a I<MIRROR> option starts with "deb " or "deb-src "
then it is used as a one-line-style format entry for apt's sources.list inside
the chroot. If a I<MIRROR> option contains a "://" then it is interpreted as a
mirror URI and the apt line inside the chroot is assembled as "deb [arch=A] B C
D" where A is the host's native architecture, B is the I<MIRROR>, C is the
given I<SUITE> and D is the components given via B<--components> (defaults to
"main"). If a I<MIRROR> option happens to be an existing file, then its
contents are pasted into the chroot's sources.list. This can be used to supply
a deb822 style sources.list. If I<MIRROR> is C<-> then standard input is pasted
into the chroot's sources.list. More than one mirror can be specified and are
appended to the chroot's sources.list in the given order. If you specify a
https or tor I<MIRROR> and you want the chroot to be able to update itself,
don't forget to also install the ca-certificates package, the
apt-transport-https package for apt versions less than 1.5 and/or the
apt-transport-tor package using the B<--include> option, as necessary.
The optional I<TARGET> argument can either be the path to a directory, the path
to a tarball filename, the path to a squashfs image, the path to an ext2 image,
a FIFO, a character special device, or C<->. Without the B<--format> option,
I<TARGET> will be used to choose the format. See the section B<FORMATS> for
more information. If no I<TARGET> was specified or if I<TARGET> is C<->, an
uncompressed tarball will be sent to standard output.
The I<SUITE> may be a valid release code name (eg, sid, stretch, jessie) or a
symbolic name (eg, unstable, testing, stable, oldstable). Any suite name that
works with apt on the given mirror will work. If no I<SUITE> was specified,
then a single I<MIRROR> C<-> is added and thus the information of the desired
suite has to come from standard input as part of a valid apt sources.list file.
The I<SUITE> option may either be a valid release code name (eg, sid, bookworm,
trixie) or a symbolic name (eg, unstable, testing, stable, oldstable). Any
suite name that works with apt on the given mirror will work. The I<SUITE>
option is optional if no I<TARGET> and no I<MIRROR> option is provided. If
I<SUITE> is missing, then the information of the desired suite has to come from
standard input as part of a valid apt sources.list file or be set up via hooks.
The value of the I<SUITE> argument will be used to determine which apt index to
use for finding out the set of C<Essential:yes> packages and/or the set of
packages with the right priority for the selected variant. See the section
packages with the right priority for the selected variant. This functionality
can be disabled by choosing the empty string for I<SUITE>. See the section
B<VARIANTS> for more information.
The I<TARGET> option may either be the path to a directory, the path to a
tarball filename, the path to a squashfs image, the path to an ext2 image, a
FIFO, a character special device, or C<->. The I<TARGET> option is optional if
no I<MIRROR> option is provided. If I<TARGET> is missing or if I<TARGET> is
C<->, an uncompressed tarball will be sent to standard output. Without the
B<--format> option, I<TARGET> will be used to choose the format. See the
section B<FORMATS> for more information.
The I<MIRROR> option may either be provided as a URI, in apt one-line format,
as a path to a file in apt's one-line or deb822-format, or C<->. If no
I<MIRROR> option is provided, then L<http://deb.debian.org/debian> is used as
the default. If I<SUITE> does not refer to "unstable" or "testing", then
I<SUITE>-updates and I<SUITE>-security mirrors are automatically added. If a
I<MIRROR> option starts with "deb " or "deb-src " then it is used as a one-line
format entry for apt's sources.list inside the chroot. If a I<MIRROR> option
contains a "://" then it is interpreted as a mirror URI and the apt line inside
the chroot is assembled as "deb [arch=A] B C D" where A is the host's native
architecture, B is the I<MIRROR>, C is the given I<SUITE> and D is the
components given via B<--components> (defaults to "main"). If a I<MIRROR>
option happens to be an existing file, then its contents are written into the
chroot's sources.list (if the first I<MIRROR> is a file in one-line format) or
into the chroot's sources.list.d directory, named with the extension .list or
.sources, depending on whether the file is in one-line or deb822 format,
respectively. If I<MIRROR> is C<-> then standard input is pasted into the
chroot's sources.list. More than one mirror can be specified and are appended
to the chroot's sources.list in the given order. If you specify a https or tor
I<MIRROR> and you want the chroot to be able to update itself, don't forget to
also install the ca-certificates package, the apt-transport-https package for
apt versions less than 1.5 and/or the apt-transport-tor package using the
B<--include> option, as necessary.
All status output is printed to standard error unless B<--logfile> is used to
redirect it to a file or B<--quiet> or B<--silent> is used to suppress any
output on standard error. Help and version information will be printed to
@ -6903,6 +6928,11 @@ available and you know your subuid/subgid offset (100000 in this example):
$ sudo systemd-nspawn --private-users=100000 \
> --directory=./debian-rootfs /bin/bash
A directory created in B<unshare> mode cannot be removed the normal way.
Instead, use something like this:
$ unshare --map-root-user --map-auto rm -rf ./debian-rootfs
If this mode is used as the root user, the user namespace is not unshared (but
the mount namespace and other still are) and created directories will have
correct ownership information. This is also useful in cases where the root user
@ -6934,10 +6964,13 @@ dpkg-root-support usertag of debian-dpkg@lists.debian.org in the Debian bug
tracking system. B<WARNING>: if this option is used carelessly with packages
that do not support C<DPKG_ROOT>, this mode can result in undesired changes to
the system running B<mmdebstrap> because maintainer-scripts will be run without
L<chroot(1)>.
L<chroot(1)>. Make sure to run this mode without superuser privileges and/or
inside a throw-away chroot enviroment like so:
=for TODO
=item B<qemu>
mmdebstrap --variant=apt --include=mmdebstrap \
--customize-hook='chroot "$1" mmdebstrap --mode=chrootless
--variant=apt unstable chrootless.tar' \
--customize-hook='copy-out chrootless.tar .' unstable /dev/null
=back
@ -6968,7 +7001,9 @@ then this variant will fail because it cannot configure the packages.
=item B<essential>
C<Essential:yes> packages.
C<Essential:yes> packages. If I<SUITE> is a non-empty string, then only
packages from the archive with suite or codename matching I<SUITE> will be
considered for selection of C<Essential:yes> packages.
=item B<apt>
@ -6983,7 +7018,7 @@ ignored without throwing an error.
=item B<required>, B<minbase>
The B<essential> set plus all packages with Priority:required and apt.
The B<essential> set plus all packages with Priority:required.
It is roughly equivalent to running mmdebstrap with
--variant=essential --include="?priority(required)"
@ -7240,6 +7275,8 @@ Upon startup, several checks are carried out, like:
=item * which mode to use and whether prerequisites are met
=item * do not allow chrootless mode as root (without fakeroot) unless inside a chroot. This check can be disabled using B<--skip=check/chrootless>
=item * whether the requested architecture can be executed (requires arch-test) using qemu binfmt_misc support. This requires arch-test and can be disabled using B<--skip=check/qemu>
=item * how the apt sources can be assembled from I<SUITE>, I<MIRROR> and B<--components> and/or from standard input as deb822 or one-line format and whether the required GPG keys exist.

View file

@ -30,7 +30,9 @@ B<mmdebstrap-autopkgtest-build-qemu> is a mostly compatible drop-in replacement
for L<autopkgtest-build-qemu(1)> with two main differences: Firstly, it uses
L<mmdebstrap(1)> instead of L<vmdb2(1)> and thus is able to create QEMU disk
images without requiring superuser privileges. Secondly, it uses
L<systemd-boot(7)> and thus only supports booting via EFI.
L<systemd-boot(7)> and thus only supports booting via EFI. For architectures
for which L<autopkgtest-virt-qemu(1)> does not default to EFI booting you must
pass B<--boot=efi> when invoking the autopkgtest virt backend.
=head1 POSITIONAL PARAMETERS
@ -96,9 +98,17 @@ Passes an additional B<--keyring> parameter to B<mmdebstrap>.
=head1 EXAMPLES
$ mmdebstrap-autopkgtest-build-qemu --boot=efi stable /path/to/debian-stable-i386.img i386
Make sure, that F</path/to/debian-unstable.img> is a path that the unshared
user has access to. This can be done by ensuring world-execute permissions on
all path components or by creating the image in a world-readable directory like
/tmp before copying it into its final location.
$ mmdebstrap-autopkgtest-build-qemu --boot=efi unstable /path/to/debian-unstable.img
$ mmdebstrap-autopkgtest-build-qemu --boot=efi --arch=amd64 unstable /path/to/debian-unstable.img
[...]
$ autopkgtest mypackage -- qemu --boot=efi --dpkg-architecture=amd64 /path/to/debian-unstable.img
Make sure to add B<--boot=efi> to both the B<mmdebstrap-autopkgtest-build-qemu>
as well as the B<autopkgtest-virt-qemu> invocation.
=head1 SEE ALSO
@ -223,21 +233,31 @@ test "$BOOT" = efi ||
case "$ARCHITECTURE" in
amd64)
EFIIMG=bootx64.efi
QEMUARCH=x86_64
VMFPKG=ovmf
;;
arm64)
EFIIMG=bootaa64.efi
QEMUARCH=aarch64
VMFPKG=qemu-efi-aarch64
;;
armhf)
EFIIMG=bootarm.efi
QEMUARCH=arm
VMFPKG=qemu-efi-arm
;;
i386)
EFIIMG=bootia32.efi
QEMUARCH=i386
VMFPKG=ovmf-ia32
;;
riscv64)
EFIIMG=bootriscv64.efi
QEMUARCH=riscv64
VMFPKG=
;;
*)
die "unsupported architecture"
die "unsupported architecture: $ARCHITECTURE"
;;
esac
@ -250,9 +270,17 @@ else
test "$(dpkg-query -f '${db:Status-Status}' -W "binutils$GNU_SUFFIX")" = installed ||
die "please install binutils$GNU_SUFFIX or binutils-multiarch"
fi
arches=" $(dpkg --print-architecture) $(dpkg --print-foreign-architectures | tr '\n' ' ') "
case $arches in
*" $ARCHITECTURE "*) : ;; # nothing to do
*) die "enable $ARCHITECTURE by running: sudo dpkg --add-architecture $ARCHITECTURE && sudo apt update" ;;
esac
for pkg in autopkgtest dosfstools e2fsprogs fdisk mount mtools passwd "systemd-boot-efi:$ARCHITECTURE" uidmap; do
test "$(dpkg-query -f '${db:Status-Status}' -W "$pkg")" = installed ||
if [ "$(dpkg-query -f '${db:Status-Status}' -W "$pkg")" != installed ]; then
die "please install $pkg"
fi
done
BOOTSTUB="/usr/lib/systemd/boot/efi/linux${EFIIMG#boot}.stub"
@ -278,6 +306,14 @@ rm -f "$IMAGE"
unshare -U -r --map-groups=auto chown 0:1 "$IMAGE"
chmod 0660 "$IMAGE"
# Make sure that the unshared user is able to access the file.
# Alternatively to using /sbin/mkfs.ext4 could use --format=ext2 which would
# add an extra copy operation and come with the limitations of ext2.
# Another solution: https://github.com/tytso/e2fsprogs/pull/118
if ! mmdebstrap --unshare-helper touch "$IMAGE"; then
die "$IMAGE cannot be accessed by the unshared user -- either make all path components up to the image itself world-executable or place the image into a world-readable path like /tmp"
fi
set -- \
--mode=unshare \
--variant=important \
@ -387,3 +423,12 @@ start=$((FAT_OFFSET_SECTORS + FAT_SIZE_SECTORS)), type=0FC63DAF-8483-4772-8E79-3
EOF
dd if="$WORKDIR/fat" of="$IMAGE" conv=notrunc,sparse bs=512 "seek=$FAT_OFFSET_SECTORS" status=none
if test "$(dpkg --print-architecture)" != "$ARCHITECTURE" && test "$(dpkg-query -f '${db:Status-Status}' -W "qemu-system-$QEMUARCH")" != installed; then
echo "I: you might need to install a package providing qemu-system-$QEMUARCH to use this image with autopkgtest-virt-qemu" >&2
fi
if test -n "$VMFPKG" && test "$(dpkg-query -f '${db:Status-Status}' -W "$VMFPKG")" != installed; then
echo "I: you might need to install $VMFPKG to use this image with autopkgtest-virt-qemu" >&2
fi
echo "I: don't forget to pass --boot=efi when running autopkgtest-virt-qemu with this image" >&2

View file

@ -10,9 +10,6 @@ cleanup() {
rv=$?
rm -f "$tmpdir/log"
[ -e "$tmpdir" ] && rmdir "$tmpdir"
if [ -n "${TAIL_PID:-}" ]; then
kill "$TAIL_PID"
fi
if [ -e shared/output.txt ]; then
res="$(cat shared/exitstatus.txt)"
if [ "$res" != "0" ]; then
@ -30,8 +27,7 @@ if [ -e shared/output.txt ]; then
rm shared/output.txt
fi
touch shared/output.txt
tail -f shared/output.txt &
TAIL_PID=$!
setpriv --pdeathsig TERM tail -f shared/output.txt &
# to connect to serial use:
# minicom -D 'unix#/tmp/ttyS0'
@ -40,6 +36,7 @@ TAIL_PID=$!
# socat stdin,raw,echo=0,escape=0x11 unix-connect:/tmp/ttyS0
ret=0
timeout --foreground 40m debvm-run --image="$(realpath "$cachedir")/debian-$DEFAULT_DIST.ext4" -- \
-nic none \
-m 4G -snapshot \
-monitor unix:/tmp/monitor,server,nowait \
-serial unix:/tmp/ttyS0,server,nowait \

View file

@ -13,6 +13,7 @@ echo "SOURCE_DATE_EPOCH=$SOURCE_DATE_EPOCH"
{{ CMD }} --variant={{ VARIANT }} --mode={{ MODE }} \
--essential-hook='[ {{ DIST }} = oldstable ] && [ {{ VARIANT }} = - ] && echo _apt:*:100:65534::/nonexistent:/usr/sbin/nologin >> "$1"/etc/passwd || :' \
"$(if [ {{ DIST }} = oldstable ]; then echo --merged-usr; else echo --hook-dir=./hooks/merged-usr; fi)" \
"$(case {{ DIST }} in oldstable) echo --include=e2fsprogs,mount,tzdata,gcc-9-base;; stable) echo --include=e2fsprogs,mount,tzdata;; *) echo --include=base-files ;; esac )" \
{{ DIST }} /tmp/debian-{{ DIST }}-mm.tar {{ MIRROR }}
mkdir /tmp/debian-{{ DIST }}-mm
@ -176,11 +177,30 @@ fi
# since debootstrap 1.0.133 there is no tzdata in the buildd variant and thus
# debootstrap creates its own /etc/localtime
if [ "{{ VARIANT }}" = "buildd" ]; then
if [ "{{ VARIANT }}" = "buildd" ] && [ "{{ DIST }}" != "stable" ] && [ "{{ DIST }}" != "oldstable" ]; then
[ "$(readlink /tmp/debian-{{ DIST }}-debootstrap/etc/localtime)" = /usr/share/zoneinfo/UTC ]
rm /tmp/debian-{{ DIST }}-debootstrap/etc/localtime
fi
# starting with systemd 255 upstream dropped splitusr support and depending on
# the installation order, symlink targets are prefixed with /usr or not
# See #1060000 and #1054137
case {{ DIST }} in testing|unstable)
for f in multi-user.target.wants/e2scrub_reap.service timers.target.wants/apt-daily-upgrade.timer timers.target.wants/apt-daily.timer timers.target.wants/e2scrub_all.timer; do
for d in mm debootstrap; do
[ -L "/tmp/debian-{{ DIST }}-$d/etc/systemd/system/$f" ] || continue
oldlink="$(readlink "/tmp/debian-{{ DIST }}-$d/etc/systemd/system/$f")"
case $oldlink in
/usr/*) : ;;
/*) oldlink="/usr$oldlink" ;;
*) echo unexpected >&2; exit 1 ;;
esac
ln -sf "$oldlink" "/tmp/debian-{{ DIST }}-$d/etc/systemd/system/$f"
done
done
;;
esac
# check if the file content differs
diff --unified --no-dereference --recursive /tmp/debian-{{ DIST }}-debootstrap /tmp/debian-{{ DIST }}-mm >&2
@ -189,8 +209,9 @@ diff --unified --no-dereference --recursive /tmp/debian-{{ DIST }}-debootstrap /
find /tmp/debian-{{ DIST }}-debootstrap /tmp/debian-{{ DIST }}-mm -type d -print0 | xargs -0 touch --date="@{{ SOURCE_DATE_EPOCH }}"
# debootstrap never ran apt -- fixing permissions
for d in ./var/lib/apt/lists/partial ./var/cache/apt/archives/partial; do
chroot /tmp/debian-{{ DIST }}-debootstrap chmod 0700 $d
chroot /tmp/debian-{{ DIST }}-debootstrap chown "$(id -u _apt):root" $d
unmergedPATH="$PATH$(if [ "{{ DIST }}" = oldstable ]; then echo :/bin:/sbin; fi)"
PATH="$unmergedPATH" chroot /tmp/debian-{{ DIST }}-debootstrap chmod 0700 $d
PATH="$unmergedPATH" chroot /tmp/debian-{{ DIST }}-debootstrap chown "$(id -u _apt):root" $d
done
tar -C /tmp/debian-{{ DIST }}-debootstrap --numeric-owner --sort=name --clamp-mtime --mtime="$(date --utc --date=@{{ SOURCE_DATE_EPOCH }} --iso-8601=seconds)" -cf /tmp/root1.tar .
tar -C /tmp/debian-{{ DIST }}-mm --numeric-owner --sort=name --clamp-mtime --mtime="$(date --utc --date=@{{ SOURCE_DATE_EPOCH }} --iso-8601=seconds)" -cf /tmp/root2.tar .

View file

@ -8,7 +8,7 @@ trap "rm -f /tmp/chrootless.tar /tmp/root.tar" EXIT INT TERM
for INCLUDE in '' 'apt' 'apt,build-essential' 'systemd-sysv'; do
for MODE in root chrootless; do
{{ CMD }} --mode=$MODE --variant={{ VARIANT }} --hook-dir=./hooks/merged-usr \
${INCLUDE:+--include="$INCLUDE"} \
${INCLUDE:+--include="$INCLUDE"} --skip=check/chrootless \
{{ DIST }} "/tmp/$MODE.tar" {{ MIRROR }}
done
cmp /tmp/root.tar /tmp/chrootless.tar || diffoscope /tmp/root.tar /tmp/chrootless.tar

View file

@ -18,18 +18,23 @@ if [ "$(id -u)" -eq 0 ] && [ "{{ MODE }}" != "root" ] && [ "{{ MODE }}" != "auto
prefix="runuser -u ${SUDO_USER:-user} --"
fi
MMTARFILTER=
[ -x /usr/bin/mmtarfilter ] && MMTARFILTER=/usr/bin/mmtarfilter
[ -x ./tarfilter ] && MMTARFILTER=./tarfilter
# we need --hook-dir=./hooks/merged-usr because usrmerge does not understand
# DPKG_ROOT
# permissions drwxr-sr-x and extended attributes of ./var/log/journal/ cannot
# be preserved under fakeroot
# this applies to 'z' lines in files in /usr/lib/tmpfiles.d/
for INCLUDE in '' 'apt' 'apt,build-essential' 'systemd-sysv'; do
{{ CMD }} --variant={{ VARIANT }} --hook-dir=./hooks/merged-usr \
--customize-hook='if [ -d "$1"/var/log/journal ]; then rmdir "$1"/var/log/journal; mkdir --mode=2755 "$1"/var/log/journal; chroot "$1" chown root:systemd-journal /var/log/journal; fi' \
--customize-hook="if [ \"$INCLUDE\" = systemd-sysv ]; then for f in var/log/journal etc/credstore etc/credstore.encrypted; do chmod 00755 \"\$1/\$f\"; done; fi" \
${INCLUDE:+--include="$INCLUDE"} \
{{ DIST }} /tmp/root.tar {{ MIRROR }}
{{ DIST }} - {{ MIRROR }} | "$MMTARFILTER" --pax-exclude='*' >/tmp/root.tar
$prefix fakeroot {{ CMD }} --mode={{ MODE }} --variant={{ VARIANT }} --hook-dir=./hooks/merged-usr \
${INCLUDE:+--include="$INCLUDE"} \
{{ DIST }} /tmp/chrootless.tar {{ MIRROR }}
{{ DIST }} - {{ MIRROR }} | "$MMTARFILTER" > /tmp/chrootless.tar
cmp /tmp/root.tar /tmp/chrootless.tar || diffoscope /tmp/root.tar /tmp/chrootless.tar
rm /tmp/chrootless.tar /tmp/root.tar
done

View file

@ -45,7 +45,7 @@ for INCLUDE in '' 'apt' 'systemd-sysv'; do
arch-test "$arch" && exit 1
{{ CMD }} --mode=chrootless --architecture="$arch" --variant={{ VARIANT }} \
--hook-dir=./hooks/merged-usr ${INCLUDE:+--include="$INCLUDE"} \
{{ DIST }} "/tmp/chrootless.tar" {{ MIRROR }}
--skip=check/chrootless {{ DIST }} "/tmp/chrootless.tar" {{ MIRROR }}
# when creating a foreign architecture chroot, the tarballs are not
# bit-by-bit identical but contain a few remaining differences:
#

View file

@ -22,12 +22,17 @@ chroot /tmp/debian-chroot dpkg-query -f '${binary:Package}\n' -W \
rm /tmp/expected
for cmd in echo cat sed grep; do
test -L /tmp/debian-chroot/bin/$cmd
test "$(readlink /tmp/debian-chroot/bin/$cmd)" = "/bin/busybox"
test "$(readlink /tmp/debian-chroot/bin/$cmd)" = "/usr/bin/busybox"
done
for cmd in sort tee; do
test -L /tmp/debian-chroot/usr/bin/$cmd
test "$(readlink /tmp/debian-chroot/usr/bin/$cmd)" = "/bin/busybox"
test "$(readlink /tmp/debian-chroot/usr/bin/$cmd)" = "/usr/bin/busybox"
done
# if /bin or /sbin are not symlinks, add /bin and /sbin to PATH
if [ ! -L /tmp/debian-chroot/bin ] || [ ! -L /tmp/debian-chroot/sbin ]; then
export PATH="$PATH:/sbin:/bin"
fi
chroot /tmp/debian-chroot echo foobar \
| chroot /tmp/debian-chroot cat \
| chroot /tmp/debian-chroot sort \