Set batch=False in OVSSwitch for low-level API

If you try to use the low-level API, you are probably
not going to call batchStartup()! So, we set batch=False
by default. This means that buildFromTopo() needs to set
it to True, so we add a bit of irritatingly complex machinery
to allow this to happen. The good fallout of this is that
now customConstructor() returns a real subclass, not simply
a constructor function! We also detect errors where people
are incorrectly attempting to give parameters to a lambda
function - since none of our lambdas accept parameters!!

Note that this is a bit like functools.partial for classes -
it would be nice if functools had a true subclassing function.
This commit is contained in:
Bob Lantz
2015-01-29 00:26:15 -08:00
parent c11e9f3316
commit a4e933688a
3 changed files with 29 additions and 15 deletions
+6 -1
View File
@@ -414,7 +414,12 @@ class Mininet( object ):
info( '\n*** Adding switches:\n' )
for switchName in topo.switches():
self.addSwitch( switchName, **topo.nodeInfo( switchName) )
# A bit ugly: add batch parameter if appropriate
params = topo.nodeInfo( switchName)
cls = params.get( 'cls', self.switch )
if hasattr( cls, 'batchStartup' ):
params.setdefault( 'batch', True )
self.addSwitch( switchName, **params )
info( switchName + ' ' )
info( '\n*** Adding links:\n' )
+2 -2
View File
@@ -1058,7 +1058,7 @@ class OVSSwitch( Switch ):
def __init__( self, name, failMode='secure', datapath='kernel',
inband=False, protocols=None,
reconnectms=1000, stp=False, batch=True, **params ):
reconnectms=1000, stp=False, batch=False, **params ):
"""name: name for switch
failMode: controller loss behavior (secure|open)
datapath: userspace or kernel mode (kernel|user)
@@ -1067,7 +1067,7 @@ class OVSSwitch( Switch ):
Unspecified (or old OVS version) uses OVS default
reconnectms: max reconnect timeout in ms (0/None for default)
stp: enable STP (False, requires failMode=standalone)
batch: enable batch startup (True)"""
batch: enable batch startup (False)"""
Switch.__init__( self, name, **params )
self.failMode = failMode
self.datapath = datapath
+21 -12
View File
@@ -536,19 +536,28 @@ def customConstructor( constructors, argStr ):
raise Exception( "error: %s is unknown - please specify one of %s" %
( cname, constructors.keys() ) )
def customized( name, *args, **params ):
"Customized constructor, useful for Node, Link, and other classes"
params = params.copy()
params.update( kwargs )
if not newargs:
return constructor( name, *args, **params )
if args:
warn( 'warning: %s replacing %s with %s\n' % (
constructor, args, newargs ) )
return constructor( name, *newargs, **params )
if not newargs and not kwargs:
return constructor
customized.__name__ = 'customConstructor(%s)' % argStr
return customized
if not isinstance( constructor, type ):
raise Exception( "error: invalid arguments %s" % argStr )
# Return a customized subclass
cls = constructor
class CustomClass( cls ):
"Customized subclass, useful for Node, Link, and other classes"
def __init__( self, name, *args, **params ):
params = params.copy()
params.update( kwargs )
if not newargs:
return cls.__init__( self, name, *args, **params )
if args:
warn( 'warning: %s replacing %s with %s\n' %
( constructor, args, newargs ) )
return cls.__init__( self, name, *newargs, **params )
CustomClass.__name__ = '%s%s' % ( cls.__name__, kwargs )
return CustomClass
def buildTopo( topos, topoStr ):
"""Create topology from string with format (object, arg1, arg2,...).