summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md6
-rw-r--r--coverage.txt2
-rwxr-xr-xmake_mirror.sh2
-rwxr-xr-xmmdebstrap98
-rwxr-xr-xrun_qemu.sh47
-rw-r--r--tests/apt-patterns2
-rw-r--r--tests/apt-patterns-custom2
-rw-r--r--tests/aspcud-apt-solver2
-rw-r--r--tests/essential-hook1
-rw-r--r--tests/include1
-rw-r--r--tests/include-foreign-libmagic-mgc1
-rw-r--r--tests/include-foreign-libmagic-mgc-with-multiple-arch-options1
-rw-r--r--tests/logfile1
-rw-r--r--tests/multiple-include1
-rw-r--r--tests/not-having-to-install-apt-in-include-because-a-hook-did-it-before2
-rw-r--r--tests/skip-tar-in-mknod5
16 files changed, 93 insertions, 81 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index eea34e4..21ed927 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+1.5.1 (2024-06-03)
+------------------
+
+ - in root and unshare mode, run 'mount --make-rprivate /' before bind-mounting
+ - switch apt variant from using 'apt-get dist-upgrade' to apt patterns
+
1.5.0 (2024-05-14)
------------------
diff --git a/coverage.txt b/coverage.txt
index dde5b33..c040b8b 100644
--- a/coverage.txt
+++ b/coverage.txt
@@ -433,4 +433,4 @@ Test: skip-output-mknod
Modes: root unshare
Test: skip-tar-in-mknod
-Modes: root
+Modes: unshare
diff --git a/make_mirror.sh b/make_mirror.sh
index 3f8aae4..419503b 100755
--- a/make_mirror.sh
+++ b/make_mirror.sh
@@ -457,7 +457,6 @@ if [ "$HAVE_QEMU" = "yes" ]; then
if [ ! -e ./mmdebstrap ]; then
pkgs="$pkgs,mmdebstrap"
fi
- pkgs="$pkgs,auditd"
arches=$HOSTARCH
if [ "$RUN_MA_SAME_TESTS" = "yes" ]; then
case "$HOSTARCH" in
@@ -551,6 +550,7 @@ END
--customize-hook='copy-in "'"$tmpdir"'/worker.sh" /' \
--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"' \
+ --customize-hook='touch "$1/etc/systemd/system/tmp.mount"' \
"$mirror"
kill $PROXYPID
diff --git a/mmdebstrap b/mmdebstrap
index 538ea02..dd168df 100755
--- a/mmdebstrap
+++ b/mmdebstrap
@@ -23,7 +23,7 @@
use strict;
use warnings;
-our $VERSION = '1.5.0';
+our $VERSION = '1.5.1';
use English;
use Getopt::Long;
@@ -36,7 +36,8 @@ use File::Find;
use Cwd qw(abs_path getcwd);
require "syscall.ph"; ## no critic (Modules::RequireBarewordIncludes)
require "sys/ioctl.ph"; ## no critic (Modules::RequireBarewordIncludes)
-use Fcntl qw(S_IFCHR S_IFBLK FD_CLOEXEC F_GETFD F_SETFD);
+use Fcntl
+ qw(S_IFCHR S_IFBLK FD_CLOEXEC F_GETFD F_SETFD LOCK_EX O_RDONLY O_DIRECTORY);
use List::Util qw(any none);
use POSIX
qw(SIGINT SIGHUP SIGPIPE SIGTERM SIG_BLOCK SIG_UNBLOCK strftime isatty);
@@ -1177,6 +1178,8 @@ sub setup_mounts {
eval {
if (any { $_ eq $options->{mode} } ('root', 'unshare')) {
+ 0 == system('mount', "--make-rprivate", "/")
+ or warning("mount --make-rprivate / failed: $?");
# if more than essential should be installed, make the system look
# more like a real one by creating or bind-mounting the device
# nodes
@@ -2067,19 +2070,16 @@ sub run_setup() {
# for authentication, use the keyrings from the host
print $conf "Dir::Etc::Trusted \"$options->{apttrusted}\";\n";
print $conf "Dir::Etc::TrustedParts \"$options->{apttrustedparts}\";\n";
- if ($options->{variant} ne 'apt') {
- # apt considers itself essential. Thus, when generating an EDSP
- # document for an external solver, it will add the Essential:yes field
- # to the apt package stanza. This is unnecessary for any other variant
- # than 'apt' because in all other variants we compile the set of
- # packages we consider essential ourselves and for the 'essential'
- # variant it would even be wrong to add apt. This workaround is only
- # needed when apt is used with an external solver but doesn't hurt
- # otherwise and we don't have a good way to figure out whether apt is
- # using an external solver or not short of parsing the --aptopt
- # options.
- print $conf "pkgCacheGen::ForceEssential \",\";\n";
- }
+ # apt considers itself essential. Thus, when generating an EDSP document
+ # for an external solver, it will add the Essential:yes field to the apt
+ # package stanza. This is unnecessary because we compile the set of
+ # packages we consider essential ourselves and for the 'essential' variant
+ # it would even be wrong to add apt. This workaround is only needed when
+ # apt is used with an external solver but doesn't hurt otherwise and we
+ # don't have a good way to figure out whether apt is using an external
+ # solver or not short of parsing the --aptopt options.
+ print $conf "pkgCacheGen::ForceEssential \",\";\n";
+
close $conf;
# We put certain configuration items in their own configuration file
@@ -2485,27 +2485,8 @@ sub run_download() {
dryrun => $options->{dryrun},
},
);
- } elsif ($options->{variant} eq 'apt') {
- # if we just want to install Essential:yes packages, apt and their
- # dependencies then we can make use of libapt treating apt as
- # implicitly essential. An upgrade with the (currently) empty status
- # file will trigger an installation of the essential packages plus apt.
- #
- # 2018-09-02, #debian-dpkg on OFTC, times in UTC+2
- # 23:39 < josch> I'll just put it in my script and if it starts
- # breaking some time I just say it's apt's fault. :P
- # 23:42 < DonKult> that is how it usually works, so yes, do that :P (<-
- # and please add that line next to it so you can
- # remind me in 5+ years that I said that after I wrote
- # in the bugreport: "Are you crazy?!? Nobody in his
- # right mind would even suggest depending on it!")
- @dl_debs = run_apt_download_progress({
- APT_ARGV => ['dist-upgrade'],
- dryrun => $options->{dryrun},
- },
- );
} elsif (any { $_ eq $options->{variant} }
- ('essential', 'standard', 'important', 'required', 'buildd')) {
+ ('essential', 'apt', 'standard', 'important', 'required', 'buildd')) {
# 2021-06-07, #debian-apt on OFTC, times in UTC+2
# 17:27 < DonKult> (?essential includes 'apt' through)
# 17:30 < josch> DonKult: no, because pkgCacheGen::ForceEssential ",";
@@ -2979,8 +2960,14 @@ sub run_install() {
my $options = shift;
my @pkgs_to_install = (@{ $options->{include} });
+ if ($options->{variant} eq 'extract') {
+ error "must not be called with variant extract";
+ }
+ if (none { $_ eq $options->{variant} } ('custom', 'essential')) {
+ push @pkgs_to_install, 'apt';
+ }
if ($options->{variant} eq 'buildd') {
- push @pkgs_to_install, 'build-essential', 'apt';
+ push @pkgs_to_install, 'build-essential';
}
if (any { $_ eq $options->{variant} }
('required', 'important', 'standard')) {
@@ -4452,8 +4439,9 @@ sub approx_disk_usage {
# image. See https://bugs.debian.org/1005857
find({ wanted => $scan_installed_size, no_chdir => 1 }, $directory);
- # because the above is only a heuristic we add 10% extra for good measure
- return int($installed_size * 1.1);
+ # the above is only a heuristic and especially ext4 will consume quite a
+ # few more blocks than the heuristic above is going to compute
+ return int($installed_size * 1.2);
}
sub main() {
@@ -5757,6 +5745,7 @@ sub main() {
$blocksize = 1048576;
}
+ my $rootdir_handle;
if (any { $_ eq $options->{format} }
('tar', 'squashfs', 'ext2', 'ext4', 'null')) {
if ($options->{format} ne 'null') {
@@ -5787,6 +5776,13 @@ sub main() {
# directory
$options->{root} = tempdir('mmdebstrap.XXXXXXXXXX', TMPDIR => 1);
info "using $options->{root} as tempdir";
+ # add an flock on the temporary directory to prevent cleanup by systemd
+ # see section Age in tmpfiles.d(5)
+ sysopen($rootdir_handle, $options->{root}, O_RDONLY | O_DIRECTORY)
+ or error "Failed to sysopen $options->{root}: $!\n";
+ flock($rootdir_handle, LOCK_EX)
+ or error "Unable to flock $options->{root}: $!\n";
+
# in unshare and root mode, other users than the current user need to
# access the rootfs, most prominently, the _apt user. Thus, make the
# temporary directory world readable.
@@ -7072,14 +7068,10 @@ considered for selection of C<Essential:yes> packages.
=item B<apt>
-The B<essential> set plus apt. This variant uses the fact that B<apt> treats
-itself as essential and thus running C<apt-get dist-upgrade> without any
-packages installed will install the B<essential> set plus B<apt>. If you just
-want B<essential> and B<apt>, then this variant is faster than using the
-B<essential> variant and adding B<apt> via C<--include> because all packages
-get installed at once. The downside of this variant is, that if it should
-happen that an B<essential> package is not installable, then it will just get
-ignored without throwing an error.
+The B<essential> set plus apt.
+It is roughly equivalent to running mmdebstrap with
+
+ --variant=essential --include="apt"
=item B<buildd>
@@ -7408,15 +7400,11 @@ the B<setup> step. This can be disabled using B<--skip=update>.
=item B<download>
In the B<extract> and B<custom> variants, C<apt-get install> is used to
-download all the packages requested via the B<--include> option. The B<apt>
-variant uses the fact that libapt treats the C<apt> packages as implicitly
-essential to download only all C<Essential:yes> packages plus apt using
-C<apt-get dist-upgrade>. In the remaining variants, all Packages files
-downloaded by the B<update> step are inspected to find the C<Essential:yes>
-package set as well as all packages of the required priority. 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.
+download all the packages requested via the B<--include> option. In the
+remaining variants, apt patterns are used to find the C<Essential:yes> packages
+from the native architecture. 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<mount>
diff --git a/run_qemu.sh b/run_qemu.sh
index fc00ed9..a51493b 100755
--- a/run_qemu.sh
+++ b/run_qemu.sh
@@ -4,6 +4,7 @@ set -eu
: "${DEFAULT_DIST:=unstable}"
: "${cachedir:=./shared/cache}"
+: "${MMDEBSTRAP_TESTS_DEBUG:=no}"
tmpdir="$(mktemp -d)"
cleanup() {
@@ -29,20 +30,42 @@ fi
touch shared/output.txt
setpriv --pdeathsig TERM tail -f shared/output.txt &
-# to connect to serial use:
-# minicom -D 'unix#/tmp/ttyS0'
-#
-# or this (quit with ctrl+q):
-# 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 \
+set -- timeout --foreground 40m \
+ debvm-run --image="$(realpath "$cachedir")/debian-$DEFAULT_DIST.ext4" \
+ --
+cpuname=$(lscpu | awk '/Model name:/ {print $3}' | tr '\n' '+')
+ncpu=$(lscpu | awk '/Core\(s\) per socket:/ {print $4}' | tr '\n' '+')
+if [ "$cpuname" = "Cortex-A53+Cortex-A73+" ] && [ "$ncpu" = "2+4+" ]; then
+ # crude detection of the big.LITTLE heterogeneous setup of cores on the
+ # amlogic a311d bananapi
+ #
+ # https://lists.nongnu.org/archive/html/qemu-devel/2020-10/msg08494.html
+ # https://gitlab.com/qemu-project/qemu/-/issues/239
+ # https://segments.zhan.science/posts/kvm_on_pinehone_pro/#trouble-with-heterogeneous-architecture
+ set -- taskset --cpu-list 2,3,4,5 "$@" -smp 4
+fi
+
+set -- "$@" -nic none -m 4G -snapshot
+
+if [ "$MMDEBSTRAP_TESTS_DEBUG" = "no" ]; then
+ # to connect to serial use:
+ # minicom -D 'unix#/tmp/ttyS0'
+ # or this (quit with ctrl+q):
+ # socat stdin,raw,echo=0,escape=0x11 unix-connect:/tmp/ttyS0
+ set -- "$@" \
-monitor unix:/tmp/monitor,server,nowait \
-serial unix:/tmp/ttyS0,server,nowait \
- -serial unix:/tmp/ttyS1,server,nowait \
- -virtfs local,id=mmdebstrap,path="$(pwd)/shared",security_model=none,mount_tag=mmdebstrap \
- >"$tmpdir/log" 2>&1 || ret=$?
+ -serial unix:/tmp/ttyS1,server,nowait
+fi
+
+set -- "$@" -virtfs local,id=mmdebstrap,path="$(pwd)/shared",security_model=none,mount_tag=mmdebstrap
+
+ret=0
+if [ "$MMDEBSTRAP_TESTS_DEBUG" = "no" ]; then
+ "$@" >"$tmpdir/log" 2>&1 || ret=$?
+else
+ "$@" 2>&1 | tee "$tmpdir/log" || ret=$?
+fi
if [ "$ret" -ne 0 ]; then
cat "$tmpdir/log"
exit $ret
diff --git a/tests/apt-patterns b/tests/apt-patterns
index c87e932..a4f03e2 100644
--- a/tests/apt-patterns
+++ b/tests/apt-patterns
@@ -5,4 +5,4 @@ trap "rm -f /tmp/debian-chroot.tar" EXIT INT TERM
{{ CMD }} --mode={{ MODE }} --variant=essential \
--include '?or(?exact-name(dummy-does-not-exist),?exact-name(apt))' \
{{ DIST }} /tmp/debian-chroot.tar {{ MIRROR }}
-tar -tf /tmp/debian-chroot.tar | sort | grep -v ./var/lib/apt/extended_states | diff -u tar1.txt -
+tar -tf /tmp/debian-chroot.tar | sort | diff -u tar1.txt -
diff --git a/tests/apt-patterns-custom b/tests/apt-patterns-custom
index 2348a76..bd78ed1 100644
--- a/tests/apt-patterns-custom
+++ b/tests/apt-patterns-custom
@@ -6,4 +6,4 @@ trap "rm -f /tmp/debian-chroot.tar" EXIT INT TERM
--include '?narrow(?archive(^{{ DIST }}$),?essential)' \
--include apt \
{{ DIST }} /tmp/debian-chroot.tar {{ MIRROR }}
-tar -tf /tmp/debian-chroot.tar | sort | diff -u tar1.txt -
+{ tar -tf /tmp/debian-chroot.tar; echo ./var/lib/apt/extended_states; } | sort | diff -u tar1.txt -
diff --git a/tests/aspcud-apt-solver b/tests/aspcud-apt-solver
index bc0fbc3..24ab3f8 100644
--- a/tests/aspcud-apt-solver
+++ b/tests/aspcud-apt-solver
@@ -6,6 +6,6 @@ trap "rm -f /tmp/debian-chroot.tar" EXIT INT TERM
--include "$(tr '\n' ',' < pkglist.txt)" \
--aptopt='APT::Solver "aspcud"' \
{{ DIST }} /tmp/debian-chroot.tar {{ MIRROR }}
-tar -tf /tmp/debian-chroot.tar | sort \
+{ tar -tf /tmp/debian-chroot.tar; echo ./var/lib/apt/extended_states; } | sort \
| grep -v '^./etc/apt/apt.conf.d/99mmdebstrap$' \
| diff -u tar1.txt -
diff --git a/tests/essential-hook b/tests/essential-hook
index dc2b01f..0013a1a 100644
--- a/tests/essential-hook
+++ b/tests/essential-hook
@@ -17,5 +17,4 @@ tar -C /tmp/debian-chroot --one-file-system -c . | tar -t | sort \
| grep -v '^./usr/share/lintian/overrides/tzdata' \
| grep -v '^./usr/share/zoneinfo' \
| grep -v '^./var/lib/dpkg/info/tzdata.' \
- | grep -v '^./var/lib/apt/extended_states$' \
| diff -u tar1.txt -
diff --git a/tests/include b/tests/include
index e284b7d..42d6936 100644
--- a/tests/include
+++ b/tests/include
@@ -6,7 +6,6 @@ trap "rm -rf /tmp/debian-chroot" EXIT INT TERM
rm /tmp/debian-chroot/usr/share/doc-base/doc-debian.debian-*
rm -r /tmp/debian-chroot/usr/share/doc/debian
rm -r /tmp/debian-chroot/usr/share/doc/doc-debian
-rm /tmp/debian-chroot/var/lib/apt/extended_states
rm /tmp/debian-chroot/var/lib/dpkg/info/doc-debian.list
rm /tmp/debian-chroot/var/lib/dpkg/info/doc-debian.md5sums
tar -C /tmp/debian-chroot --one-file-system -c . | tar -t | sort | diff -u tar1.txt -
diff --git a/tests/include-foreign-libmagic-mgc b/tests/include-foreign-libmagic-mgc
index 7845b31..6b0bd7d 100644
--- a/tests/include-foreign-libmagic-mgc
+++ b/tests/include-foreign-libmagic-mgc
@@ -36,7 +36,6 @@ rm /tmp/debian-chroot/usr/share/doc/libmagic-mgc/changelog.gz
rm /tmp/debian-chroot/usr/share/doc/libmagic-mgc/copyright
rm /tmp/debian-chroot/usr/share/file/magic.mgc
rm /tmp/debian-chroot/usr/share/misc/magic.mgc
-rm /tmp/debian-chroot/var/lib/apt/extended_states
rm /tmp/debian-chroot/var/lib/dpkg/info/libmagic-mgc.list
rm /tmp/debian-chroot/var/lib/dpkg/info/libmagic-mgc.md5sums
rmdir /tmp/debian-chroot/usr/share/doc/libmagic-mgc/
diff --git a/tests/include-foreign-libmagic-mgc-with-multiple-arch-options b/tests/include-foreign-libmagic-mgc-with-multiple-arch-options
index 8155727..6d878e0 100644
--- a/tests/include-foreign-libmagic-mgc-with-multiple-arch-options
+++ b/tests/include-foreign-libmagic-mgc-with-multiple-arch-options
@@ -37,7 +37,6 @@ rm /tmp/debian-chroot/usr/share/doc/libmagic-mgc/changelog.gz
rm /tmp/debian-chroot/usr/share/doc/libmagic-mgc/copyright
rm /tmp/debian-chroot/usr/share/file/magic.mgc
rm /tmp/debian-chroot/usr/share/misc/magic.mgc
-rm /tmp/debian-chroot/var/lib/apt/extended_states
rm /tmp/debian-chroot/var/lib/dpkg/info/libmagic-mgc.list
rm /tmp/debian-chroot/var/lib/dpkg/info/libmagic-mgc.md5sums
rmdir /tmp/debian-chroot/usr/share/doc/libmagic-mgc/
diff --git a/tests/logfile b/tests/logfile
index 5e2dbeb..eff6504 100644
--- a/tests/logfile
+++ b/tests/logfile
@@ -16,6 +16,7 @@ I: running apt-get update...
I: downloading packages with apt...
I: extracting archives...
I: installing essential packages...
+I: installing remaining packages inside the chroot...
I: cleaning package lists and apt cache...
LOG
tail --lines=1 /tmp/log | grep '^I: success in .* seconds$'
diff --git a/tests/multiple-include b/tests/multiple-include
index 36f53ec..eaef935 100644
--- a/tests/multiple-include
+++ b/tests/multiple-include
@@ -11,7 +11,6 @@ rm /tmp/debian-chroot/etc/localtime
rm /tmp/debian-chroot/etc/timezone
rm -r /tmp/debian-chroot/usr/share/doc/tzdata
rm -r /tmp/debian-chroot/usr/share/zoneinfo
-rm /tmp/debian-chroot/var/lib/apt/extended_states
for p in doc-debian tzdata; do
for f in list md5sums config postinst postrm templates preinst prerm; do
[ -e "/tmp/debian-chroot/var/lib/dpkg/info/$p.$f" ] || continue
diff --git a/tests/not-having-to-install-apt-in-include-because-a-hook-did-it-before b/tests/not-having-to-install-apt-in-include-because-a-hook-did-it-before
index 9a36307..c745cf3 100644
--- a/tests/not-having-to-install-apt-in-include-because-a-hook-did-it-before
+++ b/tests/not-having-to-install-apt-in-include-because-a-hook-did-it-before
@@ -6,4 +6,4 @@ trap "rm -f /tmp/debian-chroot.tar" EXIT INT TERM
--essential-hook='APT_CONFIG=$MMDEBSTRAP_APT_CONFIG apt-get update' \
--essential-hook='APT_CONFIG=$MMDEBSTRAP_APT_CONFIG apt-get --yes install apt' \
{{ DIST }} /tmp/debian-chroot.tar {{ MIRROR }}
-tar -tf /tmp/debian-chroot.tar | sort | grep -v ./var/lib/apt/extended_states | diff -u tar1.txt -
+tar -tf /tmp/debian-chroot.tar | sort | diff -u tar1.txt -
diff --git a/tests/skip-tar-in-mknod b/tests/skip-tar-in-mknod
index cc18977..eb3027a 100644
--- a/tests/skip-tar-in-mknod
+++ b/tests/skip-tar-in-mknod
@@ -3,7 +3,7 @@ set -eu
export LC_ALL=C.UTF-8
export SOURCE_DATE_EPOCH={{ SOURCE_DATE_EPOCH }}
-#[ {{ MODE }} = "unshare" ]
+[ {{ MODE }} = "unshare" ]
trap "rm -f /tmp/debian-chroot.tar" EXIT INT TERM
@@ -22,8 +22,7 @@ fi
$prefix {{ CMD }} --mode={{ MODE }} --variant=custom \
--skip=update,setup,cleanup,tar-in/mknod \
--setup-hook='tar-in ./cache/mmdebstrap-{{ DIST }}-apt.tar /' \
- --setup-hook='/sbin/auditctl -w "$1" -p wxa -k mykey' \
- '' /tmp/debian-chroot.tar || /sbin/ausearch --format text -k mykey
+ '' /tmp/debian-chroot.tar
cmp ./cache/mmdebstrap-{{ DIST }}-apt.tar /tmp/debian-chroot.tar \
|| diffoscope ./cache/mmdebstrap-{{ DIST }}-apt.tar /tmp/debian-chroot.tar