Add create-node CLI command, and make create-client equivalent to create-node --no...
authordavid-sarah <david-sarah@jacaranda.org>
Sat, 16 Jan 2010 05:20:55 +0000 (21:20 -0800)
committerdavid-sarah <david-sarah@jacaranda.org>
Sat, 16 Jan 2010 05:20:55 +0000 (21:20 -0800)
contrib/fuse/runtests.py
docs/configuration.txt
docs/frontends/CLI.txt
docs/frontends/webapi.txt
docs/proposed/accounting-overview.txt
src/allmydata/scripts/create_node.py
src/allmydata/test/check_grid.py
src/allmydata/test/check_memory.py
src/allmydata/test/test_runner.py
windows/installer.tmpl

index 7d13a5042272d2b51b6c2bfebb6557965c7b66c6..58dfb5b482b2dd6e715319d19039149d04524960 100644 (file)
@@ -187,7 +187,7 @@ class SystemTest (object):
         self.clientbase = None
 
     ## Top-level flow control:
-    # These "*_layer" methods call eachother in a linear fashion, using
+    # These "*_layer" methods call each other in a linear fashion, using
     # exception unwinding to do cleanup properly.  Each "layer" invokes
     # a deeper layer, and each layer does its own cleanup upon exit.
 
@@ -305,7 +305,7 @@ class SystemTest (object):
 
         base = os.path.join(self.testroot, 'client_%d' % (clientnum,))
 
-        output = self.run_tahoe('create-client', '--basedir', base)
+        output = self.run_tahoe('create-node', '--basedir', base)
         self.check_tahoe_output(output, ExpectedCreationOutput, base)
 
         if clientnum == 0:
index 1e4b248acc960f891540db8f318521c7cfbb5505..aed14c7fee1769abfdc56ce0984cb82b67025004 100644 (file)
@@ -16,9 +16,9 @@ The main file is named 'tahoe.cfg', which is an ".INI"-style configuration
 file (parsed by the Python stdlib 'ConfigParser' module: "[name]" section
 markers, lines with "key.subkey: value", rfc822-style continuations). There
 are other files that contain information which does not easily fit into this
-format. The 'tahoe create-client' command will create an initial tahoe.cfg
-file for you. After creation, the node will never modify the 'tahoe.cfg'
-file: all persistent state is put in other files.
+format. The 'tahoe create-node' or 'tahoe create-client' command will create
+an initial tahoe.cfg file for you. After creation, the node will never modify
+the 'tahoe.cfg' file: all persistent state is put in other files.
 
 The item descriptions below use the following types:
 
@@ -51,9 +51,9 @@ web.port = (strports string, optional)
  This controls where the node's webserver should listen, providing filesystem
  access and node status as defined in webapi.txt . This file contains a
  Twisted "strports" specification such as "3456" or
- "tcp:3456:interface=127.0.0.1". The 'tahoe create-client' command sets the
- web.port to "tcp:3456:interface=127.0.0.1" by default, and is overridable by
- the "--webport" option. You can make it use SSL by writing
+ "tcp:3456:interface=127.0.0.1". The 'tahoe create-node' or 'tahoe create-client'
+ commands set the web.port to "tcp:3456:interface=127.0.0.1" by default; this
is overridable by the "--webport" option. You can make it use SSL by writing
  "ssl:3456:privateKey=mykey.pem:certKey=cert.pem" instead.
 
  If this is not provided, the node will not run a web server.
@@ -382,8 +382,8 @@ held while they are being received.
 client.tac : this file defines the client, by constructing the actual Client
 instance each time the node is started. It is used by the 'twistd'
 daemonization program (in the "-y" mode), which is run internally by the
-"tahoe start" command. This file is created by the "tahoe create-client"
-command.
+"tahoe start" command. This file is created by the "tahoe create-node" or
+"tahoe create-client" commands.
 
 private/control.furl : this file contains a FURL that provides access to a
 control port on the client node, from which files can be uploaded and
index e452924f41834f10fc20706ea556314b473dfab5..de64b241ff089f9eefd200dafd674b65365e863c 100644 (file)
@@ -15,6 +15,7 @@ package), then the tahoe executable will be available somewhere else, perhaps
 in /usr/bin/tahoe . In this case, it will use your platform's normal
 PYTHONPATH search paths to find the tahoe code and other libraries.
 
+
 == CLI Command Overview ==
 
 The "tahoe" tool provides access to three categories of commands.
@@ -31,20 +32,25 @@ with the "allmydata" module (which contains the majority of the Tahoe
 functionality) and including versions for a number of dependent libraries,
 like Twisted, Foolscap, pycryptopp, and zfec.
 
+
 == Node Management ==
 
-"tahoe create-client [NODEDIR]" is the basic make-a-new-node command. It
+"tahoe create-node [NODEDIR]" is the basic make-a-new-node command. It
 creates a new directory and populates it with files that will allow the
 "tahoe start" command to use it later on. This command creates nodes that
 have client functionality (upload/download files), web API services
-(controlled by the 'webport' file), and storage services (controlled by
-"no_storage" and the like).
+(controlled by the 'webport' file), and storage services (unless
+"--no_storage" is specified).
 
-NODEDIR defaults to ~/.tahoe/ , and newly-created clients default to
+NODEDIR defaults to ~/.tahoe/ , and newly-created nodes default to
 publishing a web server on port 3456 (limited to the loopback interface, at
 127.0.0.1, to restrict access to other programs on the same host). All of the
 other "tahoe" subcommands use corresponding defaults.
 
+"tahoe create-client [NODEDIR]" creates a node with no storage service.
+That is, it behaves like "tahoe create-node --no-storage [NODEDIR]".
+(This is a change from versions prior to 1.6.0.)
+
 "tahoe create-introducer [NODEDIR]" is used to create the Introducer node.
 This node provides introduction services and nothing else. When started, this
 node will produce an introducer.furl, which should be published to all
@@ -56,15 +62,15 @@ generation to a separate process. Since RSA key generation takes several
 seconds, and must be done each time a directory is created, moving it to a
 separate process allows the first process (perhaps a busy wapi server) to
 continue servicing other requests. The key generator exports a FURL that can
-be copied into a client node to enable this functionality.
+be copied into a node to enable this functionality.
+
+"tahoe run [NODEDIR]" will start a previously-created node in the foreground.
 
 "tahoe start [NODEDIR]" will launch a previously-created node. It will launch
 the node into the background, using the standard Twisted "twistd"
-daemon-launching tool.
-
-"tahoe run [NODEDIR]" will start a previous-created node in the foreground.
-Some platforms are unable to run a daemon in the background: this command
-provides a way to use a tahoe node on such platforms.
+daemon-launching tool. On some platforms (including Windows) this command is
+unable to run a daemon in the background; in that case it behaves in the
+same way as "tahoe run".
 
 "tahoe stop [NODEDIR]" will shut down a running node.
 
@@ -91,9 +97,9 @@ local one.
 These commands also use a table of "aliases" to figure out which directory
 they ought to use a starting point. This is explained in more detail below.
 
-In Tahoe v1.3.0, passing non-ascii characters to the cli is not guaranteed to
-work, although it might work on your platform, especially if your platform
-uses utf-8 encoding.
+In Tahoe up to v1.6.0, passing non-ASCII characters to the CLI is not guaranteed
+to work, although it might work on your platform, especially if your platform
+uses UTF-8 encoding.
 
 === Starting Directories ===
 
index 91c2aa30732e7f73d69334f91f9b1a5f6b9673a4..e955933b2715da1ff417de005883817fafae4925 100644 (file)
@@ -31,7 +31,7 @@ local host can connect. Using
 "ssl:3456:privateKey=mykey.pem:certKey=cert.pem" runs an SSL server.
 
 This webport can be set when the node is created by passing a --webport
-option to the 'tahoe create-client' command. By default, the node listens on
+option to the 'tahoe create-node' command. By default, the node listens on
 port 3456, on the loopback (127.0.0.1) interface.
 
 == Basic Concepts ==
index 230813b1039a1151e074c65730effac8990e5802..91351fc5fce2ed82ac9981290291a518d1d58f41 100644 (file)
@@ -239,7 +239,7 @@ to be set by end users.
 The process starts with Bob the storage server operator, who has just created
 a new Storage Server:
 
- tahoe create-client
+ tahoe create-node
  --> creates ~/.tahoe
  # edit ~/.tahoe/tahoe.cfg, add introducer.furl, configure storage, etc
 
index 7a20ded1349d8e5bc99c4c6b79ff1c385e957813..f47ccc997822f0a3f63e24005d7f96204f3f0353 100644 (file)
@@ -5,8 +5,8 @@ from allmydata.scripts.common import BasedirMixin, NoDefaultBasedirMixin
 
 class CreateClientOptions(BasedirMixin, usage.Options):
     optParameters = [
-        ("basedir", "C", None, "which directory to create the client in"),
-        # we provide create-client -time options for the most common
+        ("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"),
@@ -14,6 +14,8 @@ class CreateClientOptions(BasedirMixin, usage.Options):
         ("webport", "p", "tcp:3456:interface=127.0.0.1",
          "which TCP port to run the HTTP interface on. Use 'none' to disable."),
         ]
+
+class CreateNodeOptions(CreateClientOptions):
     optFlags = [
         ("no-storage", None, "do not offer storage service to other nodes"),
         ]
@@ -81,7 +83,7 @@ def write_node_config(c, config):
     c.write("\n")
 
 
-def create_client(basedir, config, out=sys.stdout, err=sys.stderr):
+def create_node(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))
@@ -127,13 +129,19 @@ def create_client(basedir, config, out=sys.stdout, err=sys.stderr):
 
     from allmydata.util import fileutil
     fileutil.make_dirs(os.path.join(basedir, "private"), 0700)
-    print >>out, "client created in %s" % basedir
+    print >>out, "Node created in %s" % 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"
 
+
+def create_client(basedir, config, out=sys.stdout, err=sys.stderr):
+    config['no-storage'] = True
+    return create_node(basedir, config, out=out, err=err)
+
+
 def create_introducer(basedir, config, out=sys.stdout, err=sys.stderr):
     if os.path.exists(basedir):
         if os.listdir(basedir):
@@ -152,15 +160,18 @@ 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" % basedir
+
 
 subCommands = [
-    ["create-client", None, CreateClientOptions, "Create a client node."],
-    ["create-introducer", None, CreateIntroducerOptions, "Create a introducer node."],
+    ["create-node", None, CreateNodeOptions, "Create a node that acts as a client, server or both."],
+    ["create-client", None, CreateClientOptions, "Create a client node (with storage initially disabled)."],
+    ["create-introducer", None, CreateIntroducerOptions, "Create an introducer."],
 
 ]
 
 dispatch = {
+    "create-node": create_node,
     "create-client": create_client,
     "create-introducer": create_introducer,
     }
index b1deea0facb7ed433da9957792e293248a407f85..30d29fcd064acdcba6300dd4d87c5db8b36e742b 100644 (file)
@@ -23,7 +23,6 @@ down the node after the test finishes.
 To set up the client node, do the following:
 
   tahoe create-client DIR
-  touch DIR/no_storage
   populate DIR/introducer.furl
   tahoe start DIR
   tahoe add-alias -d DIR testgrid `tahoe mkdir -d DIR`
index 40cfa590ce3fa517f97fc89af1e5bfd5e6288af9..31c66c8a000661ea0cf59d1609a86548d844121a 100644 (file)
@@ -228,7 +228,7 @@ this file are ignored.
         log.msg("MAKING CLIENT")
         clientdir = self.clientdir = os.path.join(self.testdir, "client")
         quiet = StringIO()
-        create_node.create_client(clientdir, {}, out=quiet)
+        create_node.create_node(clientdir, {}, out=quiet)
         log.msg("DONE MAKING CLIENT")
         f = open(os.path.join(clientdir, "introducer.furl"), "w")
         f.write(self.introducer_furl + "\n")
index 4d07e626d42e4ec975e84822bd335697282d3669..bd604a57553fa96af0226b9ebd7028781c503bef 100644 (file)
@@ -42,7 +42,7 @@ class TheRightCode(common_util.SignalMixin, unittest.TestCase,
         return d
 
 class CreateNode(unittest.TestCase):
-    # exercise "tahoe create-client", create-introducer,
+    # exercise "tahoe create-node", create-introducer,
     # create-key-generator, and create-stats-gatherer, by calling the
     # corresponding code as a subroutine.
 
@@ -56,16 +56,26 @@ class CreateNode(unittest.TestCase):
         rc = runner.runner(argv, stdout=out, stderr=err)
         return rc, out.getvalue(), err.getvalue()
 
-    def test_client(self):
-        basedir = self.workdir("test_client")
-        c1 = os.path.join(basedir, "c1")
-        argv = ["--quiet", "create-client", "--basedir", c1]
+    def test_node(self, command="create-node"):
+        basedir = self.workdir("test_node")
+        c1 = os.path.join(basedir, command + "-c1")
+        argv = ["--quiet", command, "--basedir", c1]
         rc, out, err = self.run_tahoe(argv)
         self.failUnlessEqual(err, "")
         self.failUnlessEqual(out, "")
         self.failUnlessEqual(rc, 0)
         self.failUnless(os.path.exists(c1))
         self.failUnless(os.path.exists(os.path.join(c1, "tahoe-client.tac")))
+        
+        # tahoe.cfg should exist, and should have storage enabled for
+        # 'create-node', and disabled for 'create-client'.
+        tahoe_cfg = os.path.join(c1, "tahoe.cfg")
+        self.failUnless(os.path.exists(tahoe_cfg))
+        content = open(tahoe_cfg).read()
+        if command == "create-client":
+            self.failUnless("\n[storage]\nenabled = false\n" in content)
+        else:
+            self.failUnless("\n[storage]\nenabled = true\n" in content)
 
         # creating the client a second time should be rejected
         rc, out, err = self.run_tahoe(argv)
@@ -79,18 +89,22 @@ class CreateNode(unittest.TestCase):
             self.failIf(re.search("[\S][^\.!?]$", line), (line,))
 
         # test that the non --basedir form works too
-        c2 = os.path.join(basedir, "c2")
-        argv = ["--quiet", "create-client", c2]
+        c2 = os.path.join(basedir, command + "c2")
+        argv = ["--quiet", command, c2]
         rc, out, err = self.run_tahoe(argv)
         self.failUnless(os.path.exists(c2))
         self.failUnless(os.path.exists(os.path.join(c2, "tahoe-client.tac")))
 
         # make sure it rejects too many arguments
-        argv = ["create-client", "basedir", "extraarg"]
+        argv = [command, "basedir", "extraarg"]
         self.failUnlessRaises(usage.UsageError,
                               runner.runner, argv,
                               run_by_human=False)
 
+    def test_client(self):
+        # create-client should behave like create-node --no-storage.
+        self.test_node(command="create-client")
+
     def test_introducer(self):
         basedir = self.workdir("test_introducer")
         c1 = os.path.join(basedir, "c1")
@@ -347,7 +361,7 @@ class RunNode(common_util.SignalMixin, unittest.TestCase, pollmixin.PollMixin,
         TWISTD_PID_FILE = os.path.join(c1, "twistd.pid")
         PORTNUMFILE = os.path.join(c1, "client.port")
 
-        d = utils.getProcessOutputAndValue(bintahoe, args=["--quiet", "create-client", "--basedir", c1, "--webport", "0"], env=os.environ)
+        d = utils.getProcessOutputAndValue(bintahoe, args=["--quiet", "create-node", "--basedir", c1, "--webport", "0"], env=os.environ)
         def _cb(res):
             out, err, rc_or_sig = res
             self.failUnlessEqual(rc_or_sig, 0)
index daf0e4afdaa3b34f70357073d98faa9f6cff8f70..6721ed99687e8c9261758d512ffb45a9153e5b4b 100644 (file)
@@ -45,7 +45,7 @@ Filename: "{sys}\net.exe"; Parameters: "stop ""Allmydata SMB"""; Flags: runhidde
 Filename: "{sys}\net.exe"; Parameters: "stop Tahoe"; Flags: runhidden
 Filename: "{sys}\net.exe"; Parameters: "stop Allmydata Manager"; Flags: runhidden
 Filename: "{app}\Install\tahoesvc.exe"; Parameters: "-install -auto"; Flags: runhidden
-Filename: "{app}\Install\tahoe.exe"; Parameters: "create-client ""{app}\noderoot"""; Flags: runhidden
+Filename: "{app}\Install\tahoe.exe"; Parameters: "create-node ""{app}\noderoot"""; Flags: runhidden
 Filename: "{app}\Install\winfuse\AllmydataManager.exe"; Parameters: "-install -auto"; Flags: runhidden
 Filename: "{app}\Install\winfuse\InstallUtil.exe"; Parameters: """{app}\Install\winfuse\WinFUSE.exe"""; Flags: runhidden
 Filename: "{app}\Install\confwiz.exe"; Flags: hidewizard