This reverts commit 2d15e79f65764d9b0c68bea28ed6afbcbcc63467. --- configure.ac | 2 +- plugins/tar/Makefile.am | 13 +- tests/Makefile.am | 6 +- plugins/tar/{nbdkit-tar-plugin.pod => tar.pl} | 119 +++++++++++++++++- plugins/tar/tar.py | 104 --------------- tests/test-dump-plugin.sh | 4 +- tests/test-help-plugin.sh | 4 +- tests/test-tar.sh | 26 ++-- tests/test-version-plugin.sh | 4 +- wrapper.c | 21 +--- README | 8 +- 11 files changed, 149 insertions(+), 162 deletions(-) diff --git a/configure.ac b/configure.ac index bf389931..af7e6e3b 100644 --- a/configure.ac +++ b/configure.ac @@ -1222,7 +1222,7 @@ feature "nbd .................................... " \ feature "ssh .................................... " \ test "x$HAVE_SSH_TRUE" = "x" feature "tar .................................... " \ - test "x$HAVE_PYTHON_TRUE" = "x" + test "x$HAVE_PERL_TRUE" = "x" feature "torrent ................................ " \ test "x$HAVE_TORRENT_TRUE" = "x" feature "vddk ................................... " \ diff --git a/plugins/tar/Makefile.am b/plugins/tar/Makefile.am index 9e47e01d..09a6caa9 100644 --- a/plugins/tar/Makefile.am +++ b/plugins/tar/Makefile.am @@ -31,18 +31,19 @@ include $(top_srcdir)/common-rules.mk +source = tar.pl + EXTRA_DIST = \ - nbdkit-tar-plugin.pod \ - tar.py \ + $(source) \ $(NULL) -if HAVE_PYTHON +if HAVE_PERL plugin_SCRIPTS = nbdkit-tar-plugin CLEANFILES += nbdkit-tar-plugin # We have to do the rewriting here to avoid stupid exec_prefix. -nbdkit-tar-plugin: tar.py +nbdkit-tar-plugin: $(source) rm -f $@ $@-t sed 's,\@sbindir\@,${sbindir},g' < $< > $@-t mv $@-t $@ @@ -53,8 +54,8 @@ if HAVE_POD man_MANS = nbdkit-tar-plugin.1 CLEANFILES += $(man_MANS) -nbdkit-tar-plugin.1: nbdkit-tar-plugin.pod - $(PODWRAPPER) --section=1 --man $@ \ +nbdkit-tar-plugin.1: $(source) + $(PODWRAPPER) --section=1 --name nbdkit-tar-plugin --man $@ \ --html $(top_builddir)/html/$@.html \ $< diff --git a/tests/Makefile.am b/tests/Makefile.am index 51eb7660..16043f49 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -828,10 +828,10 @@ test_streaming_SOURCES = test-streaming.c test_streaming_CFLAGS = $(WARNINGS_CFLAGS) $(LIBNBD_CFLAGS) test_streaming_LDADD = $(LIBNBD_LIBS) -# tar plugin test (written in python). -if HAVE_PYTHON +# tar plugin test (written in perl). +if HAVE_PERL TESTS += test-tar.sh -endif HAVE_PYTHON +endif HAVE_PERL EXTRA_DIST += test-tar.sh # tmpdisk plugin test. diff --git a/plugins/tar/nbdkit-tar-plugin.pod b/plugins/tar/tar.pl similarity index 55% rename from plugins/tar/nbdkit-tar-plugin.pod rename to plugins/tar/tar.pl index 24a2816b..9b05b83d 100644 --- a/plugins/tar/nbdkit-tar-plugin.pod +++ b/plugins/tar/tar.pl @@ -1,3 +1,8 @@ +#!@sbindir@/nbdkit perl +# -*- perl -*- + +=pod + =head1 NAME nbdkit-tar-plugin - read and write files inside tar files without unpacking @@ -89,10 +94,11 @@ C<nbdkit-tar-plugin> first appeared in nbdkit 1.2. =head1 SEE ALSO +L<https://github.com/libguestfs/nbdkit/blob/master/plugins/tar/tar.pl>, L<nbdkit(1)>, L<nbdkit-offset-filter(1)>, L<nbdkit-plugin(3)>, -L<nbdkit-python-plugin(3)>, +L<nbdkit-perl-plugin(3)>, L<nbdkit-xz-filter(1)>, L<tar(1)>. @@ -105,3 +111,114 @@ Based on the virt-v2v OVA importer written by Tomáš Golembiovský. =head1 COPYRIGHT Copyright (C) 2017-2020 Red Hat Inc. + +=cut + +use strict; + +use Cwd qw(abs_path); +use IO::File; + +my $tar; # Tar file. +my $file; # File within the tar file. +my $offset; # Offset within tar file. +my $size; # Size of disk image within tar file. + +sub config +{ + my $k = shift; + my $v = shift; + + if ($k eq "tar") { + $tar = abs_path ($v); + } + elsif ($k eq "file") { + $file = $v; + } + else { + die "unknown parameter $k"; + } +} + +# Check all the config parameters were set. +sub config_complete +{ + die "tar or file parameter was not set\n" + unless defined $tar && defined $file; + + die "$tar: file not found\n" + unless -f $tar; +} + +# Find the extent of the file within the tar file. +sub get_ready +{ + open (my $pipe, "-|", "tar", "--no-auto-compress", "-tRvf", $tar, $file) + or die "$tar: could not open or parse tar file, see errors above"; + while (<$pipe>) { + if (/^block\s(\d+):\s\S+\s\S+\s(\d+)/) { + # Add one for the tar header, and multiply by the block size. + $offset = ($1 + 1) * 512; + $size = $2; + Nbdkit::debug ("tar: file: $file offset: $offset size: $size") + } + } + close ($pipe); + + die "offset or size could not be parsed. Probably the tar file is not a tar file or the file does not exist in the tar file. See any errors above.\n" + unless defined $offset && defined $size; +} + +# Accept a connection from a client, create and return the handle +# which is passed back to other calls. +sub open +{ + my $readonly = shift; + my $mode = "<"; + $mode = "+<" unless $readonly; + my $fh = IO::File->new; + $fh->open ($tar, $mode) or die "$tar: open: $!"; + $fh->binmode; + my $h = { fh => $fh, readonly => $readonly }; + return $h; +} + +# Close the connection. +sub close +{ + my $h = shift; + my $fh = $h->{fh}; + $fh->close; +} + +# Return the size. +sub get_size +{ + my $h = shift; + return $size; +} + +# Read. +sub pread +{ + my $h = shift; + my $fh = $h->{fh}; + my $count = shift; + my $offs = shift; + $fh->seek ($offset + $offs, 0) or die "seek: $!"; + my $r; + $fh->read ($r, $count) or die "read: $!"; + return $r; +} + +# Write. +sub pwrite +{ + my $h = shift; + my $fh = $h->{fh}; + my $buf = shift; + my $count = length ($buf); + my $offs = shift; + $fh->seek ($offset + $offs, 0) or die "seek: $!"; + print $fh ($buf); +} diff --git a/plugins/tar/tar.py b/plugins/tar/tar.py deleted file mode 100644 index 10a8066e..00000000 --- a/plugins/tar/tar.py +++ /dev/null @@ -1,104 +0,0 @@ -#!@sbindir@/nbdkit python -# -*- python -*- -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# * Neither the name of Red Hat nor the names of its contributors may be -# used to endorse or promote products derived from this software without -# specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. - -# Note this uses API v1 since we may wish to copy it and use it with -# older versions of nbdkit. Also it doesn't use get_ready() for the -# same reason. - -import builtins -import os.path -import tarfile -import nbdkit - -tar = None # Tar file. -f = None # File within the tar file. -offset = None # Offset of file within the tar file. -size = None # Size of file within the tar file. - -def config(k, v): - global tar, f - - if k == "tar": - tar = os.path.abspath(v) - elif k == "file": - f = v - else: - raise RuntimeError("unknown parameter: %s" % key) - -# Check all the config parameters were set. -def config_complete(): - global tar, f, offset, size - - if tar is None or f is None: - raise RuntimeError("tar or file parameter was not set") - if not os.path.exists(tar): - raise RuntimeError("$s: file not found" % tar) - - # Find the extent of the file within the tar file. - for m in tarfile.open(tar, mode='r:'): - if m.name == f: - offset = m.offset_data - size = m.size - if offset is None or size is None: - raise RuntimeError("offset or size could not be parsed. Probably the tar file is not a tar file or the file does not exist in the tar file.") - -# Accept a connection from a client, create and return the handle -# which is passed back to other calls. -def open(readonly): - global tar - if readonly: - mode = 'rb' - else: - mode = 'r+b' - return { 'fh': builtins.open(tar, mode) } - -# Close the connection. -def close(h): - h['fh'].close() - -# Return the size. -def get_size(h): - global size - return size - -# Read. -# -# Python plugin thread model is always -# NBDKIT_THREAD_MODEL_SERIALIZE_ALL_REQUESTS so seeking here is fine. -def pread(h, count, offs): - global offset - h['fh'].seek(offset + offs) - return h['fh'].read(count) - -# Write. -def pwrite(h, buf, offs): - global offset - h['fh'].seek(offset + offs) - h['fh'].write(buf) diff --git a/tests/test-dump-plugin.sh b/tests/test-dump-plugin.sh index 629182ef..0b4c1ce1 100755 --- a/tests/test-dump-plugin.sh +++ b/tests/test-dump-plugin.sh @@ -43,10 +43,10 @@ do_test () { vg=; [ "$NBDKIT_VALGRIND" = "1" ] && vg="-valgrind" case "$1$vg" in - python-valgrind | ruby-valgrind | tar-valgrind | tcl-valgrind) + python-valgrind | ruby-valgrind | tcl-valgrind) echo "$0: skipping $1$vg because this language doesn't support valgrind" ;; - example4*) + example4* | tar*) # These tests are written in Perl so we have to check that # the Perl plugin was compiled. if nbdkit perl --version; then run_test $1; fi diff --git a/tests/test-help-plugin.sh b/tests/test-help-plugin.sh index 65036f2e..7dc26ece 100755 --- a/tests/test-help-plugin.sh +++ b/tests/test-help-plugin.sh @@ -43,10 +43,10 @@ do_test () { vg=; [ "$NBDKIT_VALGRIND" = "1" ] && vg="-valgrind" case "$1$vg" in - python-valgrind | ruby-valgrind | tar-valgrind | tcl-valgrind) + python-valgrind | ruby-valgrind | tcl-valgrind) echo "$0: skipping $1$vg because this language doesn't support valgrind" ;; - example4*) + example4* | tar*) # These tests are written in Perl so we have to check that # the Perl plugin was compiled. if nbdkit perl --version; then run_test $1; fi diff --git a/tests/test-tar.sh b/tests/test-tar.sh index f1cebf19..c6d726c4 100755 --- a/tests/test-tar.sh +++ b/tests/test-tar.sh @@ -34,18 +34,14 @@ source ./functions.sh set -e set -x -# Python scripts break valgrind. -if [ "$NBDKIT_VALGRIND" = "1" ]; then - echo "$0: skipping Python test under valgrind." - exit 77 -fi - requires test -f disk requires guestfish --version +requires tar --version -# The tar plugin is written in Python and uses the tarfile module. -requires python --version -requires python -c 'import tarfile' +# The tar plugin requires some Perl modules, this checks if they are +# installed. +requires perl -MCwd -e 1 +requires perl -MIO::File -e 1 sock=`mktemp -u` files="tar.pid tar.tar $sock" @@ -58,15 +54,7 @@ tar cf tar.tar disk # Run nbdkit. start_nbdkit -P tar.pid -U $sock tar tar=tar.tar file=disk -# Now see if we can open, read and write the disk from the tar file. -guestfish -x --format=raw -a "nbd://?socket=$sock" -m /dev/sda1 <<EOF - # Check for existing file. +# Now see if we can open the disk from the tar file. +guestfish -x --ro --format=raw -a "nbd://?socket=$sock" -m /dev/sda1 <<EOF cat /hello.txt - - # Write a new file. - write /test.txt "hello" - cat /test.txt EOF - -# Check that the tar file isn't corrupt. -tar tvvf tar.tar diff --git a/tests/test-version-plugin.sh b/tests/test-version-plugin.sh index 8a4a2ece..7d2ab072 100755 --- a/tests/test-version-plugin.sh +++ b/tests/test-version-plugin.sh @@ -43,10 +43,10 @@ do_test () { vg=; [ "$NBDKIT_VALGRIND" = "1" ] && vg="-valgrind" case "$1$vg" in - python-valgrind | ruby-valgrind | tar-valgrind | tcl-valgrind) + python-valgrind | ruby-valgrind | tcl-valgrind) echo "$0: skipping $1$vg because this language doesn't support valgrind" ;; - example4*) + example4* | tar*) # These tests are written in Perl so we have to check that # the Perl plugin was compiled. if nbdkit perl --version; then run_test $1; fi diff --git a/wrapper.c b/wrapper.c index 24dab6ab..b1e2ce2f 100644 --- a/wrapper.c +++ b/wrapper.c @@ -78,20 +78,14 @@ static const char **cmd; static size_t len; -/* Plugins written in scripting languages need to be rewritten on the - * command line in a different way from plugins written in C. So we - * have to list those here. +/* Plugins written in scripting languages (only Perl right now) need + * to be rewritten on the command line in a different way from plugins + * written in C. So we have to list those here. */ static bool is_perl_plugin (const char *name) { - return strcmp (name, "example4") == 0; -} - -static bool -is_python_plugin (const char *name) -{ - return strcmp (name, "tar") == 0; + return strcmp (name, "example4") == 0 || strcmp (name, "tar") == 0; } static void @@ -269,13 +263,6 @@ main (int argc, char *argv[]) passthru_format ("%s/plugins/%s/nbdkit-%s-plugin", builddir, argv[optind], argv[optind]); } - /* Special plugins written in Python. */ - else if (is_python_plugin (argv[optind])) { - passthru_format ("%s/plugins/python/.libs/nbdkit-python-plugin.so", - builddir); - passthru_format ("%s/plugins/%s/nbdkit-%s-plugin", - builddir, argv[optind], argv[optind]); - } else { passthru_format ("%s/plugins/%s/.libs/nbdkit-%s-plugin.so", builddir, argv[optind], argv[optind]); diff --git a/README b/README index 88fecef6..4f584828 100644 --- a/README +++ b/README @@ -124,15 +124,15 @@ For the bittorrent plugin: - libtorrent-rasterbar (https://www.libtorrent.org) -For the Perl and example4 plugins: +For the Perl, example4 and tar plugins: - perl interpreter - perl development libraries - - perl modules ExtUtils::Embed + - perl modules ExtUtils::Embed, IO::File and Cwd -For the Python and tar plugins: +For the Python plugin: - python interpreter (version 3 only) @@ -140,8 +140,6 @@ For the Python and tar plugins: - python unittest to run the test suite - - python tarfile.py (part of standard library) - For the OCaml plugin: - OCaml >= 4.02.2 -- 2.25.0