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