]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/blob - src/allmydata/scripts/slow_operation.py
Alter CLI utilities to handle nonexistent aliases better
[tahoe-lafs/tahoe-lafs.git] / src / allmydata / scripts / slow_operation.py
1
2 import os, time
3 from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path, \
4                                      UnknownAliasError
5 from allmydata.scripts.common_http import do_http
6 from allmydata.util import base32
7 import urllib
8 import simplejson
9
10 class SlowOperationRunner:
11
12     def run(self, options):
13         stderr = options.stderr
14         self.options = options
15         self.ophandle = ophandle = base32.b2a(os.urandom(16))
16         nodeurl = options['node-url']
17         if not nodeurl.endswith("/"):
18             nodeurl += "/"
19         self.nodeurl = nodeurl
20         where = options.where
21         try:
22             rootcap, path = get_alias(options.aliases, where, DEFAULT_ALIAS)
23         except UnknownAliasError, e:
24             print >>stderr, "error: %s" % e.args[0]
25             return 1
26         if path == '/':
27             path = ''
28         url = nodeurl + "uri/%s" % urllib.quote(rootcap)
29         if path:
30             url += "/" + escape_path(path)
31         # todo: should it end with a slash?
32         url = self.make_url(url, ophandle)
33         resp = do_http("POST", url)
34         if resp.status not in (200, 302):
35             print >>stderr, "ERROR", resp.status, resp.reason, resp.read()
36             return 1
37         # now we poll for results. We nominally poll at t=1, 5, 10, 30, 60,
38         # 90, k*120 seconds, but if the poll takes non-zero time, that will
39         # be slightly longer. I'm not worried about trying to make up for
40         # that time.
41
42         return self.wait_for_results()
43
44     def poll_times(self):
45         for i in (1,5,10,30,60,90):
46             yield i
47         i = 120
48         while True:
49             yield i
50             i += 120
51
52     def wait_for_results(self):
53         last = 0
54         for next in self.poll_times():
55             delay = next - last
56             time.sleep(delay)
57             last = next
58             if self.poll():
59                 return 0
60
61     def poll(self):
62         url = self.nodeurl + "operations/" + self.ophandle
63         url += "?t=status&output=JSON&release-after-complete=true"
64         stdout = self.options.stdout
65         stderr = self.options.stderr
66         resp = do_http("GET", url)
67         if resp.status != 200:
68             print >>stderr, "ERROR", resp.status, resp.reason, resp.read()
69             return True
70         jdata = resp.read()
71         data = simplejson.loads(jdata)
72         if not data["finished"]:
73             return False
74         if self.options.get("raw"):
75             print >>stdout, jdata
76             return True
77         self.write_results(data)
78         return True
79