upgrade create_introducer

This commit is contained in:
meejah
2018-01-27 23:13:50 -07:00
parent 4f2d45626c
commit 71484b4a12
4 changed files with 63 additions and 23 deletions

View File

@ -254,8 +254,8 @@ class _Client(node.Node, pollmixin.PollMixin):
"max_segment_size": 128*KiB, "max_segment_size": 128*KiB,
} }
def __init__(self, config, main_tub, control_tub, i2p_provider, tor_provider, basedir, tub_is_listening): def __init__(self, config, main_tub, control_tub, i2p_provider, tor_provider, tub_is_listening):
node.Node.__init__(self, config, main_tub, control_tub, i2p_provider, tor_provider, basedir, tub_is_listening) node.Node.__init__(self, config, main_tub, control_tub, i2p_provider, tor_provider, tub_is_listening)
# All tub.registerReference must happen *after* we upcall, since # All tub.registerReference must happen *after* we upcall, since
# that's what does tub.setLocation() # that's what does tub.setLocation()
self._magic_folders = dict() self._magic_folders = dict()

View File

@ -2,6 +2,7 @@
import time, os.path, textwrap import time, os.path, textwrap
from zope.interface import implementer from zope.interface import implementer
from twisted.application import service from twisted.application import service
from twisted.internet import defer
from foolscap.api import Referenceable from foolscap.api import Referenceable
import allmydata import allmydata
from allmydata import node from allmydata import node
@ -27,29 +28,55 @@ def _valid_config_sections():
class FurlFileConflictError(Exception): class FurlFileConflictError(Exception):
pass pass
# this is/can-be async
# @defer.inlineCallbacks # @defer.inlineCallbacks
def create_introducer(basedir=u"."): def create_introducer(basedir=u"."):
from allmydata import node # ideally we would pass in reactor
if not os.path.exists(basedir): from twisted.internet import reactor
node.create_node_dir(basedir, INTRODUCER_README) from allmydata.node import read_config, create_connection_handlers
from allmydata.node import create_control_tub
from allmydata.node import create_tub_options, create_main_tub, PRIV_README
from allmydata.node import create_node_dir
config = node.read_config( if not os.path.exists(basedir):
create_node_dir(basedir, INTRODUCER_README)
config = read_config(
basedir, u"client.port", basedir, u"client.port",
generated_files=["introducer.furl"], generated_files=["introducer.furl"],
_valid_config_sections=_valid_config_sections, _valid_config_sections=_valid_config_sections,
) )
#defer.returnValue(
return _IntroducerNode( default_connection_handlers, foolscap_connection_handlers = create_connection_handlers(reactor, basedir, config)
config, tub_options = create_tub_options(config)
i2p_provider = None
tor_provider = None
main_tub, is_listening = create_main_tub(
basedir, config, tub_options, default_connection_handlers,
foolscap_connection_handlers,
)
control_tub = create_control_tub()
return defer.succeed(
_IntroducerNode(
config,
main_tub,
control_tub,
i2p_provider,
tor_provider,
basedir,
tub_is_listening=is_listening,
)
) )
#)
class _IntroducerNode(node.Node): class _IntroducerNode(node.Node):
NODETYPE = "introducer" NODETYPE = "introducer"
def __init__(self, config): def __init__(self, config, main_tub, control_tub, i2p_provider, tor_provider, tub_is_listening):
node.Node.__init__(self, config) node.Node.__init__(self, config, main_tub, control_tub, i2p_provider, tor_provider, tub_is_listening)
self.init_introducer() self.init_introducer()
webport = self.get_config("node", "web.port", None) webport = self.get_config("node", "web.port", None)
if webport: if webport:

View File

@ -75,6 +75,14 @@ for thing, things_version in get_package_versions().iteritems():
# group 1 will be addr (dotted quad string), group 3 if any will be portnum (string) # group 1 will be addr (dotted quad string), group 3 if any will be portnum (string)
ADDR_RE = re.compile("^([1-9][0-9]*\.[1-9][0-9]*\.[1-9][0-9]*\.[1-9][0-9]*)(:([1-9][0-9]*))?$") ADDR_RE = re.compile("^([1-9][0-9]*\.[1-9][0-9]*\.[1-9][0-9]*\.[1-9][0-9]*)(:([1-9][0-9]*))?$")
# this is put into README in new node-directories (for client and introducers)
PRIV_README = """
This directory contains files which contain private data for the Tahoe node,
such as private keys. On Unix-like systems, the permissions on this directory
are set to disallow users other than its owner from reading the contents of
the files. See the 'configuration.rst' documentation file for details.
"""
def formatTimeTahoeStyle(self, when): def formatTimeTahoeStyle(self, when):
""" """
@ -451,7 +459,7 @@ def _make_i2p_handler(i2p_provider):
return i2p_provider.get_i2p_handler() return i2p_provider.get_i2p_handler()
def create_connection_handlers(reactor, basedir, config): def create_connection_handlers(reactor, config):
""" """
:returns: 2-tuple of default_connection_handlers, foolscap_connection_handlers :returns: 2-tuple of default_connection_handlers, foolscap_connection_handlers
""" """
@ -678,7 +686,7 @@ class Node(service.MultiService):
CERTFILE = "node.pem" CERTFILE = "node.pem"
GENERATED_FILES = [] GENERATED_FILES = []
def __init__(self, config, main_tub, control_tub, i2p_provider, tor_provider, basedir, tub_is_listening): def __init__(self, config, main_tub, control_tub, i2p_provider, tor_provider, tub_is_listening):
""" """
Initialize the node with the given configuration. Its base directory Initialize the node with the given configuration. Its base directory
is the current directory by default. is the current directory by default.

View File

@ -41,21 +41,23 @@ class Node(testutil.SignalMixin, testutil.ReallyEqualMixin, unittest.TestCase):
from allmydata.introducer import IntroducerNode from allmydata.introducer import IntroducerNode
IntroducerNode # pyflakes IntroducerNode # pyflakes
@defer.inlineCallbacks
def test_create(self): def test_create(self):
""" """
A brand new introducer creates its config dir A brand new introducer creates its config dir
""" """
basedir = "introducer.IntroducerNode.test_create" basedir = "introducer.IntroducerNode.test_create"
create_introducer(basedir) yield create_introducer(basedir)
self.assertTrue(os.path.exists(basedir)) self.assertTrue(os.path.exists(basedir))
@defer.inlineCallbacks
def test_furl(self): def test_furl(self):
basedir = "introducer.IntroducerNode.test_furl" basedir = "introducer.IntroducerNode.test_furl"
create_node_dir(basedir, "testing") create_node_dir(basedir, "testing")
public_fn = os.path.join(basedir, "introducer.furl") public_fn = os.path.join(basedir, "introducer.furl")
private_fn = os.path.join(basedir, "private", "introducer.furl") private_fn = os.path.join(basedir, "private", "introducer.furl")
q1 = create_introducer(basedir) q1 = yield create_introducer(basedir)
del q1 del q1
# new nodes create unguessable furls in private/introducer.furl # new nodes create unguessable furls in private/introducer.furl
ifurl = fileutil.read(private_fn) ifurl = fileutil.read(private_fn)
@ -68,20 +70,21 @@ class Node(testutil.SignalMixin, testutil.ReallyEqualMixin, unittest.TestCase):
fileutil.write(public_fn, guessable+"\n", mode="w") # text fileutil.write(public_fn, guessable+"\n", mode="w") # text
# if we see both files, throw an error # if we see both files, throw an error
self.failUnlessRaises(FurlFileConflictError, with self.assertRaises(FurlFileConflictError):
create_introducer, basedir) yield create_introducer(basedir)
# when we see only the public one, move it to private/ and use # when we see only the public one, move it to private/ and use
# the existing furl instead of creating a new one # the existing furl instead of creating a new one
os.unlink(private_fn) os.unlink(private_fn)
q2 = create_introducer(basedir) q2 = yield create_introducer(basedir)
del q2 del q2
self.failIf(os.path.exists(public_fn)) self.failIf(os.path.exists(public_fn))
ifurl2 = fileutil.read(private_fn) ifurl2 = fileutil.read(private_fn)
self.failUnless(ifurl2) self.failUnless(ifurl2)
self.failUnlessEqual(ifurl2.strip(), guessable) self.failUnlessEqual(ifurl2.strip(), guessable)
@defer.inlineCallbacks
def test_web_static(self): def test_web_static(self):
basedir = u"introducer.Node.test_web_static" basedir = u"introducer.Node.test_web_static"
create_node_dir(basedir, "testing") create_node_dir(basedir, "testing")
@ -89,7 +92,7 @@ class Node(testutil.SignalMixin, testutil.ReallyEqualMixin, unittest.TestCase):
"[node]\n" + "[node]\n" +
"web.port = tcp:0:interface=127.0.0.1\n" + "web.port = tcp:0:interface=127.0.0.1\n" +
"web.static = relative\n") "web.static = relative\n")
c = create_introducer(basedir) c = yield create_introducer(basedir)
w = c.getServiceNamed("webish") w = c.getServiceNamed("webish")
abs_basedir = fileutil.abspath_expanduser_unicode(basedir) abs_basedir = fileutil.abspath_expanduser_unicode(basedir)
expected = fileutil.abspath_expanduser_unicode(u"relative", abs_basedir) expected = fileutil.abspath_expanduser_unicode(u"relative", abs_basedir)
@ -812,7 +815,7 @@ class Announcements(unittest.TestCase):
f.write("enabled = false\n") f.write("enabled = false\n")
f.close() f.close()
c = create_client(basedir) c = yield create_client(basedir)
ic = c.introducer_clients[0] ic = c.introducer_clients[0]
sk_s, vk_s = keyutil.make_keypair() sk_s, vk_s = keyutil.make_keypair()
sk, _ignored = keyutil.parse_privkey(sk_s) sk, _ignored = keyutil.parse_privkey(sk_s)
@ -880,13 +883,15 @@ class Announcements(unittest.TestCase):
self.failUnlessEqual(announcements[pub2]["anonymous-storage-FURL"], self.failUnlessEqual(announcements[pub2]["anonymous-storage-FURL"],
furl3) furl3)
c2 = create_client(basedir) c2 = yield create_client(basedir)
c2.introducer_clients[0]._load_announcements() c2.introducer_clients[0]._load_announcements()
yield flushEventualQueue() yield flushEventualQueue()
self.assertEqual(c2.storage_broker.get_all_serverids(), self.assertEqual(c2.storage_broker.get_all_serverids(),
frozenset([pub1, pub2])) frozenset([pub1, pub2]))
class ClientSeqnums(unittest.TestCase): class ClientSeqnums(unittest.TestCase):
@defer.inlineCallbacks
def test_client(self): def test_client(self):
basedir = "introducer/ClientSeqnums/test_client" basedir = "introducer/ClientSeqnums/test_client"
fileutil.make_dirs(basedir) fileutil.make_dirs(basedir)
@ -901,7 +906,7 @@ class ClientSeqnums(unittest.TestCase):
f.write("enabled = false\n") f.write("enabled = false\n")
f.close() f.close()
c = create_client(basedir) c = yield create_client(basedir)
ic = c.introducer_clients[0] ic = c.introducer_clients[0]
outbound = ic._outbound_announcements outbound = ic._outbound_announcements
published = ic._published_announcements published = ic._published_announcements