diff --git a/coverage.txt b/coverage.txt index 55bc042..40dc033 100644 --- a/coverage.txt +++ b/coverage.txt @@ -354,3 +354,7 @@ Needs-QEMU: true Test: pivot_root Modes: root unshare Needs-QEMU: true + +Test: jessie-or-older +Needs-QEMU: true +Variants: essential apt minbase diff --git a/hooks/jessie-or-older/extract00.sh b/hooks/jessie-or-older/extract00.sh new file mode 100755 index 0000000..cb43648 --- /dev/null +++ b/hooks/jessie-or-older/extract00.sh @@ -0,0 +1,48 @@ +#!/bin/sh + +set -eu + +if [ "${MMDEBSTRAP_VERBOSITY:-1}" -ge 3 ]; then + set -x +fi + +TARGET="$1" + +for f in available diversions cmethopt; do + if [ ! -e "$TARGET/var/lib/dpkg/$f" ]; then + touch "$TARGET/var/lib/dpkg/$f" + fi +done + +if [ -z "${MMDEBSTRAP_ESSENTIAL+x}" ]; then + MMDEBSTRAP_ESSENTIAL= + for f in "$TARGET/var/cache/apt/archives/"*.deb; do + [ -f "$f" ] || continue + f="${f#"$TARGET"}" + MMDEBSTRAP_ESSENTIAL="$MMDEBSTRAP_ESSENTIAL $f" + done +fi + +fname_base_passwd= +fname_base_files= +fname_dpkg= +for pkg in $MMDEBSTRAP_ESSENTIAL; do + pkgname=$(dpkg-deb --show --showformat='${Package}' "$TARGET/$pkg") + # shellcheck disable=SC2034 + case $pkgname in + base-passwd) fname_base_passwd=$pkg;; + base-files) fname_base_files=$pkg;; + dpkg) fname_dpkg=$pkg;; + esac +done + +for var in base_passwd base_files dpkg; do + eval 'val=$fname_'"$var" + [ -z "$val" ] && continue + chroot "$TARGET" dpkg --install --force-depends "$val" +done + +# shellcheck disable=SC2086 +chroot "$TARGET" dpkg --unpack --force-depends $MMDEBSTRAP_ESSENTIAL + +chroot "$TARGET" dpkg --configure --pending diff --git a/mmdebstrap b/mmdebstrap index 8d99ac6..1bbd00c 100755 --- a/mmdebstrap +++ b/mmdebstrap @@ -1541,8 +1541,9 @@ sub setup_mounts { } sub run_hooks { - my $name = shift; - my $options = shift; + my $name = shift; + my $options = shift; + my $essential_pkgs = shift; if (scalar @{ $options->{"${name}_hook"} } == 0) { return; @@ -1601,6 +1602,12 @@ sub run_hooks { push @env_opts, ("MMDEBSTRAP_INCLUDE=" . (join ",", @escaped_includes)); } + # Give the extract hook access to the essential packages that are about to + # be installed + if ($name eq "extract" and scalar @{$essential_pkgs} > 0) { + push @env_opts, + ("MMDEBSTRAP_ESSENTIAL=" . (join " ", @{$essential_pkgs})); + } # Unset the close-on-exec flag, so that the file descriptor does not # get closed when we exec diff --git a/tests/jessie-or-older b/tests/jessie-or-older new file mode 100644 index 0000000..b3f2705 --- /dev/null +++ b/tests/jessie-or-older @@ -0,0 +1,39 @@ +#!/bin/sh +set -eu +export LC_ALL=C.UTF-8 +if [ ! -e /mmdebstrap-testenv ]; then + echo "this test modifies the system and should only be run inside a container" >&2 + exit 1 +fi +adduser --gecos user --disabled-password user +sysctl -w kernel.unprivileged_userns_clone=1 +export SOURCE_DATE_EPOCH={{ SOURCE_DATE_EPOCH }} + +filter() { + ./tarfilter \ + --path-exclude=/usr/bin/uncompress \ + --path-exclude=/var/cache/debconf/config.dat-old \ + --path-exclude=/var/cache/debconf/templates.dat-old \ + --path-exclude=/var/lib/dpkg/available \ + --path-exclude=/var/lib/dpkg/cmethopt \ + --path-exclude=/var/lib/dpkg/status-old \ + --path-exclude=/var/lib/shells.state +} + +# base for comparison without jessie-or-older hook +{{ CMD }} --mode=root --variant={{ VARIANT }} {{ DIST }} - {{ MIRROR }} | filter > /tmp/debian-chroot-root-normal.tar + +# root +{{ CMD }} --mode=root --variant={{ VARIANT }} --hook-dir=./hooks/jessie-or-older {{ DIST }} - {{ MIRROR }} | filter > /tmp/debian-chroot-root.tar +cmp /tmp/debian-chroot-root-normal.tar /tmp/debian-chroot-root.tar +rm /tmp/debian-chroot-root.tar +# unshare +runuser -u user -- {{ CMD }} --mode=unshare --variant={{ VARIANT }} --hook-dir=./hooks/jessie-or-older {{ DIST }} - {{ MIRROR }} | filter > /tmp/debian-chroot-unshare.tar +cmp /tmp/debian-chroot-root-normal.tar /tmp/debian-chroot-unshare.tar +rm /tmp/debian-chroot-unshare.tar +# fakechroot +runuser -u user -- {{ CMD }} --mode=fakechroot --variant={{ VARIANT }} --hook-dir=./hooks/jessie-or-older {{ DIST }} - {{ MIRROR }} | filter > /tmp/debian-chroot-fakechroot.tar +cmp /tmp/debian-chroot-root-normal.tar /tmp/debian-chroot-fakechroot.tar +rm /tmp/debian-chroot-fakechroot.tar + +rm /tmp/debian-chroot-root-normal.tar