commit 19ad43d8c75768d6838642323d4078e5dc32017c
Author: Damian Johnson <atagar(a)torproject.org>
Date: Sun Dec 22 15:12:35 2013 -0800
Removing the get_chroot helper
The get_chroot() function normalizes user supplied chroot paths and fetches one
if on FreeBSD. We might as well do this in the starter during initialization
rather than lazy evaluation.
---
arm/graphing/bandwidthStats.py | 4 +++-
arm/logPanel.py | 3 ++-
arm/starter.py | 31 +++++++++++++++++++-----
arm/util/torConfig.py | 3 ++-
arm/util/torTools.py | 52 +---------------------------------------
test/starter/authenticate.py | 13 +++++-----
6 files changed, 40 insertions(+), 66 deletions(-)
diff --git a/arm/graphing/bandwidthStats.py b/arm/graphing/bandwidthStats.py
index e074716..2bf417e 100644
--- a/arm/graphing/bandwidthStats.py
+++ b/arm/graphing/bandwidthStats.py
@@ -23,6 +23,7 @@ CONFIG = conf.config_dict("arm", {
"features.graph.bw.accounting.show": True,
"features.graph.bw.accounting.rate": 10,
"features.graph.bw.accounting.isTimeLong": False,
+ "tor.chroot": "",
}, conf_handler)
DL_COLOR, UL_COLOR = "green", "cyan"
@@ -151,7 +152,8 @@ class BandwidthStats(graphPanel.GraphStats):
return False
# attempt to open the state file
- try: stateFile = open("%s%s/state" % (torTools.get_chroot(), dataDir), "r")
+ try:
+ stateFile = open("%s%s/state" % (CONFIG['tor.chroot'], dataDir), "r")
except IOError:
msg = PREPOPULATE_FAILURE_MSG % "unable to read the state file"
log.notice(msg)
diff --git a/arm/logPanel.py b/arm/logPanel.py
index 01b34f4..3b58125 100644
--- a/arm/logPanel.py
+++ b/arm/logPanel.py
@@ -57,6 +57,7 @@ CONFIG = conf.config_dict("arm", {
"features.log.regex": [],
"cache.logPanel.size": 1000,
"msg.event_types": '',
+ "tor.chroot": '',
}, conf_handler)
DUPLICATE_MSG = " [%i duplicate%s hidden]"
@@ -209,7 +210,7 @@ def getLogFileEntries(runlevels, readLimit = None, addLimit = None):
if not loggingLocation: return []
# includes the prefix for tor paths
- loggingLocation = torTools.get_chroot() + loggingLocation
+ loggingLocation = CONFIG['tor.chroot'] + loggingLocation
# if the runlevels argument is a superset of the log file then we can
# limit the read contents to the addLimit
diff --git a/arm/starter.py b/arm/starter.py
index ca2179f..707317c 100644
--- a/arm/starter.py
+++ b/arm/starter.py
@@ -36,6 +36,7 @@ import stem.util.system
SETTINGS_PATH = os.path.join(os.path.dirname(__file__), 'settings.cfg')
CONFIG = stem.util.conf.config_dict("arm", {
+ 'tor.chroot': '',
'tor.password': None,
'startup.events': 'N3',
'msg.debug_header': '',
@@ -90,15 +91,14 @@ def _authenticate(controller, password):
Authenticates to the given Controller.
:param stem.control.Controller controller: controller to be authenticated to
- :param str args: password to authenticate with, **None** if nothing was provided
+ :param str password: password to authenticate with, **None** if nothing was
+ provided
:raises: **ValueError** if unable to authenticate
"""
- chroot = arm.util.torTools.get_chroot()
-
try:
- controller.authenticate(password = password, chroot_path = chroot)
+ controller.authenticate(password = password, chroot_path = CONFIG['tor.chroot'])
except stem.connection.IncorrectSocketType:
control_socket = controller.get_socket()
@@ -127,7 +127,7 @@ def _setup_debug_logging(args):
Configures us to log at stem's trace level to debug log path, and notes some
general diagnostic information.
- :param namedtuple args: startup arguments
+ :param namedtuple args: arguments that arm was started with
:raises: **IOError** if we can't log to this location
"""
@@ -229,7 +229,17 @@ def main():
else:
stem.util.log.notice(CONFIG['msg.config_not_found'].format(path = args.config))
- config.set("startup.events", args.logged_events)
+ config.set('startup.events', args.logged_events)
+
+ # check that the chroot exists and strip trailing slashes
+
+ chroot = CONFIG['tor.chroot'].strip().rstrip(os.path.sep)
+
+ if chroot and not os.path.exists(chroot):
+ stem.util.log.notice("The chroot path set in your config (%s) doesn't exist." % chroot)
+ config.set('tor.chroot', '')
+ else:
+ config.set('tor.chroot', chroot) # use the normalized path
# validates and expands log event flags
@@ -289,6 +299,15 @@ def main():
except ValueError:
stem.util.log.warn(CONFIG['msg.unable_to_determine_pid'])
+ # If we're running under FreeBSD then check the system for a chroot path.
+
+ if not CONFIG['tor.chroot'] and platform.system() == 'FreeBSD':
+ jail_chroot = stem.util.system.get_bsd_jail_path(controller.get_pid(0))
+
+ if jail_chroot and os.path.exists(jail_chroot):
+ stem.util.log.info("Adjusting paths to account for Tor running in a FreeBSD jail at: %s" % jail_chroot)
+ config.set('tor.chroot', jail_chroot)
+
# If using our LANG variable for rendering multi-byte characters lets us
# get unicode support then then use it. This needs to be done before
# initializing curses.
diff --git a/arm/util/torConfig.py b/arm/util/torConfig.py
index f6e693c..e08fc40 100644
--- a/arm/util/torConfig.py
+++ b/arm/util/torConfig.py
@@ -48,6 +48,7 @@ CONFIG = conf.config_dict("arm", {
"startup.dataDirectory": "~/.arm",
"features.config.descriptions.enabled": True,
"features.config.descriptions.persist": True,
+ "tor.chroot": '',
}, conf_handler)
def general_conf_handler(config, key):
@@ -359,7 +360,7 @@ def getConfigLocation():
conn = torTools.getConn()
configLocation = conn.getInfo("config-file", None)
- torPid, torPrefix = conn.controller.get_pid(None), torTools.get_chroot()
+ torPid, torPrefix = conn.controller.get_pid(None), CONFIG['tor.chroot']
if not configLocation: raise IOError("unable to query the torrc location")
try:
diff --git a/arm/util/torTools.py b/arm/util/torTools.py
index 7c0a108..69cd574 100644
--- a/arm/util/torTools.py
+++ b/arm/util/torTools.py
@@ -5,33 +5,18 @@ accessing stem and notifications of state changes to subscribers.
import math
import os
-import platform
import threading
import time
import stem
import stem.control
-import stem.descriptor
-import stem.util.system
-from arm.util import connections
-
-from stem.util import conf, enum, log, proc, str_tools, system
+from stem.util import log, proc, system
CONTROLLER = None # singleton Controller instance
UNDEFINED = "<Undefined_ >"
-CONFIG = conf.config_dict("arm", {
- "tor.chroot": "",
-})
-
-# Logs issues and notices when fetching the path prefix if true. This is
-# only done once for the duration of the application to avoid pointless
-# messages.
-
-LOG_ABOUT_CHROOTS = True
-
def getConn():
"""
Singleton constructor for a Controller. Be aware that this starts as being
@@ -43,41 +28,6 @@ def getConn():
return CONTROLLER
-def get_chroot():
- """
- Provides the path prefix that should be used for fetching tor resources.
- If undefined and Tor is inside a jail under FreeBSD then this provides the
- jail's path.
-
- :returns: **str** with the path of the jail tor is running within, this is an
- empty string if none can be determined
- """
-
- global LOG_ABOUT_CHROOTS
-
- chroot = CONFIG["tor.chroot"].strip()
-
- if chroot and not os.path.exists(chroot):
- if LOG_ABOUT_CHROOTS:
- log.notice("The prefix path set in your config (%s) doesn't exist." % chroot)
-
- chroot = ''
-
- if not chroot and platform.system() == "FreeBSD":
- jail_chroot = system.get_bsd_jail_path(getConn().controller.get_pid(0))
-
- if jail_chroot and os.path.exists(jail_chroot):
- chroot = jail_chroot
-
- if LOG_ABOUT_CHROOTS:
- log.info("Adjusting paths to account for Tor running in a FreeBSD jail at: %s" % chroot)
-
- chroot = chroot.rstrip(os.path.sep) # strip off trailing slashes
- LOG_ABOUT_CHROOTS = False # don't log about further calls
-
- return chroot
-
-
class Controller:
"""
Stem wrapper providing convenience functions (mostly from the days of using
diff --git a/test/starter/authenticate.py b/test/starter/authenticate.py
index b2f7592..1b228b5 100644
--- a/test/starter/authenticate.py
+++ b/test/starter/authenticate.py
@@ -10,23 +10,25 @@ from arm.starter import (
import stem
import stem.connection
import stem.socket
+import stem.util.conf
class TestAuthenticate(unittest.TestCase):
- @patch('arm.util.torTools.get_chroot')
- def test_success(self, get_chroot_mock):
+ def setUp(self):
+ arm_conf = stem.util.conf.get_config('arm')
+ arm_conf.set('tor.chroot', '') # no chroot
+
+ def test_success(self):
controller = Mock()
- get_chroot_mock.return_value = '' # no chroot
_authenticate(controller, None)
controller.authenticate.assert_called_with(password = None, chroot_path = '')
controller.authenticate.reset_mock()
- get_chroot_mock.return_value = '/my/chroot'
+ stem.util.conf.get_config('arm').set('tor.chroot', '/my/chroot')
_authenticate(controller, 's3krit!!!')
controller.authenticate.assert_called_with(password = 's3krit!!!', chroot_path = '/my/chroot')
- @patch('arm.util.torTools.get_chroot', Mock(return_value = ''))
@patch('getpass.getpass')
def test_success_with_password_prompt(self, getpass_mock):
controller = Mock()
@@ -46,7 +48,6 @@ class TestAuthenticate(unittest.TestCase):
controller.authenticate.assert_any_call(password = None, chroot_path = '')
controller.authenticate.assert_any_call(password = 'my_password', chroot_path = '')
- @patch('arm.util.torTools.get_chroot', Mock(return_value = ''))
def test_failure(self):
controller = Mock()