[Libguestfs] [PATCH nbdkit 1/2] Revert "tar: Rewrite the tar plugin in Python."

Richard W.M. Jones rjones at redhat.com
Sun Jun 28 13:02:50 UTC 2020


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




More information about the Libguestfs mailing list