Compare commits

...

8 commits

4 changed files with 61 additions and 18 deletions

View file

@ -1,3 +1,10 @@
0.8.4 (2022-02-11)
------------------
- tarfilter: add --strip-components option
- don't install essential packages in run_install()
- remove /var/lib/dbus/machine-id
0.8.3 (2022-01-08) 0.8.3 (2022-01-08)
------------------ ------------------

View file

@ -180,6 +180,7 @@ export SOURCE_DATE_EPOCH=$SOURCE_DATE_EPOCH
# compared to the one chosen in debootstrap because of different installation # compared to the one chosen in debootstrap because of different installation
# order in comparison to the systemd users # order in comparison to the systemd users
# https://bugs.debian.org/969631 # https://bugs.debian.org/969631
# we cannot use useradd because passwd is not Essential:yes
$CMD --variant=$variant --mode=$defaultmode \ $CMD --variant=$variant --mode=$defaultmode \
--essential-hook='if [ $variant = - ]; then echo _apt:*:100:65534::/nonexistent:/usr/sbin/nologin >> "\$1"/etc/passwd; fi' \ --essential-hook='if [ $variant = - ]; then echo _apt:*:100:65534::/nonexistent:/usr/sbin/nologin >> "\$1"/etc/passwd; fi' \
$dist /tmp/debian-$dist-mm.tar $mirror $dist /tmp/debian-$dist-mm.tar $mirror
@ -321,6 +322,18 @@ else
echo no difference for /etc/shadow- on $dist $variant >&2 echo no difference for /etc/shadow- on $dist $variant >&2
fi fi
# Because of unreproducible uids (#969631) we created the _apt user ourselves
# and because passwd is not Essential:yes we didn't use useradd. But passwd
# since 1:4.11.1+dfsg1-1 will create empty mail files, so we create it too.
# https://bugs.debian.org/1004710
if [ $variant = - ]; then
if [ -e /tmp/debian-$dist-debootstrap/var/mail/_apt ]; then
touch /tmp/debian-$dist-mm/var/mail/_apt
chmod 660 /tmp/debian-$dist-mm/var/mail/_apt
chown 100:8 /tmp/debian-$dist-mm/var/mail/_apt
fi
fi
# check if the file content differs # check if the file content differs
diff --unified --no-dereference --recursive /tmp/debian-$dist-debootstrap /tmp/debian-$dist-mm diff --unified --no-dereference --recursive /tmp/debian-$dist-debootstrap /tmp/debian-$dist-mm
@ -742,9 +755,8 @@ fi
for variant in essential apt minbase buildd important standard; do for variant in essential apt minbase buildd important standard; do
for format in tar squashfs ext2; do for format in tar squashfs ext2; do
print_header "mode=root/unshare/fakechroot,variant=$variant: check for bit-by-bit identical $format output" print_header "mode=root/unshare/fakechroot,variant=$variant: check for bit-by-bit identical $format output"
# fontconfig doesn't install reproducibly because differences # pyc files and man index.db are not reproducible
# in /var/cache/fontconfig/. See # See #1004557 and #1004558
# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=864082
if [ "$variant" = "standard" ]; then if [ "$variant" = "standard" ]; then
echo "skipping test because of #864082" >&2 echo "skipping test because of #864082" >&2
skipped=$((skipped+1)) skipped=$((skipped+1))
@ -846,6 +858,7 @@ cmp /tmp/debian-chroot.tar /tmp/debian-chroot-shiftedback.tar
# manually adjust uid/gid and compare "tar -t" output # manually adjust uid/gid and compare "tar -t" output
tar --numeric-owner -tvf /tmp/debian-chroot.tar \ tar --numeric-owner -tvf /tmp/debian-chroot.tar \
| sed 's# 100/0 # 100100/100000 #' \ | sed 's# 100/0 # 100100/100000 #' \
| sed 's# 100/8 # 100100/100008 #' \
| sed 's# 0/0 # 100000/100000 #' \ | sed 's# 0/0 # 100000/100000 #' \
| sed 's# 0/5 # 100000/100005 #' \ | sed 's# 0/5 # 100000/100005 #' \
| sed 's# 0/8 # 100000/100008 #' \ | sed 's# 0/8 # 100000/100008 #' \
@ -2973,9 +2986,8 @@ fi
# into /var/cache/apt/archives/partial # into /var/cache/apt/archives/partial
for variant in extract custom essential apt minbase buildd important standard; do for variant in extract custom essential apt minbase buildd important standard; do
print_header "mode=$defaultmode,variant=$variant: compare output with pre-seeded /var/cache/apt/archives" print_header "mode=$defaultmode,variant=$variant: compare output with pre-seeded /var/cache/apt/archives"
# fontconfig doesn't install reproducibly because differences # pyc files and man index.db are not reproducible
# in /var/cache/fontconfig/. See # See #1004557 and #1004558
# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=864082
if [ "$variant" = "standard" ]; then if [ "$variant" = "standard" ]; then
echo "skipping test because of #864082" >&2 echo "skipping test because of #864082" >&2
skipped=$((skipped+1)) skipped=$((skipped+1))

View file

@ -23,7 +23,7 @@
use strict; use strict;
use warnings; use warnings;
our $VERSION = '0.8.3'; our $VERSION = '0.8.4';
use English; use English;
use Getopt::Long; use Getopt::Long;
@ -2722,13 +2722,18 @@ sub run_install() {
any { $_ eq $options->{variant} } any { $_ eq $options->{variant} }
('required', 'important', 'standard', 'buildd') ('required', 'important', 'standard', 'buildd')
) { ) {
# Many of the priority:required packages are also essential:yes. We
# make sure not to select those here to avoid useless "xxx is already
# the newest version" messages.
my $priority; my $priority;
if (any { $_ eq $options->{variant} } ('required', 'buildd')) { if (any { $_ eq $options->{variant} } ('required', 'buildd')) {
$priority = '?priority(required)'; $priority = '?and(?priority(required),?not(?essential))';
} elsif ($options->{variant} eq 'important') { } elsif ($options->{variant} eq 'important') {
$priority = '?or(?priority(required),?priority(important))'; $priority = '?and(?or(?priority(required),?priority(important)),'
. '?not(?essential))';
} elsif ($options->{variant} eq 'standard') { } elsif ($options->{variant} eq 'standard') {
$priority = '?or(~prequired,~pimportant,~pstandard)'; $priority = '?and(?or(~prequired,~pimportant,~pstandard),'
. '?not(?essential))';
} }
$pkgs_to_install{ $pkgs_to_install{
"?narrow(" "?narrow("
@ -2780,6 +2785,9 @@ sub run_install() {
# #
# - we can make use of file:// and copy:// # - we can make use of file:// and copy://
# #
# - we can use EDSP solvers without installing apt-utils or other
# solvers inside the chroot
#
# The DPkg::Install::Recursive::force=true workaround can be # The DPkg::Install::Recursive::force=true workaround can be
# dropped after this issue is fixed: # dropped after this issue is fixed:
# https://salsa.debian.org/apt-team/apt/-/merge_requests/189 # https://salsa.debian.org/apt-team/apt/-/merge_requests/189
@ -2915,7 +2923,8 @@ sub run_cleanup() {
foreach my $fname ( foreach my $fname (
'/var/log/dpkg.log', '/var/log/apt/history.log', '/var/log/dpkg.log', '/var/log/apt/history.log',
'/var/log/apt/term.log', '/var/log/alternatives.log', '/var/log/apt/term.log', '/var/log/alternatives.log',
'/var/cache/ldconfig/aux-cache', '/var/log/apt/eipp.log.xz' '/var/cache/ldconfig/aux-cache', '/var/log/apt/eipp.log.xz',
'/var/lib/dbus/machine-id'
) { ) {
my $path = "$options->{root}$fname"; my $path = "$options->{root}$fname";
if (!-e $path) { if (!-e $path) {
@ -6288,11 +6297,7 @@ needs to be able to mount and thus requires C<SYS_CAP_ADMIN>.
This mode uses Linux user namespaces to allow unprivileged use of chroot and This mode uses Linux user namespaces to allow unprivileged use of chroot and
creation of files that appear to be owned by the superuser inside the unshared creation of files that appear to be owned by the superuser inside the unshared
namespace. A tarball created in this mode should be bit-by-bit identical to a namespace. A tarball created in this mode should be bit-by-bit identical to a
tarball created with the B<root> mode. In Debian, this mode requires the sysctl tarball created with the B<root> mode.
C<kernel.unprivileged_userns_clone> being set to C<1>. The default used to be
C<0> but was changed to C<1> with linux 5.10.1 or Debian 11 (Bullseye).
B<SETTING THIS OPTION TO 1 HAS SECURITY IMPLICATIONS>. Refer to
L<https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=898446>
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. For correct ownership information, the directory must be accessed information. For correct ownership information, the directory must be accessed
@ -6716,7 +6721,7 @@ Performs cleanup tasks, unless B<--skip=cleanup> is used:
=item * Remove all files that were put into the chroot for setup purposes, like F</etc/apt/apt.conf.d/00mmdebstrap>, the temporary apt config and the qemu-user-static binary. This can be disabled using B<--skip=cleanup/mmdebstrap>. =item * Remove all files that were put into the chroot for setup purposes, like F</etc/apt/apt.conf.d/00mmdebstrap>, the temporary apt config and the qemu-user-static binary. This can be disabled using B<--skip=cleanup/mmdebstrap>.
=item * Remove all files that make the result unreproducible, like apt and dpkg logs and caches or F</etc/machine-id>. This can be disabled using B<--skip=cleanup/reproducible> =item * Remove all files that make the result unreproducible, like apt and dpkg logs and caches or F</etc/machine-id> and F</var/lib/dbus/machine-id>. This can be disabled using B<--skip=cleanup/reproducible>
=item * Remove everything in F</tmp> inside the chroot. This can be disabled using B<--skip=cleanup/tmp>. =item * Remove everything in F</tmp> inside the chroot. This can be disabled using B<--skip=cleanup/tmp>.

View file

@ -64,6 +64,10 @@ Both types of options use Unix shell-style wildcards:
? matches any single character ? matches any single character
[seq] matches any character in seq [seq] matches any character in seq
[!seq] matches any character not in seq [!seq] matches any character not in seq
Thirdly, strip leading directory components off of tar members. Just as with
GNU tar --strip-components, tar members that have less or equal components in
their path are not passed through.
""" """
) )
parser.add_argument( parser.add_argument(
@ -90,8 +94,18 @@ Both types of options use Unix shell-style wildcards:
action=PaxFilterAction, action=PaxFilterAction,
help="Re-include a pax header after a previous exclusion.", help="Re-include a pax header after a previous exclusion.",
) )
parser.add_argument(
"--strip-components",
metavar="number",
type=int,
help="Strip NUMBER leading components from file names",
)
args = parser.parse_args() args = parser.parse_args()
if not hasattr(args, "pathfilter") and not hasattr(args, "paxfilter"): if (
not hasattr(args, "pathfilter")
and not hasattr(args, "paxfilter")
and not hasattr(args, "strip_components")
):
from shutil import copyfileobj from shutil import copyfileobj
copyfileobj(sys.stdin.buffer, sys.stdout.buffer) copyfileobj(sys.stdin.buffer, sys.stdout.buffer)
@ -141,6 +155,11 @@ Both types of options use Unix shell-style wildcards:
for member in in_tar: for member in in_tar:
if path_filter_should_skip(member): if path_filter_should_skip(member):
continue continue
if args.strip_components:
comps = member.name.split("/")
if len(comps) <= args.strip_components:
continue
member.name = "/".join(comps[args.strip_components :])
member.pax_headers = { member.pax_headers = {
k: v k: v
for k, v in member.pax_headers.items() for k, v in member.pax_headers.items()