add 'tahoe find-shares' command, to locate share files on a local node's disk
authorBrian Warner <warner@allmydata.com>
Wed, 6 Feb 2008 20:19:51 +0000 (13:19 -0700)
committerBrian Warner <warner@allmydata.com>
Wed, 6 Feb 2008 20:19:51 +0000 (13:19 -0700)
src/allmydata/scripts/debug.py
src/allmydata/test/test_system.py

index ea2fefbebfb62ef1839db4d216b8a5a0dcfd32fa..7e113a9d3b281433f8164c9968b6035fcfc4b56c 100644 (file)
@@ -21,6 +21,8 @@ def dump_share(config, out=sys.stdout, err=sys.stderr):
     from allmydata import uri, storage
 
     # check the version, to see if we have a mutable or immutable share
+    print >>out, "%19s: %s" % ("share filename", config['filename'])
+
     f = open(config['filename'], "rb")
     prefix = f.read(32)
     f.close()
@@ -315,14 +317,44 @@ def dump_uri_instance(u, nodeid, secret, out, err, show_header=True):
     else:
         print >>out, "unknown cap type"
 
+class FindSharesOptions(usage.Options):
+    def parseArgs(self, storage_index_s, *nodedirs):
+        self.si_s = storage_index_s
+        self.nodedirs = nodedirs
+
+def find_shares(config, out=sys.stdout, err=sys.stderr):
+    """Given a storage index and a list of node directories, emit a list of
+    all matching shares to stdout, one per line. For example:
+
+     find-shares.py 44kai1tui348689nrw8fjegc8c ~/testnet/node-*
+
+    gives:
+
+    /home/warner/testnet/node-1/storage/shares/44k/44kai1tui348689nrw8fjegc8c/5
+    /home/warner/testnet/node-1/storage/shares/44k/44kai1tui348689nrw8fjegc8c/9
+    /home/warner/testnet/node-2/storage/shares/44k/44kai1tui348689nrw8fjegc8c/2
+    """
+    from allmydata import storage
+    from allmydata.util import idlib
+
+    sharedir = storage.storage_index_to_dir(idlib.a2b(config.si_s))
+    for d in config.nodedirs:
+        d = os.path.join(os.path.expanduser(d), "storage/shares", sharedir)
+        if os.path.exists(d):
+            for shnum in os.listdir(d):
+                print >>out, os.path.join(d, shnum)
+
+    return 0
 
 subCommands = [
     ["dump-share", None, DumpOptions,
      "Unpack and display the contents of a share (uri_extension and leases)."],
-    ["dump-cap", None, DumpCapOptions, "Unpack a read-cap or write-cap"]
+    ["dump-cap", None, DumpCapOptions, "Unpack a read-cap or write-cap"],
+    ["find-shares", None, FindSharesOptions, "Locate sharefiles in node dirs"],
     ]
 
 dispatch = {
     "dump-share": dump_share,
     "dump-cap": dump_cap,
+    "find-shares": find_shares,
     }
index 8f669f6cf10a1f442444238a8d7092f27f0e95a7..c307ef9d396594b888bbfb48c89048d2fbd19c6c 100644 (file)
@@ -1144,6 +1144,7 @@ class SystemTest(testutil.SignalMixin, testutil.PollMixin, unittest.TestCase):
 
         # we only upload a single file, so we can assert some things about
         # its size and shares.
+        self.failUnless(("share filename: %s" % filename) in output)
         self.failUnless("size: %d\n" % len(self.data) in output)
         self.failUnless("num_segments: 1\n" in output)
         # segment_size is always a multiple of needed_shares
@@ -1158,6 +1159,19 @@ class SystemTest(testutil.SignalMixin, testutil.PollMixin, unittest.TestCase):
                     "share_root_hash", "UEB_hash"):
             self.failUnless("%s: " % key in output, key)
 
+        # now use its storage index to find the other shares using the
+        # 'find-shares' tool
+        sharedir, shnum = os.path.split(filename)
+        storagedir, storage_index_s = os.path.split(sharedir)
+        out,err = StringIO(), StringIO()
+        nodedirs = [self.getdir("client%d" % i) for i in range(self.numclients)]
+        cmd = ["find-shares", storage_index_s] + nodedirs
+        rc = runner.runner(cmd, stdout=out, stderr=err)
+        self.failUnlessEqual(rc, 0)
+        out.seek(0)
+        sharefiles = [sfn.strip() for sfn in out.readlines()]
+        self.failUnlessEqual(len(sharefiles), 10)
+
     def _test_control(self, res):
         # exercise the remote-control-the-client foolscap interfaces in
         # allmydata.control (mostly used for performance tests)