]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/blob - src/allmydata/scripts/cli.py
cli: add --node-directory and --root-uri to all commands
[tahoe-lafs/tahoe-lafs.git] / src / allmydata / scripts / cli.py
1
2 import os.path, re, sys
3 from twisted.python import usage
4 from allmydata.scripts.common import BaseOptions
5
6 NODEURL_RE=re.compile("http://([^:]*)(:([1-9][0-9]*))?")
7
8 class VDriveOptions(BaseOptions, usage.Options):
9     optParameters = [
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."
17          ],
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 ."],
28         ]
29
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'])
34         if self['node-url']:
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" %
39                        (self['node-url'],))
40                 raise usage.UsageError(msg)
41         else:
42             node_url_file = os.path.join(self['node-directory'], "node.url")
43             self['node-url'] = open(node_url_file, "r").read().strip()
44
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()
52         else:
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'")
58
59
60 class ListOptions(VDriveOptions):
61     def parseArgs(self, vdrive_pathname=""):
62         self['vdrive_pathname'] = vdrive_pathname
63
64     longdesc = """List the contents of some portion of the virtual drive."""
65
66 class GetOptions(VDriveOptions):
67     def parseArgs(self, vdrive_filename, local_filename="-"):
68         self['vdrive_filename'] = vdrive_filename
69         self['local_filename'] = local_filename
70
71     def getSynopsis(self):
72         return "%s get VDRIVE_FILE LOCAL_FILE" % (os.path.basename(sys.argv[0]),)
73
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."""
77
78 class PutOptions(VDriveOptions):
79     def parseArgs(self, local_filename, vdrive_filename):
80         self['local_filename'] = local_filename
81         self['vdrive_filename'] = vdrive_filename
82
83     def getSynopsis(self):
84         return "%s put LOCAL_FILE VDRIVE_FILE" % (os.path.basename(sys.argv[0]),)
85
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)."""
89
90 class RmOptions(VDriveOptions):
91     def parseArgs(self, vdrive_pathname):
92         self['vdrive_pathname'] = vdrive_pathname
93
94     def getSynopsis(self):
95         return "%s rm VE_FILE" % (os.path.basename(sys.argv[0]),)
96
97
98 subCommands = [
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."],
103     ]
104
105 def list(config, stdout, stderr):
106     from allmydata.scripts import tahoe_ls
107     rc = tahoe_ls.list(config['node-url'],
108                        config['root-uri'],
109                        config['vdrive_pathname'])
110     return rc
111
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'],
117                        config['root-uri'],
118                        vdrive_filename,
119                        local_filename)
120     if rc == 0:
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
125             pass
126         else:
127             print >>stderr, "%s retrieved and written to %s" % \
128                   (vdrive_filename, local_filename)
129     return rc
130
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']
135     if config['quiet']:
136         verbosity = 0
137     else:
138         verbosity = 2
139     rc = tahoe_put.put(config['node-url'],
140                        config['root-uri'],
141                        local_filename,
142                        vdrive_filename,
143                        verbosity)
144     return rc
145
146 def rm(config, stdout, stderr):
147     from allmydata.scripts import tahoe_rm
148     vdrive_pathname = config['vdrive_pathname']
149     if config['quiet']:
150         verbosity = 0
151     else:
152         verbosity = 2
153     rc = tahoe_rm.rm(config['node-url'],
154                      config['root-uri'],
155                      vdrive_pathname,
156                      verbosity)
157     return rc
158
159 dispatch = {
160     "ls": list,
161     "get": get,
162     "put": put,
163     "rm": rm,
164     }
165