Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
dist: pyterm control server (incl. support for multiple testbeds)
- Loading branch information
Showing
5 changed files
with
376 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
__all__ = ["pytermcontroller"] | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
#!/usr/bin/env python2 | ||
# -*- coding: utf-8 -*- | ||
|
||
# Copyright (C) 2014 Philipp Rosenkranz <philipp.rosenkranz@fu-berlin.de> | ||
# | ||
# This library is free software; you can redistribute it and/or | ||
# modify it under the terms of the GNU Lesser General Public | ||
# License as published by the Free Software Foundation; either | ||
# version 2.1 of the License, or (at your option) any later version. | ||
# | ||
# This library is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
# Lesser General Public License for more details. | ||
# | ||
# You should have received a copy of the GNU Lesser General Public | ||
# License along with this library; if not, write to the Free Software | ||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
# 02110-1301 USA | ||
|
||
|
||
import sys, signal, threading | ||
|
||
from twisted.internet import reactor | ||
from twisted.internet.protocol import Protocol, Factory | ||
|
||
|
||
class PubProtocol(Protocol): | ||
def __init__(self, factory): | ||
self.factory = factory | ||
|
||
def connectionMade(self): | ||
print("new connection made") | ||
|
||
def connectionLost(self, reason): | ||
self.factory.numProtocols = self.factory.numProtocols - 1 | ||
|
||
def connectionLost(self, reason): | ||
self.factory.clients = {key: value for key, value in self.factory.clients.items() | ||
if value is not self.transport} | ||
|
||
def dataReceived(self, data): | ||
if data.startswith("hostname: "): | ||
remoteHostname = data.split()[1].strip() | ||
print("dataReceived added: " + remoteHostname) | ||
self.factory.clients[remoteHostname] = self.transport | ||
else: | ||
print("received some useless data...") | ||
|
||
class PubFactory(Factory): | ||
def __init__(self): | ||
self.clients = dict() | ||
|
||
def buildProtocol(self, addr): | ||
return PubProtocol(self) | ||
|
||
|
||
class ExperimentRunner(): | ||
def __init__(self, experiment, testbed): | ||
self.publisher = PubFactory() | ||
self.port = int(testbed.serverPort) | ||
self.experiment = experiment(self.publisher, self) | ||
self.testbed = testbed | ||
|
||
def run(self): | ||
signal.signal(signal.SIGINT, self.handle_sigint) | ||
self.experiment.run() | ||
reactor.listenTCP(self.port, self.publisher) | ||
# clean logfiles and start nodes but don't flash nodes | ||
self.testbed.initClean() | ||
reactor.run() | ||
|
||
def stop(self): | ||
self.testbed.stop() | ||
reactor.callFromThread(self.safeReactorStop) | ||
|
||
def safeReactorStop(self): | ||
if reactor.running: | ||
try: | ||
reactor.stop() | ||
except: | ||
print("tried to shutdown reactor twice!") | ||
|
||
|
||
def handle_sigint(self, signal, frame): | ||
self.experiment.stop() | ||
self.testbed.stop() | ||
self.stop() # shutdown if experiment didn't already | ||
|
||
|
||
class Experiment(): | ||
def __init__(self, factory, runner): | ||
self.factory = factory | ||
self.runner = runner | ||
self.hostid = dict() | ||
self.sumDelay = 0 | ||
|
||
def run(self): | ||
print("Running preHook") | ||
self.preHook() | ||
print("Running experiment") | ||
self.start() | ||
|
||
def start(self): | ||
raise NotImplementedError("Inherit from Experiment and implement start") | ||
|
||
def stop(self): | ||
print("Running postHook") | ||
self.postHook() | ||
self.runner.stop() | ||
|
||
def preHook(self): | ||
pass | ||
|
||
def postHook(self): | ||
pass | ||
|
||
def readHostFile(self, path): | ||
id = 1 | ||
with open(path) as f: | ||
for line in f: | ||
self.hostid[line.strip()] = id | ||
id += 1 | ||
|
||
def sendToHost(self, host=None, cmd=""): | ||
if host in self.factory.clients: | ||
self.factory.clients[host].write(cmd + "\n") | ||
else: | ||
print("sendToHost: no such host known: " + host + " !") | ||
|
||
def sendToAll(self, cmd=""): | ||
for host, transport in self.factory.clients.items(): | ||
self.sendToHost(host, cmd) | ||
|
||
def pauseInSeconds(self, seconds=0): | ||
from time import time, sleep | ||
start = time() | ||
while (time() - start < seconds): | ||
sleep(seconds - (time() - start)) | ||
|
||
def callLater(self, absoluteDelay = 0.0, function = None): | ||
reactor.callLater(absoluteDelay, function) | ||
|
||
def waitAndCall(self, relativeDelay = 0.0, function = None): | ||
self.sumDelay += relativeDelay | ||
self.callLater(self.sumDelay, function) | ||
|
||
def clientIterator(self): | ||
return self.factory.clients.items() | ||
|
||
def connectionByHostname(self, host=None): | ||
if host in self.factory.clients: | ||
return self.factory.clients[host] | ||
|
||
@staticmethod | ||
def sendToConnection(connection, line): | ||
connection.write(line + "\n") | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
__all__ = ["testbeds"] | ||
|
Oops, something went wrong.