[tor-commits] [nyx/master] Move chroot out of starter

atagar at torproject.org atagar at torproject.org
Tue Sep 12 18:47:18 UTC 2017


commit ee4a3205d8d9c3001b43cf802cbba2f6c5fdb714
Author: Damian Johnson <atagar at torproject.org>
Date:   Fri Sep 8 03:43:27 2017 -0700

    Move chroot out of starter
    
    There's a few things to consult to determine our chroot so making this a
    helper rather than part of the starter.
---
 nyx/__init__.py     | 37 +++++++++++++++++++++++++++++++++----
 nyx/panel/header.py |  8 ++++----
 nyx/starter.py      | 28 +---------------------------
 test/__init__.py    | 34 ++++++++++++++++++++++++++++------
 4 files changed, 66 insertions(+), 41 deletions(-)

diff --git a/nyx/__init__.py b/nyx/__init__.py
index 2239956..c5736c1 100644
--- a/nyx/__init__.py
+++ b/nyx/__init__.py
@@ -14,6 +14,7 @@ Tor curses monitoring application.
   input_prompt - prompts the user for text input
   init_controller - initializes our connection to tor
   expand_path - expands path with respect to our chroot
+  chroot - provides the chroot path we reside within
   join - joins a series of strings up to a set length
 
   Cache - application cache
@@ -44,6 +45,7 @@ Tor curses monitoring application.
 import contextlib
 import distutils.spawn
 import os
+import platform
 import sqlite3
 import sys
 import threading
@@ -99,6 +101,7 @@ CONFIG = stem.util.conf.config_dict('nyx', {
 NYX_INTERFACE = None
 TOR_CONTROLLER = None
 CACHE = None
+CHROOT = None
 BASE_DIR = os.path.sep.join(__file__.split(os.path.sep)[:-1])
 
 # technically can change but we use this query a *lot* so needs to be cached
@@ -294,8 +297,7 @@ def data_directory(filename, config):
   return os.path.join(data_dir, filename)
 
 
- at uses_settings
-def expand_path(path, config):
+def expand_path(path):
   """
   Expands relative paths and include our chroot if one was set.
 
@@ -308,14 +310,41 @@ def expand_path(path, config):
     return None
 
   try:
-    chroot = config.get('tor_chroot', '')
     tor_cwd = stem.util.system.cwd(tor_controller().get_pid(None))
-    return chroot + stem.util.system.expand_path(path, tor_cwd)
+    return chroot() + stem.util.system.expand_path(path, tor_cwd)
   except IOError as exc:
     stem.util.log.info('Unable to expand a relative path (%s): %s' % (path, exc))
     return path
 
 
+ at uses_settings
+def chroot(config):
+  global CHROOT
+
+  if CHROOT is None:
+    # If the user provided us with a chroot then validate and normalize the
+    # path.
+
+    chroot = config.get('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)
+      chroot = ''
+
+    if not chroot and platform.system() == 'FreeBSD':
+      controller = tor_controller()
+      pid = controller.get_pid(None) if controller else stem.util.system.pid_by_name('tor')
+      jail_chroot = stem.util.system.bsd_jail_path(pid) if pid else None
+
+      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)
+        chroot = jail_chroot
+
+    CHROOT = chroot
+
+  return CHROOT
+
+
 def join(entries, joiner = ' ', size = None):
   """
   Joins a series of strings similar to str.join(), but only up to a given size.
diff --git a/nyx/panel/header.py b/nyx/panel/header.py
index cf11b67..b1cbfbf 100644
--- a/nyx/panel/header.py
+++ b/nyx/panel/header.py
@@ -16,13 +16,14 @@ import stem.util.proc
 import stem.util.str_tools
 import stem.util.system
 
+import nyx
 import nyx.curses
 import nyx.panel
 import nyx.popups
 import nyx.tracker
 
 from stem.util import conf, log
-from nyx import nyx_interface, tor_controller, input_prompt
+from nyx import nyx_interface, tor_controller
 
 from nyx.curses import RED, GREEN, YELLOW, CYAN, WHITE, BOLD, HIGHLIGHT
 
@@ -33,7 +34,6 @@ UPDATE_RATE = 5  # rate in seconds at which we refresh
 CONFIG = conf.config_dict('nyx', {
   'attr.flag_colors': {},
   'attr.version_status_colors': {},
-  'tor_chroot': '',
 })
 
 
@@ -129,9 +129,9 @@ class HeaderPanel(nyx.panel.DaemonPanel):
 
       try:
         try:
-          controller.reconnect(chroot_path = CONFIG['tor_chroot'])
+          controller.reconnect(chroot_path = nyx.chroot())
         except stem.connection.MissingPassword:
-          password = input_prompt('Controller Password: ')
+          password = nyx.input_prompt('Controller Password: ')
 
           if password:
             controller.authenticate(password)
diff --git a/nyx/starter.py b/nyx/starter.py
index 88cf9f5..22e985e 100644
--- a/nyx/starter.py
+++ b/nyx/starter.py
@@ -69,7 +69,7 @@ def main(config):
     control_port = args.control_port,
     control_socket = args.control_socket,
     password_prompt = True,
-    chroot_path = config.get('tor_chroot', ''),
+    chroot_path = nyx.chroot(),
   )
 
   if controller is None:
@@ -78,7 +78,6 @@ def main(config):
   _warn_if_root(controller)
   _warn_if_unable_to_get_pid(controller)
   _warn_about_unused_config_keys()
-  _setup_freebsd_chroot(controller)
   _use_english_subcommands()
   _use_no_esc_delay()
   _use_unicode()
@@ -143,17 +142,6 @@ def _load_user_nyxrc(path, config):
   if os.path.exists(path):
     try:
       config.load(path)
-
-      # If the user provided us with a chroot then validate and normalize the
-      # path.
-
-      chroot = config.get('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
     except IOError as exc:
       stem.util.log.warn('Failed to load configuration (using defaults): "%s"' % exc.strerror)
   else:
@@ -194,20 +182,6 @@ def _warn_about_unused_config_keys(config):
       stem.util.log.notice('Unused configuration entry: %s' % key)
 
 
- at uses_settings
-def _setup_freebsd_chroot(controller, config):
-  """
-  If we're running under FreeBSD then check the system for a chroot path.
-  """
-
-  if not config.get('tor_chroot', None) and platform.system() == 'FreeBSD':
-    jail_chroot = stem.util.system.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)
-
-
 def _use_english_subcommands():
   """
   Make subcommands we run (ps, netstat, etc) provide us with English results.
diff --git a/test/__init__.py b/test/__init__.py
index 6e3ade3..4a998f0 100644
--- a/test/__init__.py
+++ b/test/__init__.py
@@ -9,7 +9,7 @@ import unittest
 
 import nyx.curses
 
-from nyx import expand_path, join, uses_settings
+from nyx import expand_path, chroot, join, uses_settings
 from mock import patch, Mock
 
 __all__ = [
@@ -107,18 +107,40 @@ def render(func, *args, **kwargs):
 
 
 class TestBaseUtil(unittest.TestCase):
-  @patch('nyx.tor_controller')
+  def setUp(self):
+    nyx.CHROOT = None
+
+  def tearDown(self):
+    nyx.CHROOT = None
+
+  @patch('nyx.chroot', Mock(return_value = ''))
+  @patch('nyx.tor_controller', Mock())
   @patch('stem.util.system.cwd', Mock(return_value = '/your_cwd'))
-  @uses_settings
-  def test_expand_path(self, tor_controller_mock, config):
-    tor_controller_mock().get_pid.return_value = 12345
+  def test_expand_path(self):
     self.assertEqual('/absolute/path/to/torrc', expand_path('/absolute/path/to/torrc'))
     self.assertEqual('/your_cwd/torrc', expand_path('torrc'))
 
-    config.set('tor_chroot', '/chroot')
+  @patch('nyx.chroot', Mock(return_value = '/chroot'))
+  @patch('nyx.tor_controller', Mock())
+  @patch('stem.util.system.cwd', Mock(return_value = '/your_cwd'))
+  def test_expand_path_with_chroot(self):
     self.assertEqual('/chroot/absolute/path/to/torrc', expand_path('/absolute/path/to/torrc'))
     self.assertEqual('/chroot/your_cwd/torrc', expand_path('torrc'))
 
+  @patch('platform.system', Mock(return_value = 'Linux'))
+  @patch('os.path.exists', Mock(return_value = True))
+  @uses_settings
+  def test_chroot_uses_config(self, config):
+    config.set('tor_chroot', '/chroot/path')
+    self.assertEqual('/chroot/path', chroot())
+    config.set('tor_chroot', None)
+
+  @patch('platform.system', Mock(return_value = 'Linux'))
+  @patch('os.path.exists', Mock(return_value = False))
+  @uses_settings
+  def test_chroot_requires_path_to_exist(self, config):
+    config.set('tor_chroot', '/chroot/path')
+    self.assertEqual('', chroot())
     config.set('tor_chroot', None)
 
   def test_join(self):





More information about the tor-commits mailing list