]> arthur.barton.de Git - bup.git/commitdiff
Include metadata when asked to restore individual non-directory paths.
authorRob Browning <rlb@defaultvalue.org>
Sat, 16 Feb 2013 21:12:47 +0000 (15:12 -0600)
committerRob Browning <rlb@defaultvalue.org>
Fri, 8 Mar 2013 04:01:02 +0000 (22:01 -0600)
Adjust bup restore to handle cases like this:

  bup restore -C tmp backup/latest/somewhere/not-a-directory

Previously bup wouldn't restore the metadata for not-a-directory; now
it should.

Add wvtest-bup.sh which includes wvmktempdir().  This function creates
all temporary directories under t/tmp, making cleanup easier.

Add t/test-restore-single-file.sh

Reported-by: Tim Riemenschneider <t.riemenschneider@detco.de>
Signed-off-by: Rob Browning <rlb@defaultvalue.org>
Makefile
cmd/restore-cmd.py
t/test-restore-single-file.sh [new file with mode: 0755]
wvtest-bup.sh [new file with mode: 0644]

index ccecfc68ef9ed9683871db493c83bc93658c8ef1..7bebe7794d43eaa04edf807ab543de59ec694e0e 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -87,6 +87,7 @@ runtests-python:
 runtests-cmdline: all
        t/test.sh
        t/test-meta.sh
+       t/test-restore-single-file.sh
 
 stupid:
        PATH=/bin:/usr/bin $(MAKE) test
@@ -163,3 +164,4 @@ clean: Documentation/clean config/clean
        if test -e bupmeta.tmp/testfs-limited; \
          then umount bupmeta.tmp/testfs-limited || true; fi
        rm -rf *.tmp *.tmp.meta t/*.tmp lib/*/*/*.tmp build lib/bup/build lib/bup/t/testfs
+       if test -e t/tmp; then rm -r t/tmp; fi
index d38fe509f335f47bcd22917872dbf18d33c85fd8..9089d9671590b9c26533389725a975640c5ad3dd 100755 (executable)
@@ -116,6 +116,29 @@ def write_file_content(fullname, n):
         outf.close()
 
 
+def find_dir_item_metadata_by_name(dir, name):
+    """Find metadata in dir (a node) for an item with the given name,
+    or for the directory itself if the name is ''."""
+    meta_stream = None
+    try:
+        mfile = dir.metadata_file() # VFS file -- cannot close().
+        if mfile:
+            meta_stream = mfile.open()
+            meta = metadata.Metadata.read(meta_stream)
+            if name == '':
+                return meta
+            for sub in dir:
+                if stat.S_ISDIR(sub.mode):
+                    return find_dir_item_metadata_by_name(sub, '')
+                else:
+                    meta = metadata.Metadata.read(meta_stream)
+                if sub.name == name:
+                    return meta
+    finally:
+        if meta_stream:
+            meta_stream.close()
+
+
 def do_root(n):
     # Very similar to do_node(), except that this function doesn't
     # create a path for n's destination directory (and so ignores
@@ -238,8 +261,9 @@ for d in extra:
             mkdirp(n.name)
             os.chdir(n.name)
             do_root(target)
-        else:
-            do_node(n.parent, n)
+        else: # Not a directory or fake symlink.
+            meta = find_dir_item_metadata_by_name(n.parent, n.name)
+            do_node(n.parent, n, meta=meta)
 
 if not opt.quiet:
     progress('Restoring: %d, done.\n' % total_restored)
diff --git a/t/test-restore-single-file.sh b/t/test-restore-single-file.sh
new file mode 100755 (executable)
index 0000000..b64a966
--- /dev/null
@@ -0,0 +1,22 @@
+#!/usr/bin/env bash
+. ./wvtest-bup.sh
+
+set -e -o pipefail
+
+WVSTART 'all'
+
+top="$(pwd)"
+tmpdir="$(wvmktempdir)"
+export BUP_DIR="$tmpdir/bup"
+
+bup() { "$top/bup" "$@"; }
+
+touch "$tmpdir/foo"
+WVPASS bup init
+WVPASS bup index "$tmpdir/foo"
+WVPASS bup save -n foo "$tmpdir/foo"
+WVPASS bup tick
+WVPASS bup restore -C "$tmpdir/restore" "foo/latest/$tmpdir/foo"
+WVPASS "$top/t/compare-trees" "$tmpdir/foo" "$tmpdir/restore/foo"
+
+rm -rf "$tmpdir"
diff --git a/wvtest-bup.sh b/wvtest-bup.sh
new file mode 100644 (file)
index 0000000..e7e7752
--- /dev/null
@@ -0,0 +1,16 @@
+# Include in your test script like this:
+#
+#   #!/usr/bin/env bash
+#   . ./wvtest-bup.sh
+
+. ./wvtest.sh
+
+_wvtop="$(pwd)"
+
+wvmktempdir ()
+(
+    local script_name="$(basename $0)"
+    set -e -o pipefail
+    mkdir -p "$_wvtop/t/tmp"
+    echo "$(mktemp -d "$_wvtop/t/tmp/$script_name-XXXXXXX")"
+)