]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/blobdiff - src/allmydata/scripts/create_node.py
bin/tahoe: clean up global-vs-subcommand arguments like --node-directory
[tahoe-lafs/tahoe-lafs.git] / src / allmydata / scripts / create_node.py
index 4e23ac07ae54b9ebb564e78845f2b10d7ed813e1..893bf08c2b0ec62f3946a398dda7ce6d6747bee4 100644 (file)
@@ -1,35 +1,46 @@
 
 import os, sys
-from twisted.python import usage
-from allmydata.scripts.common import BasedirMixin, NoDefaultBasedirMixin
+from allmydata.scripts.common import BasedirOptions
+from allmydata.util.assertutil import precondition
+from allmydata.util.encodingutil import listdir_unicode, argv_to_unicode, quote_output
+import allmydata
 
-class CreateClientOptions(BasedirMixin, usage.Options):
+class CreateClientOptions(BasedirOptions):
     optParameters = [
-        ("basedir", "C", None, "which directory to create the node in"),
         # we provide 'create-node'-time options for the most common
         # configuration knobs. The rest can be controlled by editing
         # tahoe.cfg before node startup.
-        ("nickname", "n", None, "nickname for this node"),
-        ("introducer", "i", None, "introducer FURL to use"),
+        ("nickname", "n", None, "Specify the nickname for this node."),
+        ("introducer", "i", None, "Specify the introducer FURL to use."),
         ("webport", "p", "tcp:3456:interface=127.0.0.1",
-         "which TCP port to run the HTTP interface on. Use 'none' to disable."),
+         "Specify which TCP port to run the HTTP interface on. Use 'none' to disable."),
         ]
 
+    def getSynopsis(self):
+        return "Usage:  %s create-client [options] [NODEDIR]" % (self.command_name,)
+
+
 class CreateNodeOptions(CreateClientOptions):
     optFlags = [
-        ("no-storage", None, "do not offer storage service to other nodes"),
+        ("no-storage", None, "Do not offer storage service to other nodes."),
         ]
 
-class CreateIntroducerOptions(NoDefaultBasedirMixin, usage.Options):
-    optParameters = [
-        ["basedir", "C", None, "which directory to create the introducer in"],
-        ]
+    def getSynopsis(self):
+        return "Usage:  %s create-node [options] [NODEDIR]" % (self.command_name,)
+
+
+class CreateIntroducerOptions(BasedirOptions):
+    default_nodedir = None
+
+    def getSynopsis(self):
+        return "Usage:  %s create-introducer [options] NODEDIR" % (self.command_name,)
+
 
 client_tac = """
 # -*- python -*-
 
 import pkg_resources
-pkg_resources.require('allmydata-tahoe')
+pkg_resources.require('%s')
 pkg_resources.require('twisted')
 from allmydata import client
 from twisted.application import service
@@ -38,13 +49,13 @@ c = client.Client()
 
 application = service.Application("allmydata_client")
 c.setServiceParent(application)
-"""
+""" % (allmydata.__appname__,)
 
 introducer_tac = """
 # -*- python -*-
 
 import pkg_resources
-pkg_resources.require('allmydata-tahoe')
+pkg_resources.require('%s')
 pkg_resources.require('twisted')
 from allmydata import introducer
 from twisted.application import service
@@ -53,7 +64,7 @@ c = introducer.IntroducerNode()
 
 application = service.Application("allmydata_introducer")
 c.setServiceParent(application)
-"""
+""" % (allmydata.__appname__,)
 
 def write_node_config(c, config):
     # this is shared between clients and introducers
@@ -62,16 +73,19 @@ def write_node_config(c, config):
     c.write("# This file controls the configuration of the Tahoe node that\n")
     c.write("# lives in this directory. It is only read at node startup.\n")
     c.write("# For details about the keys that can be set here, please\n")
-    c.write("# read the 'docs/configuration.txt' file that came with your\n")
+    c.write("# read the 'docs/configuration.rst' file that came with your\n")
     c.write("# Tahoe installation.\n")
     c.write("\n\n")
 
     c.write("[node]\n")
-    c.write("nickname = %s\n" % config.get("nickname", "")) #TODO: utf8 in argv?
-    webport = config.get("webport", "none")
+    nickname = argv_to_unicode(config.get("nickname") or "")
+    c.write("nickname = %s\n" % (nickname.encode('utf-8'),))
+
+    # TODO: validate webport
+    webport = argv_to_unicode(config.get("webport") or "none")
     if webport.lower() == "none":
         webport = ""
-    c.write("web.port = %s\n" % webport)
+    c.write("web.port = %s\n" % (webport.encode('utf-8'),))
     c.write("web.static = public_html\n")
     c.write("#tub.port =\n")
     c.write("#tub.location = \n")
@@ -83,10 +97,14 @@ def write_node_config(c, config):
     c.write("\n")
 
 
-def create_node(basedir, config, out=sys.stdout, err=sys.stderr):
+def create_node(config, out=sys.stdout, err=sys.stderr):
+    basedir = config['basedir']
+    # This should always be called with an absolute Unicode basedir.
+    precondition(isinstance(basedir, unicode), basedir)
+
     if os.path.exists(basedir):
-        if os.listdir(basedir):
-            print >>err, "The base directory \"%s\", which is \"%s\" is not empty." % (basedir, os.path.abspath(basedir))
+        if listdir_unicode(basedir):
+            print >>err, "The base directory %s is not empty." % quote_output(basedir)
             print >>err, "To avoid clobbering anything, I am going to quit now."
             print >>err, "Please use a different directory, or empty this one."
             return -1
@@ -102,10 +120,13 @@ def create_node(basedir, config, out=sys.stdout, err=sys.stderr):
     write_node_config(c, config)
 
     c.write("[client]\n")
+    c.write("# Which services should this client connect to?\n")
     c.write("introducer.furl = %s\n" % config.get("introducer", ""))
     c.write("helper.furl =\n")
     c.write("#key_generator.furl =\n")
     c.write("#stats_gatherer.furl =\n")
+    c.write("\n")
+    c.write("# What encoding parameters should this client use for uploads?\n")
     c.write("#shares.needed = 3\n")
     c.write("#shares.happy = 7\n")
     c.write("#shares.total = 10\n")
@@ -113,39 +134,53 @@ def create_node(basedir, config, out=sys.stdout, err=sys.stderr):
 
     boolstr = {True:"true", False:"false"}
     c.write("[storage]\n")
+    c.write("# Shall this node provide storage service?\n")
     storage_enabled = not config.get("no-storage", None)
     c.write("enabled = %s\n" % boolstr[storage_enabled])
     c.write("#readonly =\n")
-    c.write("#reserved_space =\n")
+    c.write("reserved_space = 1G\n")
     c.write("#expire.enabled =\n")
     c.write("#expire.mode =\n")
     c.write("\n")
 
     c.write("[helper]\n")
+    c.write("# Shall this node run a helper service that clients can use?\n")
+    c.write("enabled = false\n")
+    c.write("\n")
+
+    c.write("[drop_upload]\n")
+    c.write("# Shall this node automatically upload files created or modified in a local directory?\n")
     c.write("enabled = false\n")
+    c.write("# To specify the target of uploads, a mutable directory writecap URI must be placed\n"
+            "# in 'private/drop_upload_dircap'.\n")
+    c.write("local.directory = ~/drop_upload\n")
     c.write("\n")
 
     c.close()
 
     from allmydata.util import fileutil
     fileutil.make_dirs(os.path.join(basedir, "private"), 0700)
-    print >>out, "Node created in %s" % basedir
+    print >>out, "Node created in %s" % quote_output(basedir)
     if not config.get("introducer", ""):
         print >>out, " Please set [client]introducer.furl= in tahoe.cfg!"
         print >>out, " The node cannot connect to a grid without it."
     if not config.get("nickname", ""):
         print >>out, " Please set [node]nickname= in tahoe.cfg"
+    return 0
 
-
-def create_client(basedir, config, out=sys.stdout, err=sys.stderr):
+def create_client(config, out=sys.stdout, err=sys.stderr):
     config['no-storage'] = True
-    return create_node(basedir, config, out=out, err=err)
+    return create_node(config, out=out, err=err)
+
 
+def create_introducer(config, out=sys.stdout, err=sys.stderr):
+    basedir = config['basedir']
+    # This should always be called with an absolute Unicode basedir.
+    precondition(isinstance(basedir, unicode), basedir)
 
-def create_introducer(basedir, config, out=sys.stdout, err=sys.stderr):
     if os.path.exists(basedir):
-        if os.listdir(basedir):
-            print >>err, "The base directory \"%s\", which is \"%s\" is not empty." % (basedir, os.path.abspath(basedir))
+        if listdir_unicode(basedir):
+            print >>err, "The base directory %s is not empty." % quote_output(basedir)
             print >>err, "To avoid clobbering anything, I am going to quit now."
             print >>err, "Please use a different directory, or empty this one."
             return -1
@@ -160,7 +195,8 @@ def create_introducer(basedir, config, out=sys.stdout, err=sys.stderr):
     write_node_config(c, config)
     c.close()
 
-    print >>out, "Introducer created in %s" % basedir
+    print >>out, "Introducer created in %s" % quote_output(basedir)
+    return 0
 
 
 subCommands = [