Browse Source

Merge branch 'tor-termination'

Multiple options were added to the README, this resolves the conflict.
teor 7 years ago
parent
commit
8822169d7f
4 changed files with 84 additions and 27 deletions
  1. 12 6
      README
  2. 54 19
      lib/chutney/TorNet.py
  3. 12 1
      tools/test-network.sh
  4. 6 1
      torrc_templates/common.i

+ 12 - 6
README

@@ -42,9 +42,9 @@ Timing Options:
   --stop-time        CHUTNEY_STOP_TIME
 
 Traffic Options:
-  --data             CHUTNEY_DATA_BYTES
-  --connections      CHUTNEY_CONNECTIONS
-  --hs-multi-client  CHUTNEY_HS_MULTI_CLIENT
+  --data             CHUTNEY_DATA_BYTES=N
+  --connections      CHUTNEY_CONNECTIONS=N
+  --hs-multi-client  CHUTNEY_HS_MULTI_CLIENT=N
 
 Address Options:
   --ipv4             CHUTNEY_LISTEN_ADDRESS
@@ -59,9 +59,11 @@ Warning Options:
 Expert Options:
   --debug            CHUTNEY_DEBUG=true
   --coverage         USE_COVERAGE_BINARY=true
-  --net-dir          CHUTNEY_DATA_DIR
   --dry-run          NETWORK_DRY_RUN=true
   --quiet            ECHO=true
+
+  --controlling-pid  CHUTNEY_CONTROLLING_PID
+  --net-dir          CHUTNEY_DATA_DIR
   (These are advanced options: in the past, they have had long-standing bugs.)
 
 Standard Actions:
@@ -126,6 +128,10 @@ Waiting for the network:
   after verifying, then exits (default: immediately). If CHUTNEY_STOP_TIME is
   negative, the script leaves the network running, and exits after verifying.
 
+  If none of these options are negative, test-network.sh tells the tor
+  processes to exit after it exits, using CHUTNEY_CONTROLLING_PID. To disable
+  this functionality, set CHUTNEY_CONTROLLING_PID to 1 or less.
+
 Changing the network address:
 
    Chutney defaults to binding to localhost. To change the IPv4 bind address,
@@ -135,8 +141,8 @@ Changing the network address:
    Tor network available on the network.
 
    IPv6 support for both Tor and Chutney is a work in progress. Currently,
-   chutney verifies IPv6 client, bridge client, and hidden service
-   connections. It does not use IPv6 SOCKSPort or Exit traffic.
+   chutney verifies IPv6 client, bridge client (?), hidden service, and exit
+   connections. It does not use IPv6 SOCKSPorts or HiddenServicePorts.
 
 The configuration files:
   networks/basic holds the configuration for the network you're configuring

+ 54 - 19
lib/chutney/TorNet.py

@@ -702,6 +702,7 @@ class LocalNodeController(NodeController):
                     self._env['poll_launch_time_default']
             return False
 
+# XXX: document these options
 DEFAULTS = {
     'authority': False,
     'bridgeauthority': False,
@@ -751,6 +752,10 @@ DEFAULTS = {
     'bootstrap_time': int(os.environ.get('CHUTNEY_BOOTSTRAP_TIME',
                                          os.environ.get('BOOTSTRAP_TIME',
                                                         60))),
+    # the PID of the controlling script (for __OwningControllerProcess)
+    'controlling_pid': (int(os.environ.get('CHUTNEY_CONTROLLING_PID', 0))
+                        if 'CHUTNEY_CONTROLLING_PID' in os.environ
+                        else None),
 }
 
 
@@ -761,27 +766,32 @@ class TorEnviron(chutney.Templating.Environ):
 
        Environment fields provided:
 
-          orport, controlport, socksport, dirport:
-          dir:
-          nick:
-          tor_gencert:
-          auth_passphrase:
-          torrc_template_path:
-          hs_hostname:
+          orport, controlport, socksport, dirport: *Port torrc option
+          dir: DataDirectory torrc option
+          nick: Nickname torrc option
+          tor_gencert: name or path of the tor-gencert binary
+          auth_passphrase: obsoleted by CookieAuthentication
+          torrc_template_path: path to chutney torrc_templates directory
+          hs_hostname: the hostname of the key generated by a hidden service
+          owning_controller_process: the __OwningControllerProcess torrc line,
+             disabled if tor should continue after the script exits
 
        Environment fields used:
-          nodenum
-          tag
-          orport_base, controlport_base, socksport_base, dirport_base
-          tor-gencert (note hyphen)
-          chutney_dir
-          tor
-          dir
-          hs_directory
-          nick (debugging only)
-          hs-hostname (note hyphen)
-
-       XXXX document the above.  Or document all fields in one place?
+          nodenum: chutney's internal node number for the node
+          tag: a short text string that represents the type of node
+          orport_base, controlport_base, socksport_base, dirport_base: the
+             initial port numbers used by nodenum 0. Each additional node adds
+             1 to the port numbers.
+          tor-gencert (note hyphen): name or path of the tor-gencert binary (if
+             present)
+          chutney_dir: directory of the chutney source code
+          tor: name or path of the tor binary
+          net_base_dir: path to the chutney net directory
+          hs_directory: name of the hidden service directory
+          nick: Nickname torrc option (debugging only)
+          hs-hostname (note hyphen): cached hidden service hostname value
+          controlling_pid: the PID of the controlling process. After this
+             process exits, the child tor processes will exit
     """
 
     def __init__(self, parent=None, **kwargs):
@@ -842,6 +852,21 @@ class TorEnviron(chutney.Templating.Environ):
                       (my['nick'], e.errno, e.strerror, hs_hostname_file))
         return my['hs-hostname']
 
+    def _get_owning_controller_process(self, my):
+        cpid = my['controlling_pid']
+        if cpid is None:
+            cpid = 0
+        ocp_line = ('__OwningControllerProcess %d' % (cpid))
+        # if we want to leave the network running, or controlling_pid is 1
+        # (or invalid)
+        if (os.environ.get('CHUTNEY_START_TIME', 0) < 0 or
+            os.environ.get('CHUTNEY_BOOTSTRAP_TIME', 0) < 0 or
+            os.environ.get('CHUTNEY_STOP_TIME', 0) < 0 or
+            cpid <= 1):
+            return '#' + ocp_line
+        else:
+            return ocp_line
+
 
 class Network(object):
 
@@ -982,17 +1007,27 @@ class Network(object):
                 if c.isRunning():
                     c.stop(sig=sig)
             print("Waiting for nodes to finish.")
+            wrote_dot = False
             for n in range(15):
                 time.sleep(1)
                 if all(not c.isRunning() for c in controllers):
+                    # make the output clearer by adding a newline
+                    if wrote_dot:
+                        sys.stdout.write("\n")
+                        sys.stdout.flush()
                     # check for stale lock file when Tor crashes
                     for c in controllers:
                         c.cleanup_lockfile()
                     return
                 sys.stdout.write(".")
+                wrote_dot = True
                 sys.stdout.flush()
             for c in controllers:
                 c.check(listNonRunning=False)
+            # make the output clearer by adding a newline
+            if wrote_dot:
+                sys.stdout.write("\n")
+                sys.stdout.flush()
 
 
 def ConfigureNodes(nodelist):

+ 12 - 1
tools/test-network.sh

@@ -9,6 +9,9 @@ myname=$(basename "$0")
 export CHUTNEY_WARNINGS_IGNORE_EXPECTED=${CHUTNEY_WARNINGS_IGNORE_EXPECTED:-true}
 export CHUTNEY_WARNINGS_SUMMARY=${CHUTNEY_WARNINGS_SUMMARY:-true}
 
+# default to exiting when this script exits
+export CHUTNEY_CONTROLLING_PID=${CHUTNEY_CONTROLLING_PID:-$$}
+
 # what we say when we fail
 UPDATE_YOUR_CHUTNEY="Please update your chutney using 'git pull'."
 
@@ -63,6 +66,12 @@ do
       export CHUTNEY_STOP_TIME="$2"
       shift
     ;;
+    # If all of the CHUTNEY_*_TIME options are positive, chutney will ask tor
+    # to exit when this PID exits. Set to 1 or lower to disable.
+    --controlling-pid)
+      export CHUTNEY_CONTROLLING_PID="$2"
+      shift
+    ;;
     # Environmental variables used by chutney verify performance tests
     # Send this many bytes per client connection (10 KBytes)
     --data|--data-bytes|--data-byte|--bytes|--byte)
@@ -282,7 +291,7 @@ if [ "$CHUTNEY_BOOTSTRAP_TIME" -ge 0 ]; then
   VERIFY_EXIT_STATUS="$?"
 else
   $ECHO "Chutney network ready and running. To stop the network, use:"
-  $ECHO "$CHUTNEY" stop "$CHUTNEY_NETWORK"
+  $ECHO "$CHUTNEY stop $CHUTNEY_NETWORK"
   "$WARNINGS"
   exit 0
 fi
@@ -295,6 +304,8 @@ if [ "$CHUTNEY_STOP_TIME" -ge 0 ]; then
   # work around a bug/feature in make -j2 (or more)
   # where make hangs if any child processes are still alive
   "$CHUTNEY" stop "$CHUTNEY_NETWORK"
+  # Give tor time to exit gracefully
+  sleep 3
   "$WARNINGS"
   exit "$VERIFY_EXIT_STATUS"
 else

+ 6 - 1
torrc_templates/common.i

@@ -36,7 +36,8 @@ DataDirectory $dir
 RunAsDaemon 1
 ConnLimit $connlimit
 Nickname $nick
-ShutdownWaitLength 0
+# Let tor close connections gracefully before exiting
+ShutdownWaitLength 2
 DisableDebuggerAttachment 0
 
 ControlPort $controlport
@@ -44,6 +45,10 @@ ControlPort $controlport
 ControlSocket ${dir}/control
 CookieAuthentication 1
 PidFile ${dir}/pid
+# Ask all child tor processes to exit when chutney's test-network.sh exits
+# (if the CHUTNEY_*_TIME options leave the network running, this option is
+# disabled)
+${owning_controller_process}
 
 Log notice file ${dir}/notice.log
 Log info file ${dir}/info.log