mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2025-02-21 02:01:31 +00:00
Add create node args: listen, port, hostname, location
fixes ticket: 2773
This commit is contained in:
parent
2a44a8e8cc
commit
83db7e8b43
@ -1,9 +1,10 @@
|
||||
import os
|
||||
from twisted.python import usage
|
||||
from allmydata.scripts.common import BasedirOptions, NoDefaultBasedirOptions
|
||||
from allmydata.scripts.default_nodedir import _default_nodedir
|
||||
from allmydata.util.assertutil import precondition
|
||||
from allmydata.util.encodingutil import listdir_unicode, argv_to_unicode, quote_local_unicode_path
|
||||
from allmydata.util import fileutil
|
||||
from allmydata.util import fileutil, iputil
|
||||
|
||||
|
||||
dummy_tac = """
|
||||
@ -17,10 +18,38 @@ def write_tac(basedir, nodetype):
|
||||
fileutil.write(os.path.join(basedir, "tahoe-%s.tac" % (nodetype,)), dummy_tac)
|
||||
|
||||
|
||||
WHERE_OPTS = [
|
||||
("location", None, None, "Specify the location to advertise for this node."),
|
||||
("port", None, None, "Specify the server endpoint to listen on for this node."),
|
||||
]
|
||||
|
||||
def validate_where_options(options):
|
||||
if options['hostname'] and options['port']:
|
||||
raise usage.UsageError("The --hostname option cannot be used with the --port option.")
|
||||
if options['hostname'] and options['location']:
|
||||
raise usage.UsageError("The --hostname option cannot be used with the --location option.")
|
||||
if not options['hostname'] and (options['location'] and not options['port']):
|
||||
raise usage.UsageError("The --location option must be used with the --port option.")
|
||||
if not options['hostname'] and (options['port'] and not options['location']):
|
||||
raise usage.UsageError("The --port option must be used with the --location option.")
|
||||
if (options['listen'] != "tcp") and options['hostname']:
|
||||
raise usage.UsageError("The listener type must be TCP to use --hostname option.")
|
||||
|
||||
class _CreateBaseOptions(BasedirOptions):
|
||||
optFlags = [
|
||||
("hide-ip", None, "prohibit any configuration that would reveal the node's IP address"),
|
||||
]
|
||||
|
||||
# This is overridden in order to ensure we get a "Wrong number of
|
||||
# arguments." error when more than one argument is given.
|
||||
def parseArgs(self, basedir=None):
|
||||
BasedirOptions.parseArgs(self, basedir)
|
||||
|
||||
|
||||
class CreateClientOptions(_CreateBaseOptions):
|
||||
synopsis = "[options] [NODEDIR]"
|
||||
description = "Create a client-only Tahoe-LAFS node (no storage server)."
|
||||
|
||||
optParameters = [
|
||||
# we provide 'create-node'-time options for the most common
|
||||
# configuration knobs. The rest can be controlled by editing
|
||||
@ -31,32 +60,48 @@ class _CreateBaseOptions(BasedirOptions):
|
||||
"Specify which TCP port to run the HTTP interface on. Use 'none' to disable."),
|
||||
("basedir", "C", None, "Specify which Tahoe base directory should be used. This has the same effect as the global --node-directory option. [default: %s]"
|
||||
% quote_local_unicode_path(_default_nodedir)),
|
||||
|
||||
]
|
||||
|
||||
# This is overridden in order to ensure we get a "Wrong number of
|
||||
# arguments." error when more than one argument is given.
|
||||
def parseArgs(self, basedir=None):
|
||||
BasedirOptions.parseArgs(self, basedir)
|
||||
|
||||
class CreateClientOptions(_CreateBaseOptions):
|
||||
synopsis = "[options] [NODEDIR]"
|
||||
description = "Create a client-only Tahoe-LAFS node (no storage server)."
|
||||
|
||||
class CreateNodeOptions(CreateClientOptions):
|
||||
optFlags = [
|
||||
("no-storage", None, "Do not offer storage service to other nodes."),
|
||||
]
|
||||
synopsis = "[options] [NODEDIR]"
|
||||
description = "Create a full Tahoe-LAFS node (client+server)."
|
||||
optParameters = WHERE_OPTS + [
|
||||
# we provide 'create-node'-time options for the most common
|
||||
# configuration knobs. The rest can be controlled by editing
|
||||
# tahoe.cfg before node startup.
|
||||
("hostname", None, None, "Specify the hostname for listening and advertising for this node."),
|
||||
("listen", None, "tcp", "Specify the listener type for this node."),
|
||||
("nickname", "n", None, "Specify the nickname for this node."),
|
||||
("introducer", "i", None, "Specify the introducer FURL to use."),
|
||||
("webport", "p", "tcp:3456:interface=127.0.0.1",
|
||||
"Specify which TCP port to run the HTTP interface on. Use 'none' to disable."),
|
||||
("basedir", "C", None, "Specify which Tahoe base directory should be used. This has the same effect as the global --node-directory option. [default: %s]"
|
||||
% quote_local_unicode_path(_default_nodedir)),
|
||||
|
||||
]
|
||||
|
||||
def parseArgs(self, basedir=None):
|
||||
CreateClientOptions.parseArgs(self, basedir)
|
||||
validate_where_options(self)
|
||||
|
||||
class CreateIntroducerOptions(NoDefaultBasedirOptions):
|
||||
subcommand_name = "create-introducer"
|
||||
description = "Create a Tahoe-LAFS introducer."
|
||||
optFlags = [
|
||||
("hide-ip", None, "prohibit any configuration that would reveal the node's IP address"),
|
||||
]
|
||||
|
||||
]
|
||||
optParameters = WHERE_OPTS + [("listen", None, "tcp", "Specify the listener type for this node."),
|
||||
("hostname", None, None, "Specify the hostname for listening and advertising for this node."),
|
||||
]
|
||||
def parseArgs(self, basedir=None):
|
||||
NoDefaultBasedirOptions.parseArgs(self, basedir)
|
||||
validate_where_options(self)
|
||||
|
||||
def write_node_config(c, config):
|
||||
# this is shared between clients and introducers
|
||||
@ -83,11 +128,30 @@ def write_node_config(c, config):
|
||||
webport = ""
|
||||
c.write("web.port = %s\n" % (webport.encode('utf-8'),))
|
||||
c.write("web.static = public_html\n")
|
||||
c.write("# to prevent the Tub from listening at all, use this:\n")
|
||||
c.write("# tub.port = disabled\n")
|
||||
c.write("# tub.location = disabled\n")
|
||||
c.write("#tub.port =\n")
|
||||
c.write("#tub.location = \n")
|
||||
|
||||
if 'hostname' in config and config['hostname'] is not None:
|
||||
print "HOSTNAME"
|
||||
new_port = iputil.allocate_tcp_port()
|
||||
c.write("tub.port = tcp:%s\n" % new_port)
|
||||
c.write("tub.location = tcp:%s:%s\n" % (config.get('hostname').encode('utf-8'), new_port))
|
||||
elif 'listen' in config and config['listen'] == "tor":
|
||||
raise NotImplementedError("This feature addition is being tracked by this ticket:" +
|
||||
"https://tahoe-lafs.org/trac/tahoe-lafs/ticket/2490")
|
||||
elif 'listen' in config and config['listen'] == "i2p":
|
||||
raise NotImplementedError("This feature addition is being tracked by this ticket:" +
|
||||
"https://tahoe-lafs.org/trac/tahoe-lafs/ticket/2490")
|
||||
elif config.get('port') is not None:
|
||||
c.write("tub.port = %s\n" % config.get('port').encode('utf-8'))
|
||||
c.write("tub.location = %s\n" % config.get('location').encode('utf-8'))
|
||||
else:
|
||||
c.write("tub.port = disabled\n")
|
||||
c.write("tub.location = disabled\n")
|
||||
|
||||
if ('hostname' in config and config['hostname']) or ('listen' in config and config['listen']):
|
||||
c.write("# to prevent the Tub from listening at all, use this:\n")
|
||||
c.write("# tub.port = disabled\n")
|
||||
c.write("# tub.location = disabled\n")
|
||||
|
||||
c.write("#log_gatherer.furl =\n")
|
||||
c.write("#timeout.keepalive =\n")
|
||||
c.write("#timeout.disconnect =\n")
|
||||
|
@ -1,6 +1,7 @@
|
||||
import os
|
||||
from twisted.trial import unittest
|
||||
from twisted.internet import defer
|
||||
from twisted.python import usage
|
||||
from allmydata.util import configutil
|
||||
from ..common_util import run_cli
|
||||
|
||||
@ -16,6 +17,81 @@ class Config(unittest.TestCase):
|
||||
rc, out, err = yield run_cli("create-client", basedir)
|
||||
cfg = self.read_config(basedir)
|
||||
self.assertEqual(cfg.getboolean("node", "reveal-IP-address"), True)
|
||||
self.assertEqual(cfg.get("node", "tub.port"), "disabled")
|
||||
self.assertEqual(cfg.get("node", "tub.location"), "disabled")
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def test_client_hostname(self):
|
||||
basedir = self.mktemp()
|
||||
try:
|
||||
rc, out, err = yield run_cli("create-client", "--hostname=computer", basedir)
|
||||
except usage.UsageError, e:
|
||||
self.failUnlessEqual(str(e), "option --hostname not recognized")
|
||||
else:
|
||||
self.fail("UsageError expected to be raised")
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def test_client_port_location(self):
|
||||
basedir = self.mktemp()
|
||||
try:
|
||||
rc, out, err = yield run_cli("create-client",
|
||||
"--port=unix:/var/tahoe/socket",
|
||||
"--location=tor:myservice.onion:12345",
|
||||
basedir)
|
||||
except usage.UsageError, e:
|
||||
self.failUnlessEqual(str(e), "option --port not recognized")
|
||||
else:
|
||||
self.fail("UsageError expected to be raised")
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def test_client_port_only(self):
|
||||
basedir = self.mktemp()
|
||||
try:
|
||||
rc, out, err = yield run_cli("create-client", "--port=unix:/var/tahoe/socket", basedir)
|
||||
except usage.UsageError, e:
|
||||
self.failUnlessEqual(str(e), "option --port not recognized")
|
||||
else:
|
||||
self.fail("UsageError expected to be raised")
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def test_client_location_only(self):
|
||||
basedir = self.mktemp()
|
||||
try:
|
||||
rc, out, err = yield run_cli("create-client", "--location=tor:myservice.onion:12345", basedir)
|
||||
except usage.UsageError, e:
|
||||
self.failUnlessEqual(str(e), "option --location not recognized")
|
||||
else:
|
||||
self.fail("UsageError expected to be raised")
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def test_client_listen_tcp(self):
|
||||
basedir = self.mktemp()
|
||||
try:
|
||||
rc, out, err = yield run_cli("create-client", "--listen=tcp", basedir)
|
||||
except usage.UsageError, e:
|
||||
self.failUnlessEqual(str(e), "option --listen not recognized")
|
||||
else:
|
||||
self.fail("UsageError expected to be raised)")
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def test_client_listen_tor(self):
|
||||
basedir = self.mktemp()
|
||||
try:
|
||||
rc, out, err = yield run_cli("create-client", "--listen=tor", basedir)
|
||||
except usage.UsageError, e:
|
||||
self.failUnlessEqual(str(e), "option --listen not recognized")
|
||||
else:
|
||||
self.fail("UsageError expected to be raised)")
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def test_client_listen_i2p(self):
|
||||
basedir = self.mktemp()
|
||||
try:
|
||||
rc, out, err = yield run_cli("create-client", "--listen=i2p", basedir)
|
||||
except usage.UsageError, e:
|
||||
self.failUnlessEqual(str(e), "option --listen not recognized")
|
||||
else:
|
||||
self.fail("UsageError expected to be raised")
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def test_client_hide_ip(self):
|
||||
@ -30,6 +106,7 @@ class Config(unittest.TestCase):
|
||||
rc, out, err = yield run_cli("create-node", basedir)
|
||||
cfg = self.read_config(basedir)
|
||||
self.assertEqual(cfg.getboolean("node", "reveal-IP-address"), True)
|
||||
self.assertEqual(cfg.get("node", "listen"), "tcp")
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def test_node_hide_ip(self):
|
||||
@ -38,6 +115,73 @@ class Config(unittest.TestCase):
|
||||
cfg = self.read_config(basedir)
|
||||
self.assertEqual(cfg.getboolean("node", "reveal-IP-address"), False)
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def test_node_hostname(self):
|
||||
basedir = self.mktemp()
|
||||
rc, out, err = yield run_cli("create-node", "--hostname=computer", basedir)
|
||||
cfg = self.read_config(basedir)
|
||||
self.assertTrue("computer" in cfg.get("node", "tub.location"))
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def test_node_port_location(self):
|
||||
basedir = self.mktemp()
|
||||
rc, out, err = yield run_cli("create-node",
|
||||
"--port=unix:/var/tahoe/socket",
|
||||
"--location=tor:myservice.onion:12345",
|
||||
basedir)
|
||||
cfg = self.read_config(basedir)
|
||||
self.assertEqual(cfg.get("node", "tub.location"), "tor:myservice.onion:12345")
|
||||
self.assertEqual(cfg.get("node", "tub.port"), "unix:/var/tahoe/socket")
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def test_node_listen_tcp(self):
|
||||
basedir = self.mktemp()
|
||||
rc, out, err = yield run_cli("create-node", "--listen=tcp", basedir)
|
||||
cfg = self.read_config(basedir)
|
||||
self.assertEqual(cfg.get("node", "listen"), "tcp")
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def test_node_listen_tor(self):
|
||||
basedir = self.mktemp()
|
||||
try:
|
||||
rc, out, err = yield run_cli("create-node", "--listen=tor", basedir)
|
||||
except NotImplementedError, e:
|
||||
self.failUnlessEqual(str(e), "This feature addition is being tracked by this ticket:" +
|
||||
"https://tahoe-lafs.org/trac/tahoe-lafs/ticket/2490")
|
||||
else:
|
||||
self.fail("NotImplementedError expected to be raised")
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def test_node_listen_i2p(self):
|
||||
basedir = self.mktemp()
|
||||
try:
|
||||
rc, out, err = yield run_cli("create-node", "--listen=i2p", basedir)
|
||||
except NotImplementedError, e:
|
||||
self.failUnlessEqual(str(e), "This feature addition is being tracked by this ticket:" +
|
||||
"https://tahoe-lafs.org/trac/tahoe-lafs/ticket/2490")
|
||||
else:
|
||||
self.fail("NotImplementedError expected to be raised")
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def test_node_port_only(self):
|
||||
basedir = self.mktemp()
|
||||
try:
|
||||
rc, out, err = yield run_cli("create-node", "--port=unix:/var/tahoe/socket", basedir)
|
||||
except usage.UsageError, e:
|
||||
self.failUnlessEqual(str(e), "The --port option must be used with the --location option.")
|
||||
else:
|
||||
self.fail("UsageError expected to be raised")
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def test_node_location_only(self):
|
||||
basedir = self.mktemp()
|
||||
try:
|
||||
rc, out, err = yield run_cli("create-node", "--location=tor:myservice.onion:12345", basedir)
|
||||
except usage.UsageError, e:
|
||||
self.failUnlessEqual(str(e), "The --location option must be used with the --port option.")
|
||||
else:
|
||||
self.fail("UsageError expected to be raised")
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def test_introducer(self):
|
||||
basedir = self.mktemp()
|
||||
@ -51,3 +195,10 @@ class Config(unittest.TestCase):
|
||||
rc, out, err = yield run_cli("create-introducer", "--hide-ip", basedir)
|
||||
cfg = self.read_config(basedir)
|
||||
self.assertEqual(cfg.getboolean("node", "reveal-IP-address"), False)
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def test_introducer_hostname(self):
|
||||
basedir = self.mktemp()
|
||||
rc, out, err = yield run_cli("create-introducer", "--hostname=computer", basedir)
|
||||
cfg = self.read_config(basedir)
|
||||
self.assertTrue("computer" in cfg.get("node", "tub.location"))
|
||||
|
@ -344,7 +344,7 @@ class RunNode(common_util.SignalMixin, unittest.TestCase, pollmixin.PollMixin,
|
||||
node_url_file = os.path.join(c1, "node.url")
|
||||
config_file = os.path.join(c1, "tahoe.cfg")
|
||||
|
||||
d = self.run_bintahoe(["--quiet", "create-introducer", "--basedir", c1])
|
||||
d = self.run_bintahoe(["--quiet", "create-introducer", "--basedir", c1, "--hostname", "localhost"])
|
||||
def _cb(res):
|
||||
out, err, rc_or_sig = res
|
||||
self.failUnlessEqual(rc_or_sig, 0)
|
||||
@ -373,6 +373,7 @@ class RunNode(common_util.SignalMixin, unittest.TestCase, pollmixin.PollMixin,
|
||||
errstr = "rc=%d, OUT: '%s', ERR: '%s'" % (rc_or_sig, out, err)
|
||||
self.failUnlessEqual(rc_or_sig, 0, errstr)
|
||||
self.failUnlessEqual(out, "", errstr)
|
||||
print 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
|
||||
@ -393,6 +394,7 @@ class RunNode(common_util.SignalMixin, unittest.TestCase, pollmixin.PollMixin,
|
||||
# read the introducer.furl and introducer.port files so we can
|
||||
# check that their contents don't change on restart
|
||||
self.furl = fileutil.read(introducer_furl_file)
|
||||
print "portnum_file " + portnum_file
|
||||
self.failUnless(os.path.exists(portnum_file))
|
||||
self.portnum = fileutil.read(portnum_file)
|
||||
|
||||
@ -531,7 +533,7 @@ class RunNode(common_util.SignalMixin, unittest.TestCase, pollmixin.PollMixin,
|
||||
node_url_file = os.path.join(c1, "node.url")
|
||||
config_file = os.path.join(c1, "tahoe.cfg")
|
||||
|
||||
d = self.run_bintahoe(["--quiet", "create-node", "--basedir", c1, "--webport", "0"])
|
||||
d = self.run_bintahoe(["--quiet", "create-node", "--basedir", c1, "--webport", "0", "--hostname", "localhost"])
|
||||
def _cb(res):
|
||||
out, err, rc_or_sig = res
|
||||
self.failUnlessEqual(rc_or_sig, 0)
|
||||
|
Loading…
x
Reference in New Issue
Block a user