Commit 65f4b301 authored by Nick Mathewson's avatar Nick Mathewson 🦀
Browse files

Merge remote-tracking branch 'tor-github/pr/70'

parents bb4e5f61 2f0e34e4
Loading
Loading
Loading
Loading
+31 −2
Original line number Diff line number Diff line
@@ -437,6 +437,8 @@ class Node(object):
        self._controller = None

    def getN(self, N):
        """Generate 'N' nodes of the same configuration as this node.
        """
        return [Node(self) for _ in range(N)]

    def specialize(self, **kwargs):
@@ -527,22 +529,26 @@ class NodeBuilder(_NodeCommon):
    def checkConfig(self, net):
        """Try to format our torrc; raise an exception if we can't.
        """
        raise NotImplementedError()

    def preConfig(self, net):
        """Called on all nodes before any nodes configure: generates keys as
           needed.
        """
        raise NotImplementedError()

    def config(self, net):
        """Called to configure a node: creates a torrc file for it."""
        raise NotImplementedError()

    def postConfig(self, net):
        """Called on each nodes after all nodes configure."""

        raise NotImplementedError()

    def isSupported(self, net):
        """Return true if this node appears to have everything it needs;
           false otherwise."""
        raise NotImplementedError()


class NodeController(_NodeCommon):
@@ -565,9 +571,11 @@ class NodeController(_NodeCommon):
    def start(self):
        """Try to start this node; return True if we succeeded or it was
           already running, False if we failed."""
        raise NotImplementedError()

    def stop(self, sig=signal.SIGINT):
        """Try to stop this node by sending it the signal 'sig'."""
        raise NotImplementedError()


class LocalNodeBuilder(NodeBuilder):
@@ -1111,6 +1119,7 @@ class LocalNodeController(NodeController):
        os.kill(pid, sig)

    def cleanup_lockfile(self):
        """Remove lock file if this node is no longer running."""
        lf = self._env['lockfile']
        if not self.isRunning() and os.path.exists(lf):
            debug("Removing stale lock file for {} ..."
@@ -1118,11 +1127,13 @@ class LocalNodeController(NodeController):
            os.remove(lf)

    def cleanup_pidfile(self):
        """Move PID file to pidfile.old if this node is no longer running
           so that we don't try to stop the node again.
        """
        pidfile = self._env['pidfile']
        if not self.isRunning() and os.path.exists(pidfile):
            debug("Renaming stale pid file for {} ..."
                  .format(self._env['nick']))
            # Move the pidfile, so that we don't try to stop the process again
            os.rename(pidfile, pidfile + ".old")

    def waitOnLaunch(self):
@@ -2108,6 +2119,9 @@ class Network(object):
            sys.exit(1)

    def configure(self):
        """Invoked from command line: Configure and prepare the network to be
           started.
        """
        phase = self._dfltEnv['CUR_CONFIG_PHASE']
        if phase == 1:
            self.create_new_nodes_dir()
@@ -2138,6 +2152,9 @@ class Network(object):
            b.postConfig(network)

    def status(self):
        """Print how many nodes are running and how many are expected, and
           return True if all nodes are running.
        """
        statuses = [n.getController().check(listNonRunning=True)
                    for n in self._nodes]
        n_ok = len([x for x in statuses if x])
@@ -2145,10 +2162,14 @@ class Network(object):
        return n_ok == len(self._nodes)

    def restart(self):
        """Invoked from command line: Stop and subsequently start our
           network's nodes.
        """
        self.stop()
        self.start()

    def start(self):
        """Start all our network's nodes and return True on no errors."""
        # format polling correctly - avoid printing a newline
        sys.stdout.write("Starting nodes")
        sys.stdout.flush()
@@ -2162,6 +2183,9 @@ class Network(object):
        return rv

    def hup(self):
        """Send SIGHUP to all our network's running nodes and return True on no
           errors.
        """
        print("Sending SIGHUP to nodes")
        return all([n.getController().hup() for n in self._nodes])

@@ -2235,6 +2259,9 @@ class Network(object):
    CHECKS_PER_PRINT = PRINT_NETWORK_STATUS_DELAY / CHECK_NETWORK_STATUS_DELAY

    def wait_for_bootstrap(self):
        """Invoked from tools/test-network.sh to wait for the network to
           bootstrap.
        """
        print("Waiting for nodes to bootstrap...\n")
        start = time.time()
        limit = start + getenv_int("CHUTNEY_START_TIME", 60)
@@ -2398,6 +2425,7 @@ class Network(object):
                c.cleanup_pidfile()

    def stop(self):
        """Stop our network's running tor nodes."""
        any_tor_was_running = False
        controllers = [n.getController() for n in self._nodes]
        for sig, desc in [(signal.SIGINT, "SIGINT"),
@@ -2502,6 +2530,7 @@ def runConfigFile(verb, data):


def parseArgs():
    """Parse and return commandline arguments."""
    if len(sys.argv) < 3:
        exit_on_error("Not enough arguments given.")
    if not os.path.isfile(sys.argv[2]):