Refactor for compatibility with isOldOVS() == True

This commit is contained in:
Bob Lantz
2015-01-26 14:06:23 -08:00
parent 3b4738c2ca
commit 957fe1db93
+52 -55
View File
@@ -1107,10 +1107,12 @@ class OVSSwitch( Switch ):
@classmethod @classmethod
def batchShutdown( cls, switches ): def batchShutdown( cls, switches ):
"Shut down a list of OVS switches" "Shut down a list of OVS switches"
delcmd = 'del-br %s'
if not cls.isOldOVS():
delcmd = '--if-exists ' + delcmd
# First, delete them all from ovsdb # First, delete them all from ovsdb
quietRun( 'ovs-vsctl ' + quietRun( 'ovs-vsctl ' +
' -- '.join( '--if-exists del-br %s' % s ' -- '.join( delcmd % s for s in switches ) )
for s in switches ) )
# Next, shut down all of the processes # Next, shut down all of the processes
pids = ' '.join( str( switch.pid ) for switch in switches ) pids = ' '.join( str( switch.pid ) for switch in switches )
quietRun( 'kill -HUP ' + pids ) quietRun( 'kill -HUP ' + pids )
@@ -1165,17 +1167,31 @@ class OVSSwitch( Switch ):
return True return True
return self.failMode == 'standalone' return self.failMode == 'standalone'
@staticmethod def intfOpts( self, intf ):
def patchOpts( intf ): "Return OVS interface options for intf"
"Return OVS patch port options (if any) for intf" opts = ''
if not isinstance( intf, OVSIntf ): if not self.isOldOVS():
# Ignore if it's not a patch link # ofport_request is not supported
return '' opts += ' ofport_request=%s' % self.ports[ intf ]
# Patch ports don't work well with old OVS
if isinstance( intf, OVSIntf ):
intf1, intf2 = intf.link.intf1, intf.link.intf2 intf1, intf2 = intf.link.intf1, intf.link.intf2
peer = intf1 if intf1 != intf else intf2 peer = intf1 if intf1 != intf else intf2
return ( ' -- set Interface %s type=patch' opts += ' type=patch options:peer=%s' % peer
' -- set Interface %s options:peer=%s' % return '' if not opts else ' -- set Interface %s' % intf + opts
( intf, intf, peer ) )
def bridgeOpts( self ):
"Return OVS bridge options"
opts = ''
if not self.inband:
opts += ' other-config:disable-in-band=true'
if self.datapath == 'user':
opts += ' datapath_type=netdev' % self
if self.protocols and not self.isOldOVS():
opts += ' protocols=%s' % ( self, self.protocols )
if self.stp and self.failMode == 'standalone':
opts += ' stp_enable=true' % self
return opts
# pylint: disable=too-many-branches # pylint: disable=too-many-branches
def start( self, controllers ): def start( self, controllers ):
@@ -1186,53 +1202,29 @@ class OVSSwitch( Switch ):
int( self.dpid, 16 ) # DPID must be a hex string int( self.dpid, 16 ) # DPID must be a hex string
# Interfaces and controllers # Interfaces and controllers
intfs = ''.join( ' -- add-port %s %s' % ( self, intf ) + intfs = ''.join( ' -- add-port %s %s' % ( self, intf ) +
'-- set Interface %s ' % intf + self.intfOpts( intf )
'ofport_request=%s' % self.ports[ intf ]
+ self.patchOpts( intf )
for intf in self.intfList() for intf in self.intfList()
if self.ports[ intf ] and not intf.IP() ) if self.ports[ intf ] and not intf.IP() )
# Construct big ovs-vsctl command for new versions of OVS # Construct big ovs-vsctl command
clist = [ ( self.name + c.name, '%s:%s:%d' % clist = [ ( self.name + c.name, '%s:%s:%d' %
( c.protocol, c.IP(), c.port ) ) ( c.protocol, c.IP(), c.port ) )
for c in controllers ] for c in controllers ]
if self.listenPort: if self.listenPort:
clist.append( ( self.name + '-listen', clist.append( ( self.name + '-listen',
'ptcp:%s' % self.listenPort ) ) 'ptcp:%s' % self.listenPort ) )
if not self.isOldOVS():
ccmd = '-- --id=@%s create Controller target=\\"%s\\"' ccmd = '-- --id=@%s create Controller target=\\"%s\\"'
if self.reconnectms: if self.reconnectms:
ccmd += ' max_backoff=%d' % self.reconnectms ccmd += ' max_backoff=%d' % self.reconnectms
cargs = ' '.join( ccmd % ( name, target ) cargs = ' '.join( ccmd % ( name, target )
for name, target in clist ) for name, target in clist )
clist = ','.join( '@%s' % name for name, _target in clist ) cids = ','.join( '@%s' % name for name, _target in clist )
cmd = ( '-- --if-exists del-br %s' % self + if not self.isOldOVS():
cargs += ' -- --if-exists del-br %s' % self
cmd = ( cargs +
' -- add-br %s' % self + ' -- add-br %s' % self +
' -- set bridge %s' % self + ' -- set bridge %s controller=[%s]' % ( self, cids ) +
' other_config:datapath-id=%s' % self.dpid + self.bridgeOpts() +
' fail_mode=%s' % self.failMode + intfs )
' controller=[%s] ' % clist +
intfs + cargs )
# Construct ovs-vsctl commands for old versions of OVS
else:
# Annoyingly, --if-exists option seems not to work
self.vsctl( 'del-br', self )
self.vsctl( 'add-br', self )
for intf in self.intfList():
if not intf.IP():
self.vsctl( 'add-port', self, intf )
cmd = ( 'set Bridge %s' % self +
' other_config:datapath-id=%s' % self.dpid +
' -- set-fail-mode %s %s ' % ( self, self.failMode ) +
' -- set-controller %s %s ' % ( self, ' '.join( clist ) ) )
if not self.inband:
cmd += ( ' -- set bridge %s '
'other-config:disable-in-band=true' % self )
if self.datapath == 'user':
cmd += ' -- set bridge %s datapath_type=netdev' % self
if self.protocols and not self.isOldOVS():
cmd += ' -- set bridge %s protocols=%s' % ( self, self.protocols )
if self.stp and self.failMode == 'standalone':
cmd += ' -- set bridge %s stp_enable=true' % self
# Do it!! # Do it!!
self.vsctl( cmd ) self.vsctl( cmd )
# Reconnect quickly to controllers (1s vs. 15s max_backoff) # Reconnect quickly to controllers (1s vs. 15s max_backoff)
@@ -1283,6 +1275,10 @@ class OVSBatch( OVSSwitch ):
reconnectms = 1000 # shared for all switches reconnectms = 1000 # shared for all switches
# This should be ~ int( quietRun( 'getconf ARG_MAX' ) ),
# but the real limit seems to be much lower
argmax = 128000
def __init__( self, *args, **kwargs ): def __init__( self, *args, **kwargs ):
self.commands = [] self.commands = []
self.started = False self.started = False
@@ -1293,37 +1289,38 @@ class OVSBatch( OVSSwitch ):
kwargs.update( reconnectms=None ) kwargs.update( reconnectms=None )
super( OVSBatch, self ).__init__( *args, **kwargs ) super( OVSBatch, self ).__init__( *args, **kwargs )
@classmethod @classmethod
def batchStartup( cls, switches ): def batchStartup( cls, switches ):
"Batch startup for OVS" "Batch startup for OVS"
if cls.isOldOVS():
return False
info( '...' ) info( '...' )
cmds = '' cmds = 'ovs-vsctl '
for switch in switches: for switch in switches:
if cls.isOldOVS():
quietRun( 'ovs-vsctl del-br %s' % switch )
for cmd in switch.commands: for cmd in switch.commands:
cmds += ' ' + cmd.strip() cmd = cmd.strip()
# Split into 1 MB blocks # Don't exceed ARG_MAX
if len( cmds ) > 1000000: if len( cmds ) + len( cmd ) >= cls.argmax:
errRun( 'ovs-vsctl' + cmds, shell=True ) errRun( cmds, shell=True )
cmds = '' cmds = 'ovs-vsctl'
cmds += ' ' + cmd
switch.started = True switch.started = True
if cmds: if cmds:
quietRun( 'ovs-vsctl' + cmds, shell=True ) errRun( cmds, shell=True )
return True return True
def vsctl( self, *args, **kwargs ): def vsctl( self, *args, **kwargs ):
"Append ovs-vsctl command to list for later execution" "Append ovs-vsctl command to list for later execution"
if self.started: if self.started:
return OVSSwitch.vsctl( self, *args, **kwargs ) return OVSSwitch.vsctl( self, *args, **kwargs )
cmd = ' '.join( str( arg ) for arg in args ).strip() cmd = ' '.join( str( arg ).strip() for arg in args )
self.commands.append( cmd ) self.commands.append( cmd )
def cleanup( self): def cleanup( self):
"Don't bother to clean up" "Don't bother to clean up"
return return
class IVSSwitch( Switch ): class IVSSwitch( Switch ):
"Indigo Virtual Switch" "Indigo Virtual Switch"