aboutsummaryrefslogtreecommitdiff
path: root/lib/chutney/TorNet.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/chutney/TorNet.py')
-rw-r--r--lib/chutney/TorNet.py93
1 files changed, 41 insertions, 52 deletions
diff --git a/lib/chutney/TorNet.py b/lib/chutney/TorNet.py
index 8e3df89..559b635 100644
--- a/lib/chutney/TorNet.py
+++ b/lib/chutney/TorNet.py
@@ -21,6 +21,8 @@ import re
import errno
import time
+import stem.control
+
import chutney.Templating
import chutney.Traffic
@@ -35,6 +37,9 @@ def mkdir_p(d, mode=0777):
return
raise
+global nodelist
+nodelist = []
+
class Node(object):
"""A Node represents a Tor node or a set of Tor nodes. It's created
in a network configuration file.
@@ -56,9 +61,12 @@ class Node(object):
self._env = self._createEnviron(parent, kwargs)
self._builder = None
self._controller = None
+ self._stemcontroller = None
+ nodelist.append(self)
- def getN(self, N):
- return [ Node(self) for _ in xrange(N) ]
+ @staticmethod
+ def create(number, args):
+ return [Node(kwargs = args) for i in range(0, number)]
def specialize(self, **kwargs):
return Node(parent=self, **kwargs)
@@ -83,6 +91,14 @@ class Node(object):
self._controller = LocalNodeController(self._env)
return self._controller
+ def getStemController(self):
+ """Return a NodeController instance to control this node (that is,
+ to start it, stop it, see if it's running, etc.)
+ """
+ if self._stemcontroller is None:
+ self._stemcontroller = stem.control.Controller.from_port(port = self._env['controlport'])
+ return self._stemcontroller
+
def setNodenum(self, num):
"""Assign a value to the 'nodenum' element of this node. Each node
in a network gets its own nodenum.
@@ -466,43 +482,17 @@ class LocalNodeController(NodeController):
"--quiet",
"-f", torrc,
]
- forkPid = -1
- noDelay = isChild = isParent = False
- if self._env['delay']:
- try:
- forkPid = os.fork()
- if forkPid == 0:
- isChild = True
- time.sleep(self._env['delay'])
- else:
- isParent = True
-
- except OSError, e:
- print "Could not delay launch of %s (%s): %s"%(self._env['nick'],
- " ".join(cmdline),
- e.strerror())
- return False
- else:
- noDelay = True
-
- retval = True
- if noDelay or isChild:
- p = subprocess.Popen(cmdline)
- # XXXX this requires that RunAsDaemon is set.
- p.wait()
- if p.returncode != 0:
- print "Couldn't launch %s (%s): %s"%(self._env['nick'],
- " ".join(cmdline),
- p.returncode)
- retval = True
- if isChild:
- print "Launching %s after %d seconds" % (self._env['nick'],
- self._env['delay'])
- sys.exit(retval)
- elif isParent:
- print "Delaying launch of %s for %d seconds"%(self._env['nick'],
- self._env['delay'])
- return retval
+
+ p = subprocess.Popen(cmdline)
+ # XXXX this requires that RunAsDaemon is set.
+ p.wait()
+ if p.returncode != 0:
+ print "Couldn't launch %s (%s): %s"%(self._env['nick'],
+ " ".join(cmdline),
+ p.returncode)
+ return False
+
+ return True
def stop(self, sig=signal.SIGINT):
@@ -655,9 +645,9 @@ class Network(object):
self.start()
def start(self):
- print "Starting nodes"
+ print "Starting network"
self._dfltEnv['start_time'] = time.time()
- return all([n.getController().start() for n in self._nodes])
+ return self._start()
def hup(self):
print "Sending SIGHUP to nodes"
@@ -707,34 +697,33 @@ class Network(object):
('localhost', int(op._env['socksport']))))
return tt.run()
-def ConfigureNodes(nodelist):
- network = _THE_NETWORK
-
- for n in nodelist:
- network._addNode(n)
- if n._env['bridgeauthority']:
- network._dfltEnv['hasbridgeauth'] = True
-
def usage(network):
return "\n".join(["Usage: chutney {command} {networkfile}",
"Known commands are: %s" % (
" ".join(x for x in dir(network) if not x.startswith("_")))])
def runConfigFile(verb, f):
- _GLOBALS = dict(_BASE_ENVIRON= _BASE_ENVIRON,
+ _GLOBALS = dict(_BASE_ENVIRON = _BASE_ENVIRON,
Node=Node,
- ConfigureNodes=ConfigureNodes,
+ EventType=stem.control.EventType,
_THE_NETWORK=_THE_NETWORK)
exec f in _GLOBALS
network = _GLOBALS['_THE_NETWORK']
+ for n in nodelist:
+ network._addNode(n)
+ if n._env['bridgeauthority']:
+ network._dfltEnv['hasbridgeauth'] = True
+
+ network._start = _GLOBALS['start']
+
if not hasattr(network, verb):
print usage(network)
print "Error: I don't know how to %s." % verb
return
- return getattr(network,verb)()
+ return getattr(network, verb)()
def main():
global _BASE_ENVIRON