cli: add --node-directory and --root-uri to all commands
authorBrian Warner <warner@lothar.com>
Thu, 11 Oct 2007 07:30:36 +0000 (00:30 -0700)
committerBrian Warner <warner@lothar.com>
Thu, 11 Oct 2007 07:30:36 +0000 (00:30 -0700)
src/allmydata/scripts/cli.py
src/allmydata/scripts/tahoe_get.py
src/allmydata/scripts/tahoe_ls.py
src/allmydata/scripts/tahoe_put.py
src/allmydata/scripts/tahoe_rm.py
src/allmydata/test/test_cli.py [new file with mode: 0644]

index de394d35802ead42ebf077e5a7f7322ecfd12fee..7b2a7d322abe4c916ffeab9574b75011337448c2 100644 (file)
@@ -7,14 +7,56 @@ NODEURL_RE=re.compile("http://([^:]*)(:([1-9][0-9]*))?")
 
 class VDriveOptions(BaseOptions, usage.Options):
     optParameters = [
+        ["node-directory", "d", "~/.tahoe",
+         "Look here to find out which Tahoe node should be used for all "
+         "operations. The directory should either contain a full Tahoe node, "
+         "or a file named node.url which points to some other Tahoe node. "
+         "It should also contain a file named my_vdrive.uri which contains "
+         "the root dirnode URI that should be used, and a file named "
+         "global_root.uri which contains the public global root dirnode URI."
+         ],
         ["node-url", "u", None,
-         "URL of the tahoe node to use, a URL like \"http://127.0.0.1:8123\""],
+         "URL of the tahoe node to use, a URL like \"http://127.0.0.1:8123\". "
+         "This overrides the URL found in the --node-directory ."],
+        ["root-uri", "r", "private",
+         "Which dirnode URI should be used as a root directory. The string "
+         "'public' is special, and means we should use the public global root "
+         "as found in the global_root.uri file in the --node-directory . The "
+         "string 'private' is also special, and means we should use the "
+         "private vdrive as found in the my_vdrive.uri file in the "
+         "--node-directory ."],
         ]
 
     def postOptions(self):
-        if not isinstance(self['node-url'], basestring) or not NODEURL_RE.match(self['node-url']):
-            raise usage.UsageError("--node-url is required to be a string and look like \"http://HOSTNAMEORADDR:PORT\", not: %r" % (self['node-url'],))
-        
+        # compute a node-url from the existing options, put in self['node-url']
+        if self['node-directory']:
+            self['node-directory'] = os.path.expanduser(self['node-directory'])
+        if self['node-url']:
+            if (not isinstance(self['node-url'], basestring)
+                or not NODEURL_RE.match(self['node-url'])):
+                msg = ("--node-url is required to be a string and look like "
+                       "\"http://HOSTNAMEORADDR:PORT\", not: %r" %
+                       (self['node-url'],))
+                raise usage.UsageError(msg)
+        else:
+            node_url_file = os.path.join(self['node-directory'], "node.url")
+            self['node-url'] = open(node_url_file, "r").read().strip()
+
+        # also compute self['root-uri']
+        if self['root-uri'] == "private":
+            uri_file = os.path.join(self['node-directory'], "my_vdrive.uri")
+            self['root-uri'] = open(uri_file, "r").read().strip()
+        elif self['root-uri'] == "public":
+            uri_file = os.path.join(self['node-directory'], "global_root.uri")
+            self['root-uri'] = open(uri_file, "r").read().strip()
+        else:
+            from allmydata import uri
+            parsed = uri.from_string(self['root-uri'])
+            if not uri.IDirnodeURI.providedBy(parsed):
+                raise usage.UsageError("--root-uri must be a dirnode URI, or "
+                                       "'public' or 'private'")
+
+
 class ListOptions(VDriveOptions):
     def parseArgs(self, vdrive_pathname=""):
         self['vdrive_pathname'] = vdrive_pathname
@@ -63,6 +105,7 @@ subCommands = [
 def list(config, stdout, stderr):
     from allmydata.scripts import tahoe_ls
     rc = tahoe_ls.list(config['node-url'],
+                       config['root-uri'],
                        config['vdrive_pathname'])
     return rc
 
@@ -71,6 +114,7 @@ def get(config, stdout, stderr):
     vdrive_filename = config['vdrive_filename']
     local_filename = config['local_filename']
     rc = tahoe_get.get(config['node-url'],
+                       config['root-uri'],
                        vdrive_filename,
                        local_filename)
     if rc == 0:
@@ -93,6 +137,7 @@ def put(config, stdout, stderr):
     else:
         verbosity = 2
     rc = tahoe_put.put(config['node-url'],
+                       config['root-uri'],
                        local_filename,
                        vdrive_filename,
                        verbosity)
@@ -106,8 +151,9 @@ def rm(config, stdout, stderr):
     else:
         verbosity = 2
     rc = tahoe_rm.rm(config['node-url'],
-                       vdrive_pathname,
-                       verbosity)
+                     config['root-uri'],
+                     vdrive_pathname,
+                     verbosity)
     return rc
 
 dispatch = {
index 2bcf2ee42ba97bb9d3d97dfafc59c57c8112393d..ddc18d2101c67ebc53a085b799bd6bb99eae1e30 100644 (file)
@@ -2,10 +2,10 @@
 
 import sys, urllib
 
-def get(nodeurl, vdrive_fname, local_file):
+def get(nodeurl, root_uri, vdrive_fname, local_file):
     if nodeurl[-1] != "/":
         nodeurl += "/"
-    url = nodeurl + "vdrive/global/"
+    url = nodeurl + "uri/%s/" % root_uri.replace("/","!")
     if vdrive_fname:
         url += vdrive_fname
 
@@ -28,19 +28,23 @@ def main():
     import optparse, re
     parser = optparse.OptionParser()
     parser.add_option("-u", "--nodeurl", dest="nodeurl")
+    parser.add_option("-r", "--root-uri", dest="rooturi")
 
     (options, args) = parser.parse_args()
 
     NODEURL_RE=re.compile("http://([^:]*)(:([1-9][0-9]*))?")
     if not isinstance(options.nodeurl, basestring) or not NODEURL_RE.match(options.nodeurl):
         raise ValueError("--node-url is required to be a string and look like \"http://HOSTNAMEORADDR:PORT\", not: %r" % (options.nodeurl,))
+
+    if not options.rooturi:
+        raise ValueError("must provide --root-uri")
     
     vdrive_fname = args[0]
     local_file = None
     if len(args) > 1:
         local_file = args[1]
 
-    get(options.nodeurl, vdrive_fname, local_file)
+    get(options.nodeurl, options.rooturi, vdrive_fname, local_file)
 
 if __name__ == '__main__':
     main()
index 9b3e75e701123b424f635bbbfbf1f75ba82c4de0..21ad101730e36ee4a1da7b90782db3eb3ca27789 100644 (file)
@@ -3,10 +3,10 @@
 import urllib
 import simplejson
 
-def list(nodeurl, vdrive_pathname):
+def list(nodeurl, root_uri, vdrive_pathname):
     if nodeurl[-1] != "/":
         nodeurl += "/"
-    url = nodeurl + "vdrive/global/"
+    url = nodeurl + "uri/%s/" % root_uri.replace("/","!")
     if vdrive_pathname:
         url += vdrive_pathname
     url += "?t=json"
@@ -32,18 +32,22 @@ def main():
     import optparse, re
     parser = optparse.OptionParser()
     parser.add_option("-u", "--node-url", dest="nodeurl")
+    parser.add_option("-r", "--root-uri", dest="rooturi")
 
     (options, args) = parser.parse_args()
 
     NODEURL_RE=re.compile("http://([^:]*)(:([1-9][0-9]*))?")
     if not isinstance(options.nodeurl, basestring) or not NODEURL_RE.match(options.nodeurl):
         raise ValueError("--node-url is required to be a string and look like \"http://HOSTNAMEORADDR:PORT\", not: %r" % (options.nodeurl,))
-    
+
+    if not options.rooturi:
+        raise ValueError("must provide --root-uri")
+
     vdrive_pathname = ""
     if args:
         vdrive_pathname = args[0]
 
-    list(options.nodeurl, vdrive_pathname)
+    list(options.nodeurl, options.rooturi, vdrive_pathname)
 
 if __name__ == '__main__':
     main()
index 4496239b9cfdeb06f56a06063757dd48204676a6..8089078dc47b7576b55ce788a31556fbc438ae6d 100644 (file)
@@ -4,7 +4,7 @@ import re, socket
 
 NODEURL_RE=re.compile("http://([^:]*)(:([1-9][0-9]*))?")
 
-def put(nodeurl, local_fname, vdrive_fname, verbosity):
+def put(nodeurl, root_uri, local_fname, vdrive_fname, verbosity):
     """
     @param verbosity: 0, 1, or 2, meaning quiet, verbose, or very verbose
 
@@ -14,7 +14,7 @@ def put(nodeurl, local_fname, vdrive_fname, verbosity):
     host = mo.group(1)
     port = int(mo.group(3))
 
-    url = "/vdrive/global/"
+    url = "/uri/%s/" % root_uri.replace("/","!")
     if vdrive_fname:
         url += vdrive_fname
 
@@ -76,19 +76,23 @@ def main():
     import optparse, re
     parser = optparse.OptionParser()
     parser.add_option("-u", "--node-url", dest="nodeurl")
+    parser.add_option("-r", "--root-uri", dest="rooturi")
 
     (options, args) = parser.parse_args()
 
     NODEURL_RE=re.compile("http://([^:]*)(:([1-9][0-9]*))?")
     if not isinstance(options.nodeurl, basestring) or not NODEURL_RE.match(options.nodeurl):
         raise ValueError("--node-url is required to be a string and look like \"http://HOSTNAMEORADDR:PORT\", not: %r" % (options.nodeurl,))
+
+    if not options.rooturi:
+        raise ValueError("must provide --root-uri")
     
     local_file = args[0]
     vdrive_fname = None
     if len(args) > 1:
         vdrive_fname = args[1]
 
-    return put(options.nodeurl, vdrive_fname, local_file)
+    return put(options.nodeurl, options.rooturi, vdrive_fname, local_file)
 
 if __name__ == '__main__':
     main()
index 92618fd22e81a941c13866e2fcb79d80c9fb2b72..ebd1ced0de4eebe4866518c90f5a74709161d518 100644 (file)
@@ -4,7 +4,7 @@ import re, socket
 
 NODEURL_RE=re.compile("http://([^:]*)(:([1-9][0-9]*))?")
 
-def rm(nodeurl, vdrive_pathname, verbosity):
+def rm(nodeurl, root_uri, vdrive_pathname, verbosity):
     """
     @param verbosity: 0, 1, or 2, meaning quiet, verbose, or very verbose
 
@@ -14,7 +14,7 @@ def rm(nodeurl, vdrive_pathname, verbosity):
     host = mo.group(1)
     port = int(mo.group(3))
 
-    url = "/vdrive/global/"
+    url = "/uri/%s/" % root_uri.replace("/","!")
     if vdrive_pathname:
         url += vdrive_pathname
 
@@ -61,16 +61,20 @@ def main():
     import optparse, re
     parser = optparse.OptionParser()
     parser.add_option("-u", "--node-url", dest="nodeurl")
+    parser.add_option("-r", "--root-uri", dest="rooturi")
 
     (options, args) = parser.parse_args()
 
     NODEURL_RE=re.compile("http://([^:]*)(:([1-9][0-9]*))?")
     if not isinstance(options.nodeurl, basestring) or not NODEURL_RE.match(options.nodeurl):
         raise ValueError("--node-url is required to be a string and look like \"http://HOSTNAMEORADDR:PORT\", not: %r" % (options.nodeurl,))
+
+    if not options.rooturi:
+        raise ValueError("must provide --root-uri")
     
     vdrive_pathname = args[0]
 
-    return rm(options.nodeurl, vdrive_pathname, 0)
+    return rm(options.nodeurl, options.rooturi, vdrive_pathname, 0)
 
 if __name__ == '__main__':
     main()
diff --git a/src/allmydata/test/test_cli.py b/src/allmydata/test/test_cli.py
new file mode 100644 (file)
index 0000000..e675d23
--- /dev/null
@@ -0,0 +1,62 @@
+
+from twisted.trial import unittest
+
+from allmydata.util import fileutil
+from allmydata import uri
+
+# at least import the CLI scripts, even if we don't have any real tests for
+# them yet.
+
+from allmydata.scripts import cli, tahoe_ls, tahoe_get, tahoe_put, tahoe_rm
+
+
+class CLI(unittest.TestCase):
+    def test_options(self):
+        fileutil.rm_dir("cli/test_options")
+        fileutil.make_dirs("cli/test_options")
+        open("cli/test_options/node.url","w").write("http://localhost:8080/\n")
+        private_uri = uri.DirnodeURI("furl", "key").to_string()
+        public_uri = uri.DirnodeURI("furl", "publickey").to_string()
+        open("cli/test_options/my_vdrive.uri", "w").write(private_uri + "\n")
+        open("cli/test_options/global_root.uri", "w").write(public_uri + "\n")
+        o = cli.ListOptions()
+        o.parseOptions(["--node-directory", "cli/test_options"])
+        self.failUnlessEqual(o['node-url'], "http://localhost:8080/")
+        self.failUnlessEqual(o['root-uri'], private_uri)
+        self.failUnlessEqual(o['vdrive_pathname'], "")
+
+        o = cli.ListOptions()
+        o.parseOptions(["--node-directory", "cli/test_options",
+                        "--node-url", "http://example.org:8111/"])
+        self.failUnlessEqual(o['node-url'], "http://example.org:8111/")
+        self.failUnlessEqual(o['root-uri'], private_uri)
+        self.failUnlessEqual(o['vdrive_pathname'], "")
+
+        o = cli.ListOptions()
+        o.parseOptions(["--node-directory", "cli/test_options",
+                        "--root-uri", "private"])
+        self.failUnlessEqual(o['node-url'], "http://localhost:8080/")
+        self.failUnlessEqual(o['root-uri'], private_uri)
+        self.failUnlessEqual(o['vdrive_pathname'], "")
+
+        o = cli.ListOptions()
+        o.parseOptions(["--node-directory", "cli/test_options",
+                        "--root-uri", "public"])
+        self.failUnlessEqual(o['node-url'], "http://localhost:8080/")
+        self.failUnlessEqual(o['root-uri'], public_uri)
+        self.failUnlessEqual(o['vdrive_pathname'], "")
+
+        o = cli.ListOptions()
+        other_uri = uri.DirnodeURI("furl", "otherkey").to_string()
+        o.parseOptions(["--node-directory", "cli/test_options",
+                        "--root-uri", other_uri])
+        self.failUnlessEqual(o['node-url'], "http://localhost:8080/")
+        self.failUnlessEqual(o['root-uri'], other_uri)
+        self.failUnlessEqual(o['vdrive_pathname'], "")
+
+        o = cli.ListOptions()
+        o.parseOptions(["--node-directory", "cli/test_options",
+                        "--root-uri", other_uri, "subdir"])
+        self.failUnlessEqual(o['node-url'], "http://localhost:8080/")
+        self.failUnlessEqual(o['root-uri'], other_uri)
+        self.failUnlessEqual(o['vdrive_pathname'], "subdir")