Merge pull request #142 from tahoe-lafs/754.location-AUTO.2

Allow combining autodetected and statically configured locations
This commit is contained in:
Daira Hopwood 2015-02-10 18:28:09 +00:00
commit 2d9af506f1
3 changed files with 66 additions and 30 deletions

View File

@ -4,7 +4,7 @@
Configuring a Tahoe-LAFS node
=============================
1. `Node Types`_
1. `Node Types`_
2. `Overall Node Configuration`_
3. `Client Configuration`_
4. `Storage Server Configuration`_
@ -159,6 +159,11 @@ set the ``tub.location`` option described below.
this when using a Tor proxy to avoid revealing your actual IP address
through the Introducer announcement.
If ``tub.location`` is specified, by default it entirely replaces the
automatically determined set of IP addresses. To include the automatically
determined addresses as well as the specified ones, include the uppercase
string "``AUTO``" in the list.
The value is a comma-separated string of host:port location hints, like
this::
@ -177,6 +182,11 @@ set the ``tub.location`` option described below.
tub.port = 8098
tub.location = tahoe.example.com:8098
* Use a DNS name but also include the default set of addresses::
tub.port = 8098
tub.location = tahoe.example.com:8098,AUTO
* Run a node behind a firewall (which has an external IP address) that
has been configured to forward port 7912 to our internal node's port
8098::

View File

@ -326,7 +326,6 @@ class Node(service.MultiService):
service.MultiService.startService(self)
d = defer.succeed(None)
d.addCallback(lambda res: iputil.get_local_addresses_async())
d.addCallback(self._setup_tub)
def _ready(res):
self.log("%s running" % self.NODETYPE)
@ -389,7 +388,7 @@ class Node(service.MultiService):
def log(self, *args, **kwargs):
return log.msg(*args, **kwargs)
def _setup_tub(self, local_addresses):
def _setup_tub(self, ign):
# we can't get a dynamically-assigned portnum until our Tub is
# running, which means after startService.
l = self.tub.getListeners()[0]
@ -398,13 +397,29 @@ class Node(service.MultiService):
# next time
fileutil.write_atomically(self._portnumfile, "%d\n" % portnum, mode="")
base_location = ",".join([ "%s:%d" % (addr, portnum)
for addr in local_addresses ])
location = self.get_config("node", "tub.location", base_location)
self.log("Tub location set to %s" % location)
self.tub.setLocation(location)
location = self.get_config("node", "tub.location", "AUTO")
return self.tub
# Replace the location "AUTO", if present, with the detected local addresses.
split_location = location.split(",")
if "AUTO" in split_location:
d = iputil.get_local_addresses_async()
def _add_local(local_addresses):
while "AUTO" in split_location:
split_location.remove("AUTO")
split_location.extend([ "%s:%d" % (addr, portnum)
for addr in local_addresses ])
return ",".join(split_location)
d.addCallback(_add_local)
else:
d = defer.succeed(location)
def _got_location(location):
self.log("Tub location set to %s" % (location,))
self.tub.setLocation(location)
return self.tub
d.addCallback(_got_location)
return d
def when_tub_ready(self):
return self._tub_ready_observerlist.when_fired()

View File

@ -9,7 +9,7 @@ from mock import patch
from foolscap.api import flushEventualQueue
from twisted.application import service
from allmydata.node import Node, formatTimeTahoeStyle, MissingConfigEntry
from allmydata.util import fileutil
from allmydata.util import fileutil, iputil
import allmydata.test.common_util as testutil
class LoggingMultiService(service.MultiService):
@ -33,44 +33,55 @@ class TestCase(testutil.SignalMixin, unittest.TestCase):
d.addCallback(flushEventualQueue)
return d
def test_location(self):
basedir = "test_node/test_location"
def _test_location(self, basedir, expected_addresses, tub_port=None, tub_location=None, local_addresses=None):
fileutil.make_dirs(basedir)
f = open(os.path.join(basedir, 'tahoe.cfg'), 'wt')
f.write("[node]\n")
f.write("tub.location = 1.2.3.4:5\n")
if tub_port:
f.write("tub.port = %d\n" % (tub_port,))
if tub_location is not None:
f.write("tub.location = %s\n" % (tub_location,))
f.close()
if local_addresses:
self.patch(iputil, 'get_local_addresses_async', lambda target=None: defer.succeed(local_addresses))
n = TestNode(basedir)
n.setServiceParent(self.parent)
d = n.when_tub_ready()
def _check_addresses(ignored_result):
furl = n.tub.registerReference(n)
self.failUnless("1.2.3.4:5" in furl, furl)
for address in expected_addresses:
self.failUnlessIn(address, furl)
d.addCallback(_check_addresses)
return d
def test_location1(self):
return self._test_location(basedir="test_node/test_location1",
expected_addresses=["192.0.2.0:1234"],
tub_location="192.0.2.0:1234")
def test_location2(self):
basedir = "test_node/test_location2"
fileutil.make_dirs(basedir)
f = open(os.path.join(basedir, 'tahoe.cfg'), 'wt')
f.write("[node]\n")
f.write("tub.location = 1.2.3.4:5,example.org:8091\n")
f.close()
return self._test_location(basedir="test_node/test_location2",
expected_addresses=["192.0.2.0:1234", "example.org:8091"],
tub_location="192.0.2.0:1234,example.org:8091")
n = TestNode(basedir)
n.setServiceParent(self.parent)
d = n.when_tub_ready()
def test_location_not_set(self):
"""Checks the autogenerated furl when tub.location is not set."""
return self._test_location(basedir="test_node/test_location3",
expected_addresses=["127.0.0.1:1234", "192.0.2.0:1234"],
tub_port=1234,
local_addresses=["127.0.0.1", "192.0.2.0"])
def _check_addresses(ignored_result):
furl = n.tub.registerReference(n)
self.failUnless("1.2.3.4:5" in furl, furl)
self.failUnless("example.org:8091" in furl, furl)
d.addCallback(_check_addresses)
return d
def test_location_auto_and_explicit(self):
"""Checks the autogenerated furl when tub.location contains 'AUTO'."""
return self._test_location(basedir="test_node/test_location4",
expected_addresses=["127.0.0.1:1234", "192.0.2.0:1234", "example.com:4321"],
tub_port=1234,
tub_location="AUTO,example.com:4321",
local_addresses=["127.0.0.1", "192.0.2.0", "example.com:4321"])
def test_tahoe_cfg_utf8(self):
basedir = "test_node/test_tahoe_cfg_utf8"