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