set MMDEBSTRAP_APT_CONFIG, MMDEBSTRAP_MODE and MMDEBSTRAP_HOOKSOCK for hook scripts

This commit is contained in:
Johannes 'josch' Schauer 2021-01-09 19:41:59 +01:00
parent 5a7dbc10c7
commit ac21074243
Signed by untrusted user: josch
GPG key ID: F2CBA5C78FBD83E1
2 changed files with 77 additions and 4 deletions

View file

@ -119,7 +119,7 @@ if [ ! -e shared/hooks/eatmydata/customize.sh ] || [ hooks/eatmydata/customize.s
fi
fi
starttime=
total=170
total=171
skipped=0
runtests=0
i=1
@ -2188,6 +2188,50 @@ else
runtests=$((runtests+1))
fi
print_header "mode=root,variant=apt: test special hooks using helpers"
cat << END > shared/test.sh
#!/bin/sh
set -eu
export LC_ALL=C.UTF-8
cat << 'SCRIPT' > /tmp/script.sh
#!/bin/sh
set -eu
echo "MMDEBSTRAP_APT_CONFIG \$MMDEBSTRAP_APT_CONFIG"
[ "\$MMDEBSTRAP_MODE" = "root" ]
echo test-content \$2 > test
$CMD --hook-helper "\$1" "\$MMDEBSTRAP_MODE" "\$2" env 1 upload test /test <&\$MMDEBSTRAP_HOOKSOCK >&\$MMDEBSTRAP_HOOKSOCK
rm test
echo "content inside chroot:"
cat "\$1/test"
[ "test-content \$2" = "\$(cat "\$1/test")" ]
$CMD --hook-helper "\$1" "\$MMDEBSTRAP_MODE" "\$2" env 1 download /test test <&\$MMDEBSTRAP_HOOKSOCK >&\$MMDEBSTRAP_HOOKSOCK
echo "content outside chroot:"
cat test
[ "test-content \$2" = "\$(cat test)" ]
rm test
SCRIPT
chmod +x /tmp/script.sh
for h in setup extract essential customize; do
printf '#!/bin/sh\nset -eu\nexec /tmp/script.sh "\$1" "'"\$h"'"' > "/tmp/\$h.sh"
chmod +x "/tmp/\$h.sh"
done
$CMD --mode=root --variant=apt \
--setup-hook=/tmp/setup.sh \
--extract-hook=/tmp/extract.sh \
--essential-hook=/tmp/essential.sh \
--customize-hook=/tmp/customize.sh \
$DEFAULT_DIST /tmp/debian-chroot $mirror
rm /tmp/script.sh /tmp/setup.sh /tmp/extract.sh /tmp/essential.sh /tmp/customize.sh
rm -r /tmp/debian-chroot
END
if [ "$HAVE_QEMU" = "yes" ]; then
./run_qemu.sh
runtests=$((runtests+1))
else
./run_null.sh SUDO
runtests=$((runtests+1))
fi
# test special hooks
for mode in root unshare fakechroot proot; do
print_header "mode=$mode,variant=apt: test special hooks with $mode mode"

View file

@ -1188,6 +1188,28 @@ sub run_hooks {
return;
}
my @env_opts = ();
# There is no need to unset TMPDIR because we already have set it ourselves
# to "$options->{root}/tmp" in run_setup(). This is to have a writable
# TMPDIR even in unshare mode.
#
# The APT_CONFIG variable, if set, will confuse any manual calls to
# apt-get. If you want to use the same config used by mmdebstrap, the
# original value is stored in MMDEBSTRAP_APT_CONFIG.
if (defined $ENV{APT_CONFIG} && $ENV{APT_CONFIG} ne "") {
push @env_opts, '--unset=APT_CONFIG';
}
if (defined $ENV{APT_CONFIG} && $ENV{APT_CONFIG} ne "") {
push @env_opts, "MMDEBSTRAP_APT_CONFIG=$ENV{APT_CONFIG}";
}
# Storing the mode is important for hook scripts to potentially change
# their behavior depending on the mode. It's also important for when the
# hook wants to use the mmdebstrap --hook-helper.
push @env_opts, "MMDEBSTRAP_MODE=$options->{mode}";
# This is the file descriptor of the socket that the mmdebstrap
# --hook-helper can write to and read from to communicate with the outside.
push @env_opts, ("MMDEBSTRAP_HOOKSOCK=" . fileno($options->{hooksock}));
my $runner = sub {
foreach my $script (@{ $options->{"${name}_hook"} }) {
if (
@ -1246,20 +1268,25 @@ sub run_hooks {
# execute it directly if it's an executable file
# or if it there are no shell metacharacters
# (the /a regex modifier makes \w match only ASCII)
0 == system('env', '--unset=TMPDIR', '--unset=APT_CONFIG',
$script, $options->{root})
0 == system('env', @env_opts, $script, $options->{root})
or error "command failed: $script";
} else {
info "running --$name-hook in shell: sh -c '$script' exec"
. " $options->{root}";
# otherwise, wrap everything in sh -c
0 == system('env', '--unset=TMPDIR', '--unset=APT_CONFIG',
0 == system('env', @env_opts,
'sh', '-c', $script, 'exec', $options->{root})
or error "command failed: $script";
}
}
};
# Unset the close-on-exec flag, so that the file descriptor does not
# get closed when we exec
my $flags = fcntl($options->{hooksock}, F_GETFD, 0)
or error "fcntl F_GETFD: $!";
fcntl($options->{hooksock}, F_SETFD, $flags & ~FD_CLOEXEC)
or error "fcntl F_SETFD: $!";
if ($name eq 'setup') {
# execute directly without mounting anything (the mount points do not
# exist yet)
@ -1267,6 +1294,8 @@ sub run_hooks {
} else {
run_chroot(\&$runner, $options);
}
# Restore flags
fcntl($options->{hooksock}, F_SETFD, $flags) or error "fcntl F_SETFD: $!";
return;
}