]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/blob - src/allmydata/scripts/runner.py
210efb6546468aef3839cca9970ecca7ef7961c6
[tahoe-lafs/tahoe-lafs.git] / src / allmydata / scripts / runner.py
1
2 import sys
3 from cStringIO import StringIO
4
5 from twisted.python import usage
6
7 from allmydata.scripts.common import BaseOptions
8 from allmydata.scripts import debug, create_node, startstop_node, cli, keygen, stats_gatherer, admin
9 from allmydata.util.encodingutil import quote_output, get_io_encoding
10
11 def GROUP(s):
12     # Usage.parseOptions compares argv[1] against command[0], so it will
13     # effectively ignore any "subcommand" that starts with a newline. We use
14     # these to insert section headers into the --help output.
15     return [("\n" + s, None, None, None)]
16
17
18 class Options(BaseOptions, usage.Options):
19     synopsis = "\nUsage:  tahoe <command> [command options]"
20     subCommands = ( GROUP("Administration")
21                     +   create_node.subCommands
22                     +   keygen.subCommands
23                     +   stats_gatherer.subCommands
24                     +   admin.subCommands
25                     + GROUP("Controlling a node")
26                     +   startstop_node.subCommands
27                     + GROUP("Debugging")
28                     +   debug.subCommands
29                     + GROUP("Using the filesystem")
30                     +   cli.subCommands
31                     )
32
33     def getUsage(self, **kwargs):
34         t = usage.Options.getUsage(self, **kwargs)
35         return t + "\nPlease run 'tahoe <command> --help' for more details on each command.\n"
36
37     def postOptions(self):
38         if not hasattr(self, 'subOptions'):
39             if not hasattr(self, 'no_command_needed'):
40                 raise usage.UsageError("must specify a command")
41             sys.exit(0)
42
43
44 create_dispatch = {}
45 for module in (create_node, keygen, stats_gatherer):
46     create_dispatch.update(module.dispatch)
47
48 def runner(argv,
49            run_by_human=True,
50            stdin=None, stdout=None, stderr=None,
51            install_node_control=True, additional_commands=None):
52
53     stdin  = stdin  or sys.stdin
54     stdout = stdout or sys.stdout
55     stderr = stderr or sys.stderr
56
57     config = Options()
58     if install_node_control:
59         config.subCommands.extend(startstop_node.subCommands)
60
61     ac_dispatch = {}
62     if additional_commands:
63         for ac in additional_commands:
64             config.subCommands.extend(ac.subCommands)
65             ac_dispatch.update(ac.dispatch)
66
67     try:
68         config.parseOptions(argv)
69     except usage.error, e:
70         if not run_by_human:
71             raise
72         c = config
73         while hasattr(c, 'subOptions'):
74             c = c.subOptions
75         print >>stdout, str(c)
76         try:
77             msg = e.args[0].decode(get_io_encoding())
78         except Exception:
79             msg = repr(e)
80         print >>stdout, "%s:  %s\n" % (sys.argv[0], quote_output(msg, quotemarks=False))
81         return 1
82
83     command = config.subCommand
84     so = config.subOptions
85
86     if config['quiet']:
87         stdout = StringIO()
88
89     so.stdout = stdout
90     so.stderr = stderr
91     so.stdin = stdin
92
93     if command in create_dispatch:
94         rc = create_dispatch[command](so, stdout, stderr)
95     elif command in startstop_node.dispatch:
96         rc = startstop_node.dispatch[command](so, stdout, stderr)
97     elif command in debug.dispatch:
98         rc = debug.dispatch[command](so)
99     elif command in admin.dispatch:
100         rc = admin.dispatch[command](so)
101     elif command in cli.dispatch:
102         rc = cli.dispatch[command](so)
103     elif command in ac_dispatch:
104         rc = ac_dispatch[command](so, stdout, stderr)
105     else:
106         raise usage.UsageError()
107
108     return rc
109
110
111 def run(install_node_control=True):
112     try:
113         if sys.platform == "win32":
114             from allmydata.windows.fixups import initialize
115             initialize()
116
117         rc = runner(sys.argv[1:], install_node_control=install_node_control)
118     except Exception:
119         import traceback
120         traceback.print_exc()
121         rc = 1
122
123     sys.exit(rc)