2 import os.path, re, sys
3 from twisted.python import usage
4 from allmydata.scripts.common import BaseOptions
6 NODEURL_RE=re.compile("http://([^:]*)(:([1-9][0-9]*))?")
8 class VDriveOptions(BaseOptions, usage.Options):
10 ["node-directory", "d", "~/.tahoe",
11 "Look here to find out which Tahoe node should be used for all "
12 "operations. The directory should either contain a full Tahoe node, "
13 "or a file named node.url which points to some other Tahoe node. "
14 "It should also contain a file named my_vdrive.uri which contains "
15 "the root dirnode URI that should be used, and a file named "
16 "global_root.uri which contains the public global root dirnode URI."
18 ["node-url", "u", None,
19 "URL of the tahoe node to use, a URL like \"http://127.0.0.1:8123\". "
20 "This overrides the URL found in the --node-directory ."],
21 ["root-uri", "r", "private",
22 "Which dirnode URI should be used as a root directory. The string "
23 "'public' is special, and means we should use the public global root "
24 "as found in the global_root.uri file in the --node-directory . The "
25 "string 'private' is also special, and means we should use the "
26 "private vdrive as found in the my_vdrive.uri file in the "
27 "--node-directory ."],
30 def postOptions(self):
31 # compute a node-url from the existing options, put in self['node-url']
32 if self['node-directory']:
33 self['node-directory'] = os.path.expanduser(self['node-directory'])
35 if (not isinstance(self['node-url'], basestring)
36 or not NODEURL_RE.match(self['node-url'])):
37 msg = ("--node-url is required to be a string and look like "
38 "\"http://HOSTNAMEORADDR:PORT\", not: %r" %
40 raise usage.UsageError(msg)
42 node_url_file = os.path.join(self['node-directory'], "node.url")
43 self['node-url'] = open(node_url_file, "r").read().strip()
45 # also compute self['root-uri']
46 if self['root-uri'] == "private":
47 uri_file = os.path.join(self['node-directory'], "my_vdrive.uri")
48 self['root-uri'] = open(uri_file, "r").read().strip()
49 elif self['root-uri'] == "public":
50 uri_file = os.path.join(self['node-directory'], "global_root.uri")
51 self['root-uri'] = open(uri_file, "r").read().strip()
53 from allmydata import uri
54 parsed = uri.from_string(self['root-uri'])
55 if not uri.IDirnodeURI.providedBy(parsed):
56 raise usage.UsageError("--root-uri must be a dirnode URI, or "
57 "'public' or 'private'")
60 class ListOptions(VDriveOptions):
61 def parseArgs(self, vdrive_pathname=""):
62 self['vdrive_pathname'] = vdrive_pathname
64 longdesc = """List the contents of some portion of the virtual drive."""
66 class GetOptions(VDriveOptions):
67 def parseArgs(self, vdrive_filename, local_filename="-"):
68 self['vdrive_filename'] = vdrive_filename
69 self['local_filename'] = local_filename
71 def getSynopsis(self):
72 return "%s get VDRIVE_FILE LOCAL_FILE" % (os.path.basename(sys.argv[0]),)
74 longdesc = """Retrieve a file from the virtual drive and write it to the
75 local filesystem. If LOCAL_FILE is omitted or '-', the contents of the file
76 will be written to stdout."""
78 class PutOptions(VDriveOptions):
79 def parseArgs(self, local_filename, vdrive_filename):
80 self['local_filename'] = local_filename
81 self['vdrive_filename'] = vdrive_filename
83 def getSynopsis(self):
84 return "%s put LOCAL_FILE VDRIVE_FILE" % (os.path.basename(sys.argv[0]),)
86 longdesc = """Put a file into the virtual drive (copying the file's
87 contents from the local filesystem). LOCAL_FILE is required to be a
88 local file (it can't be stdin)."""
90 class RmOptions(VDriveOptions):
91 def parseArgs(self, vdrive_pathname):
92 self['vdrive_pathname'] = vdrive_pathname
94 def getSynopsis(self):
95 return "%s rm VE_FILE" % (os.path.basename(sys.argv[0]),)
99 ["ls", None, ListOptions, "List a directory"],
100 ["get", None, GetOptions, "Retrieve a file from the virtual drive."],
101 ["put", None, PutOptions, "Upload a file into the virtual drive."],
102 ["rm", None, RmOptions, "Unlink a file or directory in the virtual drive."],
105 def list(config, stdout, stderr):
106 from allmydata.scripts import tahoe_ls
107 rc = tahoe_ls.list(config['node-url'],
109 config['vdrive_pathname'])
112 def get(config, stdout, stderr):
113 from allmydata.scripts import tahoe_get
114 vdrive_filename = config['vdrive_filename']
115 local_filename = config['local_filename']
116 rc = tahoe_get.get(config['node-url'],
121 if local_filename is None or local_filename == "-":
122 # be quiet, since the file being written to stdout should be
123 # proof enough that it worked, unless the user is unlucky
124 # enough to have picked an empty file
127 print >>stderr, "%s retrieved and written to %s" % \
128 (vdrive_filename, local_filename)
131 def put(config, stdout, stderr):
132 from allmydata.scripts import tahoe_put
133 vdrive_filename = config['vdrive_filename']
134 local_filename = config['local_filename']
139 rc = tahoe_put.put(config['node-url'],
146 def rm(config, stdout, stderr):
147 from allmydata.scripts import tahoe_rm
148 vdrive_pathname = config['vdrive_pathname']
153 rc = tahoe_rm.rm(config['node-url'],