diff --git a/build.xml b/build.xml index 364eed9df6d828e00b2c39ce36e602e5a7824c98..90adfa85964faedc5bcc45b216333dcc00c76a93 100644 --- a/build.xml +++ b/build.xml @@ -28,6 +28,7 @@ <property name="test-output" location="${target}/test"/> <property name="source" location="src/main/java"/> <property name="source-test" location="src/test/java"/> + <property name="python-src" location="src/main/python"/> <property name="docs" location="${target}/docs"/> <property name="main-class" value="net.floodlightcontroller.core.internal.Controller"/> <property name="packetstreamer-gen" location="${target}/gen-java" /> @@ -50,6 +51,7 @@ <include name="simple-4.1.21.jar"/> <include name="netty-3.2.6.Final.jar"/> <include name="concurrentlinkedhashmap-lru-1.2.jar"/> + <include name="jython-2.5.2.jar"/> </patternset> <patternset id="genlib"> <include name="libthrift-0.7.0.jar"/> @@ -156,6 +158,9 @@ <attribute name="Class-Path" value="."/> </manifest> <fileset dir="${build}"/> + <fileset dir="${python-src}"> + <include name="**/*.py"/> + </fileset> <zipgroupfileset dir="lib"> <patternset refid="lib"/> </zipgroupfileset> diff --git a/src/main/java/net/floodlightcontroller/core/internal/Controller.java b/src/main/java/net/floodlightcontroller/core/internal/Controller.java index 18e045bc66b7e9097a83a6f2e97573c552a59439..15b4b30b01ca6e760ed04c7a784ec450fbf77453 100644 --- a/src/main/java/net/floodlightcontroller/core/internal/Controller.java +++ b/src/main/java/net/floodlightcontroller/core/internal/Controller.java @@ -65,6 +65,8 @@ import net.floodlightcontroller.counter.ICounter; import net.floodlightcontroller.counter.CounterStore.NetworkLayer; import net.floodlightcontroller.devicemanager.internal.DeviceManagerImpl; import net.floodlightcontroller.learningswitch.LearningSwitch; +import net.floodlightcontroller.forwarding.Forwarding; +import net.floodlightcontroller.jython.Server; import net.floodlightcontroller.packet.Ethernet; import net.floodlightcontroller.packet.IPv4; import net.floodlightcontroller.staticflowentry.StaticFlowEntryPusher; @@ -1478,9 +1480,29 @@ public class Controller log.debug("Starting staticFlowEntryPusher service"); staticFlowEntryPusher.startUp(); + log.debug("Starting DebugServer"); + this.debugserver_start(); } - /** + /** + * Start debug server, put global state as local variables for the jython shell + */ + protected void debugserver_start() { + Map<String, Object> locals = new HashMap<String, Object>(); + locals.put("controller", this); + locals.put("deviceManager", this.deviceManager); + locals.put("topology", this.topology); + locals.put("staticFlowEntryPusher", this.staticFlowEntryPusher); + locals.put("counterStore", this.counterStore); + locals.put("storageSource", this.storageSource); + locals.put("switches", this.switches); + locals.put("messageFilterManager", this.messageFilterManager); + + Server debug_server = new Server(6655, locals); + debug_server.start(); + } + + /** * Main function entry point; override init() for adding modules * @param args */ diff --git a/src/main/java/net/floodlightcontroller/jython/Server.java b/src/main/java/net/floodlightcontroller/jython/Server.java new file mode 100644 index 0000000000000000000000000000000000000000..8f17b9964bbb6d82cf1b267657c017cbdbada68c --- /dev/null +++ b/src/main/java/net/floodlightcontroller/jython/Server.java @@ -0,0 +1,30 @@ +package net.floodlightcontroller.jython; + +import java.util.Map; + +import org.python.util.PythonInterpreter; + +public class Server extends Thread { + int port; + Map<String, Object> locals; + + public Server(int port_, Map<String, Object> locals_) { + this.port = port_ ; + this.locals = locals_; + + } + + public void run() { + PythonInterpreter p = new PythonInterpreter(); + for (String name : this.locals.keySet()) { + p.set(name, this.locals.get(name)); + } + + String jarPath = Server.class.getProtectionDomain().getCodeSource().getLocation().getPath(); + p.exec("import sys"); + p.exec("sys.path.append('" + jarPath + "')"); + p.exec("from debugserver import run_server"); + p.exec("run_server(" + this.port + ", '0.0.0.0', locals())"); + } + +} diff --git a/src/main/python/debugserver.py b/src/main/python/debugserver.py new file mode 100644 index 0000000000000000000000000000000000000000..2f6346f028a2bfacbfd6640a7acb7505ec74bb20 --- /dev/null +++ b/src/main/python/debugserver.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python + +import sys +from SocketServer import BaseRequestHandler, TCPServer +from code import InteractiveConsole + +_locals = None + +class DebugConsole(InteractiveConsole): + def __init__(self, request): + self.request = request + InteractiveConsole.__init__(self, _locals) + + def raw_input(self, prompt): + self.request.send(prompt) + data = self.request.recv(10000).rstrip() + if len(data) == 1 and ord(data[0]) == 4: + sys.exit() + return data + + def write(self, data): + self.request.send(str(data)) + + def write_nl(self, data): + self.write(str(data)+"\r\n") + +class DebugServerHandler(BaseRequestHandler): + def __init__(self, request, client_address, server): + print 'Open connection to DebugServer from: %s' % str(client_address) + BaseRequestHandler.__init__(self, request, client_address, server) + + def handle(self): + console = DebugConsole(self.request) + sys.displayhook = console.write_nl + console.interact('DebugServer') + self.request.close() + +class DebugServer(TCPServer): + def handle_error(self, request, client_address): + print 'Closing connection to DebugServer from: %s' % str(client_address) + request.close() + +def run_server(port=6655, host='0.0.0.0', locals=locals()): + global _locals + _locals = locals + + print "Starting DebugServer on port %d" % port + server = DebugServer(('', port), DebugServerHandler) + try: + server.serve_forever() + except KeyboardInterrupt: + pass + +if __name__ == "__main__": + run_server()