From f0b0ad1c8fb47ab34cc7afe00947d91d7c386a7e Mon Sep 17 00:00:00 2001 From: Brian Warner Date: Sun, 15 Mar 2009 16:19:58 -0700 Subject: [PATCH] tahoe cp -r: add --caps-only flag, to write filecaps into local files instead of actual file contents. Used only for debugging and as a quick tree-comparison tool. --- src/allmydata/scripts/cli.py | 3 +++ src/allmydata/scripts/tahoe_cp.py | 31 +++++++++++++++++++++++++++---- src/allmydata/test/test_system.py | 10 ++++++++++ 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/allmydata/scripts/cli.py b/src/allmydata/scripts/cli.py index 196a3fc0..de8d6249 100644 --- a/src/allmydata/scripts/cli.py +++ b/src/allmydata/scripts/cli.py @@ -169,6 +169,9 @@ class CpOptions(VDriveOptions): optFlags = [ ("recursive", "r", "Copy source directory recursively."), ("verbose", "v", "Be noisy about what is happening."), + ("caps-only", None, + "When copying to local files, write out filecaps instead of actual " + "data. (only useful for debugging and tree-comparison purposes)"), ] def parseArgs(self, *args): if len(args) < 2: diff --git a/src/allmydata/scripts/tahoe_cp.py b/src/allmydata/scripts/tahoe_cp.py index 026a6cd9..797f8782 100644 --- a/src/allmydata/scripts/tahoe_cp.py +++ b/src/allmydata/scripts/tahoe_cp.py @@ -2,6 +2,7 @@ import os.path import urllib import simplejson +from cStringIO import StringIO from twisted.python.failure import Failure from allmydata.scripts.common import get_alias, escape_path, DefaultAliasMarker from allmydata.scripts.common_http import do_http @@ -73,7 +74,7 @@ class LocalFileSource: def need_to_copy_bytes(self): return True - def open(self): + def open(self, caps_only): return open(self.pathname, "rb") class LocalFileTarget: @@ -183,7 +184,9 @@ class TahoeFileSource: return True return False - def open(self): + def open(self, caps_only): + if caps_only: + return StringIO(self.readcap) url = self.nodeurl + "uri/" + urllib.quote(self.readcap) return GET_to_file(url) @@ -435,6 +438,7 @@ class Copier: def progress(message): print >>self.stderr, message self.progressfunc = progress + self.caps_only = options["caps-only"] self.cache = {} try: self.try_copy() @@ -713,7 +717,7 @@ class Copier: # if the target is a local directory, this will just write the # bytes to disk. If it is a tahoe directory, it will upload the # data, and stash the new filecap for a later set_children call. - f = source.open() + f = source.open(self.caps_only) target.put_file(f) return self.announce_success("file copied") # otherwise we're copying tahoe to tahoe, and using immutable files, @@ -729,7 +733,7 @@ class Copier: # if the target is a local directory, this will just write the # bytes to disk. If it is a tahoe directory, it will upload the # data, and stash the new filecap for a later set_children call. - f = source.open() + f = source.open(self.caps_only) target.put_file(name, f) return # otherwise we're copying tahoe to tahoe, and using immutable files, @@ -753,3 +757,22 @@ class Copier: def copy(options): return Copier().do_copy(options) + +# error cases that need improvement: +# local-file-in-the-way +# touch proposed +# tahoe cp -r my:docs/proposed/denver.txt proposed/denver.txt + +# things that maybe should be errors but aren't +# local-dir-in-the-way +# mkdir denver.txt +# tahoe cp -r my:docs/proposed/denver.txt denver.txt +# (creates denver.txt/denver.txt) + +# error cases that look good: +# tahoe cp -r my:docs/missing missing +# disconnect servers +# tahoe cp -r my:docs/missing missing -> No JSON object could be decoded +# tahoe-file-in-the-way (when we want to make a directory) +# tahoe put README my:docs +# tahoe cp -r docs/proposed my:docs/proposed diff --git a/src/allmydata/test/test_system.py b/src/allmydata/test/test_system.py index e1d16a25..f66c4e4c 100644 --- a/src/allmydata/test/test_system.py +++ b/src/allmydata/test/test_system.py @@ -1711,6 +1711,16 @@ class SystemTest(SystemTestMixin, unittest.TestCase): # and copy it a second time, which ought to overwrite the same files d.addCallback(run, "cp", "-r", "tahoe:dir1", dn_copy) + # and again, only writing filecaps + dn_copy2 = os.path.join(self.basedir, "dir1-copy-capsonly") + d.addCallback(run, "cp", "-r", "--caps-only", "tahoe:dir1", dn_copy2) + def _check_capsonly((out,err)): + # these should all be LITs + x = open(os.path.join(dn_copy2, "subdir2", "rfile4")).read() + y = uri.from_string_filenode(x) + self.failUnlessEqual(y.data, "rfile4") + d.addCallback(_check_capsonly) + # and tahoe-to-tahoe d.addCallback(run, "cp", "-r", "tahoe:dir1", "tahoe:dir1-copy") d.addCallback(run, "ls") -- 2.37.2