diff --git a/docs/configuration.rst b/docs/configuration.rst index 7a19ae624e..fb40e92a82 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -69,8 +69,7 @@ The item descriptions below use the following types: Node Types ========== -A node can be a client/server, an introducer, a statistics gatherer, or a -key generator. +A node can be a client/server, an introducer, or a statistics gatherer. Client/server nodes provide one or more of the following services: @@ -335,12 +334,6 @@ Client Configuration If provided, the node will attempt to connect to and use the given helper for uploads. See :doc:`helper` for details. -``key_generator.furl = (FURL string, optional)`` - - If provided, the node will attempt to connect to and use the given - key-generator service, using RSA keys from the external process rather - than generating its own. - ``stats_gatherer.furl = (FURL string, optional)`` If provided, the node will connect to the given stats gatherer and @@ -612,11 +605,6 @@ This section describes these other files. This file is used to construct an introducer, and is created by the "``tahoe create-introducer``" command. -``tahoe-key-generator.tac`` - - This file is used to construct a key generator, and is created by the - "``tahoe create-key-gernerator``" command. - ``tahoe-stats-gatherer.tac`` This file is used to construct a statistics gatherer, and is created by the diff --git a/docs/frontends/CLI.rst b/docs/frontends/CLI.rst index 30dc4db9cb..25e16bf5a0 100644 --- a/docs/frontends/CLI.rst +++ b/docs/frontends/CLI.rst @@ -105,14 +105,6 @@ This node provides introduction services and nothing else. When started, this node will produce a ``private/introducer.furl`` file, which should be published to all clients. -"``tahoe create-key-generator [NODEDIR]``" is used to create a special -"key-generation" service, which allows a client to offload their RSA key -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 web-API server) to -continue servicing other requests. The key generator exports a FURL that can -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 diff --git a/docs/man/man1/tahoe.1 b/docs/man/man1/tahoe.1 index 09ef35b6f3..aa9854bec1 100644 --- a/docs/man/man1/tahoe.1 +++ b/docs/man/man1/tahoe.1 @@ -46,9 +46,6 @@ Create a client node (with storage initially disabled). .B \f[B]create-introducer\f[] Create an introducer node. .TP -.B \f[B]create-key-generator\f[] -Create a key generator service. -.TP .B \f[B]create-stats-gatherer\f[] Create a stats-gatherer service. .SS OPTIONS diff --git a/src/allmydata/client.py b/src/allmydata/client.py index fe404d43b5..defbc5585c 100644 --- a/src/allmydata/client.py +++ b/src/allmydata/client.py @@ -58,11 +58,8 @@ class KeyGenerator: to generate(), then with a default set by set_default_keysize(), then with a built-in default of 2048 bits.""" def __init__(self): - self._remote = None self.default_keysize = 2048 - def set_remote_generator(self, keygen): - self._remote = keygen def set_default_keysize(self, keysize): """Call this to override the size of the RSA keys created for new mutable files which don't otherwise specify a size. This will affect @@ -80,20 +77,11 @@ def generate(self, keysize=None): set_default_keysize() has never been called, I will create 2048 bit keys.""" keysize = keysize or self.default_keysize - if self._remote: - d = self._remote.callRemote('get_rsa_key_pair', keysize) - def make_key_objs((verifying_key, signing_key)): - v = rsa.create_verifying_key_from_string(verifying_key) - s = rsa.create_signing_key_from_string(signing_key) - return v, s - d.addCallback(make_key_objs) - return d - else: - # RSA key generation for a 2048 bit key takes between 0.8 and 3.2 - # secs - signer = rsa.generate(keysize) - verifier = signer.get_verifying_key() - return defer.succeed( (verifier, signer) ) + # RSA key generation for a 2048 bit key takes between 0.8 and 3.2 + # secs + signer = rsa.generate(keysize) + verifier = signer.get_verifying_key() + return defer.succeed( (verifier, signer) ) class Terminator(service.Service): def __init__(self): @@ -145,7 +133,7 @@ def __init__(self, basedir="."): self._key_generator = KeyGenerator() key_gen_furl = self.get_config("client", "key_generator.furl", None) if key_gen_furl: - self.init_key_gen(key_gen_furl) + log.msg("[client]key_generator.furl= is now ignored, see #2783") self.init_client() self.helper = None if self.get_config("helper", "enabled", False, boolean=True): @@ -442,16 +430,6 @@ def init_helper(self): "private", "helper.furl").encode(get_filesystem_encoding()) self.tub.registerReference(self.helper, furlFile=helper_furlfile) - def init_key_gen(self, key_gen_furl): - self.tub.connectTo(key_gen_furl, self._got_key_generator) - - def _got_key_generator(self, key_generator): - self._key_generator.set_remote_generator(key_generator) - key_generator.notifyOnDisconnect(self._lost_key_generator) - - def _lost_key_generator(self): - self._key_generator.set_remote_generator(None) - def set_default_mutable_keysize(self, keysize): self._key_generator.set_default_keysize(keysize) diff --git a/src/allmydata/interfaces.py b/src/allmydata/interfaces.py index 23e879532c..6a9c352cb0 100644 --- a/src/allmydata/interfaces.py +++ b/src/allmydata/interfaces.py @@ -2808,20 +2808,6 @@ def get_stats(): to be monitored, and numeric values. """ -class RIKeyGenerator(RemoteInterface): - __remote_name__ = "RIKeyGenerator.tahoe.allmydata.com" - """ - Provides a service offering to make RSA key pairs. - """ - - def get_rsa_key_pair(key_size=int): - """ - @param key_size: the size of the signature key. - @return: tuple(verifying_key, signing_key) - """ - return TupleOf(str, str) - - class FileTooLargeError(Exception): pass diff --git a/src/allmydata/key_generator.py b/src/allmydata/key_generator.py deleted file mode 100644 index 63bf51b833..0000000000 --- a/src/allmydata/key_generator.py +++ /dev/null @@ -1,111 +0,0 @@ - -import os -import time - -from foolscap.api import Referenceable, Tub -from zope.interface import implements -from twisted.internet import reactor -from twisted.application import service -from allmydata.util import log, fileutil - -from pycryptopp.publickey import rsa -from allmydata.interfaces import RIKeyGenerator - -class KeyGenerator(service.MultiService, Referenceable): - implements(RIKeyGenerator) - - pool_size = 16 # no. keys to keep on hand in the pool - pool_refresh_delay = 6 # no. sec to wait after a fetch before generating new keys - verbose = False - - def __init__(self, default_key_size=2048): - service.MultiService.__init__(self) - self.keypool = [] - self.last_fetch = 0 - self.default_key_size = default_key_size - - def startService(self): - self.timer = reactor.callLater(0, self.maybe_refill_pool) - return service.MultiService.startService(self) - - def stopService(self): - if self.timer.active(): - self.timer.cancel() - return service.MultiService.stopService(self) - - def __repr__(self): - return '' % (len(self.keypool),) - - def vlog(self, msg): - if self.verbose: - log.msg(msg) - - def reset_timer(self): - self.last_fetch = time.time() - if self.timer.active(): - self.timer.reset(self.pool_refresh_delay) - else: - self.timer = reactor.callLater(self.pool_refresh_delay, self.maybe_refill_pool) - - def maybe_refill_pool(self): - now = time.time() - if self.last_fetch + self.pool_refresh_delay < now: - self.vlog('%s refilling pool' % (self,)) - while len(self.keypool) < self.pool_size: - self.keypool.append(self.gen_key(self.default_key_size)) - else: - self.vlog('%s not refilling pool' % (self,)) - reactor.callLater(1, self.maybe_refill_pool) - - def gen_key(self, key_size): - self.vlog('%s generating key size %s' % (self, key_size, )) - signer = rsa.generate(key_size) - verifier = signer.get_verifying_key() - return verifier.serialize(), signer.serialize() - - def remote_get_rsa_key_pair(self, key_size): - self.vlog('%s remote_get_key' % (self,)) - if key_size != self.default_key_size or not self.keypool: - key = self.gen_key(key_size) - self.reset_timer() - return key - else: - self.reset_timer() - return self.keypool.pop() - -class KeyGeneratorService(service.MultiService): - furl_file = 'key_generator.furl' - - def __init__(self, basedir='.', display_furl=True, default_key_size=2048): - service.MultiService.__init__(self) - self.basedir = basedir - fileutil.make_dirs(self.basedir) - self.tub = Tub(certFile=os.path.join(self.basedir, 'key_generator.pem')) - self.tub.setOption("expose-remote-exception-types", False) - self.tub.setServiceParent(self) - self.key_generator = KeyGenerator(default_key_size=default_key_size) - self.key_generator.setServiceParent(self) - - portnum = self.get_portnum() - self.listener = self.tub.listenOn(portnum or 'tcp:0') - d = self.tub.setLocationAutomatically() - if portnum is None: - d.addCallback(self.save_portnum) - d.addCallback(self.tub_ready, display_furl) - d.addErrback(log.err) - - def get_portnum(self): - portnumfile = os.path.join(self.basedir, 'portnum') - if os.path.exists(portnumfile): - return file(portnumfile, 'rb').read().strip() - - def save_portnum(self, junk): - portnum = self.listener.getPortnum() - portnumfile = os.path.join(self.basedir, 'portnum') - file(portnumfile, 'wb').write('%d\n' % (portnum,)) - - def tub_ready(self, junk, display_furl): - kgf = os.path.join(self.basedir, self.furl_file) - self.keygen_furl = self.tub.registerReference(self.key_generator, furlFile=kgf) - if display_furl: - print 'key generator at:', self.keygen_furl diff --git a/src/allmydata/scripts/create_node.py b/src/allmydata/scripts/create_node.py index 461f03deaf..1c7f1f0f17 100644 --- a/src/allmydata/scripts/create_node.py +++ b/src/allmydata/scripts/create_node.py @@ -109,7 +109,6 @@ def create_node(config, out=sys.stdout, err=sys.stderr): 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("# Encoding parameters this client will use for newly-uploaded files\n") diff --git a/src/allmydata/scripts/keygen.py b/src/allmydata/scripts/keygen.py deleted file mode 100644 index 9a6383dbd5..0000000000 --- a/src/allmydata/scripts/keygen.py +++ /dev/null @@ -1,38 +0,0 @@ - -import os, sys - -from allmydata.scripts.common import NoDefaultBasedirOptions -from allmydata.scripts.create_node import write_tac -from allmydata.util.assertutil import precondition -from allmydata.util.encodingutil import listdir_unicode, quote_output - - -class CreateKeyGeneratorOptions(NoDefaultBasedirOptions): - subcommand_name = "create-key-generator" - - -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) - write_tac(basedir, "key-generator") - return 0 - -subCommands = [ - ["create-key-generator", None, CreateKeyGeneratorOptions, "Create a key generator service."], -] - -dispatch = { - "create-key-generator": create_key_generator, - } - diff --git a/src/allmydata/scripts/runner.py b/src/allmydata/scripts/runner.py index f6f167fcd0..c5c6da19b0 100644 --- a/src/allmydata/scripts/runner.py +++ b/src/allmydata/scripts/runner.py @@ -5,7 +5,7 @@ from twisted.python import usage from allmydata.scripts.common import get_default_nodedir -from allmydata.scripts import debug, create_node, startstop_node, cli, keygen, stats_gatherer, admin +from allmydata.scripts import debug, create_node, startstop_node, cli, stats_gatherer, admin from allmydata.util.encodingutil import quote_output, quote_local_unicode_path, get_io_encoding def GROUP(s): @@ -36,7 +36,6 @@ class Options(usage.Options): synopsis = "\nUsage: tahoe [command options]" subCommands = ( GROUP("Administration") + create_node.subCommands - + keygen.subCommands + stats_gatherer.subCommands + admin.subCommands + GROUP("Controlling a node") @@ -85,7 +84,7 @@ def postOptions(self): create_dispatch = {} -for module in (create_node, keygen, stats_gatherer): +for module in (create_node, stats_gatherer): create_dispatch.update(module.dispatch) def runner(argv, diff --git a/src/allmydata/scripts/startstop_node.py b/src/allmydata/scripts/startstop_node.py index e3b2e72c44..761984e0f2 100644 --- a/src/allmydata/scripts/startstop_node.py +++ b/src/allmydata/scripts/startstop_node.py @@ -80,8 +80,7 @@ def makeService(self, so): from allmydata.introducer.server import IntroducerNode return IntroducerNode(self.basedir) if self.nodetype == "key-generator": - from allmydata.key_generator import KeyGeneratorService - return KeyGeneratorService(default_key_size=2048) + raise ValueError("key-generator support removed, see #2783") if self.nodetype == "stats-gatherer": from allmydata.stats import StatsGathererService return StatsGathererService(verbose=True) diff --git a/src/allmydata/test/common.py b/src/allmydata/test/common.py index e9f521e428..6c291d3503 100644 --- a/src/allmydata/test/common.py +++ b/src/allmydata/test/common.py @@ -22,7 +22,6 @@ from allmydata.util.assertutil import precondition from allmydata.util.consumer import download_to_data from allmydata.stats import StatsGathererService -from allmydata.key_generator import KeyGeneratorService import allmydata.test.common_util as testutil from allmydata import immutable @@ -448,8 +447,6 @@ def setUp(self): self.stats_gatherer = None self.stats_gatherer_furl = None - self.key_generator_svc = None - self.key_generator_furl = None def tearDown(self): log.msg("shutting down SystemTest services") @@ -464,8 +461,7 @@ def add_service(self, s): s.setServiceParent(self.sparent) return s - def set_up_nodes(self, NUMCLIENTS=5, - use_stats_gatherer=False, use_key_generator=False): + def set_up_nodes(self, NUMCLIENTS=5, use_stats_gatherer=False): self.numclients = NUMCLIENTS iv_dir = self.getdir("introducer") if not os.path.isdir(iv_dir): @@ -485,8 +481,6 @@ def set_up_nodes(self, NUMCLIENTS=5, d = defer.succeed(None) if use_stats_gatherer: d.addCallback(self._set_up_stats_gatherer) - if use_key_generator: - d.addCallback(self._set_up_key_generator) d.addCallback(self._set_up_nodes_2) if use_stats_gatherer: d.addCallback(self._grab_stats) @@ -514,27 +508,6 @@ def get_furl(junk): d.addCallback(get_furl) return d - def _set_up_key_generator(self, res): - kgsdir = self.getdir("key_generator") - fileutil.make_dirs(kgsdir) - - self.key_generator_svc = KeyGeneratorService(kgsdir, - display_furl=False, - default_key_size=TEST_RSA_KEY_SIZE) - self.key_generator_svc.key_generator.pool_size = 4 - self.key_generator_svc.key_generator.pool_refresh_delay = 60 - self.add_service(self.key_generator_svc) - - d = fireEventually() - def check_for_furl(): - return os.path.exists(os.path.join(kgsdir, 'key_generator.furl')) - d.addCallback(lambda junk: self.poll(check_for_furl, timeout=30)) - def get_furl(junk): - kgf = os.path.join(kgsdir, 'key_generator.furl') - self.key_generator_furl = file(kgf, 'rb').read().strip() - d.addCallback(get_furl) - return d - def _set_up_nodes_2(self, res): q = self.introducer self.introducer_furl = q.introducer_url @@ -563,17 +536,14 @@ def _set_up_nodes_2(self, res): nodeconfig += "tub.location = tcp:127.0.0.1:%d\n" % tub_port if i == 0: - # clients[0] runs a webserver and a helper, no key_generator + # clients[0] runs a webserver and a helper config += nodeconfig config += "web.port = tcp:0:interface=127.0.0.1\n" config += "timeout.keepalive = 600\n" config += "[helper]\n" config += "enabled = True\n" elif i == 3: - # clients[3] runs a webserver and uses a helper, uses - # key_generator - if self.key_generator_furl: - config += "key_generator.furl = %s\n" % self.key_generator_furl + # clients[3] runs a webserver and uses a helper config += nodeconfig config += "web.port = tcp:0:interface=127.0.0.1\n" config += "timeout.disconnect = 1800\n" diff --git a/src/allmydata/test/no_network.py b/src/allmydata/test/no_network.py index 137acae190..cf2a0b75ed 100644 --- a/src/allmydata/test/no_network.py +++ b/src/allmydata/test/no_network.py @@ -10,8 +10,8 @@ # This should be useful for tests which want to examine and/or manipulate the # uploaded shares, checker/verifier/repairer tests, etc. The clients have no -# Tubs, so it is not useful for tests that involve a Helper, a KeyGenerator, -# or the control.furl . +# Tubs, so it is not useful for tests that involve a Helper or the +# control.furl . import os from zope.interface import implements diff --git a/src/allmydata/test/test_cli.py b/src/allmydata/test/test_cli.py index 789e177d15..42ae11dda7 100644 --- a/src/allmydata/test/test_cli.py +++ b/src/allmydata/test/test_cli.py @@ -17,10 +17,10 @@ from pycryptopp.publickey import ed25519 # Test that the scripts can be imported. -from allmydata.scripts import create_node, debug, keygen, startstop_node, \ +from allmydata.scripts import create_node, debug, startstop_node, \ tahoe_add_alias, tahoe_backup, tahoe_check, tahoe_cp, tahoe_get, tahoe_ls, \ tahoe_manifest, tahoe_mkdir, tahoe_mv, tahoe_put, tahoe_unlink, tahoe_webopen -_hush_pyflakes = [create_node, debug, keygen, startstop_node, +_hush_pyflakes = [create_node, debug, startstop_node, tahoe_add_alias, tahoe_backup, tahoe_check, tahoe_cp, tahoe_get, tahoe_ls, tahoe_manifest, tahoe_mkdir, tahoe_mv, tahoe_put, tahoe_unlink, tahoe_webopen] diff --git a/src/allmydata/test/test_keygen.py b/src/allmydata/test/test_keygen.py deleted file mode 100644 index 71d7eafd95..0000000000 --- a/src/allmydata/test/test_keygen.py +++ /dev/null @@ -1,100 +0,0 @@ - -import os -from twisted.trial import unittest -from twisted.application import service - -from foolscap.api import Tub, fireEventually, flushEventualQueue - -from allmydata import key_generator -from allmydata.util import pollmixin -from allmydata.test.common import TEST_RSA_KEY_SIZE -from pycryptopp.publickey import rsa - -def flush_but_dont_ignore(res): - d = flushEventualQueue() - def _done(ignored): - return res - d.addCallback(_done) - return d - -class KeyGenService(unittest.TestCase, pollmixin.PollMixin): - def setUp(self): - self.parent = service.MultiService() - self.parent.startService() - - self.tub = t = Tub() - t.setOption("expose-remote-exception-types", False) - t.setServiceParent(self.parent) - t.listenOn("tcp:0") - t.setLocationAutomatically() - return fireEventually() - - def tearDown(self): - d = self.parent.stopService() - d.addCallback(fireEventually) - d.addBoth(flush_but_dont_ignore) - return d - - def test_key_gen_service(self): - def p(junk, msg): - #import time - #print time.asctime(), msg - return junk - - #print 'starting key generator service' - keysize = TEST_RSA_KEY_SIZE - kgs = key_generator.KeyGeneratorService(display_furl=False, default_key_size=keysize, basedir="key_generator_service") - kgs.key_generator.verbose = True - kgs.setServiceParent(self.parent) - kgs.key_generator.pool_size = 8 - - def keypool_full(): - return len(kgs.key_generator.keypool) == kgs.key_generator.pool_size - - # first wait for key gen pool to fill up - d = fireEventually() - d.addCallback(p, 'waiting for pool to fill up') - d.addCallback(lambda junk: self.poll(keypool_full)) - - d.addCallback(p, 'grabbing a few keys') - # grab a few keys, check that pool size shrinks - def get_key(junk=None): - d = self.tub.getReference(kgs.keygen_furl) - d.addCallback(lambda kg: kg.callRemote('get_rsa_key_pair', keysize)) - return d - - def check_poolsize(junk, size): - self.failUnlessEqual(len(kgs.key_generator.keypool), size) - - n_keys_to_waste = 4 - for i in range(n_keys_to_waste): - d.addCallback(get_key) - d.addCallback(check_poolsize, kgs.key_generator.pool_size - n_keys_to_waste) - - d.addCallback(p, 'checking a key works') - # check that a retrieved key is actually useful - d.addCallback(get_key) - def check_key_works(keys): - verifying_key, signing_key = keys - v = rsa.create_verifying_key_from_string(verifying_key) - s = rsa.create_signing_key_from_string(signing_key) - junk = os.urandom(42) - sig = s.sign(junk) - self.failUnless(v.verify(junk, sig)) - d.addCallback(check_key_works) - - d.addCallback(p, 'checking pool exhaustion') - # exhaust the pool - for i in range(kgs.key_generator.pool_size): - d.addCallback(get_key) - d.addCallback(check_poolsize, 0) - - # and check it still works (will gen key synchronously on demand) - d.addCallback(get_key) - d.addCallback(check_key_works) - - d.addCallback(p, 'checking pool replenishment') - # check that the pool will refill - d.addCallback(lambda junk: self.poll(keypool_full)) - - return d diff --git a/src/allmydata/test/test_runner.py b/src/allmydata/test/test_runner.py index 4b872a6184..26ee369c0c 100644 --- a/src/allmydata/test/test_runner.py +++ b/src/allmydata/test/test_runner.py @@ -281,9 +281,6 @@ def test_client(self): def test_introducer(self): self.do_create("introducer") - def test_key_generator(self): - self.do_create("key-generator") - def test_stats_gatherer(self): self.do_create("stats-gatherer") @@ -651,83 +648,3 @@ def _cb3(res): self.failUnlessIn("does not look like a directory at all", err) d.addCallback(_cb3) return d - - def test_keygen(self): - self.skip_if_cannot_daemonize() - - basedir = self.workdir("test_keygen") - c1 = os.path.join(basedir, "c1") - twistd_pid_file = os.path.join(c1, "twistd.pid") - keygen_furl_file = os.path.join(c1, "key_generator.furl") - - d = self.run_bintahoe(["--quiet", "create-key-generator", "--basedir", c1]) - def _cb(res): - out, err, rc_or_sig = res - self.failUnlessEqual(rc_or_sig, 0) - d.addCallback(_cb) - - def _start(res): - return self.run_bintahoe(["--quiet", "start", c1]) - d.addCallback(_start) - - def _cb2(res): - out, err, rc_or_sig = res - errstr = "rc=%d, OUT: '%s', ERR: '%s'" % (rc_or_sig, out, err) - self.failUnlessEqual(rc_or_sig, 0, errstr) - self.failUnlessEqual(out, "", errstr) - # self.failUnlessEqual(err, "", errstr) # See test_client_no_noise -- for now we ignore noise. - - # the parent (twistd) has exited. However, twistd writes the pid - # from the child, not the parent, so we can't expect twistd.pid - # to exist quite yet. - - # the node is running, but it might not have made it past the - # first reactor turn yet, and if we kill it too early, it won't - # remove the twistd.pid file. So wait until it does something - # that we know it won't do until after the first turn. - d.addCallback(_cb2) - - def _node_has_started(): - return os.path.exists(keygen_furl_file) - d.addCallback(lambda res: self.poll(_node_has_started)) - - def _started(res): - self.failUnless(os.path.exists(twistd_pid_file)) - # rm this so we can detect when the second incarnation is ready - os.unlink(keygen_furl_file) - return self.run_bintahoe(["--quiet", "restart", c1]) - d.addCallback(_started) - - def _cb3(res): - out, err, rc_or_sig = res - errstr = "rc=%d, OUT: '%s', ERR: '%s'" % (rc_or_sig, out, err) - self.failUnlessEqual(rc_or_sig, 0, errstr) - self.failUnlessEqual(out, "", errstr) - # self.failUnlessEqual(err, "", errstr) # See test_client_no_noise -- for now we ignore noise. - d.addCallback(_cb3) - - # again, the second incarnation of the node might not be ready yet, - # so poll until it is - d.addCallback(lambda res: self.poll(_node_has_started)) - - # now we can kill it. TODO: On a slow machine, the node might kill - # itself before we get a chance too, especially if spawning the - # 'tahoe stop' command takes a while. - def _stop(res): - self.failUnless(os.path.exists(twistd_pid_file)) - return self.run_bintahoe(["--quiet", "stop", c1]) - d.addCallback(_stop) - - def _cb4(res): - out, err, rc_or_sig = res - # the parent has exited by now - errstr = "rc=%d, OUT: '%s', ERR: '%s'" % (rc_or_sig, out, err) - self.failUnlessEqual(rc_or_sig, 0, errstr) - self.failUnlessEqual(out, "", errstr) - # self.failUnlessEqual(err, "", errstr) # See test_client_no_noise -- for now we ignore noise. - # the parent was supposed to poll and wait until it sees - # twistd.pid go away before it exits, so twistd.pid should be - # gone by now. - self.failIf(os.path.exists(twistd_pid_file)) - d.addCallback(_cb4) - return d diff --git a/src/allmydata/test/test_system.py b/src/allmydata/test/test_system.py index cfd592aa8c..e039b4aac7 100644 --- a/src/allmydata/test/test_system.py +++ b/src/allmydata/test/test_system.py @@ -475,7 +475,7 @@ def test_mutable(self): NEWERDATA = "this is getting old" NEWERDATA_uploadable = MutableData(NEWERDATA) - d = self.set_up_nodes(use_key_generator=True) + d = self.set_up_nodes() def _create_mutable(res): c = self.clients[0] @@ -673,25 +673,6 @@ def _created_dirnode(dnode): return d1 d.addCallback(_created_dirnode) - def wait_for_c3_kg_conn(): - return self.clients[3]._key_generator is not None - d.addCallback(lambda junk: self.poll(wait_for_c3_kg_conn)) - - def check_kg_poolsize(junk, size_delta): - self.failUnlessEqual(len(self.key_generator_svc.key_generator.keypool), - self.key_generator_svc.key_generator.pool_size + size_delta) - - d.addCallback(check_kg_poolsize, 0) - d.addCallback(lambda junk: - self.clients[3].create_mutable_file(MutableData('hello, world'))) - d.addCallback(check_kg_poolsize, -1) - d.addCallback(lambda junk: self.clients[3].create_dirnode()) - d.addCallback(check_kg_poolsize, -2) - # use_helper induces use of clients[3], which is the using-key_gen client - d.addCallback(lambda junk: - self.POST("uri?t=mkdir&name=george", use_helper=True)) - d.addCallback(check_kg_poolsize, -3) - return d def flip_bit(self, good): diff --git a/topfiles/2783.docs b/topfiles/2783.docs new file mode 100644 index 0000000000..51a0acf632 --- /dev/null +++ b/topfiles/2783.docs @@ -0,0 +1,10 @@ +The "key-generator" node type has been removed. This was a standalone process +that maintained a queue of RSA keys. Clients could offload the key-generation +work by adding "key_generator.furl=" in their tahoe.cfg files, to create +mutable files and directories faster. This seemed important back in 2006, but +these days computers are faster and RSA key generation only takes about 90ms. + +This removes the "tahoe create-key-generator" command. Any +"key_generator.furl" settings in tahoe.cfg will log a warning and otherwise +ignored. Attempts to "tahoe start" a previously-generated key-generator node +will result in an error.