diff --git a/mininet/cli.py b/mininet/cli.py index 8ea0345..3f5560b 100644 --- a/mininet/cli.py +++ b/mininet/cli.py @@ -34,7 +34,7 @@ from subprocess import call from cmd import Cmd from mininet.log import info, output, error -from mininet.xterm import makeXterms +from mininet.term import makeTerms class CLI( Cmd ): @@ -163,17 +163,23 @@ class CLI( Cmd ): else: self.mn.configLinkStatus( *args ) - def do_xterm( self, args ): - "Spawn xterm for the given node." + def do_term( self, args ): + "Spawn terminal for the given node." args = args.split() if not args: - error( 'please specify node list: xterm node1 node2 ...\n' ) + error( 'please specify node list: term [type] node1 node2 ...\n' ) else: + if args[ 0 ] in [ 'xterm', 'gnome' ]: + term = args[ 0 ] + args = args[ 1: ] + else: + term = 'xterm' for arg in args: if arg not in self.nodemap: error( 'arg not in network: %s\n' % arg ) else: - self.mn.terms += makeXterms( [ self.nodemap[ arg ] ] ) + node = self.nodemap[ arg ] + self.mn.terms += makeTerms( [ node ], term = term ) def do_exit( self, args ): "Exit" diff --git a/mininet/net.py b/mininet/net.py index 7f6d266..391b30e 100755 --- a/mininet/net.py +++ b/mininet/net.py @@ -67,7 +67,7 @@ using a topology object (e.g. LinearTopo) from mininet.topo or mininet.topolib, and a Controller which the switches will connect to. Several configuration options are provided for functions such as automatically setting MAC addresses, populating the ARP table, or -even running a set of xterms to allow direct interaction with nodes. +even running a set of terminals to allow direct interaction with nodes. After the network is created, it can be started using start(), and a variety of useful tasks maybe performed, including basic connectivity @@ -95,7 +95,7 @@ from mininet.node import Host, UserSwitch, KernelSwitch, Controller from mininet.node import ControllerParams from mininet.util import quietRun, fixLimits from mininet.util import createLink, macColonHex, ipStr, ipParse -from mininet.xterm import cleanUpScreens, makeXterms +from mininet.term import cleanUpScreens, makeTerms DATAPATHS = [ 'kernel' ] # [ 'user', 'kernel' ] @@ -310,19 +310,19 @@ class Mininet( object ): info( '*** Configuring hosts\n' ) self.configHosts() if self.xterms: - self.startXterms() + self.startTerms() if self.autoSetMacs: self.setMacs() if self.autoStaticArp: self.staticArp() - def startXterms( self ): - "Start an xterm for each node." - info( "*** Running xterms on %s\n" % os.environ[ 'DISPLAY' ] ) + def startTerms( self ): + "Start a terminal for each node." + info( "*** Running terms on %s\n" % os.environ[ 'DISPLAY' ] ) cleanUpScreens() - self.terms += makeXterms( self.controllers, 'controller' ) - self.terms += makeXterms( self.switches, 'switch' ) - self.terms += makeXterms( self.hosts, 'host' ) + self.terms += makeTerms( self.controllers, 'controller' ) + self.terms += makeTerms( self.switches, 'switch' ) + self.terms += makeTerms( self.hosts, 'host' ) def stopXterms( self ): "Kill each xterm." diff --git a/mininet/term.py b/mininet/term.py new file mode 100644 index 0000000..3b3536e --- /dev/null +++ b/mininet/term.py @@ -0,0 +1,55 @@ +""" +Terminal creation and cleanup. +Utility functions to run a term (connected via screen(1)) on each host. + +Requires GNU screen(1) and xterm(1). +Optionally uses gnome-terminal. +""" + +import re +from subprocess import Popen + +from mininet.log import error +from mininet.util import quietRun + +def makeTerm( node, title = '', term = 'xterm' ): + """Run screen on a node, and hook up an xterm. + node: Node object + title: base title + returns: process created""" + title += ': ' + node.name + if not node.inNamespace: + title += ' (root)' + cmd = '' + if term == 'xterm': + cmd = [ 'xterm', '-title', title, '-e' ] + elif term == 'gnome': + cmd = [ 'gnome-terminal', '--title', title, '-e' ] + else: + error( 'invalid terminal type: %s' % term ) + return + if not node.execed: + node.cmd( 'screen -dmS ' + node.name) + #cmd += [ 'screen', '-D', '-RR', '-S', node.name ] + # Compress these for gnome-terminal, which expects one token to follow + # the -e option . + 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 quit' ) + +def makeTerms( nodes, title = '', term = 'xterm' ): + """Create terminals. + nodes: list of Node objects + title: base title for each + returns: list of created terminal processes""" + return [ makeTerm( node, title, term ) for node in nodes ] diff --git a/mininet/xterm.py b/mininet/xterm.py deleted file mode 100644 index 41210f2..0000000 --- a/mininet/xterm.py +++ /dev/null @@ -1,42 +0,0 @@ -""" -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 re -from subprocess import Popen -from mininet.util import quietRun - -def makeXterm( node, title = '' ): - """Run screen on a node, and hook up an xterm. - node: Node object - title: base title - returns: process created""" - title += ': ' + node.name - if not node.inNamespace: - title += ' (root)' - cmd = [ 'xterm', '-title', title, '-e' ] - if not node.execed: - node.cmd( '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 quit' ) - -def makeXterms( nodes, title = '' ): - """Create XTerms. - nodes: list of Node objects - title: base title for each - returns: list of created xterm processes""" - return [ makeXterm( node, title ) for node in nodes ]