Support creating a fakechroot with merged-/usr on an unmerged-/usr system

Thanks: Helmut Grohne for finding this issue and help interating this
This commit is contained in:
Johannes Schauer Marin Rodrigues 2023-01-23 16:35:35 +01:00
parent d554c0b469
commit f737cce3f1
Signed by untrusted user: josch
GPG key ID: F2CBA5C78FBD83E1
4 changed files with 63 additions and 4 deletions

View file

@ -364,3 +364,6 @@ Test: apt-patterns
Test: apt-patterns-custom
Test: empty-sources.list
Test: merged-fakechroot-inside-unmerged-chroot
Needs-Root: true

View file

@ -264,7 +264,7 @@ END
--or --field=Priority important --or --field=Priority standard \
\))
pkgs="$pkgs build-essential busybox gpg eatmydata"
pkgs="$pkgs build-essential busybox gpg eatmydata fakechroot fakeroot"
# we need usr-is-merged to simulate debootstrap behaviour for all dists
# starting from Debian 12 (Bullseye)

View file

@ -2602,12 +2602,19 @@ sub run_prepare {
$subst{ldconfig}
= '/usr/libexec/mmdebstrap/ldconfig.fakechroot';
}
my %mergedusrmap = (
"/bin" => "/usr/bin",
"/sbin" => "/usr/sbin",
"/usr/bin/" => "/bin",
"/usr/sbin" => "/sbin"
);
my %fakechrootsubst;
foreach my $d (split ':', $ENV{PATH}) {
foreach my $k (sort %subst) {
if (-e "$d/$k") {
$fakechrootsubst{"$d/$k=$subst{$k}"} = 1;
}
my $mapped_path = $mergedusrmap{$d} // $d;
next if !-e "$d/$k" && !-e "$mapped_path/$k";
$fakechrootsubst{"$d/$k=$subst{$k}"} = 1;
$fakechrootsubst{"$mapped_path/$k=$subst{$k}"} = 1;
}
}
if (defined $ENV{FAKECHROOT_CMD_SUBST}

View file

@ -0,0 +1,49 @@
#!/bin/sh
#
# make sure that the $FAKECHROOT_CMD_SUBST environment variable is set up
# such that one can create a merged-/usr chroot from an unmerged-/usr system
set -eu
export LC_ALL=C.UTF-8
export SOURCE_DATE_EPOCH={{ SOURCE_DATE_EPOCH }}
trap "rm -f /tmp/chroot-fakechroot.tar /tmp/chroot-root.tar" EXIT INT TERM
[ "$(whoami)" = "root" ]
{{ CMD }} --mode=root --variant=apt --hook-dir=./hooks/merged-usr {{ DIST }} /tmp/chroot-root.tar {{ MIRROR }}
cat << 'SCRIPT' > script.sh
#!/bin/sh
set -exu
rootfs="$1"
mkdir -p "$rootfs/mnt/hooks"
[ -e /usr/libexec/mmdebstrap/ldconfig.fakechroot ] && cp -a /usr/libexec/mmdebstrap/ldconfig.fakechroot "$rootfs/mnt"
[ -e ./ldconfig.fakechroot ] && cp -a ./ldconfig.fakechroot "$rootfs/mnt"
[ -e /usr/share/mmdebstrap/hooks/merged-usr ] && cp -a /usr/share/mmdebstrap/hooks/merged-usr "$rootfs/mnt/hooks"
[ -e ./hooks/merged-usr ] && cp -a ./hooks/merged-usr "$rootfs/mnt/hooks"
[ -e /usr/bin/mmdebstrap ] && cp -aT /usr/bin/mmdebstrap "$rootfs/usr/bin/mmdebstrap"
[ -e ./mmdebstrap ] && cp -aT ./mmdebstrap "$rootfs/mnt/mmdebstrap"
chroot "$rootfs" env --chdir=/mnt \
runuser -u user -- \
{{ CMD }} --mode=fakechroot --variant=apt \
--hook-dir=./hooks/merged-usr \
--customize-hook='chroot "$1" echo "$FAKECHROOT_CMD_SUBST" | tr ":" "\n" | sort' \
--customize-hook='chroot "$1" sh -c "exec test \"\$(readlink /bin)\" = usr/bin"' \
--customize-hook='chroot "$1" sh -c "exec test \"\$(realpath -e /bin/ldd)\" = /usr/bin/ldd"' \
--customize-hook='chroot "$1" echo ":$FAKECHROOT_CMD_SUBST" | grep --quiet :/usr/bin/ldd=' \
--customize-hook='chroot "$1" echo ":$FAKECHROOT_CMD_SUBST" | grep --quiet :/bin/ldd=' \
--customize-hook='chroot "$1" env PATH=/bin ldd /bin/true 2>&1 | grep --quiet "fakeldd: objdump: command not found: install binutils package"' \
--customize-hook='chroot "$1" sh -c "exec test \"\$(readlink /sbin)\" = usr/sbin"' \
--customize-hook='chroot "$1" sh -c "exec test \"\$(realpath -e /sbin/ldconfig)\" = /usr/sbin/ldconfig"' \
--customize-hook='chroot "$1" echo ":$FAKECHROOT_CMD_SUBST" | grep --quiet :/usr/sbin/ldconfig=' \
--customize-hook='chroot "$1" echo ":$FAKECHROOT_CMD_SUBST" | grep --quiet :/sbin/ldconfig=' \
--customize-hook='chroot "$1" env PATH=/sbin ldconfig 2>&1 | grep --quiet "/usr/bin/env: python3: No such file or directory"' \
{{ DIST }} /tmp/chroot-fakechroot.tar {{ MIRROR }}
SCRIPT
chmod +x script.sh
{{ CMD }} --mode=root --variant=apt --include=perl,python3,adduser,fakeroot,fakechroot \
--hook-dir=./hooks/no-merged-usr \
--customize-hook='chroot "$1" adduser --gecos user --disabled-password user' \
--customize-hook='chroot "$1" sh -c "exec test \"\$(realpath -e /usr/bin/ldd)\" = /usr/bin/ldd"' \
--customize-hook='chroot "$1" sh -c "exec test ! -e /usr/sbin/ldconfig"' \
--customize-hook=./script.sh \
--customize-hook="copy-out /tmp/chroot-fakechroot.tar /tmp" \
{{ DIST }} /dev/null {{ MIRROR }}
cmp /tmp/chroot-fakechroot.tar /tmp/chroot-root.tar