]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/blobdiff - src/allmydata/scripts/startstop_node.py
cli: improve formatting of all commands
[tahoe-lafs/tahoe-lafs.git] / src / allmydata / scripts / startstop_node.py
index 3f8eb7af14f72a9e34218de62cfa5f2972b7de33..b1aad6acdc35cb4d252ce69152348bafd22e2547 100644 (file)
@@ -3,42 +3,62 @@ import os, sys, signal, time
 from allmydata.scripts.common import BasedirOptions
 from twisted.scripts import twistd
 from twisted.python import usage
+from allmydata.scripts.default_nodedir import _default_nodedir
 from allmydata.util import fileutil
-from allmydata.util.encodingutil import listdir_unicode, quote_output
+from allmydata.util.encodingutil import listdir_unicode, quote_local_unicode_path
 
 
 class StartOptions(BasedirOptions):
+    subcommand_name = "start"
+    optParameters = [
+        ("basedir", "C", None, "Specify which Tahoe base directory should be used. This has the same effect as the global --node-directory option. [default: %s]"
+         % quote_local_unicode_path(_default_nodedir)),
+        ]
+
     def parseArgs(self, basedir=None, *twistd_args):
-        # this can't handle e.g. 'tahoe start --nodaemon', since then
-        # --nodaemon looks like a basedir. So you can either use 'tahoe
-        # start' or 'tahoe start BASEDIR --TWISTD-OPTIONS'.
+        # This can't handle e.g. 'tahoe start --nodaemon', since '--nodaemon'
+        # looks like an option to the tahoe subcommand, not to twistd.
+        # So you can either use 'tahoe start' or 'tahoe start NODEDIR --TWISTD-OPTIONS'.
+        # Note that 'tahoe --node-directory=NODEDIR start --TWISTD-OPTIONS' also
+        # isn't allowed, unfortunately.
+
         BasedirOptions.parseArgs(self, basedir)
         self.twistd_args = twistd_args
 
     def getSynopsis(self):
-        return "Usage:  %s [global-opts] start [options] [NODEDIR]" % (self.command_name,)
+        return "Usage:  %s [global-options] %s [options] [NODEDIR [twistd-options]]" % (self.command_name, self.subcommand_name)
 
+    def getUsage(self, width=None):
+        t = BasedirOptions.getUsage(self, width) + "\n"
+        twistd_options = str(MyTwistdConfig()).partition("\n")[2].partition("\n\n")[0]
+        t += twistd_options.replace("Options:", "twistd-options:", 1)
+        t += """
 
-class StopOptions(BasedirOptions):
-    def getSynopsis(self):
-        return "Usage:  %s [global-opts] stop [options] [NODEDIR]" % (self.command_name,)
+Note that if any twistd-options are used, NODEDIR must be specified explicitly
+(not by default or using -C/--basedir or -d/--node-directory), and followed by
+the twistd-options.
+"""
+        return t
 
+class StopOptions(BasedirOptions):
+    def parseArgs(self, basedir=None):
+        BasedirOptions.parseArgs(self, basedir)
 
-class RestartOptions(StartOptions):
     def getSynopsis(self):
-        return "Usage:  %s [global-opts] restart [options] [NODEDIR]" % (self.command_name,)
+        return "Usage:  %s [global-options] stop [options] [NODEDIR]" % (self.command_name,)
 
+class RestartOptions(StartOptions):
+    subcommand_name = "restart"
 
 class RunOptions(StartOptions):
-    def getSynopsis(self):
-        return "Usage:  %s [global-opts] run [options] [NODEDIR]" % (self.command_name,)
+    subcommand_name = "run"
 
 
 class MyTwistdConfig(twistd.ServerOptions):
-    subCommands = [("XYZ", None, usage.Options, "node")]
+    subCommands = [("StartTahoeNode", None, usage.Options, "node")]
 
-class NodeStartingPlugin:
-    tapname = "xyznode"
+class StartTahoeNodePlugin:
+    tapname = "tahoenode"
     def __init__(self, nodetype, basedir):
         self.nodetype = nodetype
         self.basedir = basedir
@@ -77,13 +97,14 @@ def identify_node_type(basedir):
 
 def start(config, out=sys.stdout, err=sys.stderr):
     basedir = config['basedir']
-    print >>out, "STARTING", quote_output(basedir)
+    quoted_basedir = quote_local_unicode_path(basedir)
+    print >>out, "STARTING", quoted_basedir
     if not os.path.isdir(basedir):
-        print >>err, "%s does not look like a directory at all" % quote_output(basedir)
+        print >>err, "%s does not look like a directory at all" % quoted_basedir
         return 1
     nodetype = identify_node_type(basedir)
     if not nodetype:
-        print >>err, "%s is not a recognizable node directory" % quote_output(basedir)
+        print >>err, "%s is not a recognizable node directory" % quoted_basedir
         return 1
     # Now prepare to turn into a twistd process. This os.chdir is the point
     # of no return.
@@ -93,20 +114,20 @@ def start(config, out=sys.stdout, err=sys.stderr):
         and "--nodaemon" not in config.twistd_args
         and "--syslog" not in config.twistd_args
         and "--logfile" not in config.twistd_args):
-        fileutil.make_dirs(os.path.join(basedir, "logs"))
+        fileutil.make_dirs(os.path.join(basedir, u"logs"))
         twistd_args.extend(["--logfile", os.path.join("logs", "twistd.log")])
     twistd_args.extend(config.twistd_args)
-    twistd_args.append("XYZ") # point at our NodeStartingPlugin
+    twistd_args.append("StartTahoeNode") # point at our StartTahoeNodePlugin
 
     twistd_config = MyTwistdConfig()
     try:
         twistd_config.parseOptions(twistd_args)
     except usage.error, ue:
         # these arguments were unsuitable for 'twistd'
-        print >>err, twistd_config
-        print >>err, "tahoe start: %s" % (config.subCommand, ue)
+        print >>err, config
+        print >>err, "tahoe %s: usage error from twistd: %s\n" % (config.subcommand_name, ue)
         return 1
-    twistd_config.loadedPlugins = {"XYZ": NodeStartingPlugin(nodetype, basedir)}
+    twistd_config.loadedPlugins = {"StartTahoeNode": StartTahoeNodePlugin(nodetype, basedir)}
 
     # On Unix-like platforms:
     #   Unless --nodaemon was provided, the twistd.runApp() below spawns off a
@@ -139,17 +160,18 @@ def start(config, out=sys.stdout, err=sys.stderr):
     else:
         verb = "starting"
 
-    print >>out, "%s node in %s" % (verb, basedir)
+    print >>out, "%s node in %s" % (verb, quoted_basedir)
     twistd.runApp(twistd_config)
     # we should only reach here if --nodaemon or equivalent was used
     return 0
 
 def stop(config, out=sys.stdout, err=sys.stderr):
     basedir = config['basedir']
-    print >>out, "STOPPING", quote_output(basedir)
-    pidfile = os.path.join(basedir, "twistd.pid")
+    quoted_basedir = quote_local_unicode_path(basedir)
+    print >>out, "STOPPING", quoted_basedir
+    pidfile = os.path.join(basedir, u"twistd.pid")
     if not os.path.exists(pidfile):
-        print >>err, "%s does not look like a running node directory (no twistd.pid)" % quote_output(basedir)
+        print >>err, "%s does not look like a running node directory (no twistd.pid)" % quoted_basedir
         # we define rc=2 to mean "nothing is running, but it wasn't me who
         # stopped it"
         return 2