From fc398a462da10112ca6f37213738dab786e8e19d Mon Sep 17 00:00:00 2001
From: Daira Hopwood <daira@jacaranda.org>
Date: Sun, 7 Dec 2014 18:10:17 +0000
Subject: [PATCH] tac files no longer need to contain initialization code. Also
 factor out common code in basedir creation between node types. refs #2011,
 #2325

Signed-off-by: Daira Hopwood <daira@jacaranda.org>
---
 src/allmydata/scripts/common.py         | 32 +++++++++-
 src/allmydata/scripts/create_node.py    | 78 +++++--------------------
 src/allmydata/scripts/keygen.py         | 46 +++------------
 src/allmydata/scripts/stats_gatherer.py | 42 +++----------
 4 files changed, 62 insertions(+), 136 deletions(-)

diff --git a/src/allmydata/scripts/common.py b/src/allmydata/scripts/common.py
index 21481e35..b7d4d222 100644
--- a/src/allmydata/scripts/common.py
+++ b/src/allmydata/scripts/common.py
@@ -3,10 +3,40 @@ import os, sys, urllib
 import codecs
 from twisted.python import usage
 from allmydata.util.assertutil import precondition
-from allmydata.util.encodingutil import unicode_to_url, quote_output, argv_to_abspath
+from allmydata.util.encodingutil import listdir_unicode, unicode_to_url, quote_output, argv_to_abspath
+from allmydata.util import fileutil
 from allmydata.util.fileutil import abspath_expanduser_unicode
 
 
+class NonEmptyBasedirException(Exception):
+    pass
+
+_DUMMY_TAC = """
+# %s
+import sys
+print >>sys.stderr, "Tahoe-LAFS v1.10 or earlier cannot run nodes with"
+print >>sys.stderr, "base directories created by versions after v1.11."
+sys.exit(1)
+"""
+
+def create_basedir(basedir, nodetype, err=sys.stderr):
+    # This should always be called with an absolute Unicode basedir.
+    precondition(isinstance(basedir, unicode), basedir)
+
+    if os.path.exists(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."
+            raise NonEmptyBasedirException()
+        # we're willing to use an empty directory
+    else:
+        os.mkdir(basedir)
+
+    fileutil.write(os.path.join(basedir, u"tahoe-%s.tac" % (nodetype,)),
+                   _DUMMY_TAC % (nodetype,), mode="w")
+
+
 _default_nodedir = None
 if sys.platform == 'win32':
     from allmydata.windows import registry
diff --git a/src/allmydata/scripts/create_node.py b/src/allmydata/scripts/create_node.py
index 6663d125..2b87c345 100644
--- a/src/allmydata/scripts/create_node.py
+++ b/src/allmydata/scripts/create_node.py
@@ -1,9 +1,10 @@
 
 import os, sys
-from allmydata.scripts.common import BasedirOptions, NoDefaultBasedirOptions
-from allmydata.util.assertutil import precondition
-from allmydata.util.encodingutil import listdir_unicode, argv_to_unicode, quote_output
-import allmydata
+from allmydata.scripts.common import BasedirOptions, NoDefaultBasedirOptions, create_basedir, \
+    NonEmptyBasedirException
+from allmydata.util.encodingutil import argv_to_unicode, quote_output
+from allmydata.util import fileutil
+
 
 class CreateClientOptions(BasedirOptions):
     optParameters = [
@@ -38,36 +39,6 @@ class CreateIntroducerOptions(NoDefaultBasedirOptions):
     subcommand_name = "create-introducer"
 
 
-client_tac = """
-# -*- python -*-
-
-import pkg_resources
-pkg_resources.require('%s')
-pkg_resources.require('twisted')
-from allmydata import client
-from twisted.application import service
-
-c = client.Client()
-
-application = service.Application("allmydata_client")
-c.setServiceParent(application)
-""" % (allmydata.__appname__,)
-
-introducer_tac = """
-# -*- python -*-
-
-import pkg_resources
-pkg_resources.require('%s')
-pkg_resources.require('twisted')
-from allmydata import introducer
-from twisted.application import service
-
-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
     c.write("# -*- mode: conf; coding: utf-8 -*-\n")
@@ -101,21 +72,10 @@ def write_node_config(c, config):
 
 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 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
-        # we're willing to use an empty directory
-    else:
-        os.mkdir(basedir)
-    f = open(os.path.join(basedir, "tahoe-client.tac"), "w")
-    f.write(client_tac)
-    f.close()
+    try:
+        create_basedir(basedir, "client", err=err)
+    except NonEmptyBasedirException:
+        return -1
 
     c = open(os.path.join(basedir, "tahoe.cfg"), "w")
 
@@ -160,7 +120,6 @@ def create_node(config, out=sys.stdout, err=sys.stderr):
 
     c.close()
 
-    from allmydata.util import fileutil
     fileutil.make_dirs(os.path.join(basedir, "private"), 0700)
     print >>out, "Node created in %s" % quote_output(basedir)
     if not config.get("introducer", ""):
@@ -177,21 +136,10 @@ def create_client(config, out=sys.stdout, err=sys.stderr):
 
 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)
-
-    if os.path.exists(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
-        # we're willing to use an empty directory
-    else:
-        os.mkdir(basedir)
-    f = open(os.path.join(basedir, "tahoe-introducer.tac"), "w")
-    f.write(introducer_tac)
-    f.close()
+    try:
+        create_basedir(basedir, "introducer", err=err)
+    except NonEmptyBasedirException:
+        return -1
 
     c = open(os.path.join(basedir, "tahoe.cfg"), "w")
     write_node_config(c, config)
diff --git a/src/allmydata/scripts/keygen.py b/src/allmydata/scripts/keygen.py
index 47069e39..cd94d80c 100644
--- a/src/allmydata/scripts/keygen.py
+++ b/src/allmydata/scripts/keygen.py
@@ -1,49 +1,21 @@
 
-import os, sys
-from allmydata.scripts.common import NoDefaultBasedirOptions
-from allmydata.util.assertutil import precondition
-from allmydata.util.encodingutil import listdir_unicode, quote_output
+import sys
+from allmydata.scripts.common import NoDefaultBasedirOptions, create_basedir, NonEmptyBasedirException
+from allmydata.util.encodingutil import quote_output
 
 
 class CreateKeyGeneratorOptions(NoDefaultBasedirOptions):
     subcommand_name = "create-key-generator"
 
 
-keygen_tac = """
-# -*- python -*-
-
-import pkg_resources
-pkg_resources.require('allmydata-tahoe')
-
-from allmydata import key_generator
-from twisted.application import service
-
-k = key_generator.KeyGeneratorService(default_key_size=2048)
-#k.key_generator.verbose = False
-#k.key_generator.pool_size = 16
-#k.key_generator.pool_refresh_delay = 6
-
-application = service.Application("allmydata_key_generator")
-k.setServiceParent(application)
-"""
-
 def create_key_generator(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 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
-        # we're willing to use an empty directory
-    else:
-        os.mkdir(basedir)
-    f = open(os.path.join(basedir, "tahoe-key-generator.tac"), "wb")
-    f.write(keygen_tac)
-    f.close()
+    try:
+        create_basedir(basedir, "key-generator", err=err)
+    except NonEmptyBasedirException:
+        return -1
+
+    print >>out, "Key generator created in %s" % quote_output(basedir)
     return 0
 
 subCommands = [
diff --git a/src/allmydata/scripts/stats_gatherer.py b/src/allmydata/scripts/stats_gatherer.py
index efe4f487..44456f6e 100644
--- a/src/allmydata/scripts/stats_gatherer.py
+++ b/src/allmydata/scripts/stats_gatherer.py
@@ -1,45 +1,21 @@
 
-import os, sys
-from allmydata.scripts.common import NoDefaultBasedirOptions
-from allmydata.util.assertutil import precondition
-from allmydata.util.encodingutil import listdir_unicode, quote_output
+import sys
+from allmydata.scripts.common import NoDefaultBasedirOptions, create_basedir, NonEmptyBasedirException
+from allmydata.util.encodingutil import quote_output
 
 
 class CreateStatsGathererOptions(NoDefaultBasedirOptions):
     subcommand_name = "create-stats-gatherer"
 
 
-stats_gatherer_tac = """
-# -*- python -*-
-
-from allmydata import stats
-from twisted.application import service
-
-verbose = True
-g = stats.StatsGathererService(verbose=verbose)
-
-application = service.Application('allmydata_stats_gatherer')
-g.setServiceParent(application)
-"""
-
-
 def create_stats_gatherer(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 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
-        # we're willing to use an empty directory
-    else:
-        os.mkdir(basedir)
-    f = open(os.path.join(basedir, "tahoe-stats-gatherer.tac"), "wb")
-    f.write(stats_gatherer_tac)
-    f.close()
+    try:
+        create_basedir(basedir, "stats-gatherer", err=err)
+    except NonEmptyBasedirException:
+        return -1
+
+    print >>out, "Stats gatherer created in %s" % quote_output(basedir)
     return 0
 
 subCommands = [
-- 
2.45.2