Refactor for compatibility with isOldOVS() == True
This commit is contained in:
+62
-65
@@ -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 ]
|
||||||
intf1, intf2 = intf.link.intf1, intf.link.intf2
|
# Patch ports don't work well with old OVS
|
||||||
peer = intf1 if intf1 != intf else intf2
|
if isinstance( intf, OVSIntf ):
|
||||||
return ( ' -- set Interface %s type=patch'
|
intf1, intf2 = intf.link.intf1, intf.link.intf2
|
||||||
' -- set Interface %s options:peer=%s' %
|
peer = intf1 if intf1 != intf else intf2
|
||||||
( intf, intf, peer ) )
|
opts += ' type=patch options:peer=%s' % peer
|
||||||
|
return '' if not opts else ' -- set Interface %s' % intf + opts
|
||||||
|
|
||||||
|
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 ):
|
||||||
@@ -1185,54 +1201,30 @@ class OVSSwitch( Switch ):
|
|||||||
'OVS kernel switch does not work in a namespace' )
|
'OVS kernel switch does not work in a namespace' )
|
||||||
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 ]
|
for intf in self.intfList()
|
||||||
+ self.patchOpts( intf )
|
if self.ports[ intf ] and not intf.IP() )
|
||||||
for intf in self.intfList()
|
# Construct big ovs-vsctl command
|
||||||
if self.ports[ intf ] and not intf.IP() )
|
|
||||||
# Construct big ovs-vsctl command for new versions of OVS
|
|
||||||
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 ) )
|
||||||
|
ccmd = '-- --id=@%s create Controller target=\\"%s\\"'
|
||||||
|
if self.reconnectms:
|
||||||
|
ccmd += ' max_backoff=%d' % self.reconnectms
|
||||||
|
cargs = ' '.join( ccmd % ( name, target )
|
||||||
|
for name, target in clist )
|
||||||
|
cids = ','.join( '@%s' % name for name, _target in clist )
|
||||||
if not self.isOldOVS():
|
if not self.isOldOVS():
|
||||||
ccmd = ' -- --id=@%s create Controller target=\\"%s\\"'
|
cargs += ' -- --if-exists del-br %s' % self
|
||||||
if self.reconnectms:
|
cmd = ( cargs +
|
||||||
ccmd += ' max_backoff=%d' % self.reconnectms
|
' -- add-br %s' % self +
|
||||||
cargs = ''.join( ccmd % ( name, target )
|
' -- set bridge %s controller=[%s]' % ( self, cids ) +
|
||||||
for name, target in clist )
|
self.bridgeOpts() +
|
||||||
clist = ','.join( '@%s' % name for name, _target in clist )
|
intfs )
|
||||||
cmd = ( '-- --if-exists del-br %s' % self +
|
|
||||||
' -- add-br %s' % self +
|
|
||||||
' -- set bridge %s' % self +
|
|
||||||
' other_config:datapath-id=%s' % self.dpid +
|
|
||||||
' fail_mode=%s' % self.failMode +
|
|
||||||
' 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"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user