changed CLI to MininetFacade; a great deal of logic also changed

This commit is contained in:
Brian O'Connor
2013-09-11 12:00:13 -07:00
committed by Brian O'Connor
parent ad5a0e42d0
commit 15146d900c
3 changed files with 64 additions and 39 deletions
+45 -31
View File
@@ -31,30 +31,43 @@ class DataController( Controller ):
pass pass
class CLI2( CLI ): class MininetFacade:
"CLI that can talk to two networks" "TODO: CLI that can talk to two or more networks"
def __init__( self, *args, **kwargs ): def __init__( self, *args ):
"cnet: second network" self.nets = args
self.cnet = kwargs.pop( 'cnet' )
CLI.__init__( self, *args, **kwargs )
def updateVars( self ): # default is first net
"Update variables to include cnet" def __getattr__( self, name ):
cnet = self.cnet return getattr( self.nets[ 0 ], name )
nodes2 = cnet.controllers + cnet.switches + cnet.hosts
self.nodelist += nodes2
for node in nodes2:
self.nodemap[ node.name ] = node
self.locals[ 'cnet' ] = cnet
self.locals.update( self.nodemap )
def cmdloop( self, *args, **kwargs ):
"Patch to add cnet if needed"
if 'cnet' not in self.locals:
self.updateVars()
CLI.cmdloop( self, *args, **kwargs )
def __getitem__( self, key ):
for net in self.nets:
if key in net:
return net[ key ]
def __iter__( self ):
for net in self.nets:
for node in net:
yield node
def __len__( self ):
count = 0
for net in self.nets:
count += len(net)
return count
def __contains__( self, key ):
return key in self.keys()
def keys( self ):
return list( self )
def values( self ):
return [ self[ key ] for key in self ]
def items( self ):
return zip( self.keys(), self.values() )
# A real control network! # A real control network!
@@ -83,32 +96,33 @@ setLogLevel( 'info' )
info( '* Creating Control Network\n' ) info( '* Creating Control Network\n' )
ctopo = ControlNetwork( n=4, dataController=DataController ) ctopo = ControlNetwork( n=4, dataController=DataController )
cnet = Mininet( topo=ctopo, ipBase='192.168.123.0/24', build=False ) cnet = Mininet( topo=ctopo, ipBase='192.168.123.0/24', controller=None )
info( '* Adding Control Network Controller\n') info( '* Adding Control Network Controller\n')
cnet.addController( 'cc0' ) cnet.addController( 'cc0', controller=Controller )
info( '* Starting Control Network\n') info( '* Starting Control Network\n')
cnet.build()
cnet.start() cnet.start()
dataControllers = cnet.hosts[ : -1 ] # ignore 'root' node
info( '* Creating Data Network\n' ) info( '* Creating Data Network\n' )
topo = TreeTopo( depth=2, fanout=2 ) topo = TreeTopo( depth=2, fanout=2 )
# UserSwitch so we can easily test failover # UserSwitch so we can easily test failover
net = Mininet( topo=topo, switch=UserSwitch, build=False ) net = Mininet( topo=topo, switch=UserSwitch, controller=None )
info( '* Adding Controllers to Data Network\n' ) info( '* Adding Controllers to Data Network\n' )
net.controllers = dataControllers for host in cnet.hosts:
net.build() if isinstance(host, Controller):
net.addController( host )
info( '* Starting Data Network\n') info( '* Starting Data Network\n')
net.start() net.start()
CLI2( net, cnet=cnet ) mn = MininetFacade( net, cnet )
mn.keys()
CLI( mn )
info( '* Stopping Data Network\n' ) info( '* Stopping Data Network\n' )
net.stop() net.stop()
info( '* Stopping Control Network\n' ) info( '* Stopping Control Network\n' )
# dataControllers have already been stopped # dataControllers have already been stopped -- now terminate is idempotent
cnet.hosts = list( set( cnet.hosts ) - set( dataControllers ) ) #cnet.hosts = list( set( cnet.hosts ) - set( dataControllers ) )
cnet.stop() cnet.stop()
+16 -7
View File
@@ -209,9 +209,16 @@ class Mininet( object ):
def addController( self, name='c0', controller=None, **params ): def addController( self, name='c0', controller=None, **params ):
"""Add controller. """Add controller.
controller: Controller class""" controller: Controller class"""
#Get controller class
if not controller: if not controller:
controller = self.controller controller = self.controller
controller_new = controller( name, **params ) #Construct new controller if one is not given
if isinstance(name, Controller):
controller_new = name
name = controller_new.name
else:
controller_new = controller( name, **params )
#Add new controller to net
if controller_new: # allow controller-less setups if controller_new: # allow controller-less setups
self.controllers.append( controller_new ) self.controllers.append( controller_new )
self.nameToNode[ name ] = controller_new self.nameToNode[ name ] = controller_new
@@ -230,9 +237,9 @@ class Mininet( object ):
return self.getNodeByName( *args ) return self.getNodeByName( *args )
# Even more convenient syntax for node lookup and iteration # Even more convenient syntax for node lookup and iteration
def __getitem__( self, *args ): def __getitem__( self, key ):
"""net [ name ] operator: Return node(s) with given name(s)""" """net [ name ] operator: Return node(s) with given name(s)"""
return self.getNodeByName( *args ) return self.nameToNode[ key ]
def __iter__( self ): def __iter__( self ):
"return iterator over nodes" "return iterator over nodes"
@@ -246,15 +253,17 @@ class Mininet( object ):
def __contains__( self, item ): def __contains__( self, item ):
"returns True if net contains named node" "returns True if net contains named node"
return item in self.keys() return item in self.nameToNode
def keys( self ): def keys( self ):
"return a list of all node names or net's keys" "return a list of all node names or net's keys"
return list( self.__iter__() ) #TODO: fix this
return list( self )
def values( self ): def values( self ):
"return a list of all nodes or net's values" "return a list of all nodes or net's values"
return [ self[name] for name in self.__iter__() ] #TODO: fix this
return [ self[name] for name in self ]
def items( self ): def items( self ):
"return (key,value) tuple list for every node in net" "return (key,value) tuple list for every node in net"
@@ -307,7 +316,7 @@ class Mininet( object ):
info( '*** Creating network\n' ) info( '*** Creating network\n' )
if not self.controllers: if not self.controllers and self.controller:
# Add a default controller # Add a default controller
info( '*** Adding controller\n' ) info( '*** Adding controller\n' )
classes = self.controller classes = self.controller
+3 -1
View File
@@ -183,7 +183,8 @@ class Node( object ):
def terminate( self ): def terminate( self ):
"Send kill signal to Node and clean up after it." "Send kill signal to Node and clean up after it."
os.kill( self.pid, signal.SIGKILL ) if self.shell:
os.kill( self.pid, signal.SIGKILL )
self.cleanup() self.cleanup()
def stop( self ): def stop( self ):
@@ -1240,3 +1241,4 @@ class RemoteController( Controller ):
if 'Unable' in listening: if 'Unable' in listening:
warn( "Unable to contact the remote controller" warn( "Unable to contact the remote controller"
" at %s:%d\n" % ( self.ip, self.port ) ) " at %s:%d\n" % ( self.ip, self.port ) )