diff --git a/bin/mn_clean.py b/bin/mn_clean.py index 5bbe7e7..68d2657 100755 --- a/bin/mn_clean.py +++ b/bin/mn_clean.py @@ -15,6 +15,7 @@ from subprocess import Popen, PIPE import re from mininet.util import quietRun +from mininet.xterm import cleanUpScreens def sh( cmd ): "Print a command and send it to the shell" @@ -22,14 +23,6 @@ def sh( cmd ): return Popen( [ '/bin/sh', '-c', cmd ], stdout=PIPE ).communicate()[ 0 ] -def cleanUpScreens(): - "Remove moldy old screen sessions." - r = r'(\d+.[hsc]\d+)' - output = sh( 'screen -ls' ).split( '\n' ) - for line in output: - m = re.search( r, line ) - if m is not None: - quietRun( 'screen -S ' + m.group( 1 ) + ' -X kill' ) def cleanup(): """Clean up junk which might be left over from old runs; diff --git a/bin/mn_run.py b/bin/mn_run.py index 2c566c4..3167f09 100755 --- a/bin/mn_run.py +++ b/bin/mn_run.py @@ -85,7 +85,7 @@ class MininetRunner(object): opts.add_option('--test', type = 'choice', choices = TESTS, default = TESTS[0], help = '[' + ' '.join(TESTS) + ']') - opts.add_option('--xterm', '-x', action = 'store_true', + opts.add_option('--xterms', '-x', action = 'store_true', default = False, help = 'spawn xterms for each node') opts.add_option('--verbosity', '-v', type = 'choice', choices = LEVELS.keys(), default = 'info', @@ -117,7 +117,9 @@ class MininetRunner(object): controller = CONTROLLERS[self.options.controller] controller_params = ControllerParams(0x0a000000, 8) # 10.0.0.0/8 - mn = Mininet(topo, switch, host, controller, controller_params) + xterms = self.options.xterms + mn = Mininet(topo, switch, host, controller, controller_params, + xterms = xterms) test = self.options.test if test != 'build': diff --git a/examples/xterms.py b/examples/xterms.py deleted file mode 100755 index 787d992..0000000 --- a/examples/xterms.py +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/python - -""" -Create a network and run an xterm (connected via screen(1) ) on each -host. Requires xterm(1) and GNU screen(1). -""" - -import os, re -from subprocess import Popen -from mininet.mininet import init, TreeNet, quietRun - -def makeXterm( node, title ): - "Run screen on a node, and hook up an xterm." - title += ': ' + node.name - if not node.inNamespace: title += ' (root)' - cmd = [ 'xterm', '-title', title, '-e' ] - if not node.execed: - node.cmdPrint( 'screen -dmS ' + node.name ) - cmd += [ 'screen', '-D', '-RR', '-S', node.name ] - else: - cmd += [ 'sh', '-c', 'exec tail -f /tmp/' + node.name + '*.log' ] - return Popen( cmd ) - -def cleanUpScreens(): - "Remove moldy old screen sessions." - r = r'(\d+.[hsc]\d+)' - output = quietRun( 'screen -ls' ).split( '\n' ) - for line in output: - m = re.search( r, line ) - if m is not None: - quietRun( 'screen -S ' + m.group( 1 ) + ' -X kill' ) - -def makeXterms( nodes, title ): - return [ makeXterm( node, title) for node in nodes] - -def xterms( controllers, switches, hosts ): - cleanUpScreens() - terms = makeXterms( controllers, 'controller' ) - terms += makeXterms( switches, 'switch' ) - terms += makeXterms( hosts, 'host' ) - # Wait for xterms to exit - for term in terms: - os.waitpid( term.pid, 0 ) - cleanUpScreens() - -if __name__ == '__main__': - init() - print "Running xterms on", os.environ[ 'DISPLAY' ] - network = TreeNet( depth=2, fanout=2, kernel=True ) - network.run( xterms ) diff --git a/mininet/net.py b/mininet/net.py index 0a72349..77e7f5d 100755 --- a/mininet/net.py +++ b/mininet/net.py @@ -47,6 +47,7 @@ Naming: """ import os import re +import signal from subprocess import call import sys from time import sleep @@ -54,6 +55,7 @@ from time import sleep from mininet.logging_mod import lg from mininet.util import quietRun, fixLimits from mininet.util import make_veth_pair, move_intf, retry, MOVEINTF_DELAY +from mininet.xterm import cleanUpScreens, makeXterms DATAPATHS = ['kernel'] #['user', 'kernel'] @@ -101,6 +103,8 @@ class Mininet(object): self.in_namespace = in_namespace self.switch_is_kernel = switch_is_kernel + self.terms = [] # list of spawned xterm processes + self.kernel = True #temporary! if build: @@ -286,7 +290,30 @@ class Mininet(object): self._config_hosts() if xterms: - pass # build xterms + self.start_xterms() + + def switch_nodes(self): + '''Return switch nodes.''' + return [self.nodes[dpid] for dpid in self.topo.switches()] + + def host_nodes(self): + '''Return host nodes.''' + return [self.nodes[dpid] for dpid in self.topo.hosts()] + + def start_xterms(self): + '''Start an xterm for each node in the topo.''' + lg.info("*** Running xterms on %s\n" % os.environ['DISPLAY']) + cleanUpScreens() + self.terms += makeXterms(self.controllers.values(), 'controller') + self.terms += makeXterms(self.switch_nodes(), 'switch') + self.terms += makeXterms(self.host_nodes(), 'host') + + def stop_xterms(self): + '''Kill each xterm.''' + # Kill xterms + for term in self.terms: + os.kill(term.pid, signal.SIGKILL) + cleanUpScreens() def start(self): '''Start controller and switches\n''' @@ -303,6 +330,9 @@ class Mininet(object): def stop(self): '''Stop the controller(s), switches and hosts\n''' + if self.terms: + lg.info('*** Stopping %i terms\n' % len(self.terms)) + self.stop_xterms() lg.info('*** Stopping %i hosts\n' % len(self.topo.hosts())) for host_dpid in self.topo.hosts(): host = self.nodes[host_dpid] diff --git a/mininet/xterm.py b/mininet/xterm.py new file mode 100755 index 0000000..9dbb96f --- /dev/null +++ b/mininet/xterm.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python +"""XTerm creation and cleanup. + +Utility functions to run an xterm (connected via screen(1)) on each host. + +Requires xterm(1) and GNU screen(1). +""" + +import os +import re +from subprocess import Popen + +from mininet.util import quietRun + +def makeXterm(node, title): + '''Run screen on a node, and hook up an xterm. + + @param node Node object + @param title base title + @return process created + ''' + title += ': ' + node.name + if not node.inNamespace: + title += ' (root)' + cmd = ['xterm', '-title', title, '-e'] + if not node.execed: + node.cmdPrint('screen -dmS ' + node.name) + cmd += ['screen', '-D', '-RR', '-S', node.name] + else: + cmd += ['sh', '-c', 'exec tail -f /tmp/' + node.name + '*.log'] + return Popen(cmd) + + +def cleanUpScreens(): + '''Remove moldy old screen sessions.''' + r = r'(\d+.[hsc]\d+)' + output = quietRun('screen -ls').split('\n') + for line in output: + m = re.search(r, line) + if m: + quietRun('screen -S ' + m.group(1) + ' -X kill') + + +def makeXterms(nodes, title): + '''Create XTerms. + + @param nodes list of Node objects + @param title base title for each + @return list of created xterm processes + ''' + return [makeXterm(node, title) for node in nodes] \ No newline at end of file