add ldconfig.fakechroot and translate symlinks for bit-by-bit identical buildd variant
This commit is contained in:
parent
b3e08897c3
commit
6d59d51a4a
3 changed files with 127 additions and 20 deletions
13
coverage.sh
13
coverage.sh
|
@ -96,6 +96,13 @@ if [ ! -e shared/proxysolver ] || [ proxysolver -nt shared/proxysolver ]; then
|
||||||
cp -a /usr/lib/apt/solvers/mmdebstrap-dump-solution shared/proxysolver
|
cp -a /usr/lib/apt/solvers/mmdebstrap-dump-solution shared/proxysolver
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
if [ ! -e shared/ldconfig.fakechroot ] || [ ldconfig.fakechroot -nt shared/ldconfig.fakechroot ]; then
|
||||||
|
if [ -e ./ldconfig.fakechroot ]; then
|
||||||
|
cp -a ldconfig.fakechroot shared
|
||||||
|
else
|
||||||
|
cp -a /usr/libexec/mmdebstrap/ldconfig.fakechroot shared/ldconfig.fakechroot
|
||||||
|
fi
|
||||||
|
fi
|
||||||
mkdir -p shared/hooks
|
mkdir -p shared/hooks
|
||||||
if [ ! -e shared/hooks/setup00-merged-usr.sh ] || [ hooks/setup00-merged-usr.sh -nt shared/hooks/setup00-merged-usr.sh ]; then
|
if [ ! -e shared/hooks/setup00-merged-usr.sh ] || [ hooks/setup00-merged-usr.sh -nt shared/hooks/setup00-merged-usr.sh ]; then
|
||||||
if [ -e hooks/setup00-merged-usr.sh ]; then
|
if [ -e hooks/setup00-merged-usr.sh ]; then
|
||||||
|
@ -754,8 +761,10 @@ fi
|
||||||
runuser -u user -- $CMD --mode=unshare --variant=$variant $DEFAULT_DIST /tmp/debian-chroot-unshare.$format $mirror
|
runuser -u user -- $CMD --mode=unshare --variant=$variant $DEFAULT_DIST /tmp/debian-chroot-unshare.$format $mirror
|
||||||
cmp /tmp/debian-chroot-root.$format /tmp/debian-chroot-unshare.$format
|
cmp /tmp/debian-chroot-root.$format /tmp/debian-chroot-unshare.$format
|
||||||
rm /tmp/debian-chroot-unshare.$format
|
rm /tmp/debian-chroot-unshare.$format
|
||||||
case $variant in essential|apt|minbase)
|
case $variant in essential|apt|minbase|buildd)
|
||||||
# /etc/ld.so.cache differs with some variants
|
# variants important and standard differ because permissions drwxr-sr-x
|
||||||
|
# and extended attributes of ./var/log/journal/ cannot be preserved
|
||||||
|
# in fakechroot mode
|
||||||
runuser -u user -- $CMD --mode=fakechroot --variant=$variant $DEFAULT_DIST /tmp/debian-chroot-fakechroot.$format $mirror
|
runuser -u user -- $CMD --mode=fakechroot --variant=$variant $DEFAULT_DIST /tmp/debian-chroot-fakechroot.$format $mirror
|
||||||
cmp /tmp/debian-chroot-root.$format /tmp/debian-chroot-fakechroot.$format
|
cmp /tmp/debian-chroot-root.$format /tmp/debian-chroot-fakechroot.$format
|
||||||
rm /tmp/debian-chroot-fakechroot.$format
|
rm /tmp/debian-chroot-fakechroot.$format
|
||||||
|
|
111
ldconfig.fakechroot
Executable file
111
ldconfig.fakechroot
Executable file
|
@ -0,0 +1,111 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
#
|
||||||
|
# This script is in the public domain
|
||||||
|
#
|
||||||
|
# Author: Johannes Schauer Marin Rodrigues <josch@mister-muffin.de>
|
||||||
|
#
|
||||||
|
# This is command substitution for ldconfig under fakechroot:
|
||||||
|
#
|
||||||
|
# export FAKECHROOT_CMD_SUBST=/sbin/ldconfig=/path/to/ldconfig.fakechroot
|
||||||
|
#
|
||||||
|
# Statically linked binaries cannot work with fakechroot and thus have to be
|
||||||
|
# replaced by either /bin/true or a more clever solution like this one. The
|
||||||
|
# ldconfig command supports the -r option which allows passing a chroot
|
||||||
|
# directory for ldconfig to work in. This can be used to run ldconfig without
|
||||||
|
# fakechroot but still let it create /etc/ld.so.cache inside the chroot.
|
||||||
|
#
|
||||||
|
# Since absolute symlinks are broken without fakechroot to translate them,
|
||||||
|
# we read /etc/ld.so.conf and turn all absolute symlink shared libraries into
|
||||||
|
# relative ones. At program exit, the original state is restored.
|
||||||
|
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import subprocess
|
||||||
|
import atexit
|
||||||
|
import glob
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
symlinks = []
|
||||||
|
|
||||||
|
|
||||||
|
def restore_symlinks():
|
||||||
|
for (link, target, atime, mtime) in symlinks:
|
||||||
|
link.unlink()
|
||||||
|
link.symlink_to(target)
|
||||||
|
os.utime(link, times=None, ns=(atime, mtime), follow_symlinks=False)
|
||||||
|
|
||||||
|
|
||||||
|
atexit.register(restore_symlinks)
|
||||||
|
|
||||||
|
|
||||||
|
def get_libdirs(chroot, configs):
|
||||||
|
res = []
|
||||||
|
for conf in configs:
|
||||||
|
for line in (Path(conf)).read_text().splitlines():
|
||||||
|
line = line.strip()
|
||||||
|
if not line:
|
||||||
|
continue
|
||||||
|
if line.startswith("#"):
|
||||||
|
continue
|
||||||
|
if line.startswith("include "):
|
||||||
|
assert line.startswith("include /")
|
||||||
|
res.extend(
|
||||||
|
get_libdirs(chroot, chroot.glob(line.removeprefix("include /")))
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
assert line.startswith("/"), line
|
||||||
|
line = line.lstrip("/")
|
||||||
|
if not (chroot / Path(line)).is_dir():
|
||||||
|
continue
|
||||||
|
for f in (chroot / Path(line)).iterdir():
|
||||||
|
if not f.is_symlink():
|
||||||
|
continue
|
||||||
|
linktarget = f.readlink()
|
||||||
|
# make sure that the linktarget is an absolute path inside the
|
||||||
|
# chroot
|
||||||
|
if not str(linktarget).startswith("/"):
|
||||||
|
continue
|
||||||
|
if chroot not in linktarget.parents:
|
||||||
|
continue
|
||||||
|
# store original link so that we can restore it later
|
||||||
|
symlinks.append(
|
||||||
|
(f, linktarget, f.lstat().st_atime_ns, f.lstat().st_mtime_ns)
|
||||||
|
)
|
||||||
|
# replace absolute symlink by relative link
|
||||||
|
relative = os.path.relpath(linktarget, f.parent)
|
||||||
|
f.unlink()
|
||||||
|
f.symlink_to(relative)
|
||||||
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
if "FAKECHROOT_BASE_ORIG" not in os.environ:
|
||||||
|
print("FAKECHROOT_BASE_ORIG is not set", file=sys.stderr)
|
||||||
|
print(
|
||||||
|
"must be executed under fakechroot using FAKECHROOT_CMD_SUBST",
|
||||||
|
file=sys.stderr,
|
||||||
|
)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
chroot = Path(os.environ["FAKECHROOT_BASE_ORIG"])
|
||||||
|
|
||||||
|
if not (chroot / "sbin" / "ldconfig").exists():
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
(chroot / "var" / "cache" / "ldconfig").mkdir(
|
||||||
|
mode=0o700, parents=True, exist_ok=True
|
||||||
|
)
|
||||||
|
|
||||||
|
for d in get_libdirs(chroot, [chroot / "etc" / "ld.so.conf"]):
|
||||||
|
make_relative(d)
|
||||||
|
|
||||||
|
# we add any additional arguments before "-r" such that any other "-r"
|
||||||
|
# option will be overwritten by the one we set
|
||||||
|
subprocess.check_call(
|
||||||
|
[chroot / "sbin" / "ldconfig"] + sys.argv[1:] + ["-r", chroot]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
23
mmdebstrap
23
mmdebstrap
|
@ -2660,28 +2660,15 @@ sub run_prepare {
|
||||||
# /etc/fakechroot/debootstrap.env and
|
# /etc/fakechroot/debootstrap.env and
|
||||||
# /etc/fakechroot/chroot.env
|
# /etc/fakechroot/chroot.env
|
||||||
{
|
{
|
||||||
# we add "$@" before "-r" such that any other "-r" options will be
|
my $ldconfig = getcwd() . '/ldconfig.fakechroot';
|
||||||
# overwritten by the one we set
|
if (!-x $ldconfig) {
|
||||||
my $escapedroot = shellescape $options->{root};
|
$ldconfig = '/usr/libexec/mmdebstrap/ldconfig.fakechroot';
|
||||||
my ($fh, $filename) = tempfile(
|
}
|
||||||
"mmdebstrap.ldconfig.XXXXXXXXXXXX",
|
|
||||||
UNLINK => 1,
|
|
||||||
TMPDIR => 1
|
|
||||||
);
|
|
||||||
print $fh <<EOF;
|
|
||||||
#!/bin/sh
|
|
||||||
set -e
|
|
||||||
if [ ! -e $escapedroot/sbin/ldconfig ]; then exit 0; fi
|
|
||||||
mkdir --mode=700 --parents $escapedroot/var/cache/ldconfig
|
|
||||||
$escapedroot/sbin/ldconfig "\$@" -r $escapedroot
|
|
||||||
EOF
|
|
||||||
close $fh;
|
|
||||||
chmod 0755, $filename or error "cannot chmod $filename";
|
|
||||||
my @fakechrootsubst = ();
|
my @fakechrootsubst = ();
|
||||||
foreach my $d ('/usr/sbin', '/usr/bin', '/sbin', '/bin') {
|
foreach my $d ('/usr/sbin', '/usr/bin', '/sbin', '/bin') {
|
||||||
push @fakechrootsubst, "$d/chroot=/usr/sbin/chroot.fakechroot";
|
push @fakechrootsubst, "$d/chroot=/usr/sbin/chroot.fakechroot";
|
||||||
push @fakechrootsubst, "$d/mkfifo=/bin/true";
|
push @fakechrootsubst, "$d/mkfifo=/bin/true";
|
||||||
push @fakechrootsubst, "$d/ldconfig=$filename";
|
push @fakechrootsubst, "$d/ldconfig=$ldconfig";
|
||||||
push @fakechrootsubst, "$d/ldd=/usr/bin/ldd.fakechroot";
|
push @fakechrootsubst, "$d/ldd=/usr/bin/ldd.fakechroot";
|
||||||
push @fakechrootsubst, "$d/ischroot=/bin/true";
|
push @fakechrootsubst, "$d/ischroot=/bin/true";
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue