add --skip=tar-in/mknod,copy-in/mknod,sync-in/mknod

This commit is contained in:
Johannes Schauer Marin Rodrigues 2023-10-23 11:47:27 +02:00
parent c33f719278
commit cb500ef6ba
Signed by untrusted user: josch
GPG key ID: F2CBA5C78FBD83E1
3 changed files with 80 additions and 7 deletions

View file

@ -428,3 +428,6 @@ Modes: root unshare
Test: skip-output-mknod Test: skip-output-mknod
Modes: root unshare Modes: root unshare
Test: skip-tar-in-mknod
Modes: unshare

View file

@ -3459,8 +3459,48 @@ sub hookhelper {
@cmdprefix, @tarcmd, '--xattrs-include=*', @cmdprefix, @tarcmd, '--xattrs-include=*',
'--directory', $directory, '--extract', '--file', '-' '--directory', $directory, '--extract', '--file', '-'
); );
# 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)); debug("helper: running " . (join " ", @cmd));
open($fh, '|-', @cmd) // error "failed to fork(): $!"; open($fh, '|-', @cmd) // error "failed to fork(): $!";
}
} else { } else {
error "unknown command: $command"; error "unknown command: $command";
} }
@ -7088,7 +7128,9 @@ only update the content of an existing directory.
=item B<tar-in> I<outside.tar> I<pathinside> =item B<tar-in> I<outside.tar> I<pathinside>
Unpacks a tarball I<outside.tar> from outside the chroot into a certain Unpacks a tarball I<outside.tar> from outside the chroot into a certain
location I<pathinside> inside the chroot. location I<pathinside> inside the chroot. In B<unshare> mode, device nodes
cannot be created. To ignore device nodes in tarballs, use
B<--skip=tar-in/mknod>.
=item B<tar-out> I<pathinside> I<outside.tar> =item B<tar-out> I<pathinside> I<outside.tar>
@ -7530,9 +7572,9 @@ Create a system that can be used with podman:
As a docker/podman replacement: 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 /' \ --setup-hook='tar-in chroot.tar /' \
--customize-hook='chroot "$1" whoami' unstable /dev/null --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: twice you can instead build on top of the already present minimal chroot:
$ mmdebstrap --variant=apt unstable chroot.tar $ mmdebstrap --variant=apt unstable chroot.tar
$ mmdebstrap --variant=custom --setup-hook \ $ mmdebstrap --variant=custom --skip=update,setup,cleanup,tar-in/mknod \
'mmtarfilter "--path-exclude=/dev/*" < chroot.tar | tar -C "$1" -x' \ --setup-hook='tar-in chroot.tar /' \
--customize-hook='chroot "$1" apt-get install --yes pkg1 pkg2' \ --customize-hook='chroot "$1" apt-get install --yes pkg1 pkg2' \
'' chroot-full.tar '' chroot-full.tar

28
tests/skip-tar-in-mknod Normal file
View file

@ -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