|
@@ -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):
|