[Pkg-privacy-commits] [txtorcon] 54/96: refactor launch_tor(), get rid of temp torrc
Jérémy Bobbio
lunar at moszumanska.debian.org
Sun Sep 6 18:33:39 UTC 2015
This is an automated email from the git hooks/post-receive script.
lunar pushed a commit to branch master
in repository txtorcon.
commit d51ab17b12e89a500b82078481edbc6e3eb7eab5
Author: meejah <meejah at meejah.ca>
Date: Thu Feb 5 18:06:26 2015 -0700
refactor launch_tor(), get rid of temp torrc
- fix bug if tor dies with exit-code 0 during startup
- support passing arguments via command-line (instead of torrc)
- allow access to TorConfig's argument-list
- update TorConfig to give access to saved + unsaved bits
---
test/test_torconfig.py | 3 +-
txtorcon/torconfig.py | 116 +++++++++++++++++++++++++++++++------------------
2 files changed, 76 insertions(+), 43 deletions(-)
diff --git a/test/test_torconfig.py b/test/test_torconfig.py
index 6f65b1e..0f47c39 100644
--- a/test/test_torconfig.py
+++ b/test/test_torconfig.py
@@ -883,7 +883,8 @@ class LaunchTorTests(unittest.TestCase):
self.assertEqual("", stderr.getvalue())
todel = proto.to_delete
self.assertTrue(len(todel) > 0)
- proto.processEnded(Failure(error.ProcessDone(0)))
+ # ...because we know it's a TorProcessProtocol :/
+ proto.cleanup()
self.assertEqual(len(proto.to_delete), 0)
for f in todel:
self.assertTrue(not os.path.exists(f))
diff --git a/txtorcon/torconfig.py b/txtorcon/torconfig.py
index 389837f..6f30e18 100644
--- a/txtorcon/torconfig.py
+++ b/txtorcon/torconfig.py
@@ -184,10 +184,6 @@ class TorProcessProtocol(protocol.ProcessProtocol):
self.cleanup()
- if isinstance(status.value,
- error.ProcessDone) and not self._did_timeout:
- return
-
if status.value.exitCode is None:
if self._did_timeout:
err = RuntimeError("Timeout waiting for Tor launch..")
@@ -407,28 +403,41 @@ def launch_tor(config, reactor,
control_port = 9052 # FIXME choose a random, unoccupied one?
config.ControlPort = control_port
+ # so, we support passing in ControlPort=0 -- not really sure if
+ # this is a good idea (since then the caller has to kill the tor
+ # off, etc), but at least one person has requested it :/
if control_port != 0:
config.CookieAuthentication = 1
config.__OwningControllerProcess = os.getpid()
+ if connection_creator is None:
+ connection_creator = functools.partial(
+ TCP4ClientEndpoint(reactor, 'localhost', control_port).connect,
+ TorProtocolFactory()
+ )
else:
connection_creator = None
- config.save()
+ # NOTE well, that if we don't pass "-f" then Tor will merrily load
+ # it's default torrc, and apply our options over top... :/
+ config_args = ['-f', '/non-existant', '--ignore-missing-torrc']
- (fd, torrc) = tempfile.mkstemp(prefix='tortmp')
- os.write(fd, config.create_torrc())
- os.close(fd)
+ # ...now add all our config options on the command-line. This
+ # avoids writing a temporary torrc.
+ for (k, v) in config.config_args():
+ config_args.append(k)
+ config_args.append(v)
- # txtorlog.msg('Running with config:\n', open(torrc, 'r').read())
+ # txtorlog.msg('Running with config:\n', ' '.join(config_args))
- if connection_creator is None and control_port > 0:
- connection_creator = functools.partial(
- TCP4ClientEndpoint(reactor, 'localhost', control_port).connect,
- TorProtocolFactory())
- process_protocol = TorProcessProtocol(connection_creator, progress_updates,
- config, reactor, timeout,
- kill_on_stderr,
- stdout, stderr)
+ process_protocol = TorProcessProtocol(
+ connection_creator,
+ progress_updates,
+ config, reactor,
+ timeout,
+ kill_on_stderr,
+ stdout,
+ stderr
+ )
# we set both to_delete and the shutdown events because this
# process might be shut down way before the reactor, but if the
@@ -438,24 +447,23 @@ def launch_tor(config, reactor,
# we don't want to delete the user's directories, just temporary
# ones this method created.
- if user_set_data_directory:
- process_protocol.to_delete = [torrc]
- reactor.addSystemEventTrigger('before', 'shutdown',
- functools.partial(delete_file_or_tree,
- torrc))
- else:
- process_protocol.to_delete = [torrc, data_directory]
- reactor.addSystemEventTrigger('before', 'shutdown',
- functools.partial(delete_file_or_tree,
- torrc,
- data_directory))
+ if not user_set_data_directory:
+ process_protocol.to_delete = [data_directory]
+ reactor.addSystemEventTrigger(
+ 'before', 'shutdown',
+ functools.partial(delete_file_or_tree, data_directory)
+ )
try:
log.msg('Spawning tor process with DataDirectory', data_directory)
- transport = reactor.spawnProcess(process_protocol, tor_binary,
- args=(tor_binary, '-f', torrc),
- env={'HOME': data_directory},
- path=data_directory)
+ args = [tor_binary] + config_args
+ transport = reactor.spawnProcess(
+ process_protocol,
+ tor_binary,
+ args=args,
+ env={'HOME': data_directory},
+ path=data_directory
+ )
# FIXME? don't need rest of the args: uid, gid, usePTY, childFDs)
transport.closeStdin()
@@ -896,12 +904,14 @@ class TorConfig(object):
return True
return item in self.config
- def __iter__(self, *args, **kw):
+ def __iter__(self):
'''
- FIXME should work with .saved as well!
- ...and needs proper iterator tests in test_torconfig too
+ FIXME needs proper iterator tests in test_torconfig too
'''
- return self.config.__iter__(*args, **kw)
+ for x in self.config.__iter__():
+ yield x
+ for x in self.__dict__['unsaved'].__iter__():
+ yield x
def get_type(self, name):
"""
@@ -1126,27 +1136,49 @@ class TorConfig(object):
raise RuntimeError("Can't parse HiddenServiceOptions: " + k)
if directory is not None:
- hs.append(HiddenService(self, directory, ports, auth, ver, group_read))
+ hs.append(
+ HiddenService(
+ self, directory, ports, auth, ver, group_read
+ )
+ )
name = 'HiddenServices'
self.config[name] = _ListWrapper(
hs, functools.partial(self.mark_unsaved, name))
- def create_torrc(self):
- rtn = StringIO()
+ def config_args(self):
+ '''
+ Returns an iterator of 2-tuples (config_name, value), one for
+ each configuration option in this config. This is more-or-less
+ and internal method, but see, e.g., launch_tor()'s
+ implementation if you thing you need to use this for
+ something.
+
+ See :meth:`txtorcon.TorConfig.create_torrc` which returns a
+ string which is also a valid ``torrc`` file
+
+ '''
for (k, v) in self.config.items() + self.unsaved.items():
if type(v) is _ListWrapper:
if k.lower() == 'hiddenservices':
for x in v:
for (kk, vv) in x.config_attributes():
- rtn.write('%s %s\n' % (kk, vv))
+ yield (str(kk), str(vv))
else:
+ # FIXME actually, is this right? don't we want ALL
+ # the values in one string?!
for x in v:
- rtn.write('%s %s\n' % (k, x))
+ yield (str(k), str(x))
else:
- rtn.write('%s %s\n' % (k, v))
+ yield (str(k), str(v))
+
+ def create_torrc(self):
+ rtn = StringIO()
+
+ for (k, v) in self.config_args():
+ rtn.write('%s %s\n' % (k, v))
return rtn.getvalue()
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-privacy/packages/txtorcon.git
More information about the Pkg-privacy-commits
mailing list