Compare commits

..

No commits in common. "fdbb66f75a8061681477d42bbb5a065ada7f2c4d" and "98aef0d023492326d676c48cb0b62f8905ab0fee" have entirely different histories.

35 changed files with 314 additions and 497 deletions

View file

@ -13,13 +13,14 @@ from collections import defaultdict
from itertools import product from itertools import product
have_qemu = os.getenv("HAVE_QEMU", "yes") == "yes" have_qemu = os.getenv("HAVE_QEMU", "yes") == "yes"
have_unshare = os.getenv("HAVE_UNSHARE", "yes") == "yes"
have_binfmt = os.getenv("HAVE_BINFMT", "yes") == "yes" have_binfmt = os.getenv("HAVE_BINFMT", "yes") == "yes"
run_ma_same_tests = os.getenv("RUN_MA_SAME_TESTS", "yes") == "yes" run_ma_same_tests = os.getenv("RUN_MA_SAME_TESTS", "yes") == "yes"
cmd = os.getenv("CMD", "./mmdebstrap") cmd = os.getenv("CMD", "./mmdebstrap")
default_dist = os.getenv("DEFAULT_DIST", "unstable") default_dist = os.getenv("DEFAULT_DIST", "unstable")
all_dists = ["oldstable", "stable", "testing", "unstable"] all_dists = ["oldstable", "stable", "testing", "unstable"]
default_mode = "auto" default_mode = "auto" if have_unshare else "root"
all_modes = ["auto", "root", "unshare", "fakechroot", "chrootless"] all_modes = ["auto", "root", "unshare", "fakechroot", "chrootless"]
default_variant = "apt" default_variant = "apt"
all_variants = [ all_variants = [
@ -201,7 +202,7 @@ def main():
args = parser.parse_args() args = parser.parse_args()
# copy over files from git or as distributed # copy over files from git or as distributed
for git, dist, target in [ for (git, dist, target) in [
("./mmdebstrap", "/usr/bin/mmdebstrap", "mmdebstrap"), ("./mmdebstrap", "/usr/bin/mmdebstrap", "mmdebstrap"),
("./tarfilter", "/usr/bin/mmtarfilter", "tarfilter"), ("./tarfilter", "/usr/bin/mmtarfilter", "tarfilter"),
( (
@ -272,8 +273,12 @@ def main():
tt = ("skip", "test needs QEMU") tt = ("skip", "test needs QEMU")
elif test.get("Needs-Root", "false") == "true": elif test.get("Needs-Root", "false") == "true":
tt = "sudo" tt = "sudo"
elif mode == "auto" and not have_unshare:
tt = "sudo"
elif mode == "root": elif mode == "root":
tt = "sudo" tt = "sudo"
elif mode == "unshare" and not have_unshare:
tt = ("skip", "test needs unshare")
else: else:
tt = "null" tt = "null"
tests.append((tt, name, dist, mode, variant, fmt)) tests.append((tt, name, dist, mode, variant, fmt))
@ -366,9 +371,7 @@ def main():
argv = ["./run_null.sh"] argv = ["./run_null.sh"]
case ("skip", reason): case ("skip", reason):
skipped[reason].append( skipped[reason].append(
format_test( ("(%d/%d) %s" % (i + 1, len(tests), name), dist, mode, variant, fmt)
i + 1, len(tests), name, dist, mode, variant, fmt, config_dict
)
) )
print(f"skipped because of {reason}", file=sys.stderr) print(f"skipped because of {reason}", file=sys.stderr)
continue continue

View file

@ -51,6 +51,21 @@ if [ "$HAVE_QEMU" = "yes" ]; then
fi fi
fi fi
# check if all required debootstrap tarballs exist
notfound=0
for dist in oldstable stable testing unstable; do
for variant in minbase buildd -; do
if [ ! -e "shared/cache/debian-$dist-$variant.tar" ]; then
echo "shared/cache/debian-$dist-$variant.tar does not exist" >&2
notfound=1
fi
done
done
if [ "$notfound" -ne 0 ]; then
echo "not all required debootstrap tarballs are present" >&2
exit 1
fi
# choose the timestamp of the unstable Release file, so that we get # choose the timestamp of the unstable Release file, so that we get
# reproducible results for the same mirror timestamp # reproducible results for the same mirror timestamp
SOURCE_DATE_EPOCH=$(date --date="$(grep-dctrl -s Date -n '' "$mirrordir/dists/$DEFAULT_DIST/Release")" +%s) SOURCE_DATE_EPOCH=$(date --date="$(grep-dctrl -s Date -n '' "$mirrordir/dists/$DEFAULT_DIST/Release")" +%s)
@ -58,6 +73,7 @@ SOURCE_DATE_EPOCH=$(date --date="$(grep-dctrl -s Date -n '' "$mirrordir/dists/$D
# for traditional sort order that uses native byte values # for traditional sort order that uses native byte values
export LC_ALL=C.UTF-8 export LC_ALL=C.UTF-8
: "${HAVE_UNSHARE:=yes}"
: "${HAVE_BINFMT:=yes}" : "${HAVE_BINFMT:=yes}"
# by default, use the mmdebstrap executable in the current directory together # by default, use the mmdebstrap executable in the current directory together
@ -65,7 +81,7 @@ export LC_ALL=C.UTF-8
: "${CMD:=perl -MDevel::Cover=-silent,-nogcov ./mmdebstrap}" : "${CMD:=perl -MDevel::Cover=-silent,-nogcov ./mmdebstrap}"
mirror="http://127.0.0.1/debian" mirror="http://127.0.0.1/debian"
export HAVE_QEMU HAVE_BINFMT RUN_MA_SAME_TESTS DEFAULT_DIST SOURCE_DATE_EPOCH CMD mirror export HAVE_QEMU HAVE_UNSHARE HAVE_BINFMT RUN_MA_SAME_TESTS DEFAULT_DIST SOURCE_DATE_EPOCH CMD mirror
./coverage.py ./coverage.py
@ -83,6 +99,8 @@ cover -delete cover_db >&2
END END
if [ "$HAVE_QEMU" = "yes" ]; then if [ "$HAVE_QEMU" = "yes" ]; then
./run_qemu.sh ./run_qemu.sh
elif [ "$HAVE_UNSHARE" != "yes" ]; then
./run_null.sh SUDO
else else
./run_null.sh ./run_null.sh
fi fi

View file

@ -1,17 +1,10 @@
Test: debootstrap
Dists: any
Variants: minbase buildd -
Needs-Root: true
Test: check-against-debootstrap-dist Test: check-against-debootstrap-dist
Dists: any Dists: any
Variants: minbase buildd - Variants: minbase buildd -
Needs-Root: true Needs-Root: true
Test: as-debootstrap-unshare-wrapper Test: as-debootstrap-unshare-wrapper
Modes: unshare Needs-QEMU: true
Needs-Root: true
Variants: minbase -
Test: help Test: help
@ -41,7 +34,7 @@ Test: root-mode-inside-chroot
Needs-Root: true Needs-Root: true
Test: root-mode-inside-unshare-chroot Test: root-mode-inside-unshare-chroot
Modes: unshare Needs-QEMU: true
Test: root-without-cap-sys-admin Test: root-without-cap-sys-admin
Needs-Root: true Needs-Root: true
@ -50,8 +43,7 @@ Test: mount-is-missing
Needs-QEMU: true Needs-QEMU: true
Test: check-for-bit-by-bit-identical-format-output Test: check-for-bit-by-bit-identical-format-output
Needs-Root: true Needs-QEMU: true
Modes: unshare fakechroot
Formats: tar squashfs ext2 Formats: tar squashfs ext2
Variants: essential apt minbase buildd - standard Variants: essential apt minbase buildd - standard
Skip-If: Skip-If:
@ -59,9 +51,6 @@ Skip-If:
variant == "important" and dist == "oldstable" # /var/lib/systemd/catalog/database differs variant == "important" and dist == "oldstable" # /var/lib/systemd/catalog/database differs
fmt == "squashfs" and dist == "oldstable" # squashfs-tools-ng is not available fmt == "squashfs" and dist == "oldstable" # squashfs-tools-ng is not available
fmt == "ext2" and dist == "oldstable" # genext2fs does not support SOURCE_DATE_EPOCH fmt == "ext2" and dist == "oldstable" # genext2fs does not support SOURCE_DATE_EPOCH
mode == "fakechroot" and variant in ["-", "standard"] # no extended attributes
mode == "fakechroot" and hostarch in ["i386", "armel", "armhf", "mipsel"] # #1030638
variant == "standard" and hostarch in ["armel", "armhf", "mipsel"] # #1031276
Test: tarfilter-idshift Test: tarfilter-idshift
Needs-QEMU: true Needs-QEMU: true
@ -85,21 +74,19 @@ Test: missing-device-nodes-outside-the-chroot
Needs-QEMU: true Needs-QEMU: true
Test: missing-dev-sys-proc-inside-the-chroot Test: missing-dev-sys-proc-inside-the-chroot
Modes: unshare Needs-QEMU: true
Variants: custom
Test: chroot-directory-not-accessible-by-apt-user Test: chroot-directory-not-accessible-by-apt-user
Needs-Root: true Needs-Root: true
Test: cwd-directory-not-accessible-by-unshared-user Test: cwd-directory-not-accessible-by-unshared-user
Needs-Root: true Needs-QEMU: true
Modes: unshare
Test: create-gzip-compressed-tarball Test: create-gzip-compressed-tarball
Needs-QEMU: true
Test: custom-tmpdir Test: custom-tmpdir
Needs-Root: true Needs-QEMU: true
Modes: unshare
Test: xz-compressed-tarball Test: xz-compressed-tarball
@ -246,6 +233,7 @@ Needs-Root: true
Test: special-hooks-with-mode-mode Test: special-hooks-with-mode-mode
Modes: root unshare fakechroot Modes: root unshare fakechroot
Needs-QEMU: true
Test: debootstrap-no-op-options Test: debootstrap-no-op-options
Needs-Root: true Needs-Root: true
@ -286,14 +274,14 @@ Skip-If:
variant == "important" and dist == "oldstable" # /var/lib/systemd/catalog/database differs variant == "important" and dist == "oldstable" # /var/lib/systemd/catalog/database differs
Test: create-directory-dry-run Test: create-directory-dry-run
Modes: root
Test: create-tarball-dry-run Test: create-tarball-dry-run
Variants: any Variants: any
Modes: any Modes: any
Test: unpack-doc-debian Test: unpack-doc-debian
Modes: root fakechroot Needs-QEMU: true
Modes: any
Variants: extract Variants: extract
Test: install-doc-debian Test: install-doc-debian
@ -310,6 +298,7 @@ Skip-If:
Test: chrootless-fakeroot Test: chrootless-fakeroot
Variants: essential Variants: essential
Modes: chrootless Modes: chrootless
Needs-QEMU: true
Skip-If: Skip-If:
dist in ["oldstable", "stable"] dist in ["oldstable", "stable"]
@ -331,8 +320,6 @@ Variants: custom
Modes: chrootless Modes: chrootless
Test: install-libmagic-mgc-on-arm64 Test: install-libmagic-mgc-on-arm64
Variants: custom
Modes: chrootless
Skip-If: Skip-If:
hostarch != "amd64" hostarch != "amd64"
not have_binfmt not have_binfmt
@ -352,6 +339,7 @@ Modes: fakechroot
Test: dev-ptmx Test: dev-ptmx
Modes: root unshare Modes: root unshare
Needs-QEMU: true
Test: error-if-stdout-is-tty Test: error-if-stdout-is-tty
@ -361,13 +349,14 @@ Test: include-deb-file
Test: unshare-include-deb Test: unshare-include-deb
Modes: unshare Modes: unshare
Needs-QEMU: true
Test: pivot_root Test: pivot_root
Modes: root unshare Modes: root unshare
Needs-QEMU: true
Test: jessie-or-older Test: jessie-or-older
Needs-Root: true Needs-QEMU: true
Modes: root unshare fakechroot
Variants: essential apt minbase Variants: essential apt minbase
Test: apt-patterns Test: apt-patterns
@ -378,6 +367,3 @@ Test: empty-sources.list
Test: merged-fakechroot-inside-unmerged-chroot Test: merged-fakechroot-inside-unmerged-chroot
Needs-Root: true Needs-Root: true
Test: auto-mode-as-normal-user
Modes: auto

View file

@ -673,6 +673,37 @@ END
trap "cleanup_newcachedir" EXIT INT TERM trap "cleanup_newcachedir" EXIT INT TERM
fi fi
mirror="http://127.0.0.1/debian"
for dist in oldstable stable testing unstable; do
for variant in minbase buildd -; do
echo "running debootstrap --variant=$variant $dist \${TEMPDIR} $mirror"
cat << END > shared/test.sh
#!/bin/sh
set -eu
export LC_ALL=C.UTF-8
export SOURCE_DATE_EPOCH=$SOURCE_DATE_EPOCH
echo "SOURCE_DATE_EPOCH=\$SOURCE_DATE_EPOCH"
tmpdir="\$(mktemp -d)"
chmod 755 "\$tmpdir"
case "$dist" in
oldstable|stable)
debootstrap --no-merged-usr --variant=$variant $dist "\$tmpdir" $mirror
;;
*)
debootstrap --merged-usr --variant=$variant $dist "\$tmpdir" $mirror
;;
esac
tar --sort=name --mtime=@$SOURCE_DATE_EPOCH --clamp-mtime --numeric-owner --one-file-system --xattrs -C "\$tmpdir" -c . > "$newcache/debian-$dist-$variant.tar"
rm -r "\$tmpdir"
END
if [ "$HAVE_QEMU" = "yes" ]; then
cachedir=$newcachedir ./run_qemu.sh
else
./run_null.sh SUDO
fi
done
done
if [ "$HAVE_QEMU" = "yes" ]; then if [ "$HAVE_QEMU" = "yes" ]; then
# now replace the minihttpd config with one that serves the new repository # now replace the minihttpd config with one that serves the new repository
guestfish -a "$newcachedir/debian-$DEFAULT_DIST.qcow" -i <<EOF guestfish -a "$newcachedir/debian-$DEFAULT_DIST.qcow" -i <<EOF

View file

@ -1336,11 +1336,11 @@ sub setup_mounts {
. " /sys directory is missing in the target"); . " /sys directory is missing in the target");
} elsif ((any { $_ eq $options->{mode} } ('root', 'unshare')) } elsif ((any { $_ eq $options->{mode} } ('root', 'unshare'))
&& !-e "/sys") { && !-e "/sys") {
warning("skipping mounting /sys because" warning("skipping bind-mounting /sys because"
. " /sys does not exist on the outside"); . " /sys does not exist on the outside");
} elsif ((any { $_ eq $options->{mode} } ('root', 'unshare')) } elsif ((any { $_ eq $options->{mode} } ('root', 'unshare'))
&& !-d "/sys") { && !-d "/sys") {
warning("skipping mounting /sys because" warning("skipping bind-mounting /sys because"
. " /sys on the outside is not a directory"); . " /sys on the outside is not a directory");
} elsif ($options->{mode} eq 'root') { } elsif ($options->{mode} eq 'root') {
# we don't know whether we run in root mode inside an unshared # we don't know whether we run in root mode inside an unshared
@ -1411,19 +1411,18 @@ sub setup_mounts {
. " /proc directory is missing in the target"); . " /proc directory is missing in the target");
} elsif ((any { $_ eq $options->{mode} } ('root', 'unshare')) } elsif ((any { $_ eq $options->{mode} } ('root', 'unshare'))
&& !-e "/proc") { && !-e "/proc") {
warning("skipping mounting /proc because" warning("skipping bind-mounting /proc because"
. " /proc does not exist on the outside"); . " /proc does not exist on the outside");
} elsif ((any { $_ eq $options->{mode} } ('root', 'unshare')) } elsif ((any { $_ eq $options->{mode} } ('root', 'unshare'))
&& !-d "/proc") { && !-d "/proc") {
warning("skipping mounting /proc because" warning("skipping bind-mounting /proc because"
. " /proc on the outside is not a directory"); . " /proc on the outside is not a directory");
} elsif (any { $_ eq $options->{mode} } ('root', 'unshare')) { } elsif ($options->{mode} eq 'root') {
# we don't know whether we run in root mode inside an unshared # we don't know whether we run in root mode inside an unshared
# user namespace or as real root so we first try the real mount and # user namespace or as real root so we first try the real mount and
# then fall back to mounting in a way that works in unshared # then fall back to mounting in a way that works in unshared
if ( if (
$options->{mode} eq 'root' 0 == system(
&& 0 == system(
'mount', '-t', 'proc', '-o', 'ro', 'proc', 'mount', '-t', 'proc', '-o', 'ro', 'proc',
"$options->{root}/proc" "$options->{root}/proc"
) )
@ -1452,35 +1451,22 @@ sub setup_mounts {
0 == system('umount', '--no-mtab', "$options->{root}/proc") 0 == system('umount', '--no-mtab', "$options->{root}/proc")
or warning("umount /proc failed: $?"); or warning("umount /proc failed: $?");
}; };
} elsif (
# if mounting proc failed, try bind-mounting it read-only as a
# last resort
0 == system(
'mount', '-o',
'rbind', '/proc',
"$options->{root}/proc"
)
) {
warning("since mounting /proc normally failed, /proc is now "
. "bind-mounted instead");
# to make sure that changes (like unmounting) to the
# bind-mounted /proc do not affect the outside /proc, change
# all the bind-mounts under /proc to be a slave mount.
if (
0 != system('mount', '--make-rslave',
"$options->{root}/proc")) {
warning("mount --make-rslave /proc failed");
}
push @cleanup_tasks, sub {
# since we cannot write to /etc/mtab we need --no-mtab
0 == system(
'umount', '--no-mtab',
'--lazy', "$options->{root}/proc"
) or warning("umount /proc failed: $?");
};
} else { } else {
error "mount /proc failed: $?"; error "mount /proc failed: $?";
} }
} elsif ($options->{mode} eq 'unshare') {
# naturally we have to clean up after ourselves in sudo mode where
# we do a real mount. But we also need to unmount in unshare mode
# because otherwise, even with the --one-file-system tar option,
# the permissions of the mount source will be stored and not the
# mount target (the directory)
push @cleanup_tasks, sub {
# since we cannot write to /etc/mtab we need --no-mtab
0 == system('umount', '--no-mtab', "$options->{root}/proc")
or warning("umount /proc failed: $?");
};
0 == system('mount', '-t', 'proc', 'proc', "$options->{root}/proc")
or error "mount /proc failed: $?";
} elsif (any { $_ eq $options->{mode} } ('fakechroot', 'chrootless')) { } elsif (any { $_ eq $options->{mode} } ('fakechroot', 'chrootless')) {
# we cannot mount in fakechroot mode # we cannot mount in fakechroot mode
} else { } else {
@ -4725,7 +4711,7 @@ sub main() {
); );
close $fh; close $fh;
if ( $? == 0 if ( $? == 0
and $content =~ /^apt (\d+\.\d+\.\d+)\S* \(\S+\)$/am) { and $content =~ /^apt (\d+\.\d+\.\d+)\w* \(\S+\)$/am) {
$aptversion = version->new($1); $aptversion = version->new($1);
} }
if ($aptversion < "2.3.14") { if ($aptversion < "2.3.14") {
@ -6649,30 +6635,14 @@ needs to be able to mount and thus requires C<SYS_CAP_ADMIN>.
=item B<unshare> =item B<unshare>
When used as a normal (not root) user, this mode uses Linux user namespaces to This mode uses Linux user namespaces to allow unprivileged use of chroot and
allow unprivileged use of chroot and creation of files that appear to be owned creation of files that appear to be owned by the superuser inside the unshared
by the superuser inside the unshared namespace. A tarball created in this mode namespace. A tarball created in this mode should be bit-by-bit identical to a
will be bit-by-bit identical to a tarball created with the B<root> mode. With tarball created with the B<root> mode.
this mode, the only binaries that will run as the root user will be
B<newuidmap(1)> and B<newgidmap(1)> via their setuid bit. Running those
successfully requires F</etc/subuid> and F</etc/subgid> to have an entry for
your username. This entry was usually created by B<adduser(8)> already.
The unshared user will not automatically have access to the same files as you
do. This is intentional and an additional security against unintended changes
to your files that could theoretically result from running B<mmdebstrap> and
package maintainer scripts. To copy files in and out of the chroot, either use
globally readable or writable directories or use special hooks like B<copy-in>
and B<copy-out>.
Besides the user namespace, the mount, pid (process ids), uts (hostname) and
ipc namespaces will be unshared as well. See the man pages of B<namespaces(7)>
and B<unshare(2)> as well as the manual pages they are linking to.
A directory chroot created with this mode will end up with wrong ownership A directory chroot created with this mode will end up with wrong ownership
information (seen from outside the unshared user namespace). For correct information. For correct ownership information, the directory must be accessed
ownership information, the directory must be accessed from a user namespace from a user namespace with the right subuid/subgid offset, like so:
with the right subuid/subgid offset, like so:
$ lxc-usernsexec -- lxc-unshare -s 'MOUNT|PID|UTSNAME|IPC' -- \ $ lxc-usernsexec -- lxc-unshare -s 'MOUNT|PID|UTSNAME|IPC' -- \
> /usr/sbin/chroot ./debian-rootfs /bin/bash > /usr/sbin/chroot ./debian-rootfs /bin/bash

View file

@ -178,14 +178,14 @@ Lastly, shift user id and group id of each entry by the value given by the
skip = False skip = False
if not hasattr(args, "pathfilter"): if not hasattr(args, "pathfilter"):
return False return False
for t, r in args.pathfilter: for (t, r) in args.pathfilter:
if r.match(member.name[1:]) is not None: if r.match(member.name[1:]) is not None:
if t == "path_include": if t == "path_include":
skip = False skip = False
else: else:
skip = True skip = True
if skip and (member.isdir() or member.issym()): if skip and (member.isdir() or member.issym()):
for t, r in args.pathfilter: for (t, r) in args.pathfilter:
if t != "path_include": if t != "path_include":
continue continue
prefix = prefix_prog.sub(r"\1", r.pattern) prefix = prefix_prog.sub(r"\1", r.pattern)
@ -198,7 +198,7 @@ Lastly, shift user id and group id of each entry by the value given by the
if not hasattr(args, "paxfilter"): if not hasattr(args, "paxfilter"):
return False return False
skip = False skip = False
for t, r in args.paxfilter: for (t, r) in args.paxfilter:
if r.match(header) is None: if r.match(header) is None:
continue continue
if t == "pax_include": if t == "pax_include":

View file

@ -2,58 +2,18 @@
set -eu set -eu
export LC_ALL=C.UTF-8 export LC_ALL=C.UTF-8
export SOURCE_DATE_EPOCH={{ SOURCE_DATE_EPOCH }} export SOURCE_DATE_EPOCH={{ SOURCE_DATE_EPOCH }}
if [ ! -e /mmdebstrap-testenv ]; then
prefix= echo "this test modifies the system and should only be run inside a container" >&2
if [ "$(id -u)" -eq 0 ] && [ "{{ MODE }}" != "root" ] && [ "{{ MODE }}" != "auto" ]; then exit 1
if ! id "${SUDO_USER:-user}" >/dev/null 2>&1; then
if [ ! -e /mmdebstrap-testenv ]; then
echo "this test modifies the system and should only be run inside a container" >&2
exit 1
fi
useradd --home-dir "/home/${SUDO_USER:-user}" --create-home "${SUDO_USER:-user}"
fi
prefix="runuser -u ${SUDO_USER:-user} --"
fi
# debootstrap uses apt-config to figure out whether the system running it has
# any proxies configured and then runs the binary to set the http_proxy
# environment variable. This will fail if debootstrap is run in a linux user
# namespace because auto-apt-proxy will see /tmp/.auto-apt-proxy-0 as being
# owned by the user "nobody" and group "nogroup" and fail with:
# insecure cache dir /tmp/.auto-apt-proxy-0. Must be owned by UID 0 and have permissions 700
# We cannot overwrite a configuration item using the APT_CONFIG environment
# variable, so instead we use it to set the Dir configuration option
# to /dev/null to force all apt settings to their defaults.
# There is currently no better way to disable this behavior. See also:
# https://bugs.debian.org/1031105
# https://salsa.debian.org/installer-team/debootstrap/-/merge_requests/90
AUTOPROXY=
eval "$(apt-config shell AUTOPROXY Acquire::http::Proxy-Auto-Detect)"
if [ -n "$AUTOPROXY" ] && [ -x "$AUTOPROXY" ] && [ -e /tmp/.auto-apt-proxy-0 ]; then
TMP_APT_CONFIG=$(mktemp)
echo "Dir \"/dev/null\";" > "$TMP_APT_CONFIG"
chmod 644 "$TMP_APT_CONFIG"
fi
# debootstrap runs mount -t proc proc /proc which doesn't work in an unshared
# namespace on privileged docker (like salsaci), so mount /proc manually
# https://bugs.debian.org/1031222
# https://salsa.debian.org/installer-team/debootstrap/-/merge_requests/91
$prefix {{ CMD }} --variant=custom --mode={{ MODE }} \
--setup-hook='env '"${AUTOPROXY:+APT_CONFIG='$TMP_APT_CONFIG'}"' container=lxc debootstrap --variant={{ VARIANT }} unstable "$1" {{ MIRROR }}' \
--setup-hook='mount -o rbind /proc "$1/proc"' \
--setup-hook='chroot "$1" dpkg-reconfigure systemd || true' \
--setup-hook='umount --lazy "$1/proc"' \
- /tmp/debian-mm.tar {{ MIRROR }}
if [ -n "$AUTOPROXY" ] && [ -x "$AUTOPROXY" ] && [ -e /tmp/.auto-apt-proxy-0 ]; then
rm "$TMP_APT_CONFIG"
fi fi
useradd --home-dir /home/user --create-home user
runuser -u user -- {{ CMD }} --variant=custom --mode=unshare --setup-hook='env container=lxc debootstrap unstable "$1" {{ MIRROR }}' - /tmp/debian-mm.tar {{ MIRROR }}
mkdir /tmp/debian-mm mkdir /tmp/debian-mm
tar --xattrs --xattrs-include='*' -C /tmp/debian-mm -xf /tmp/debian-mm.tar tar --xattrs --xattrs-include='*' -C /tmp/debian-mm -xf /tmp/debian-mm.tar
mkdir /tmp/debian-debootstrap mkdir /tmp/debian-debootstrap
tar --xattrs --xattrs-include='*' -C /tmp/debian-debootstrap -xf "cache/debian-unstable-{{ VARIANT }}.tar" tar --xattrs --xattrs-include='*' -C /tmp/debian-debootstrap -xf "cache/debian-unstable--.tar"
# diff cannot compare device nodes, so we use tar to do that for us and then # diff cannot compare device nodes, so we use tar to do that for us and then
# delete the directory # delete the directory
@ -81,9 +41,7 @@ rm /tmp/debian-debootstrap/var/lib/apt/lists/127.0.0.1_debian_dists_unstable_mai
/tmp/debian-debootstrap/var/lib/apt/lists/127.0.0.1_debian_dists_unstable_Release \ /tmp/debian-debootstrap/var/lib/apt/lists/127.0.0.1_debian_dists_unstable_Release \
/tmp/debian-debootstrap/var/lib/apt/lists/127.0.0.1_debian_dists_unstable_Release.gpg /tmp/debian-debootstrap/var/lib/apt/lists/127.0.0.1_debian_dists_unstable_Release.gpg
if [ -e /tmp/debian-debootstrap/etc/machine-id ]; then rm /tmp/debian-debootstrap/etc/machine-id /tmp/debian-mm/etc/machine-id
rm /tmp/debian-debootstrap/etc/machine-id /tmp/debian-mm/etc/machine-id
fi
rm /tmp/debian-mm/var/cache/apt/archives/lock rm /tmp/debian-mm/var/cache/apt/archives/lock
rm /tmp/debian-mm/var/lib/apt/lists/lock rm /tmp/debian-mm/var/lib/apt/lists/lock
rm /tmp/debian-mm/var/lib/dpkg/arch rm /tmp/debian-mm/var/lib/dpkg/arch
@ -92,9 +50,6 @@ rm /tmp/debian-mm/var/lib/dpkg/arch
# also needed for users that are created by systemd-sysusers before systemd 252 # also needed for users that are created by systemd-sysusers before systemd 252
# https://github.com/systemd/systemd/pull/24534 # https://github.com/systemd/systemd/pull/24534
for f in shadow shadow-; do for f in shadow shadow-; do
if [ ! -e /tmp/debian-debootstrap/etc/$f ]; then
continue
fi
if ! cmp /tmp/debian-debootstrap/etc/$f /tmp/debian-mm/etc/$f >&2; then if ! cmp /tmp/debian-debootstrap/etc/$f /tmp/debian-mm/etc/$f >&2; then
echo patching /etc/$f >&2 echo patching /etc/$f >&2
awk -v FS=: -v OFS=: -v SDE={{ SOURCE_DATE_EPOCH }} '{ print $1,$2,int(SDE/60/60/24),$4,$5,$6,$7,$8,$9 }' < /tmp/debian-mm/etc/$f > /tmp/debian-mm/etc/$f.bak awk -v FS=: -v OFS=: -v SDE={{ SOURCE_DATE_EPOCH }} '{ print $1,$2,int(SDE/60/60/24),$4,$5,$6,$7,$8,$9 }' < /tmp/debian-mm/etc/$f > /tmp/debian-mm/etc/$f.bak

View file

@ -1,22 +0,0 @@
#!/bin/sh
set -eu
export LC_ALL=C.UTF-8
trap "rm -f /tmp/debian-chroot.tar.gz" EXIT INT TERM
[ {{ MODE }} = "auto" ]
prefix=
if [ "$(id -u)" -eq 0 ]; then
if ! id "${SUDO_USER:-user}" >/dev/null 2>&1; then
if [ ! -e /mmdebstrap-testenv ]; then
echo "this test modifies the system and should only be run inside a container" >&2
exit 1
fi
useradd --home-dir "/home/${SUDO_USER:-user}" --create-home "${SUDO_USER:-user}"
fi
prefix="runuser -u ${SUDO_USER:-user} --"
fi
$prefix {{ CMD }} --mode={{ MODE }} --variant=apt {{ DIST }} /tmp/debian-chroot.tar.gz {{ MIRROR }}
tar -tf /tmp/debian-chroot.tar.gz | sort | diff -u tar1.txt -

View file

@ -1,21 +1,12 @@
#!/bin/sh #!/bin/sh
set -eu set -eu
export LC_ALL=C.UTF-8 export LC_ALL=C.UTF-8
export SOURCE_DATE_EPOCH={{ SOURCE_DATE_EPOCH }} if [ ! -e /mmdebstrap-testenv ]; then
echo "this test modifies the system and should only be run inside a container" >&2
trap "rm -f /tmp/debian-chroot-{{ MODE }}.{{ FORMAT }} /tmp/debian-chroot-root.{{ FORMAT }}" EXIT INT TERM exit 1
[ "$(id -u)" -eq 0 ]
if ! id "${SUDO_USER:-user}" >/dev/null 2>&1; then
if [ ! -e /mmdebstrap-testenv ]; then
echo "this test modifies the system and should only be run inside a container" >&2
exit 1
fi
useradd --home-dir "/home/${SUDO_USER:-user}" --create-home "${SUDO_USER:-user}"
fi fi
prefix="runuser -u ${SUDO_USER:-user} --" useradd --home-dir /home/user --create-home user
export SOURCE_DATE_EPOCH={{ SOURCE_DATE_EPOCH }}
{{ CMD }} --mode=root --variant={{ VARIANT }} {{ DIST }} /tmp/debian-chroot-root.{{ FORMAT }} {{ MIRROR }} {{ CMD }} --mode=root --variant={{ VARIANT }} {{ DIST }} /tmp/debian-chroot-root.{{ FORMAT }} {{ MIRROR }}
if [ "{{ FORMAT }}" = tar ]; then if [ "{{ FORMAT }}" = tar ]; then
printf 'ustar ' | cmp --bytes=6 --ignore-initial=257:0 /tmp/debian-chroot-root.tar - printf 'ustar ' | cmp --bytes=6 --ignore-initial=257:0 /tmp/debian-chroot-root.tar -
@ -27,11 +18,19 @@ else
echo "unknown format: {{ FORMAT }}" >&2 echo "unknown format: {{ FORMAT }}" >&2
exit 1 exit 1
fi fi
runuser -u user -- {{ CMD }} --mode=unshare --variant={{ VARIANT }} {{ DIST }} /tmp/debian-chroot-unshare.{{ FORMAT }} {{ MIRROR }}
$prefix {{ CMD }} --mode={{ MODE }} --variant={{ VARIANT }} {{ DIST }} /tmp/debian-chroot-{{ MODE }}.{{ FORMAT }} {{ MIRROR }} cmp /tmp/debian-chroot-root.{{ FORMAT }} /tmp/debian-chroot-unshare.{{ FORMAT }}
cmp /tmp/debian-chroot-root.{{ FORMAT }} /tmp/debian-chroot-{{ MODE }}.{{ FORMAT }} \ rm /tmp/debian-chroot-unshare.{{ FORMAT }}
|| diffoscope /tmp/debian-chroot-root.{{ FORMAT }} /tmp/debian-chroot-{{ MODE }}.{{ FORMAT }} case {{ VARIANT }} in essential|apt|minbase|buildd)
# 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 }} {{ DIST }} /tmp/debian-chroot-fakechroot.{{ FORMAT }} {{ MIRROR }}
cmp /tmp/debian-chroot-root.{{ FORMAT }} /tmp/debian-chroot-fakechroot.{{ FORMAT }}
rm /tmp/debian-chroot-fakechroot.{{ FORMAT }}
;;
esac
# we cannot test chrootless mode here, because mmdebstrap relies on the # we cannot test chrootless mode here, because mmdebstrap relies on the
# usrmerge package to set up merged-/usr and that doesn't work in chrootless # usrmerge package to set up merged-/usr and that doesn't work in chrootless
# mode # mode
rm /tmp/debian-chroot-root.{{ FORMAT }}

View file

@ -11,6 +11,6 @@ for INCLUDE in '' 'apt' 'apt,build-essential' 'systemd-sysv'; do
${INCLUDE:+--include="$INCLUDE"} \ ${INCLUDE:+--include="$INCLUDE"} \
{{ DIST }} "/tmp/$MODE.tar" {{ MIRROR }} {{ DIST }} "/tmp/$MODE.tar" {{ MIRROR }}
done done
cmp /tmp/root.tar /tmp/chrootless.tar || diffoscope /tmp/root.tar /tmp/chrootless.tar cmp /tmp/root.tar /tmp/chrootless.tar
rm /tmp/chrootless.tar /tmp/root.tar rm /tmp/chrootless.tar /tmp/root.tar
done done

View file

@ -3,21 +3,15 @@ set -eu
export LC_ALL=C.UTF-8 export LC_ALL=C.UTF-8
export SOURCE_DATE_EPOCH={{ SOURCE_DATE_EPOCH }} export SOURCE_DATE_EPOCH={{ SOURCE_DATE_EPOCH }}
trap "rm -f /tmp/chrootless.tar /tmp/root.tar" EXIT INT TERM trap "rm -f /tmp/chrootless.tar /tmp/root.tar" EXIT INT TERM
if [ "$(id -u)" -eq 0 ] && ! id -u user > /dev/null 2>&1; then
[ {{ MODE }} = chrootless ] if [ ! -e /mmdebstrap-testenv ]; then
echo "this test modifies the system and should only be run inside a container" >&2
prefix= exit 1
if [ "$(id -u)" -eq 0 ] && [ "{{ MODE }}" != "root" ] && [ "{{ MODE }}" != "auto" ]; then
if ! id "${SUDO_USER:-user}" >/dev/null 2>&1; then
if [ ! -e /mmdebstrap-testenv ]; then
echo "this test modifies the system and should only be run inside a container" >&2
exit 1
fi
useradd --home-dir "/home/${SUDO_USER:-user}" --create-home "${SUDO_USER:-user}"
fi fi
prefix="runuser -u ${SUDO_USER:-user} --" useradd --home-dir /home/user --create-home user
fi fi
prefix=
[ "$(id -u)" -eq 0 ] && prefix="runuser -u user --"
# we need --hook-dir=./hooks/merged-usr because usrmerge does not understand # we need --hook-dir=./hooks/merged-usr because usrmerge does not understand
# DPKG_ROOT # DPKG_ROOT
# permissions drwxr-sr-x and extended attributes of ./var/log/journal/ cannot # permissions drwxr-sr-x and extended attributes of ./var/log/journal/ cannot
@ -27,9 +21,9 @@ for INCLUDE in '' 'apt' 'apt,build-essential' 'systemd-sysv'; do
--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 [ -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' \
${INCLUDE:+--include="$INCLUDE"} \ ${INCLUDE:+--include="$INCLUDE"} \
{{ DIST }} /tmp/root.tar {{ MIRROR }} {{ DIST }} /tmp/root.tar {{ MIRROR }}
$prefix fakeroot {{ CMD }} --mode={{ MODE }} --variant={{ VARIANT }} --hook-dir=./hooks/merged-usr \ $prefix fakeroot {{ CMD }} --mode=chrootless --variant={{ VARIANT }} --hook-dir=./hooks/merged-usr \
${INCLUDE:+--include="$INCLUDE"} \ ${INCLUDE:+--include="$INCLUDE"} \
{{ DIST }} /tmp/chrootless.tar {{ MIRROR }} {{ DIST }} /tmp/chrootless.tar {{ MIRROR }}
cmp /tmp/root.tar /tmp/chrootless.tar || diffoscope /tmp/root.tar /tmp/chrootless.tar cmp /tmp/root.tar /tmp/chrootless.tar
rm /tmp/chrootless.tar /tmp/root.tar rm /tmp/chrootless.tar /tmp/root.tar
done done

View file

@ -63,6 +63,6 @@ for INCLUDE in '' 'apt' 'systemd-sysv'; do
> "/tmp/$tar.tar.tmp" > "/tmp/$tar.tar.tmp"
mv "/tmp/$tar.tar.tmp" "/tmp/$tar.tar" mv "/tmp/$tar.tar.tmp" "/tmp/$tar.tar"
done done
cmp /tmp/root.tar /tmp/chrootless.tar || diffoscope /tmp/root.tar /tmp/chrootless.tar cmp /tmp/root.tar /tmp/chrootless.tar
rm /tmp/chrootless.tar /tmp/root.tar rm /tmp/chrootless.tar /tmp/root.tar
done done

View file

@ -1,19 +1,15 @@
#!/bin/sh #!/bin/sh
set -eu set -eu
export LC_ALL=C.UTF-8 export LC_ALL=C.UTF-8
if [ "$(id -u)" -eq 0 ] && ! id -u user > /dev/null 2>&1; then
prefix= if [ ! -e /mmdebstrap-testenv ]; then
if [ "$(id -u)" -eq 0 ] && [ "{{ MODE }}" != "root" ] && [ "{{ MODE }}" != "auto" ]; then echo "this test modifies the system and should only be run inside a container" >&2
if ! id "${SUDO_USER:-user}" >/dev/null 2>&1; then exit 1
if [ ! -e /mmdebstrap-testenv ]; then
echo "this test modifies the system and should only be run inside a container" >&2
exit 1
fi
useradd --home-dir "/home/${SUDO_USER:-user}" --create-home "${SUDO_USER:-user}"
fi fi
prefix="runuser -u ${SUDO_USER:-user} --" useradd --home-dir /home/user --create-home user
fi fi
prefix=
[ "$(id -u)" -eq 0 ] && [ "{{ MODE }}" != "root" ] && prefix="runuser -u user --"
[ "{{ MODE }}" = "fakechroot" ] && prefix="$prefix fakechroot fakeroot" [ "{{ MODE }}" = "fakechroot" ] && prefix="$prefix fakechroot fakeroot"
$prefix {{ CMD }} --mode={{ MODE }} --variant=apt --architectures=arm64 {{ DIST }} /tmp/debian-chroot.tar {{ MIRROR }} $prefix {{ CMD }} --mode={{ MODE }} --variant=apt --architectures=arm64 {{ DIST }} /tmp/debian-chroot.tar {{ MIRROR }}
# we ignore differences between architectures by ignoring some files # we ignore differences between architectures by ignoring some files

View file

@ -1,20 +1,12 @@
#!/bin/sh #!/bin/sh
set -eu set -eu
export LC_ALL=C.UTF-8 export LC_ALL=C.UTF-8
if [ ! -e /mmdebstrap-testenv ]; then
prefix= echo "this test modifies the system and should only be run inside a container" >&2
if [ "$(id -u)" -eq 0 ] && [ "{{ MODE }}" != "root" ] && [ "{{ MODE }}" != "auto" ]; then exit 1
if ! id "${SUDO_USER:-user}" >/dev/null 2>&1; then
if [ ! -e /mmdebstrap-testenv ]; then
echo "this test modifies the system and should only be run inside a container" >&2
exit 1
fi
useradd --home-dir "/home/${SUDO_USER:-user}" --create-home "${SUDO_USER:-user}"
fi
prefix="runuser -u ${SUDO_USER:-user} --"
fi fi
useradd --home-dir /home/user --create-home user
$prefix {{ CMD }} --mode={{ MODE }} --variant=apt {{ DIST }} /tmp/debian-chroot.tar.gz {{ MIRROR }} runuser -u user -- {{ CMD }} --mode=unshare --variant=apt {{ DIST }} /tmp/debian-chroot.tar.gz {{ MIRROR }}
printf '\037\213\010' | cmp --bytes=3 /tmp/debian-chroot.tar.gz - printf '\037\213\010' | cmp --bytes=3 /tmp/debian-chroot.tar.gz -
tar -tf /tmp/debian-chroot.tar.gz | sort | diff -u tar1.txt - tar -tf /tmp/debian-chroot.tar.gz | sort | diff -u tar1.txt -
rm /tmp/debian-chroot.tar.gz rm /tmp/debian-chroot.tar.gz

View file

@ -8,14 +8,15 @@ export LC_ALL=C.UTF-8
prefix= prefix=
include=, include=,
if [ "$(id -u)" -eq 0 ] && [ "{{ MODE }}" != root ] && [ "{{ MODE }}" != auto ]; then if [ "$(id -u)" -eq 0 ] && [ "{{ MODE }}" != root ] && [ "{{ MODE }}" != auto ]; then
if ! id "${SUDO_USER:-user}" >/dev/null 2>&1; then # this must be qemu
if ! id -u user >/dev/null 2>&1; then
if [ ! -e /mmdebstrap-testenv ]; then if [ ! -e /mmdebstrap-testenv ]; then
echo "this test modifies the system and should only be run inside a container" >&2 echo "this test modifies the system and should only be run inside a container" >&2
exit 1 exit 1
fi fi
useradd --home-dir "/home/${SUDO_USER:-user}" --create-home "${SUDO_USER:-user}" useradd --home-dir /home/user --create-home user
fi fi
prefix="runuser -u ${SUDO_USER:-user} --" prefix="runuser -u user --"
if [ "{{ VARIANT }}" = extract ] || [ "{{ VARIANT }}" = custom ]; then if [ "{{ VARIANT }}" = extract ] || [ "{{ VARIANT }}" = custom ]; then
include="$(tr '\n' ',' < pkglist.txt)" include="$(tr '\n' ',' < pkglist.txt)"
fi fi

View file

@ -1,33 +1,25 @@
#!/bin/sh #!/bin/sh
set -eu set -eu
export LC_ALL=C.UTF-8 export LC_ALL=C.UTF-8
if [ ! -e /mmdebstrap-testenv ]; then
[ "$(id -u)" -eq 0 ] echo "this test modifies the system and should only be run inside a container" >&2
[ {{ MODE }} = "unshare" ] exit 1
if ! id "${SUDO_USER:-user}" >/dev/null 2>&1; then
if [ ! -e /mmdebstrap-testenv ]; then
echo "this test modifies the system and should only be run inside a container" >&2
exit 1
fi
useradd --home-dir "/home/${SUDO_USER:-user}" --create-home "${SUDO_USER:-user}"
fi fi
prefix="runuser -u ${SUDO_USER:-user} --"
# https://www.etalabs.net/sh_tricks.html # https://www.etalabs.net/sh_tricks.html
quote () { printf %s\\n "$1" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/'/" ; } quote () { printf %s\\n "$1" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/'/" ; }
homedir=$($prefix sh -c 'cd && pwd') useradd --home-dir /home/user --create-home user
homedir=$(runuser -u user -- sh -c 'cd && pwd')
# apt:test/integration/test-apt-key # apt:test/integration/test-apt-key
TMPDIR_ADD="This is fü\$\$ing cràzy, \$(apt -v)\$!" TMPDIR_ADD="This is fü\$\$ing cràzy, \$(apt -v)\$!"
$prefix mkdir "$homedir/$TMPDIR_ADD" runuser -u user -- mkdir "$homedir/$TMPDIR_ADD"
# make sure the unshared user can traverse into the TMPDIR # make sure the unshared user can traverse into the TMPDIR
chmod 711 "$homedir" chmod 711 "$homedir"
# set permissions and sticky bit like the real /tmp # set permissions and sticky bit like the real /tmp
chmod 1777 "$homedir/$TMPDIR_ADD" chmod 1777 "$homedir/$TMPDIR_ADD"
$prefix env TMPDIR="$homedir/$TMPDIR_ADD" {{ CMD }} --mode={{ MODE }} --variant=apt \ runuser -u user -- env TMPDIR="$homedir/$TMPDIR_ADD" {{ CMD }} --mode=unshare --variant=apt \
--setup-hook='case "$1" in '"$(quote "$homedir/$TMPDIR_ADD/mmdebstrap.")"'??????????) exit 0;; *) echo "$1"; exit 1;; esac' \ --setup-hook='case "$1" in '"$(quote "$homedir/$TMPDIR_ADD/mmdebstrap.")"'??????????) exit 0;; *) echo "$1"; exit 1;; esac' \
{{ DIST }} /tmp/debian-chroot.tar {{ MIRROR }} {{ DIST }} /tmp/debian-chroot.tar {{ MIRROR }}
tar -tf /tmp/debian-chroot.tar | sort | diff -u tar1.txt - tar -tf /tmp/debian-chroot.tar | sort | diff -u tar1.txt -
# use rmdir as a quick check that nothing is remaining in TMPDIR # use rmdir as a quick check that nothing is remaining in TMPDIR
$prefix rmdir "$homedir/$TMPDIR_ADD" runuser -u user -- rmdir "$homedir/$TMPDIR_ADD"
rm /tmp/debian-chroot.tar rm /tmp/debian-chroot.tar

View file

@ -1,30 +1,21 @@
#!/bin/sh #!/bin/sh
set -eu set -eu
export LC_ALL=C.UTF-8 export LC_ALL=C.UTF-8
if [ ! -e /mmdebstrap-testenv ]; then
[ "$(id -u)" -eq 0 ] echo "this test modifies the system and should only be run inside a container" >&2
[ {{ MODE }} = "unshare" ] exit 1
if ! id "${SUDO_USER:-user}" >/dev/null 2>&1; then
if [ ! -e /mmdebstrap-testenv ]; then
echo "this test modifies the system and should only be run inside a container" >&2
exit 1
fi
useradd --home-dir "/home/${SUDO_USER:-user}" --create-home "${SUDO_USER:-user}"
fi fi
prefix="runuser -u ${SUDO_USER:-user} --" useradd --home-dir /home/user --create-home user
mkdir /tmp/debian-chroot mkdir /tmp/debian-chroot
chmod 700 /tmp/debian-chroot chmod 700 /tmp/debian-chroot
chown "${SUDO_USER:-user}:${SUDO_USER:-user}" /tmp/debian-chroot chown user:user /tmp/debian-chroot
set -- env --chdir=/tmp/debian-chroot
if [ "{{ CMD }}" = "./mmdebstrap" ]; then if [ "{{ CMD }}" = "./mmdebstrap" ]; then
set -- "$@" "$(realpath --canonicalize-existing ./mmdebstrap)" set -- "$(realpath --canonicalize-existing ./mmdebstrap)"
elif [ "{{ CMD }}" = "perl -MDevel::Cover=-silent,-nogcov ./mmdebstrap" ]; then elif [ "{{ CMD }}" = "perl -MDevel::Cover=-silent,-nogcov ./mmdebstrap" ]; then
set -- "$@" perl -MDevel::Cover=-silent,-nogcov "$(realpath --canonicalize-existing ./mmdebstrap)" set -- perl -MDevel::Cover=-silent,-nogcov "$(realpath --canonicalize-existing ./mmdebstrap)"
else else
set -- "$@" {{ CMD }} set -- {{ CMD }}
fi fi
$prefix "$@" --mode={{ MODE }} --variant=apt {{ DIST }} /tmp/debian-chroot.tar {{ MIRROR }} env --chdir=/tmp/debian-chroot runuser -u user -- "$@" --mode=unshare --variant=apt {{ DIST }} /tmp/debian-chroot.tar {{ MIRROR }}
tar -tf /tmp/debian-chroot.tar | sort | diff -u tar1.txt - tar -tf /tmp/debian-chroot.tar | sort | diff -u tar1.txt -
rm /tmp/debian-chroot.tar rm /tmp/debian-chroot.tar

View file

@ -1,17 +0,0 @@
#!/bin/sh
set -eu
export LC_ALL=C.UTF-8
export SOURCE_DATE_EPOCH={{ SOURCE_DATE_EPOCH }}
tmpdir="$(mktemp -d)"
chmod 755 "$tmpdir"
case "{{ DIST }}" in
oldstable|stable)
debootstrap --no-merged-usr --variant={{ VARIANT }} {{ DIST }} "$tmpdir" {{ MIRROR }}
;;
*)
debootstrap --merged-usr --variant={{ VARIANT }} {{ DIST }} "$tmpdir" {{ MIRROR }}
;;
esac
tar --sort=name --mtime=@$SOURCE_DATE_EPOCH --clamp-mtime --numeric-owner --one-file-system --xattrs -C "$tmpdir" -c . > "./cache/debian-{{ DIST }}-{{ VARIANT }}.tar"
rm -r "$tmpdir"

View file

@ -7,17 +7,15 @@ if [ {{ MODE }} != unshare ] && [ {{ MODE }} != root ]; then
exit 1 exit 1
fi fi
prefix= if [ ! -e /mmdebstrap-testenv ]; then
if [ "$(id -u)" -eq 0 ] && [ "{{ MODE }}" != "root" ] && [ "{{ MODE }}" != "auto" ]; then echo "this test modifies the system and should only be run inside a container" >&2
if ! id "${SUDO_USER:-user}" >/dev/null 2>&1; then exit 1
if [ ! -e /mmdebstrap-testenv ]; then
echo "this test modifies the system and should only be run inside a container" >&2
exit 1
fi
useradd --home-dir "/home/${SUDO_USER:-user}" --create-home "${SUDO_USER:-user}"
fi
prefix="runuser -u ${SUDO_USER:-user} --"
fi fi
if [ "$(id -u)" -eq 0 ] && ! id -u user > /dev/null 2>&1; then
useradd --home-dir /home/user --create-home user
fi
prefix=
[ "$(id -u)" -eq 0 ] && [ "{{ MODE }}" != "root" ] && prefix="runuser -u user --"
# this mimics what apt does in apt-pkg/deb/dpkgpm.cc/pkgDPkgPM::StartPtyMagic() # this mimics what apt does in apt-pkg/deb/dpkgpm.cc/pkgDPkgPM::StartPtyMagic()
cat > /tmp/test.c << 'END' cat > /tmp/test.c << 'END'
@ -125,13 +123,12 @@ script -qfec "$prefix {{ CMD }} --mode={{ MODE }} --variant=apt \
--customize-hook='chroot \"\$1\" runuser -u user -- python3 -c \"import pty; print(pty.openpty())\"' \ --customize-hook='chroot \"\$1\" runuser -u user -- python3 -c \"import pty; print(pty.openpty())\"' \
--customize-hook='chroot \"\$1\" script -c \"echo foobar\"' \ --customize-hook='chroot \"\$1\" script -c \"echo foobar\"' \
--customize-hook='chroot \"\$1\" runuser -u user -- env --chdir=/home/user script -c \"echo foobar\"' \ --customize-hook='chroot \"\$1\" runuser -u user -- env --chdir=/home/user script -c \"echo foobar\"' \
--customize-hook='chroot \"\$1\" apt-get install --yes doc-debian 2>&1 | tee \"\$1\"/tmp/log' \ --customize-hook='chroot \"\$1\" apt-get install --yes doc-debian 2>&1 | tee /tmp/log' \
--customize-hook=\"copy-in /tmp/test.c /tmp\" \ --customize-hook=\"copy-in /tmp/test.c /tmp\" \
--customize-hook='chroot \"\$1\" gcc /tmp/test.c -o /tmp/test' \ --customize-hook='chroot \"\$1\" gcc /tmp/test.c -o /tmp/test' \
--customize-hook='chroot \"\$1\" /tmp/test' \ --customize-hook='chroot \"\$1\" /tmp/test' \
--customize-hook='chroot \"\$1\" runuser -u user -- /tmp/test' \ --customize-hook='chroot \"\$1\" runuser -u user -- /tmp/test' \
--customize-hook='rm \"\$1\"/tmp/test \"\$1\"/tmp/test.c' \ --customize-hook='rm \"\$1\"/tmp/test \"\$1\"/tmp/test.c' \
--customize-hook=\"copy-out /tmp/log /tmp\" \
{{ DIST }} /dev/null {{ MIRROR }}" /dev/null {{ DIST }} /dev/null {{ MIRROR }}" /dev/null
fail=0 fail=0

View file

@ -4,10 +4,8 @@
set -eu set -eu
export LC_ALL=C.UTF-8 export LC_ALL=C.UTF-8
trap "rm -f Release; rm -rf /tmp/debian-chroot.tar /tmp/expected" EXIT INT TERM trap "rm -f Release; rm -rf /tmp/debian-chroot" EXIT INT TERM
/usr/lib/apt/apt-helper download-file "{{ MIRROR }}/dists/{{ DIST }}/Release" Release /usr/lib/apt/apt-helper download-file "{{ MIRROR }}/dists/{{ DIST }}/Release" Release
codename=$(awk '/^Codename: / { print $2; }' Release) codename=$(awk '/^Codename: / { print $2; }' Release)
{{ CMD }} --mode={{ MODE }} --variant=apt "$codename" /tmp/debian-chroot.tar {{ MIRROR }} {{ CMD }} --mode={{ MODE }} --variant=apt "$codename" /tmp/debian-chroot {{ MIRROR }}
echo "deb {{ MIRROR }} $codename main" > /tmp/expected echo "deb {{ MIRROR }} $codename main" | diff -u - /tmp/debian-chroot/etc/apt/sources.list
tar --to-stdout --extract --file /tmp/debian-chroot.tar ./etc/apt/sources.list \
| diff -u /tmp/expected -

View file

@ -8,7 +8,7 @@ echo tzdata tzdata/Zones/Europe select Berlin | chroot "$1" debconf-set-selectio
SCRIPT SCRIPT
chmod +x /tmp/essential.sh chmod +x /tmp/essential.sh
{{ CMD }} --mode=root --variant=apt --include=tzdata --essential-hook='echo tzdata tzdata/Areas select Europe | chroot "$1" debconf-set-selections' --essential-hook=/tmp/essential.sh {{ DIST }} /tmp/debian-chroot {{ MIRROR }} {{ CMD }} --mode=root --variant=apt --include=tzdata --essential-hook='echo tzdata tzdata/Areas select Europe | chroot "$1" debconf-set-selections' --essential-hook=/tmp/essential.sh {{ DIST }} /tmp/debian-chroot {{ MIRROR }}
[ "$(readlink /tmp/debian-chroot/etc/localtime)" = "/usr/share/zoneinfo/Europe/Berlin" ] echo Europe/Berlin | cmp /tmp/debian-chroot/etc/timezone
tar -C /tmp/debian-chroot --one-file-system -c . | tar -t | sort \ tar -C /tmp/debian-chroot --one-file-system -c . | tar -t | sort \
| grep -v '^./etc/localtime' \ | grep -v '^./etc/localtime' \
| grep -v '^./etc/timezone' \ | grep -v '^./etc/timezone' \

View file

@ -1,23 +1,16 @@
#!/bin/sh #!/bin/sh
set -eu set -eu
export LC_ALL=C.UTF-8 export LC_ALL=C.UTF-8
if [ "$(id -u)" -eq 0 ] && ! id -u user > /dev/null 2>&1; then
[ {{ VARIANT }} = "custom" ] if [ ! -e /mmdebstrap-testenv ]; then
[ {{ MODE }} = "chrootless" ] echo "this test modifies the system and should only be run inside a container" >&2
exit 1
prefix=
if [ "$(id -u)" -eq 0 ] && [ "{{ MODE }}" != "root" ] && [ "{{ MODE }}" != "auto" ]; then
if ! id "${SUDO_USER:-user}" >/dev/null 2>&1; then
if [ ! -e /mmdebstrap-testenv ]; then
echo "this test modifies the system and should only be run inside a container" >&2
exit 1
fi
useradd --home-dir "/home/${SUDO_USER:-user}" --create-home "${SUDO_USER:-user}"
fi fi
prefix="runuser -u ${SUDO_USER:-user} --" useradd --home-dir /home/user --create-home user
fi fi
prefix=
$prefix {{ CMD }} --mode={{ MODE }} --variant={{ VARIANT }} --include=doc-debian {{ DIST }} /tmp/debian-chroot {{ MIRROR }} [ "$(id -u)" -eq 0 ] && prefix="runuser -u user --"
$prefix {{ CMD }} --mode=chrootless --variant=custom --include=doc-debian {{ DIST }} /tmp/debian-chroot {{ MIRROR }}
tar -C /tmp/debian-chroot --owner=0 --group=0 --numeric-owner --sort=name --clamp-mtime --mtime="$(date --utc --date=@{{ SOURCE_DATE_EPOCH }} --iso-8601=seconds)" -cf /tmp/debian-chroot.tar . tar -C /tmp/debian-chroot --owner=0 --group=0 --numeric-owner --sort=name --clamp-mtime --mtime="$(date --utc --date=@{{ SOURCE_DATE_EPOCH }} --iso-8601=seconds)" -cf /tmp/debian-chroot.tar .
tar tvf /tmp/debian-chroot.tar > doc-debian.tar.list tar tvf /tmp/debian-chroot.tar > doc-debian.tar.list
rm /tmp/debian-chroot.tar rm /tmp/debian-chroot.tar

View file

@ -2,22 +2,15 @@
set -eu set -eu
export LC_ALL=C.UTF-8 export LC_ALL=C.UTF-8
export SOURCE_DATE_EPOCH={{ SOURCE_DATE_EPOCH }} export SOURCE_DATE_EPOCH={{ SOURCE_DATE_EPOCH }}
if [ "$(id -u)" -eq 0 ] && ! id -u user > /dev/null 2>&1; then
[ {{ VARIANT }} = "custom" ] if [ ! -e /mmdebstrap-testenv ]; then
[ {{ MODE }} = "chrootless" ] echo "this test modifies the system and should only be run inside a container" >&2
exit 1
prefix=
if [ "$(id -u)" -eq 0 ] && [ "{{ MODE }}" != "root" ] && [ "{{ MODE }}" != "auto" ]; then
if ! id "${SUDO_USER:-user}" >/dev/null 2>&1; then
if [ ! -e /mmdebstrap-testenv ]; then
echo "this test modifies the system and should only be run inside a container" >&2
exit 1
fi
useradd --home-dir "/home/${SUDO_USER:-user}" --create-home "${SUDO_USER:-user}"
fi fi
prefix="runuser -u ${SUDO_USER:-user} --" useradd --home-dir /home/user --create-home user
fi fi
prefix=
$prefix {{ CMD }} --mode={{ MODE }} --variant={{ VARIANT }} --include=doc-debian {{ DIST }} /tmp/debian-chroot.tar {{ MIRROR }} [ "$(id -u)" -eq 0 ] && prefix="runuser -u user --"
$prefix {{ CMD }} --mode=chrootless --variant=custom --include=doc-debian {{ DIST }} /tmp/debian-chroot.tar {{ MIRROR }}
tar tvf /tmp/debian-chroot.tar | grep -v ' ./dev' | diff -u doc-debian.tar.list - tar tvf /tmp/debian-chroot.tar | grep -v ' ./dev' | diff -u doc-debian.tar.list -
rm /tmp/debian-chroot.tar rm /tmp/debian-chroot.tar

View file

@ -2,23 +2,16 @@
set -eu set -eu
export LC_ALL=C.UTF-8 export LC_ALL=C.UTF-8
export SOURCE_DATE_EPOCH={{ SOURCE_DATE_EPOCH }} export SOURCE_DATE_EPOCH={{ SOURCE_DATE_EPOCH }}
if [ "$(id -u)" -eq 0 ] && ! id -u user > /dev/null 2>&1; then
[ {{ VARIANT }} = "custom" ] if [ ! -e /mmdebstrap-testenv ]; then
[ {{ MODE }} = "chrootless" ] echo "this test modifies the system and should only be run inside a container" >&2
exit 1
prefix=
if [ "$(id -u)" -eq 0 ] && [ "{{ MODE }}" != "root" ] && [ "{{ MODE }}" != "auto" ]; then
if ! id "${SUDO_USER:-user}" >/dev/null 2>&1; then
if [ ! -e /mmdebstrap-testenv ]; then
echo "this test modifies the system and should only be run inside a container" >&2
exit 1
fi
useradd --home-dir "/home/${SUDO_USER:-user}" --create-home "${SUDO_USER:-user}"
fi fi
prefix="runuser -u ${SUDO_USER:-user} --" useradd --home-dir /home/user --create-home user
fi fi
prefix=
$prefix {{ CMD }} --mode={{ MODE }} --skip=cleanup/tmp --variant={{ VARIANT }} --include=doc-debian --setup-hook='touch "$1/tmp/setup"' --customize-hook='touch "$1/tmp/customize"' {{ DIST }} /tmp/debian-chroot {{ MIRROR }} [ "$(id -u)" -eq 0 ] && prefix="runuser -u user --"
$prefix {{ CMD }} --mode=chrootless --skip=cleanup/tmp --variant=custom --include=doc-debian --setup-hook='touch "$1/tmp/setup"' --customize-hook='touch "$1/tmp/customize"' {{ DIST }} /tmp/debian-chroot {{ MIRROR }}
rm /tmp/debian-chroot/tmp/setup rm /tmp/debian-chroot/tmp/setup
rm /tmp/debian-chroot/tmp/customize rm /tmp/debian-chroot/tmp/customize
tar -C /tmp/debian-chroot --owner=0 --group=0 --numeric-owner --sort=name --clamp-mtime --mtime="$(date --utc --date=@{{ SOURCE_DATE_EPOCH }} --iso-8601=seconds)" -cf /tmp/debian-chroot.tar . tar -C /tmp/debian-chroot --owner=0 --group=0 --numeric-owner --sort=name --clamp-mtime --mtime="$(date --utc --date=@{{ SOURCE_DATE_EPOCH }} --iso-8601=seconds)" -cf /tmp/debian-chroot.tar .

View file

@ -1,23 +1,16 @@
#!/bin/sh #!/bin/sh
set -eu set -eu
export LC_ALL=C.UTF-8 export LC_ALL=C.UTF-8
if [ "$(id -u)" -eq 0 ] && ! id -u user > /dev/null 2>&1; then
[ {{ VARIANT }} = "custom" ] if [ ! -e /mmdebstrap-testenv ]; then
[ {{ MODE }} = "chrootless" ] echo "this test modifies the system and should only be run inside a container" >&2
exit 1
prefix=
if [ "$(id -u)" -eq 0 ] && [ "{{ MODE }}" != "root" ] && [ "{{ MODE }}" != "auto" ]; then
if ! id "${SUDO_USER:-user}" >/dev/null 2>&1; then
if [ ! -e /mmdebstrap-testenv ]; then
echo "this test modifies the system and should only be run inside a container" >&2
exit 1
fi
useradd --home-dir "/home/${SUDO_USER:-user}" --create-home "${SUDO_USER:-user}"
fi fi
prefix="runuser -u ${SUDO_USER:-user} --" useradd --home-dir /home/user --create-home user
fi fi
prefix=
$prefix {{ CMD }} --mode={{ MODE }} --variant={{ VARIANT }} --architectures=arm64 --include=libmagic-mgc {{ DIST }} /tmp/debian-chroot {{ MIRROR }} [ "$(id -u)" -eq 0 ] && prefix="runuser -u user --"
$prefix {{ CMD }} --mode=chrootless --variant=custom --architectures=arm64 --include=libmagic-mgc {{ DIST }} /tmp/debian-chroot {{ MIRROR }}
# delete contents of libmagic-mgc # delete contents of libmagic-mgc
rm /tmp/debian-chroot/usr/lib/file/magic.mgc rm /tmp/debian-chroot/usr/lib/file/magic.mgc
rm /tmp/debian-chroot/usr/share/doc/libmagic-mgc/README.Debian rm /tmp/debian-chroot/usr/share/doc/libmagic-mgc/README.Debian

View file

@ -1,30 +1,15 @@
#!/bin/sh #!/bin/sh
set -eu set -eu
export LC_ALL=C.UTF-8 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
useradd --home-dir /home/user --create-home user
export SOURCE_DATE_EPOCH={{ SOURCE_DATE_EPOCH }} export SOURCE_DATE_EPOCH={{ SOURCE_DATE_EPOCH }}
trap "rm -f /tmp/debian-chroot-{{ MODE }}.tar /tmp/debian-chroot-root-normal.tar" EXIT INT TERM
[ "$(id -u)" -eq 0 ]
prefix=
if [ "$(id -u)" -eq 0 ] && [ "{{ MODE }}" != "root" ] && [ "{{ MODE }}" != "auto" ]; then
if ! id "${SUDO_USER:-user}" >/dev/null 2>&1; then
if [ ! -e /mmdebstrap-testenv ]; then
echo "this test modifies the system and should only be run inside a container" >&2
exit 1
fi
useradd --home-dir "/home/${SUDO_USER:-user}" --create-home "${SUDO_USER:-user}"
fi
prefix="runuser -u ${SUDO_USER:-user} --"
fi
MMTARFILTER=
[ -x /usr/bin/mmtarfilter ] && MMTARFILTER=/usr/bin/mmtarfilter
[ -x ./tarfilter ] && MMTARFILTER=./tarfilter
filter() { filter() {
"$MMTARFILTER" \ ./tarfilter \
--path-exclude=/usr/bin/uncompress \ --path-exclude=/usr/bin/uncompress \
--path-exclude=/var/cache/debconf/config.dat-old \ --path-exclude=/var/cache/debconf/config.dat-old \
--path-exclude=/var/cache/debconf/templates.dat-old \ --path-exclude=/var/cache/debconf/templates.dat-old \
@ -35,7 +20,19 @@ filter() {
} }
# base for comparison without jessie-or-older hook # base for comparison without jessie-or-older hook
{{ CMD }} --mode=root --variant={{ VARIANT }} {{ DIST }} - {{ MIRROR }} > /tmp/debian-chroot-root-normal.tar {{ CMD }} --mode=root --variant={{ VARIANT }} {{ DIST }} - {{ MIRROR }} | filter > /tmp/debian-chroot-root-normal.tar
$prefix {{ CMD }} --mode={{ MODE }} --variant={{ VARIANT }} --hook-dir=./hooks/jessie-or-older {{ DIST }} - {{ MIRROR }} | filter > /tmp/debian-chroot-{{ MODE }}.tar # root
filter < /tmp/debian-chroot-root-normal.tar | cmp - /tmp/debian-chroot-{{ MODE }}.tar {{ 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

View file

@ -46,4 +46,4 @@ chmod +x script.sh
--customize-hook=./script.sh \ --customize-hook=./script.sh \
--customize-hook="copy-out /tmp/chroot-fakechroot.tar /tmp" \ --customize-hook="copy-out /tmp/chroot-fakechroot.tar /tmp" \
{{ DIST }} /dev/null {{ MIRROR }} {{ DIST }} /dev/null {{ MIRROR }}
cmp /tmp/chroot-fakechroot.tar /tmp/chroot-root.tar || diffoscope /tmp/chroot-fakechroot.tar /tmp/chroot-root.tar cmp /tmp/chroot-fakechroot.tar /tmp/chroot-root.tar

View file

@ -1,20 +1,9 @@
#!/bin/sh #!/bin/sh
set -eu set -eu
export LC_ALL=C.UTF-8 export LC_ALL=C.UTF-8
if [ ! -e /mmdebstrap-testenv ]; then
[ {{ MODE }} = "unshare" ] echo "this test modifies the system and should only be run inside a container" >&2
[ {{ VARIANT }} = "custom" ] exit 1
prefix=
if [ "$(id -u)" -eq 0 ] && [ "{{ MODE }}" != "root" ] && [ "{{ MODE }}" != "auto" ]; then
if ! id "${SUDO_USER:-user}" >/dev/null 2>&1; then
if [ ! -e /mmdebstrap-testenv ]; then
echo "this test modifies the system and should only be run inside a container" >&2
exit 1
fi
useradd --home-dir "/home/${SUDO_USER:-user}" --create-home "${SUDO_USER:-user}"
fi
prefix="runuser -u ${SUDO_USER:-user} --"
fi fi
useradd --home-dir /home/user --create-home user
$prefix {{ CMD }} --mode={{ MODE }} --variant={{ VARIANT }} --include=dpkg,dash,diffutils,coreutils,libc-bin,sed {{ DIST }} /dev/null {{ MIRROR }} runuser -u user -- {{ CMD }} --mode=unshare --variant=custom --include=dpkg,dash,diffutils,coreutils,libc-bin,sed {{ DIST }} /dev/null {{ MIRROR }}

View file

@ -8,6 +8,7 @@ rm -r /tmp/debian-chroot/usr/share/doc/debian
rm -r /tmp/debian-chroot/usr/share/doc/doc-debian rm -r /tmp/debian-chroot/usr/share/doc/doc-debian
rm /tmp/debian-chroot/usr/share/lintian/overrides/tzdata rm /tmp/debian-chroot/usr/share/lintian/overrides/tzdata
rm /tmp/debian-chroot/etc/localtime 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/doc/tzdata
rm -r /tmp/debian-chroot/usr/share/zoneinfo rm -r /tmp/debian-chroot/usr/share/zoneinfo
rm /tmp/debian-chroot/var/lib/apt/extended_states rm /tmp/debian-chroot/var/lib/apt/extended_states

View file

@ -7,22 +7,16 @@
set -eu set -eu
export LC_ALL=C.UTF-8 export LC_ALL=C.UTF-8
trap "rm -f /tmp/debian-chroot.tar" EXIT INT TERM
[ "{{ MODE }}" = "fakechroot" ] [ "{{ MODE }}" = "fakechroot" ]
trap "rm -f /tmp/debian-chroot.tar" EXIT INT TERM
prefix= if [ "$(id -u)" -eq 0 ] && ! id -u user > /dev/null 2>&1; then
if [ "$(id -u)" -eq 0 ] && [ "{{ MODE }}" != "root" ] && [ "{{ MODE }}" != "auto" ]; then if [ ! -e /mmdebstrap-testenv ]; then
if ! id "${SUDO_USER:-user}" >/dev/null 2>&1; then echo "this test modifies the system and should only be run inside a container" >&2
if [ ! -e /mmdebstrap-testenv ]; then exit 1
echo "this test modifies the system and should only be run inside a container" >&2
exit 1
fi
useradd --home-dir "/home/${SUDO_USER:-user}" --create-home "${SUDO_USER:-user}"
fi fi
prefix="runuser -u ${SUDO_USER:-user} --" useradd --home-dir /home/user --create-home user
fi fi
prefix=
$prefix env PATH=/usr/bin:/bin fakechroot fakeroot {{ CMD }} --mode={{ MODE }} --variant=apt {{ DIST }} /tmp/debian-chroot.tar {{ MIRROR }} [ "$(id -u)" -eq 0 ] && prefix="runuser -u user --"
$prefix env PATH=/usr/bin:/bin fakechroot fakeroot {{ CMD }} --mode=fakechroot --variant=apt {{ DIST }} /tmp/debian-chroot.tar {{ MIRROR }}
tar -tf /tmp/debian-chroot.tar | sort | diff -u tar1.txt - tar -tf /tmp/debian-chroot.tar | sort | diff -u tar1.txt -

View file

@ -4,18 +4,22 @@ export LC_ALL=C.UTF-8
export SOURCE_DATE_EPOCH={{ SOURCE_DATE_EPOCH }} export SOURCE_DATE_EPOCH={{ SOURCE_DATE_EPOCH }}
trap "rm -f /tmp/chroot1.tar /tmp/chroot2.tar /tmp/chroot3.tar /tmp/mmdebstrap" EXIT INT TERM trap "rm -f /tmp/chroot1.tar /tmp/chroot2.tar /tmp/chroot3.tar /tmp/mmdebstrap" EXIT INT TERM
prefix= if [ ! -e /mmdebstrap-testenv ]; then
if [ "$(id -u)" -eq 0 ] && [ "{{ MODE }}" != "root" ] && [ "{{ MODE }}" != "auto" ]; then echo "this test modifies the system and should only be run inside a container" >&2
if ! id "${SUDO_USER:-user}" 2>/dev/null; then exit 1
if [ ! -e /mmdebstrap-testenv ]; then
echo "this test modifies the system and should only be run inside a container" >&2
exit 1
fi
useradd --home-dir "/home/${SUDO_USER:-user}" --create-home "${SUDO_USER:-user}"
fi
prefix="runuser -u ${SUDO_USER:-user} --"
fi fi
if [ "$(id -u)" -eq 0 ] && ! id -u user > /dev/null 2>&1; then
useradd --home-dir /home/user --create-home user
fi
prefix=
[ "$(id -u)" -eq 0 ] && [ "{{ MODE }}" != "root" ] && prefix="runuser -u user --"
MMDEBSTRAP=
[ -e /usr/bin/mmdebstrap ] && MMDEBSTRAP=/usr/bin/mmdebstrap
[ -e ./mmdebstrap ] && MMDEBSTRAP=./mmdebstrap
$prefix {{ CMD }} --mode={{ MODE }} --variant=apt \ $prefix {{ CMD }} --mode={{ MODE }} --variant=apt \
--include=mount \ --include=mount \
{{ DIST }} /tmp/chroot1.tar {{ MIRROR }} {{ DIST }} /tmp/chroot1.tar {{ MIRROR }}
@ -24,31 +28,28 @@ if [ {{ MODE }} = "unshare" ]; then
# calling pivot_root in root mode does not work for mysterious reasons: # calling pivot_root in root mode does not work for mysterious reasons:
# pivot_root: failed to change root from `.' to `mnt': Invalid argument # pivot_root: failed to change root from `.' to `mnt': Invalid argument
$prefix {{ CMD }} --mode={{ MODE }} --variant=apt --include=mount \ $prefix {{ CMD }} --mode={{ MODE }} --variant=apt --include=mount \
--customize-hook='mkdir -p "$1/mnt" "$1/oldroot"' \ --customize-hook="upload $MMDEBSTRAP /$MMDEBSTRAP" \
--customize-hook='[ ! -e /usr/bin/mmdebstrap ] || cp -aT /usr/bin/mmdebstrap "$1/usr/bin/mmdebstrap"' \ --customize-hook='chmod +x "$1"/'"$MMDEBSTRAP" \
--customize-hook='[ ! -e ./mmdebstrap ] || cp -aT ./mmdebstrap "$1/mnt/mmdebstrap"' \ --customize-hook='mount -o rbind "$1" /mnt && cd /mnt && /sbin/pivot_root . mnt' \
--customize-hook='mount -o rbind "$1" /mnt && cd /mnt && /sbin/pivot_root . oldroot' \
--customize-hook='unshare -U echo nested unprivileged unshare' \ --customize-hook='unshare -U echo nested unprivileged unshare' \
--customize-hook='env --chdir=/mnt {{ CMD }} --mode=unshare --variant=apt --include=mount {{ DIST }} /tmp/chroot3.tar {{ MIRROR }}' \ --customize-hook="/$MMDEBSTRAP"' --mode=unshare --variant=apt --include=mount {{ DIST }} /tmp/chroot3.tar {{ MIRROR }}' \
--customize-hook='copy-out /tmp/chroot3.tar /tmp' \ --customize-hook='copy-out /tmp/chroot3.tar /tmp' \
--customize-hook='rm -f "/usr/bin/mmdebstrap" "/mnt/mmdebstrap"' \ --customize-hook='rm "$1/'"$MMDEBSTRAP"'"' \
--customize-hook='umount -l oldroot sys' \ --customize-hook='umount -l mnt sys' \
--customize-hook='rmdir /oldroot' \
{{ DIST }} /tmp/chroot2.tar {{ MIRROR }} {{ DIST }} /tmp/chroot2.tar {{ MIRROR }}
cmp /tmp/chroot1.tar /tmp/chroot2.tar || diffoscope /tmp/chroot1.tar /tmp/chroot2.tar cmp /tmp/chroot1.tar /tmp/chroot2.tar
cmp /tmp/chroot1.tar /tmp/chroot3.tar || diffoscope /tmp/chroot1.tar /tmp/chroot3.tar cmp /tmp/chroot1.tar /tmp/chroot3.tar
rm /tmp/chroot2.tar /tmp/chroot3.tar rm /tmp/chroot2.tar /tmp/chroot3.tar
fi fi
$prefix {{ CMD }} --mode={{ MODE }} --variant=apt --include=mount \ $prefix {{ CMD }} --mode={{ MODE }} --variant=apt --include=mount \
--customize-hook='mkdir -p "$1/mnt"' \ --customize-hook="upload $MMDEBSTRAP /$MMDEBSTRAP" \
--customize-hook='[ ! -e /usr/bin/mmdebstrap ] || cp -aT /usr/bin/mmdebstrap "$1/usr/bin/mmdebstrap"' \ --customize-hook='chmod +x "$1"/'"$MMDEBSTRAP" \
--customize-hook='[ ! -e ./mmdebstrap ] || cp -aT ./mmdebstrap "$1/mnt/mmdebstrap"' \ --chrooted-customize-hook="/$MMDEBSTRAP"' --mode=unshare --variant=apt --include=mount {{ DIST }} /tmp/chroot3.tar {{ MIRROR }}' \
--chrooted-customize-hook='env --chdir=/mnt {{ CMD }} --mode=unshare --variant=apt --include=mount {{ DIST }} /tmp/chroot3.tar {{ MIRROR }}' \
--customize-hook='copy-out /tmp/chroot3.tar /tmp' \ --customize-hook='copy-out /tmp/chroot3.tar /tmp' \
--customize-hook='rm -f "$1/usr/bin/mmdebstrap" "$1/mnt/mmdebstrap"' \ --customize-hook='rm "$1/'"$MMDEBSTRAP"'"' \
{{ DIST }} /tmp/chroot2.tar {{ MIRROR }} {{ DIST }} /tmp/chroot2.tar {{ MIRROR }}
cmp /tmp/chroot1.tar /tmp/chroot2.tar || diffoscope /tmp/chroot1.tar /tmp/chroot2.tar cmp /tmp/chroot1.tar /tmp/chroot2.tar
cmp /tmp/chroot1.tar /tmp/chroot3.tar || diffoscope /tmp/chroot1.tar /tmp/chroot3.tar cmp /tmp/chroot1.tar /tmp/chroot3.tar

View file

@ -5,22 +5,13 @@
set -eu set -eu
export LC_ALL=C.UTF-8 export LC_ALL=C.UTF-8
if [ ! -e /mmdebstrap-testenv ]; then
[ {{ MODE }} = "unshare" ] echo "this test modifies the system and should only be run inside a container" >&2
exit 1
prefix=
if [ "$(id -u)" -eq 0 ] && [ "{{ MODE }}" != "root" ] && [ "{{ MODE }}" != "auto" ]; then
if ! id "${SUDO_USER:-user}" >/dev/null 2>&1; then
if [ ! -e /mmdebstrap-testenv ]; then
echo "this test modifies the system and should only be run inside a container" >&2
exit 1
fi
useradd --home-dir "/home/${SUDO_USER:-user}" --create-home "${SUDO_USER:-user}"
fi
prefix="runuser -u ${SUDO_USER:-user} --"
fi fi
[ "$(whoami)" = "root" ]
cat << 'SCRIPT' > /tmp/script.sh useradd --home-dir /home/user --create-home user
cat << 'SCRIPT' > script.sh
#!/bin/sh #!/bin/sh
set -eu set -eu
rootfs="$1" rootfs="$1"
@ -31,10 +22,10 @@ chroot "$rootfs" env --chdir=/mnt \
{{ CMD }} --mode=root --variant=apt \ {{ CMD }} --mode=root --variant=apt \
{{ DIST }} /tmp/debian-chroot.tar {{ MIRROR }} {{ DIST }} /tmp/debian-chroot.tar {{ MIRROR }}
SCRIPT SCRIPT
chmod +x /tmp/script.sh chmod +x script.sh
$prefix {{ CMD }} --mode={{ MODE }} --variant=apt --include=perl,mount \ runuser -u user -- {{ CMD }} --mode=unshare --variant=apt --include=perl,mount \
--customize-hook=/tmp/script.sh \ --customize-hook=./script.sh \
--customize-hook="download /tmp/debian-chroot.tar /tmp/debian-chroot.tar" \ --customize-hook="download /tmp/debian-chroot.tar /tmp/debian-chroot.tar" \
{{ DIST }} /dev/null {{ MIRROR }} {{ DIST }} /dev/null {{ MIRROR }}
tar -tf /tmp/debian-chroot.tar | sort | diff -u tar1.txt - tar -tf /tmp/debian-chroot.tar | sort | diff -u tar1.txt -
rm /tmp/debian-chroot.tar /tmp/script.sh rm /tmp/debian-chroot.tar script.sh

View file

@ -1,19 +1,15 @@
#!/bin/sh #!/bin/sh
set -eu set -eu
export LC_ALL=C.UTF-8 export LC_ALL=C.UTF-8
if [ "$(id -u)" -eq 0 ] && ! id -u user > /dev/null 2>&1; then
prefix= if [ ! -e /mmdebstrap-testenv ]; then
if [ "$(id -u)" -eq 0 ] && [ "{{ MODE }}" != "root" ] && [ "{{ MODE }}" != "auto" ]; then echo "this test modifies the system and should only be run inside a container" >&2
if ! id "${SUDO_USER:-user}" >/dev/null 2>&1; then exit 1
if [ ! -e /mmdebstrap-testenv ]; then
echo "this test modifies the system and should only be run inside a container" >&2
exit 1
fi
useradd --home-dir "/home/${SUDO_USER:-user}" --create-home "${SUDO_USER:-user}"
fi fi
prefix="runuser -u ${SUDO_USER:-user} --" useradd --home-dir /home/user --create-home user
fi fi
prefix=
[ "$(id -u)" -eq 0 ] && [ "{{ MODE }}" != "root" ] && prefix="runuser -u user --"
[ "{{ MODE }}" = "fakechroot" ] && prefix="$prefix fakechroot fakeroot" [ "{{ MODE }}" = "fakechroot" ] && prefix="$prefix fakechroot fakeroot"
symlinktarget=/real symlinktarget=/real
[ "{{ MODE }}" = "fakechroot" ] && symlinktarget='$1/real' [ "{{ MODE }}" = "fakechroot" ] && symlinktarget='$1/real'

View file

@ -1,23 +1,17 @@
#!/bin/sh #!/bin/sh
set -eu set -eu
export LC_ALL=C.UTF-8 export LC_ALL=C.UTF-8
if [ "$(id -u)" -eq 0 ] && ! id -u user > /dev/null 2>&1; then
[ {{ VARIANT }} = extract ] if [ ! -e /mmdebstrap-testenv ]; then
echo "this test modifies the system and should only be run inside a container" >&2
prefix= exit 1
if [ "$(id -u)" -eq 0 ] && [ "{{ MODE }}" != "root" ] && [ "{{ MODE }}" != "auto" ]; then
if ! id "${SUDO_USER:-user}" >/dev/null 2>&1; then
if [ ! -e /mmdebstrap-testenv ]; then
echo "this test modifies the system and should only be run inside a container" >&2
exit 1
fi
useradd --home-dir "/home/${SUDO_USER:-user}" --create-home "${SUDO_USER:-user}"
fi fi
prefix="runuser -u ${SUDO_USER:-user} --" useradd --home-dir /home/user --create-home user
fi fi
prefix=
[ "$(id -u)" -eq 0 ] && [ "{{ MODE }}" != "root" ] && prefix="runuser -u user --"
[ "{{ MODE }}" = "fakechroot" ] && prefix="$prefix fakechroot fakeroot" [ "{{ MODE }}" = "fakechroot" ] && prefix="$prefix fakechroot fakeroot"
$prefix {{ CMD }} --mode={{ MODE }} --variant={{ VARIANT }} --include=doc-debian {{ DIST }} /tmp/debian-chroot {{ MIRROR }} $prefix {{ CMD }} --mode={{ MODE }} --variant=extract --include=doc-debian {{ DIST }} /tmp/debian-chroot {{ MIRROR }}
# delete contents of doc-debian # delete contents of doc-debian
rm /tmp/debian-chroot/usr/share/doc-base/debian-* rm /tmp/debian-chroot/usr/share/doc-base/debian-*
rm -r /tmp/debian-chroot/usr/share/doc/debian rm -r /tmp/debian-chroot/usr/share/doc/debian

View file

@ -5,17 +5,14 @@ export LC_ALL=C.UTF-8
[ "{{ MODE }}" = unshare ] [ "{{ MODE }}" = unshare ]
prefix= if [ "$(id -u)" -eq 0 ] && ! id -u user > /dev/null 2>&1; then
if [ "$(id -u)" -eq 0 ] && [ "{{ MODE }}" != "root" ] && [ "{{ MODE }}" != "auto" ]; then if [ ! -e /mmdebstrap-testenv ]; then
if ! id "${SUDO_USER:-user}" >/dev/null 2>&1; then echo "this test modifies the system and should only be run inside a container" >&2
if [ ! -e /mmdebstrap-testenv ]; then exit 1
echo "this test modifies the system and should only be run inside a container" >&2
exit 1
fi
useradd --home-dir "/home/${SUDO_USER:-user}" --create-home "${SUDO_USER:-user}"
fi fi
prefix="runuser -u ${SUDO_USER:-user} --" useradd --home-dir /home/user --create-home user
fi fi
[ "$(id -u)" -eq 0 ] && prefix="runuser -u user --"
# instead of obtaining a .deb from our cache, we create a new package because # instead of obtaining a .deb from our cache, we create a new package because
# otherwise apt might decide to download the package with the same name and # otherwise apt might decide to download the package with the same name and
@ -34,8 +31,9 @@ Description: dummypkg
END END
dpkg-deb --build "/tmp/dummypkg" "/tmp/dummypkg.deb" dpkg-deb --build "/tmp/dummypkg" "/tmp/dummypkg.deb"
# make the .deb only redable by its owner which will exclude the unshared user # make the .deb only redable by user which will exclude the unshared user
chmod 600 /tmp/dummypkg.deb chmod 600 /tmp/dummypkg.deb
chown user /tmp/dummypkg.deb
ret=0 ret=0
$prefix {{ CMD }} --variant=apt --mode={{ MODE }} --include="/tmp/dummypkg.deb" \ $prefix {{ CMD }} --variant=apt --mode={{ MODE }} --include="/tmp/dummypkg.deb" \