commit f3c5f334ce84621547139ae70eedb2c3fbfa2076 Author: Damian Johnson atagar@torproject.org Date: Fri May 11 09:05:18 2012 -0700
Expanding launch_tor to support commandline options
When writing small scripts we often want to start a tor instance for a special purpose, for instance to test a new feature. When doing this we want a bare-bones tor instance with just a few specific options. Adding better support for this by making the launch_tor function accept command-line options and the ability to use a blank torrc. --- stem/process.py | 33 +++++++++++++++++++++++++++++---- test/runner.py | 2 +- 2 files changed, 30 insertions(+), 5 deletions(-)
diff --git a/stem/process.py b/stem/process.py index 2b00117..8d65072 100644 --- a/stem/process.py +++ b/stem/process.py @@ -8,12 +8,18 @@ launch_tor - starts up a tor process import re import os import signal +import tempfile import subprocess
# number of seconds before we time out our attempt to start a tor instance DEFAULT_INIT_TIMEOUT = 90
-def launch_tor(tor_cmd = "tor", torrc_path = None, completion_percent = 100, init_msg_handler = None, timeout = DEFAULT_INIT_TIMEOUT): +# special parameter that can be set for the torrc_path to run with a blank +# configuration + +NO_TORRC = "<no torrc>" + +def launch_tor(tor_cmd = "tor", options = None, torrc_path = None, completion_percent = 100, init_msg_handler = None, timeout = DEFAULT_INIT_TIMEOUT): """ Initializes a tor process. This blocks until initialization completes or we error out. @@ -25,6 +31,7 @@ def launch_tor(tor_cmd = "tor", torrc_path = None, completion_percent = 100, ini
Arguments: tor_cmd (str) - command for starting tor + options (dict) - configuration options, such as ("ControlPort": "9051") torrc_path (str) - location of the torrc for us to use completion_percent (int) - percent of bootstrap completion at which this'll return @@ -42,18 +49,32 @@ def launch_tor(tor_cmd = "tor", torrc_path = None, completion_percent = 100, ini """
# double check that we have a torrc to work with - if not os.path.exists(torrc_path): + if not torrc_path in (None, NO_TORRC) and not os.path.exists(torrc_path): raise OSError("torrc doesn't exist (%s)" % torrc_path)
# starts a tor subprocess, raising an OSError if it fails - runtime_args = [tor_cmd] - if torrc_path: runtime_args += ["-f", torrc_path] + runtime_args, temp_file = [tor_cmd], None + if torrc_path: + if torrc_path == NO_TORRC: + temp_file = tempfile.mkstemp("-empty-torrc", text = True)[1] + runtime_args += ["-f", temp_file] + else: + runtime_args += ["-f", torrc_path] + + if options: + for key, value in options.items(): + value = value.replace('"', '\"') + runtime_args += ["--%s" % key.lower(), value]
tor_process = subprocess.Popen(runtime_args, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
if timeout: def timeout_handler(signum, frame): # terminates the uninitialized tor process and raise on timeout + if temp_file: + try: os.remove(temp_file) + except: pass + tor_process.kill() raise OSError("reached a %i second timeout without success" % timeout)
@@ -77,5 +98,9 @@ def launch_tor(tor_cmd = "tor", torrc_path = None, completion_percent = 100, ini bootstrap_match = bootstrap_line.search(init_line)
if bootstrap_match and int(bootstrap_match.groups()[0]) >= completion_percent: + if temp_file: + try: os.remove(temp_file) + except: pass + return tor_process
diff --git a/test/runner.py b/test/runner.py index 66636f2..6acc68e 100644 --- a/test/runner.py +++ b/test/runner.py @@ -637,7 +637,7 @@ class Runner: print_init_line = lambda line: test.output.print_line(" %s" % line, *SUBSTATUS_ATTR)
torrc_dst = os.path.join(self._test_dir, "torrc") - self._tor_process = stem.process.launch_tor(tor_cmd, torrc_dst, complete_percent, print_init_line) + self._tor_process = stem.process.launch_tor(tor_cmd, None, torrc_dst, complete_percent, print_init_line)
runtime = time.time() - start_time test.output.print_line(" done (%i seconds)\n" % runtime, *STATUS_ATTR)
tor-commits@lists.torproject.org