diff --git a/coverage.txt b/coverage.txt index db10eec..7b98883 100644 --- a/coverage.txt +++ b/coverage.txt @@ -428,3 +428,6 @@ Modes: root unshare Test: skip-output-mknod Modes: root unshare + +Test: skip-tar-in-mknod +Modes: unshare diff --git a/mmdebstrap b/mmdebstrap index 992e4f4..7cf7cb6 100755 --- a/mmdebstrap +++ b/mmdebstrap @@ -3459,8 +3459,48 @@ sub hookhelper { @cmdprefix, @tarcmd, '--xattrs-include=*', '--directory', $directory, '--extract', '--file', '-' ); - debug("helper: running " . (join " ", @cmd)); - open($fh, '|-', @cmd) // error "failed to fork(): $!"; + # go via mmtarfilter if copy-in/mknod, tar-in/mknod or + # sync-in/mknod were part of the skip options + if (any { $_ eq "$command/mknod" } @skipopts) { + info "skipping $command/mknod as requested"; + my $tarfilter = "mmtarfilter"; + if (-x "./tarfilter") { + $tarfilter = "./tarfilter"; + } + pipe my $filter_reader, $fh or error "pipe failed: $!"; + pipe my $tar_reader, my $filter_writer + or error "pipe failed: $!"; + my $pid1 = fork() // error "fork() failed: $!"; + if ($pid1 == 0) { + open(STDIN, '<&', $filter_reader) + or error "cannot open STDIN: $!"; + open(STDOUT, '>&', $filter_writer) + or error "cannot open STDOUT: $!"; + close($tar_reader) + or error "cannot close tar_reader: $!"; + debug( + "helper: running $tarfilter --type-exclude=3 " + . "--type-exclude=4"); + eval { Devel::Cover::set_coverage("none") } + if $is_covering; + exec $tarfilter, '--type-exclude=3', + '--type-exclude=4'; + } + my $pid2 = fork() // error "fork() failed: $!"; + if ($pid2 == 0) { + open(STDIN, '<&', $tar_reader) + or error "cannot open STDIN: $!"; + close($filter_writer) + or error "cannot close filter_writer: $!"; + debug("helper: running " . (join " ", @cmd)); + eval { Devel::Cover::set_coverage("none") } + if $is_covering; + exec { $cmd[0] } @cmd; + } + } else { + debug("helper: running " . (join " ", @cmd)); + open($fh, '|-', @cmd) // error "failed to fork(): $!"; + } } else { error "unknown command: $command"; } @@ -7088,7 +7128,9 @@ only update the content of an existing directory. =item B I I Unpacks a tarball I from outside the chroot into a certain -location I inside the chroot. +location I inside the chroot. In B mode, device nodes +cannot be created. To ignore device nodes in tarballs, use +B<--skip=tar-in/mknod>. =item B I I @@ -7530,9 +7572,9 @@ Create a system that can be used with podman: As a docker/podman replacement: - $ mmdebstrap --skip=output/mknod unstable chroot.tar + $ mmdebstrap unstable chroot.tar [...] - $ mmdebstrap --variant=custom --skip=update \ + $ mmdebstrap --variant=custom --skip=update,tar-in/mknod \ --setup-hook='tar-in chroot.tar /' \ --customize-hook='chroot "$1" whoami' unstable /dev/null [...] @@ -7545,8 +7587,8 @@ installed, then instead of downloading and installing the essential packages twice you can instead build on top of the already present minimal chroot: $ mmdebstrap --variant=apt unstable chroot.tar - $ mmdebstrap --variant=custom --setup-hook \ - 'mmtarfilter "--path-exclude=/dev/*" < chroot.tar | tar -C "$1" -x' \ + $ mmdebstrap --variant=custom --skip=update,setup,cleanup,tar-in/mknod \ + --setup-hook='tar-in chroot.tar /' \ --customize-hook='chroot "$1" apt-get install --yes pkg1 pkg2' \ '' chroot-full.tar diff --git a/tests/skip-tar-in-mknod b/tests/skip-tar-in-mknod new file mode 100644 index 0000000..eb3027a --- /dev/null +++ b/tests/skip-tar-in-mknod @@ -0,0 +1,28 @@ +#!/bin/sh +set -eu +export LC_ALL=C.UTF-8 +export SOURCE_DATE_EPOCH={{ SOURCE_DATE_EPOCH }} + +[ {{ MODE }} = "unshare" ] + +trap "rm -f /tmp/debian-chroot.tar" EXIT INT TERM + +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 + +$prefix {{ CMD }} --mode={{ MODE }} --variant=custom \ + --skip=update,setup,cleanup,tar-in/mknod \ + --setup-hook='tar-in ./cache/mmdebstrap-{{ DIST }}-apt.tar /' \ + '' /tmp/debian-chroot.tar + +cmp ./cache/mmdebstrap-{{ DIST }}-apt.tar /tmp/debian-chroot.tar \ + || diffoscope ./cache/mmdebstrap-{{ DIST }}-apt.tar /tmp/debian-chroot.tar