Added ability to show switches and controllers.
This commit is contained in:
+61
-31
@@ -19,20 +19,15 @@ class Console( Frame ):
|
|||||||
|
|
||||||
def __init__( self, parent, net, node, height=10, width=32 ):
|
def __init__( self, parent, net, node, height=10, width=32 ):
|
||||||
Frame.__init__( self, parent )
|
Frame.__init__( self, parent )
|
||||||
|
|
||||||
self.net = net
|
self.net = net
|
||||||
self.node = node
|
self.node = node
|
||||||
self.prompt = node.name + '# '
|
self.prompt = node.name + '# '
|
||||||
self.height, self.width = height, width
|
self.height, self.width = height, width
|
||||||
self.text = self.makeWidgets( )
|
|
||||||
self.bindEvents()
|
|
||||||
self.append( self.prompt )
|
|
||||||
|
|
||||||
def makeWidgets( self ):
|
# Initialize widget styles
|
||||||
"Make a label, a text area, and a scroll bar."
|
self.buttonStyle = { 'font': 'Monaco 7' }
|
||||||
buttonStyle = {
|
self.textStyle = {
|
||||||
'font': 'Monaco 7',
|
|
||||||
}
|
|
||||||
textStyle = {
|
|
||||||
'font': 'Monaco 7',
|
'font': 'Monaco 7',
|
||||||
'bg': 'black',
|
'bg': 'black',
|
||||||
'fg': 'green',
|
'fg': 'green',
|
||||||
@@ -44,12 +39,22 @@ class Console( Frame ):
|
|||||||
'selectforeground': 'black',
|
'selectforeground': 'black',
|
||||||
'selectbackground': 'green'
|
'selectbackground': 'green'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Set up widgets
|
||||||
|
self.text = self.makeWidgets( )
|
||||||
|
self.bindEvents()
|
||||||
|
self.append( self.prompt )
|
||||||
|
|
||||||
|
def makeWidgets( self ):
|
||||||
|
"Make a label, a text area, and a scroll bar."
|
||||||
|
|
||||||
def newTerm( net=self.net, node=self.node ):
|
def newTerm( net=self.net, node=self.node ):
|
||||||
"Pop up a new terminal window for a node."
|
"Pop up a new terminal window for a node."
|
||||||
net.terms += makeTerms( [ node ] )
|
net.terms += makeTerms( [ node ] )
|
||||||
label = Button( self, text=self.node.name, command=newTerm, **buttonStyle )
|
label = Button( self, text=self.node.name, command=newTerm,
|
||||||
|
**self.buttonStyle )
|
||||||
label.pack( side='top', fill='x' )
|
label.pack( side='top', fill='x' )
|
||||||
text = Text( self, wrap='word', **textStyle )
|
text = Text( self, wrap='word', **self.textStyle )
|
||||||
ybar = Scrollbar( self, orient='vertical', width=7, command=text.yview )
|
ybar = Scrollbar( self, orient='vertical', width=7, command=text.yview )
|
||||||
text.configure( yscrollcommand=ybar.set )
|
text.configure( yscrollcommand=ybar.set )
|
||||||
text.pack( side='left', expand=True, fill='both' )
|
text.pack( side='left', expand=True, fill='both' )
|
||||||
@@ -113,41 +118,59 @@ class Console( Frame ):
|
|||||||
|
|
||||||
class ConsoleApp( Frame ):
|
class ConsoleApp( Frame ):
|
||||||
|
|
||||||
def __init__( self, net, nodes, parent=None, width=4 ):
|
menuStyle = { 'font': 'Geneva 7 bold' }
|
||||||
|
|
||||||
|
def __init__( self, net, parent=None, width=4 ):
|
||||||
Frame.__init__( self, parent )
|
Frame.__init__( self, parent )
|
||||||
self.top = self.winfo_toplevel()
|
self.top = self.winfo_toplevel()
|
||||||
self.top.title( 'Mininet' )
|
self.top.title( 'Mininet' )
|
||||||
self.net = net
|
self.net = net
|
||||||
self.nodes = nodes
|
self.menubar = self.createMenuBar()
|
||||||
self.createMenuBar( font='Geneva 7' )
|
cframe = self.cframe = Frame( self )
|
||||||
self.consoles = self.createConsoles( nodes, width )
|
self.consoles = {} # consoles themselves
|
||||||
|
for name in 'hosts', 'switches', 'controllers':
|
||||||
|
nodes = getattr( net, name )
|
||||||
|
frame, consoles = self.createConsoles( cframe, nodes, width )
|
||||||
|
self.consoles[ name ] = Object( frame=frame, consoles=consoles )
|
||||||
|
self.selected = None
|
||||||
|
self.select( 'hosts' )
|
||||||
|
self.cframe.pack( expand=True, fill='both' )
|
||||||
self.pack( expand=True, fill='both' )
|
self.pack( expand=True, fill='both' )
|
||||||
cleanUpScreens()
|
cleanUpScreens()
|
||||||
# Close window gracefully
|
# Close window gracefully
|
||||||
Wm.wm_protocol( self.top, name='WM_DELETE_WINDOW', func=self.quit )
|
Wm.wm_protocol( self.top, name='WM_DELETE_WINDOW', func=self.quit )
|
||||||
|
|
||||||
def createConsoles( self, nodes, width ):
|
def createConsoles( self, parent, nodes, width ):
|
||||||
"Create a grid of consoles in a frame."
|
"Create a grid of consoles in a frame."
|
||||||
f = Frame( self )
|
f = Frame( parent )
|
||||||
# Create consoles
|
# Create consoles
|
||||||
consoles = []
|
consoles = []
|
||||||
index = 0
|
index = 0
|
||||||
for node in nodes:
|
for node in nodes:
|
||||||
console = Console( f, net, node )
|
console = Console( f, net, node )
|
||||||
consoles.append( console )
|
consoles.append( console )
|
||||||
row = int( index / width )
|
row = index / width
|
||||||
column = index % width
|
column = index % width
|
||||||
console.grid( row=row, column=column, sticky='nsew' )
|
console.grid( row=row, column=column, sticky='nsew' )
|
||||||
index += 1
|
index += 1
|
||||||
f.rowconfigure( row, weight=1 )
|
f.rowconfigure( row, weight=1 )
|
||||||
f.columnconfigure( column, weight=1 )
|
f.columnconfigure( column, weight=1 )
|
||||||
f.pack( expand=True, fill='both' )
|
return f, consoles
|
||||||
return consoles
|
|
||||||
|
|
||||||
def createMenuBar( self, font ):
|
def select( self, set ):
|
||||||
|
"Select a set of consoles to display."
|
||||||
|
if self.selected is not None:
|
||||||
|
self.selected.frame.pack_forget()
|
||||||
|
self.selected = self.consoles[ set ]
|
||||||
|
self.selected.frame.pack( expand=True, fill='both' )
|
||||||
|
|
||||||
|
def createMenuBar( self ):
|
||||||
"Create and return a menu (really button) bar."
|
"Create and return a menu (really button) bar."
|
||||||
f = Frame( self )
|
f = Frame( self )
|
||||||
buttons = [
|
buttons = [
|
||||||
|
( 'Hosts', lambda: self.select( 'hosts' ) ),
|
||||||
|
( 'Switches', lambda: self.select( 'switches' ) ),
|
||||||
|
( 'Controllers', lambda: self.select( 'controllers' ) ),
|
||||||
( 'Ping', self.ping ),
|
( 'Ping', self.ping ),
|
||||||
( 'Iperf', self.iperf ),
|
( 'Iperf', self.iperf ),
|
||||||
( 'Interrupt', self.stop ),
|
( 'Interrupt', self.stop ),
|
||||||
@@ -155,19 +178,19 @@ class ConsoleApp( Frame ):
|
|||||||
( 'Quit', self.quit )
|
( 'Quit', self.quit )
|
||||||
]
|
]
|
||||||
for name, cmd in buttons:
|
for name, cmd in buttons:
|
||||||
b = Button( f, text=name, command=cmd, font=font )
|
b = Button( f, text=name, command=cmd, **self.menuStyle )
|
||||||
b.pack( side='left' )
|
b.pack( side='left' )
|
||||||
f.pack( padx=4, pady=4, fill='x' )
|
f.pack( padx=4, pady=4, fill='x' )
|
||||||
return f
|
return f
|
||||||
|
|
||||||
def clear( self ):
|
def clear( self ):
|
||||||
"Clear all consoles."
|
"Clear all consoles."
|
||||||
for console in self.consoles:
|
for console in self.selected.consoles:
|
||||||
console.clear()
|
console.clear()
|
||||||
|
|
||||||
def ping( self ):
|
def ping( self ):
|
||||||
"Tell each console to ping the next one."
|
"Tell each host to ping the next one."
|
||||||
consoles = self.consoles
|
consoles = self.consoles[ 'hosts' ].consoles
|
||||||
count = len( consoles )
|
count = len( consoles )
|
||||||
i = 0
|
i = 0
|
||||||
for console in consoles:
|
for console in consoles:
|
||||||
@@ -176,8 +199,8 @@ class ConsoleApp( Frame ):
|
|||||||
console.sendCmd( 'ping ' + ip )
|
console.sendCmd( 'ping ' + ip )
|
||||||
|
|
||||||
def iperf( self ):
|
def iperf( self ):
|
||||||
"Tell each console to iperf to the next one."
|
"Tell each host to iperf to the next one."
|
||||||
consoles = self.consoles
|
consoles = self.consoles[ 'hosts' ].consoles
|
||||||
count = len( consoles )
|
count = len( consoles )
|
||||||
for console in consoles:
|
for console in consoles:
|
||||||
console.node.cmd( 'iperf -sD' )
|
console.node.cmd( 'iperf -sD' )
|
||||||
@@ -188,10 +211,11 @@ class ConsoleApp( Frame ):
|
|||||||
console.sendCmd( 'iperf -t 99999 -i 1 -c ' + ip )
|
console.sendCmd( 'iperf -t 99999 -i 1 -c ' + ip )
|
||||||
|
|
||||||
def stop( self ):
|
def stop( self ):
|
||||||
"Interrupt all consoles."
|
"Interrupt all hosts."
|
||||||
for console in self.consoles:
|
consoles = self.consoles[ 'hosts' ].consoles
|
||||||
|
for console in consoles:
|
||||||
console.handleInt()
|
console.handleInt()
|
||||||
for console in self.consoles:
|
for console in consoles:
|
||||||
console.waitOutput()
|
console.waitOutput()
|
||||||
# Shut down any iperfs that might still be running
|
# Shut down any iperfs that might still be running
|
||||||
quietRun( 'killall -9 iperf' )
|
quietRun( 'killall -9 iperf' )
|
||||||
@@ -202,10 +226,16 @@ class ConsoleApp( Frame ):
|
|||||||
self.stop()
|
self.stop()
|
||||||
Frame.quit( self )
|
Frame.quit( self )
|
||||||
|
|
||||||
|
class Object( object ):
|
||||||
|
"Generic object you can stuff junk into."
|
||||||
|
def __init__( self, **kwargs ):
|
||||||
|
for name, value in kwargs.items():
|
||||||
|
setattr( self, name, value )
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
setLogLevel( 'info' )
|
setLogLevel( 'info' )
|
||||||
net = TreeNet( depth=2, fanout=4 )
|
net = TreeNet( depth=2, fanout=4 )
|
||||||
net.start()
|
net.start()
|
||||||
app = ConsoleApp( net, net.hosts, width=4 )
|
app = ConsoleApp( net, width=4 )
|
||||||
app.mainloop()
|
app.mainloop()
|
||||||
net.stop()
|
net.stop()
|
||||||
|
|||||||
Reference in New Issue
Block a user