add sync-in and sync-out hooks

This commit is contained in:
Johannes 'josch' Schauer 2020-01-16 10:38:14 +01:00
parent 5e0f6d0ca8
commit 7d152ec7e0
Signed by untrusted user: josch
GPG key ID: F2CBA5C78FBD83E1
2 changed files with 100 additions and 19 deletions

View file

@ -1533,6 +1533,12 @@ rm /tmp/tar-in-customize
echo upload-setup > /tmp/upload-setup echo upload-setup > /tmp/upload-setup
echo upload-essential > /tmp/upload-essential echo upload-essential > /tmp/upload-essential
echo upload-customize > /tmp/upload-customize echo upload-customize > /tmp/upload-customize
mkdir /tmp/sync-in-setup
mkdir /tmp/sync-in-essential
mkdir /tmp/sync-in-customize
echo sync-in-setup > /tmp/sync-in-setup/file
echo sync-in-essential > /tmp/sync-in-essential/file
echo sync-in-customize > /tmp/sync-in-customize/file
\$prefix $CMD --mode=$mode --variant=apt \ \$prefix $CMD --mode=$mode --variant=apt \
--setup-hook='mkdir "\$1/real"' \ --setup-hook='mkdir "\$1/real"' \
--setup-hook='copy-in /tmp/copy-in-setup /real' \ --setup-hook='copy-in /tmp/copy-in-setup /real' \
@ -1549,6 +1555,10 @@ echo upload-customize > /tmp/upload-customize
--setup-hook='echo upload-setup | cmp "\$1/real/upload" -' \ --setup-hook='echo upload-setup | cmp "\$1/real/upload" -' \
--setup-hook='download /real/upload /tmp/download-setup' \ --setup-hook='download /real/upload /tmp/download-setup' \
--setup-hook='rm "\$1/real/upload"' \ --setup-hook='rm "\$1/real/upload"' \
--setup-hook='sync-in /tmp/sync-in-setup /real' \
--setup-hook='echo sync-in-setup | cmp "\$1/real/file" -' \
--setup-hook='sync-out /real /tmp/sync-out-setup' \
--setup-hook='rm "\$1/real/file"' \
--essential-hook='ln -s "'"\$symlinktarget"'" "\$1/symlink"' \ --essential-hook='ln -s "'"\$symlinktarget"'" "\$1/symlink"' \
--essential-hook='copy-in /tmp/copy-in-essential /symlink' \ --essential-hook='copy-in /tmp/copy-in-essential /symlink' \
--essential-hook='echo copy-in-essential | cmp "\$1/real/copy-in-essential" -' \ --essential-hook='echo copy-in-essential | cmp "\$1/real/copy-in-essential" -' \
@ -1564,6 +1574,10 @@ echo upload-customize > /tmp/upload-customize
--essential-hook='echo upload-essential | cmp "\$1/real/upload" -' \ --essential-hook='echo upload-essential | cmp "\$1/real/upload" -' \
--essential-hook='download /symlink/upload /tmp/download-essential' \ --essential-hook='download /symlink/upload /tmp/download-essential' \
--essential-hook='rm "\$1/real/upload"' \ --essential-hook='rm "\$1/real/upload"' \
--essential-hook='sync-in /tmp/sync-in-essential /symlink' \
--essential-hook='echo sync-in-essential | cmp "\$1/real/file" -' \
--essential-hook='sync-out /real /tmp/sync-out-essential' \
--essential-hook='rm "\$1/real/file"' \
--customize-hook='copy-in /tmp/copy-in-customize /symlink' \ --customize-hook='copy-in /tmp/copy-in-customize /symlink' \
--customize-hook='echo copy-in-customize | cmp "\$1/real/copy-in-customize" -' \ --customize-hook='echo copy-in-customize | cmp "\$1/real/copy-in-customize" -' \
--customize-hook='rm "\$1/real/copy-in-customize"' \ --customize-hook='rm "\$1/real/copy-in-customize"' \
@ -1578,6 +1592,10 @@ echo upload-customize > /tmp/upload-customize
--customize-hook='echo upload-customize | cmp "\$1/real/upload" -' \ --customize-hook='echo upload-customize | cmp "\$1/real/upload" -' \
--customize-hook='download /symlink/upload /tmp/download-customize' \ --customize-hook='download /symlink/upload /tmp/download-customize' \
--customize-hook='rm "\$1/real/upload"' \ --customize-hook='rm "\$1/real/upload"' \
--customize-hook='sync-in /tmp/sync-in-customize /symlink' \
--customize-hook='echo sync-in-customize | cmp "\$1/real/file" -' \
--customize-hook='sync-out /real /tmp/sync-out-customize' \
--customize-hook='rm "\$1/real/file"' \
--customize-hook='rmdir "\$1/real"' \ --customize-hook='rmdir "\$1/real"' \
--customize-hook='rm "\$1/symlink"' \ --customize-hook='rm "\$1/symlink"' \
$DEFAULT_DIST /tmp/debian-chroot.tar $mirror $DEFAULT_DIST /tmp/debian-chroot.tar $mirror
@ -1614,6 +1632,9 @@ echo copy-out-customize | cmp /tmp/copy-out-customize -
echo upload-setup | cmp /tmp/download-setup - echo upload-setup | cmp /tmp/download-setup -
echo upload-essential | cmp /tmp/download-essential - echo upload-essential | cmp /tmp/download-essential -
echo upload-customize | cmp /tmp/download-customize - echo upload-customize | cmp /tmp/download-customize -
echo sync-in-setup | cmp /tmp/sync-out-setup/file -
echo sync-in-essential | cmp /tmp/sync-out-essential/file -
echo sync-in-customize | cmp /tmp/sync-out-customize/file -
# in fakechroot mode, we use a fake ldconfig, so we have to # in fakechroot mode, we use a fake ldconfig, so we have to
# artificially add some files # artificially add some files
{ tar -tf /tmp/debian-chroot.tar; { tar -tf /tmp/debian-chroot.tar;
@ -1626,7 +1647,11 @@ rm /tmp/debian-chroot.tar \
/tmp/tar-in-setup.tar /tmp/tar-in-essential.tar /tmp/tar-in-customize.tar \ /tmp/tar-in-setup.tar /tmp/tar-in-essential.tar /tmp/tar-in-customize.tar \
/tmp/tar-out-setup.tar /tmp/tar-out-essential.tar /tmp/tar-out-customize.tar \ /tmp/tar-out-setup.tar /tmp/tar-out-essential.tar /tmp/tar-out-customize.tar \
/tmp/upload-setup /tmp/upload-essential /tmp/upload-customize \ /tmp/upload-setup /tmp/upload-essential /tmp/upload-customize \
/tmp/download-setup /tmp/download-essential /tmp/download-customize /tmp/download-setup /tmp/download-essential /tmp/download-customize \
/tmp/sync-in-setup/file /tmp/sync-in-essential/file /tmp/sync-in-customize/file \
/tmp/sync-out-setup/file /tmp/sync-out-essential/file /tmp/sync-out-customize/file
rmdir /tmp/sync-in-setup /tmp/sync-in-essential /tmp/sync-in-customize \
/tmp/sync-out-setup /tmp/sync-out-essential /tmp/sync-out-customize
END END
if [ "$HAVE_QEMU" = "yes" ]; then if [ "$HAVE_QEMU" = "yes" ]; then
./run_qemu.sh ./run_qemu.sh

View file

@ -1078,8 +1078,14 @@ sub run_hooks {
my $runner = sub { my $runner = sub {
foreach my $script (@{ $options->{"${name}_hook"} }) { foreach my $script (@{ $options->{"${name}_hook"} }) {
if ($script if (
=~ /^(copy-in|copy-out|tar-in|tar-out|upload|download) /) { $script =~ /^(
copy-in|copy-out
|tar-in|tar-out
|upload|download
|sync-in|sync-out
)\ /x
) {
info "running special hook: $script"; info "running special hook: $script";
if ( if (
any { $_ eq $options->{variant} } ('extract', 'custom') any { $_ eq $options->{variant} } ('extract', 'custom')
@ -2374,7 +2380,10 @@ sub main() {
error "unknown hook: $hook"; error "unknown hook: $hook";
} }
if (any { $_ eq $command } ('copy-in', 'tar-in', 'upload')) { if (
any { $_ eq $command }
('copy-in', 'tar-in', 'upload', 'sync-in')
) {
if (scalar @ARGV < 9) { if (scalar @ARGV < 9) {
error "copy-in and tar-in need at least one path on the" error "copy-in and tar-in need at least one path on the"
. " outside and the output path inside the chroot"; . " outside and the output path inside the chroot";
@ -2404,13 +2413,18 @@ sub main() {
# open the requested file for writing # open the requested file for writing
open $fh, '|-', @cmdprefix, 'sh', '-c', 'cat > "$1"', open $fh, '|-', @cmdprefix, 'sh', '-c', 'cat > "$1"',
'exec', $directory // error "failed to fork(): $!"; 'exec', $directory // error "failed to fork(): $!";
} else { } elsif (
any { $_ eq $command }
('copy-in', 'tar-in', 'sync-in')
) {
# open a tar process that extracts the tarfile that we # open a tar process that extracts the tarfile that we
# supply it with on stdin to the output directory inside # supply it with on stdin to the output directory inside
# the chroot # the chroot
open $fh, '|-', @cmdprefix, @tarcmd, '--directory', open $fh, '|-', @cmdprefix, @tarcmd, '--directory',
$directory, '--extract', '--file', $directory, '--extract', '--file',
'-' // error "failed to fork(): $!"; '-' // error "failed to fork(): $!";
} else {
error "unknown command: $command";
} }
if ($command eq 'copy-in') { if ($command eq 'copy-in') {
@ -2419,12 +2433,20 @@ sub main() {
debug "sending mktar"; debug "sending mktar";
print STDOUT ( print STDOUT (
pack("n", length $ARGV[$i]) . "mktar" . $ARGV[$i]); pack("n", length $ARGV[$i]) . "mktar" . $ARGV[$i]);
} else { } elsif ($command eq 'sync-in') {
# instruct the parent process to create a tarball of the
# content of the requested path outside the chroot
debug "sending mktac";
print STDOUT (
pack("n", length $ARGV[$i]) . "mktac" . $ARGV[$i]);
} elsif (any { $_ eq $command } ('upload', 'tar-in')) {
# instruct parent process to open a tarball of the # instruct parent process to open a tarball of the
# requested path outside the chroot for reading # requested path outside the chroot for reading
debug "sending openr"; debug "sending openr";
print STDOUT ( print STDOUT (
pack("n", length $ARGV[$i]) . "openr" . $ARGV[$i]); pack("n", length $ARGV[$i]) . "openr" . $ARGV[$i]);
} else {
error "unknown command: $command";
} }
STDOUT->flush(); STDOUT->flush();
debug "waiting for okthx"; debug "waiting for okthx";
@ -2481,7 +2503,10 @@ sub main() {
error "tar failed"; error "tar failed";
} }
} }
} elsif (any { $_ eq $command } ('copy-out', 'tar-out', 'download')) { } elsif (
any { $_ eq $command }
('copy-out', 'tar-out', 'download', 'sync-out')
) {
if (scalar @ARGV < 9) { if (scalar @ARGV < 9) {
error "copy-out needs at least one path inside the chroot and" error "copy-out needs at least one path inside the chroot and"
. " the output path on the outside"; . " the output path on the outside";
@ -2511,28 +2536,39 @@ sub main() {
# open the requested file for reading # open the requested file for reading
open $fh, '-|', @cmdprefix, 'sh', '-c', 'cat "$1"', open $fh, '-|', @cmdprefix, 'sh', '-c', 'cat "$1"',
'exec', $directory // error "failed to fork(): $!"; 'exec', $directory // error "failed to fork(): $!";
} else { } elsif ($command eq 'sync-out') {
# Open a tar process that creates a tarfile of everything # Open a tar process that creates a tarfile of everything
# in the requested directory inside the chroot and writes # inside the requested directory inside the chroot and
# it to stdout. To emulate the behaviour of cp, change to # writes it to stdout.
# the dirname of the requested path first. open $fh, '-|', @cmdprefix, @tarcmd, '--directory',
$directory, '--create', '--file', '-',
'.' // error "failed to fork(): $!";
} elsif (any { $_ eq $command } ('copy-out', 'tar-out')) {
# Open a tar process that creates a tarfile of the
# requested directory inside the chroot and writes it to
# stdout. To emulate the behaviour of cp, change to the
# dirname of the requested path first.
open $fh, '-|', @cmdprefix, @tarcmd, '--directory', open $fh, '-|', @cmdprefix, @tarcmd, '--directory',
dirname($directory), '--create', '--file', '-', dirname($directory), '--create', '--file', '-',
basename($directory) // error "failed to fork(): $!"; basename($directory) // error "failed to fork(): $!";
} else {
error "unknown command: $command";
} }
if ($command eq 'copy-out') { if (any { $_ eq $command } ('copy-out', 'sync-out')) {
# instruct the parent process to extract a tarball to a # instruct the parent process to extract a tarball to a
# certain path outside the chroot # certain path outside the chroot
debug "sending untar"; debug "sending untar";
print STDOUT ( print STDOUT (
pack("n", length $outpath) . "untar" . $outpath); pack("n", length $outpath) . "untar" . $outpath);
} else { } elsif (any { $_ eq $command } ('download', 'tar-out')) {
# instruct parent process to open a tarball of the # instruct parent process to open a tarball of the
# requested path outside the chroot for writing # requested path outside the chroot for writing
debug "sending openw"; debug "sending openw";
print STDOUT ( print STDOUT (
pack("n", length $outpath) . "openw" . $outpath); pack("n", length $outpath) . "openw" . $outpath);
} else {
error "unknown command: $command";
} }
STDOUT->flush(); STDOUT->flush();
debug "waiting for okthx"; debug "waiting for okthx";
@ -2562,8 +2598,8 @@ sub main() {
checkokthx \*STDIN; checkokthx \*STDIN;
close $fh; close $fh;
if ($command ne 'download' and $? != 0) { if ($? != 0) {
error "tar failed"; error "$command failed";
} }
} }
} else { } else {
@ -3833,9 +3869,9 @@ sub main() {
$parentsock->flush(); $parentsock->flush();
} }
close $fh; close $fh;
} elsif ($msg eq "mktar") { } elsif (any { $_ eq $msg } ('mktar', 'mktac')) {
# handle the mktar message # handle the mktar message
debug "received message: mktar"; debug "received message: $msg";
my $indir; my $indir;
{ {
my $ret = read($parentsock, $indir, $len) my $ret = read($parentsock, $indir, $len)
@ -3859,9 +3895,11 @@ sub main() {
# Open a tar process creating a tarfile of the instructed # Open a tar process creating a tarfile of the instructed
# path. To emulate the behaviour of cp, change to the # path. To emulate the behaviour of cp, change to the
# dirname of the requested path first. # dirname of the requested path first.
open my $fh, '-|', 'tar', '--directory', dirname($indir), open my $fh, '-|', 'tar', '--directory',
$msg eq 'mktar' ? dirname($indir) : $indir,
'--create', '--file', '-', '--create', '--file', '-',
basename($indir) // error "failed to fork(): $!"; $msg eq 'mktar' ? basename($indir) : '.'
// error "failed to fork(): $!";
# read from the tar process and send as payload to the child # read from the tar process and send as payload to the child
# process # process
@ -4649,6 +4687,24 @@ placing them into I<pathoutside> outside of the chroot.
Recursively copies one or more files and directories into the chroot into, Recursively copies one or more files and directories into the chroot into,
placing them into I<pathinside> inside of the chroot. placing them into I<pathinside> inside of the chroot.
=item B<sync-out> I<pathinside> I<pathoutside>
Recursively copy everything inside I<pathinside> inside the chroot into
I<pathoutside>. In contrast to B<copy-out>, this command synchronizes the
content of I<pathinside> with the content of I<pathoutside> without deleting
anything from I<pathoutside> but overwriting content as necessary. Use this
command over B<copy-out> if you don't want to create a new directory outside
the chroot but only update the content of an existing directory.
=item B<sync-in> I<pathoutside> I<pathinside>
Recursively copy everything inside I<pathoutside> into I<pathinside> inside the
chroot. In contrast to B<copy-in>, this command synchronizes the content of
I<pathoutside> with the content of I<pathinside> without deleting anything from
I<pathinside> but overwriting content as necessary. Use this command over
B<copy-in> if you don't want to create a new directory inside the chroot but
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