Fixing pylint errors
This commit is contained in:
+4
-4
@@ -87,7 +87,7 @@ from signal import signal, SIGINT, SIG_IGN
|
|||||||
from subprocess import Popen, PIPE, STDOUT
|
from subprocess import Popen, PIPE, STDOUT
|
||||||
import os
|
import os
|
||||||
from random import randrange
|
from random import randrange
|
||||||
from sys import exit
|
import sys
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from distutils.version import StrictVersion
|
from distutils.version import StrictVersion
|
||||||
@@ -282,7 +282,7 @@ class RemoteOVSSwitch( RemoteMixin, OVSSwitch ):
|
|||||||
cls = type( self )
|
cls = type( self )
|
||||||
if self.server not in cls.OVSVersions:
|
if self.server not in cls.OVSVersions:
|
||||||
vers = self.cmd( 'ovs-vsctl --version' )
|
vers = self.cmd( 'ovs-vsctl --version' )
|
||||||
cls.OVSVersions[ self.server ] = re.findall( '\d+\.\d+', vers )[ 0 ]
|
cls.OVSVersions[ self.server ] = re.findall( r'\d+\.\d+', vers )[ 0 ]
|
||||||
return ( StrictVersion( cls.OVSVersions[ self.server ] ) <
|
return ( StrictVersion( cls.OVSVersions[ self.server ] ) <
|
||||||
StrictVersion( '1.10' ) )
|
StrictVersion( '1.10' ) )
|
||||||
|
|
||||||
@@ -387,7 +387,7 @@ class RemoteLink( Link ):
|
|||||||
tunnel.wait()
|
tunnel.wait()
|
||||||
error( ch + tunnel.stdout.read() )
|
error( ch + tunnel.stdout.read() )
|
||||||
error( tunnel.stderr.read() )
|
error( tunnel.stderr.read() )
|
||||||
exit( 1 )
|
sys.exit( 1 )
|
||||||
# 3. Move interfaces if necessary
|
# 3. Move interfaces if necessary
|
||||||
for node in node1, node2:
|
for node in node1, node2:
|
||||||
if node.inNamespace:
|
if node.inNamespace:
|
||||||
@@ -660,7 +660,7 @@ class MininetCluster( Mininet ):
|
|||||||
'*** Make sure that the above ssh command works correctly.\n'
|
'*** Make sure that the above ssh command works correctly.\n'
|
||||||
'*** You may also need to run mn -c on all nodes, and/or\n'
|
'*** You may also need to run mn -c on all nodes, and/or\n'
|
||||||
'*** use sudo -E.\n' )
|
'*** use sudo -E.\n' )
|
||||||
exit( 1 )
|
sys.exit( 1 )
|
||||||
info( '\n' )
|
info( '\n' )
|
||||||
|
|
||||||
def modifiedaddHost( self, *args, **kwargs ):
|
def modifiedaddHost( self, *args, **kwargs ):
|
||||||
|
|||||||
+5
-4
@@ -10,7 +10,8 @@ It may also get rid of 'false positives', but hopefully
|
|||||||
nothing irreplaceable!
|
nothing irreplaceable!
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from subprocess import Popen, PIPE, check_output as co
|
from subprocess import ( Popen, PIPE, check_output as co,
|
||||||
|
CalledProcessError )
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from mininet.log import info
|
from mininet.log import info
|
||||||
@@ -28,11 +29,11 @@ def killprocs( pattern ):
|
|||||||
# Make sure they are gone
|
# Make sure they are gone
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
pids = co( 'pgrep -f %s' % pattern )
|
pids = co( [ 'pgrep', '-f', pattern ] )
|
||||||
except:
|
except CalledProcessError:
|
||||||
pids = ''
|
pids = ''
|
||||||
if pids:
|
if pids:
|
||||||
sh( 'pkill -f 9 mininet:' )
|
sh( 'pkill -9 -f %s' % pattern )
|
||||||
time.sleep( .5 )
|
time.sleep( .5 )
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
|
|||||||
+9
-8
@@ -96,7 +96,7 @@ class CLI( Cmd ):
|
|||||||
# Disable pylint "Unused argument: 'arg's'" messages, as well as
|
# Disable pylint "Unused argument: 'arg's'" messages, as well as
|
||||||
# "method could be a function" warning, since each CLI function
|
# "method could be a function" warning, since each CLI function
|
||||||
# must have the same interface
|
# must have the same interface
|
||||||
# pylint: disable-msg=R0201
|
# pylint: disable=R0201
|
||||||
|
|
||||||
helpStr = (
|
helpStr = (
|
||||||
'You may also send a command to a node using:\n'
|
'You may also send a command to a node using:\n'
|
||||||
@@ -128,7 +128,7 @@ class CLI( Cmd ):
|
|||||||
nodes = ' '.join( sorted( self.mn ) )
|
nodes = ' '.join( sorted( self.mn ) )
|
||||||
output( 'available nodes are: \n%s\n' % nodes )
|
output( 'available nodes are: \n%s\n' % nodes )
|
||||||
|
|
||||||
def do_ports( self, line ):
|
def do_ports( self, _line ):
|
||||||
"display ports and interfaces for each switch"
|
"display ports and interfaces for each switch"
|
||||||
dumpPorts( self.mn.switches )
|
dumpPorts( self.mn.switches )
|
||||||
|
|
||||||
@@ -142,7 +142,7 @@ class CLI( Cmd ):
|
|||||||
call( line, shell=True )
|
call( line, shell=True )
|
||||||
|
|
||||||
# do_py() and do_px() need to catch any exception during eval()/exec()
|
# do_py() and do_px() need to catch any exception during eval()/exec()
|
||||||
# pylint: disable-msg=W0703
|
# pylint: disable=W0703
|
||||||
|
|
||||||
def do_py( self, line ):
|
def do_py( self, line ):
|
||||||
"""Evaluate a Python expression.
|
"""Evaluate a Python expression.
|
||||||
@@ -159,7 +159,7 @@ class CLI( Cmd ):
|
|||||||
output( str( e ) + '\n' )
|
output( str( e ) + '\n' )
|
||||||
|
|
||||||
# We are in fact using the exec() pseudo-function
|
# We are in fact using the exec() pseudo-function
|
||||||
# pylint: disable-msg=W0122
|
# pylint: disable=W0122
|
||||||
|
|
||||||
def do_px( self, line ):
|
def do_px( self, line ):
|
||||||
"""Execute a Python statement.
|
"""Execute a Python statement.
|
||||||
@@ -169,7 +169,7 @@ class CLI( Cmd ):
|
|||||||
except Exception, e:
|
except Exception, e:
|
||||||
output( str( e ) + '\n' )
|
output( str( e ) + '\n' )
|
||||||
|
|
||||||
# pylint: enable-msg=W0703,W0122
|
# pylint: enable=W0703,W0122
|
||||||
|
|
||||||
def do_pingall( self, line ):
|
def do_pingall( self, line ):
|
||||||
"Ping between all hosts."
|
"Ping between all hosts."
|
||||||
@@ -346,7 +346,7 @@ class CLI( Cmd ):
|
|||||||
elapsed = time.time() - start
|
elapsed = time.time() - start
|
||||||
self.stdout.write("*** Elapsed time: %0.6f secs\n" % elapsed)
|
self.stdout.write("*** Elapsed time: %0.6f secs\n" % elapsed)
|
||||||
|
|
||||||
def do_links( self, line ):
|
def do_links( self, _line ):
|
||||||
"Report on links"
|
"Report on links"
|
||||||
for link in self.mn.links:
|
for link in self.mn.links:
|
||||||
print link, link.status()
|
print link, link.status()
|
||||||
@@ -355,7 +355,8 @@ class CLI( Cmd ):
|
|||||||
"Starts or stops a switch"
|
"Starts or stops a switch"
|
||||||
args = line.split()
|
args = line.split()
|
||||||
if len(args) != 2:
|
if len(args) != 2:
|
||||||
error( 'invalid number of args: switch <switch name> {start, stop}\n' )
|
error( 'invalid number of args: switch <switch name>'
|
||||||
|
'{start, stop}\n' )
|
||||||
return
|
return
|
||||||
sw = args[ 0 ]
|
sw = args[ 0 ]
|
||||||
command = args[ 1 ]
|
command = args[ 1 ]
|
||||||
@@ -397,7 +398,7 @@ class CLI( Cmd ):
|
|||||||
else:
|
else:
|
||||||
error( '*** Unknown command: %s\n' % line )
|
error( '*** Unknown command: %s\n' % line )
|
||||||
|
|
||||||
# pylint: enable-msg=R0201
|
# pylint: enable=R0201
|
||||||
|
|
||||||
def waitForNode( self, node ):
|
def waitForNode( self, node ):
|
||||||
"Wait for a node to finish, and print its output."
|
"Wait for a node to finish, and print its output."
|
||||||
|
|||||||
+9
-4
@@ -33,7 +33,7 @@ class Intf( object ):
|
|||||||
"Basic interface object that can configure itself."
|
"Basic interface object that can configure itself."
|
||||||
|
|
||||||
def __init__( self, name, node=None, port=None, link=None,
|
def __init__( self, name, node=None, port=None, link=None,
|
||||||
mac=None, srcNode=None, **params ):
|
mac=None, **params ):
|
||||||
"""name: interface name (e.g. h1-eth0)
|
"""name: interface name (e.g. h1-eth0)
|
||||||
node: owning node (where this intf most likely lives)
|
node: owning node (where this intf most likely lives)
|
||||||
link: parent link if we're part of a link
|
link: parent link if we're part of a link
|
||||||
@@ -71,7 +71,8 @@ class Intf( object ):
|
|||||||
return self.ifconfig( ipstr, 'up' )
|
return self.ifconfig( ipstr, 'up' )
|
||||||
else:
|
else:
|
||||||
if prefixLen is None:
|
if prefixLen is None:
|
||||||
raise Exception( 'No prefix length set for IP address %s' % ( ipstr, ) )
|
raise Exception( 'No prefix length set for IP address %s'
|
||||||
|
% ( ipstr, ) )
|
||||||
self.ip, self.prefixLen = ipstr, prefixLen
|
self.ip, self.prefixLen = ipstr, prefixLen
|
||||||
return self.ifconfig( '%s/%s' % ( ipstr, prefixLen ) )
|
return self.ifconfig( '%s/%s' % ( ipstr, prefixLen ) )
|
||||||
|
|
||||||
@@ -196,7 +197,7 @@ class Intf( object ):
|
|||||||
|
|
||||||
def status( self ):
|
def status( self ):
|
||||||
"Return intf status as a string"
|
"Return intf status as a string"
|
||||||
links, err_, result_ = self.node.pexec( 'ip link show' )
|
links, _err, _result = self.node.pexec( 'ip link show' )
|
||||||
if self.name in links:
|
if self.name in links:
|
||||||
return "OK"
|
return "OK"
|
||||||
else:
|
else:
|
||||||
@@ -419,15 +420,19 @@ class Link( object ):
|
|||||||
|
|
||||||
def intfName( self, node, n ):
|
def intfName( self, node, n ):
|
||||||
"Construct a canonical interface name node-ethN for interface n."
|
"Construct a canonical interface name node-ethN for interface n."
|
||||||
|
# Leave this as an instance method for now
|
||||||
|
assert self
|
||||||
return node.name + '-eth' + repr( n )
|
return node.name + '-eth' + repr( n )
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def makeIntfPair( _cls, intfname1, intfname2, addr1=None, addr2=None ):
|
def makeIntfPair( cls, intfname1, intfname2, addr1=None, addr2=None ):
|
||||||
"""Create pair of interfaces
|
"""Create pair of interfaces
|
||||||
intfname1: name of interface 1
|
intfname1: name of interface 1
|
||||||
intfname2: name of interface 2
|
intfname2: name of interface 2
|
||||||
(override this method [and possibly delete()]
|
(override this method [and possibly delete()]
|
||||||
to change link type)"""
|
to change link type)"""
|
||||||
|
# Leave this as a class method for now
|
||||||
|
assert cls
|
||||||
return makeIntfPair( intfname1, intfname2, addr1, addr2 )
|
return makeIntfPair( intfname1, intfname2, addr1, addr2 )
|
||||||
|
|
||||||
def delete( self ):
|
def delete( self ):
|
||||||
|
|||||||
+2
-2
@@ -124,7 +124,7 @@ class MininetLogger( Logger, object ):
|
|||||||
self.setLevel( level )
|
self.setLevel( level )
|
||||||
self.handlers[ 0 ].setLevel( level )
|
self.handlers[ 0 ].setLevel( level )
|
||||||
|
|
||||||
# pylint: disable-msg=E0202
|
# pylint: disable=E0202
|
||||||
# "An attribute inherited from mininet.log hide this method"
|
# "An attribute inherited from mininet.log hide this method"
|
||||||
# Not sure why this is occurring - this function definitely gets called.
|
# Not sure why this is occurring - this function definitely gets called.
|
||||||
|
|
||||||
@@ -142,7 +142,7 @@ class MininetLogger( Logger, object ):
|
|||||||
if self.isEnabledFor( OUTPUT ):
|
if self.isEnabledFor( OUTPUT ):
|
||||||
self._log( OUTPUT, msg, args, kwargs )
|
self._log( OUTPUT, msg, args, kwargs )
|
||||||
|
|
||||||
# pylint: enable-msg=E0202
|
# pylint: enable=E0202
|
||||||
|
|
||||||
lg = MininetLogger()
|
lg = MininetLogger()
|
||||||
|
|
||||||
|
|||||||
+32
-17
@@ -98,7 +98,8 @@ from math import ceil
|
|||||||
|
|
||||||
from mininet.cli import CLI
|
from mininet.cli import CLI
|
||||||
from mininet.log import info, error, debug, output, warn
|
from mininet.log import info, error, debug, output, warn
|
||||||
from mininet.node import Host, OVSKernelSwitch, DefaultController, Controller
|
from mininet.node import ( Node, Host, OVSKernelSwitch, DefaultController,
|
||||||
|
Controller )
|
||||||
from mininet.nodelib import NAT
|
from mininet.nodelib import NAT
|
||||||
from mininet.link import Link, Intf
|
from mininet.link import Link, Intf
|
||||||
from mininet.util import quietRun, fixLimits, numCores, ensureRoot
|
from mininet.util import quietRun, fixLimits, numCores, ensureRoot
|
||||||
@@ -264,14 +265,24 @@ class Mininet( object ):
|
|||||||
self.nameToNode[ name ] = controller_new
|
self.nameToNode[ name ] = controller_new
|
||||||
return controller_new
|
return controller_new
|
||||||
|
|
||||||
def addNAT( self, name='nat0', connect=True, inNamespace=False, **params ):
|
def addNAT( self, name='nat0', connect=True, inNamespace=False,
|
||||||
|
**params):
|
||||||
|
"""Add a NAT to the Mininet network
|
||||||
|
name: name of NAT node
|
||||||
|
connect: switch to connect to | True (s1) | None
|
||||||
|
inNamespace: create in a network namespace
|
||||||
|
params: other NAT node params, notably:
|
||||||
|
ip: used as default gateway address"""
|
||||||
nat = self.addHost( name, cls=NAT, inNamespace=inNamespace,
|
nat = self.addHost( name, cls=NAT, inNamespace=inNamespace,
|
||||||
subnet=self.ipBase, **params )
|
subnet=self.ipBase, **params )
|
||||||
# find first switch and create link
|
# find first switch and create link
|
||||||
if connect:
|
if connect:
|
||||||
# connect the nat to the first switch
|
if not isinstance( connect, Node ):
|
||||||
|
# Use first switch if not specified
|
||||||
|
connect = self.switches[ 0 ]
|
||||||
|
# Connect the nat to the switch
|
||||||
self.addLink( nat, self.switches[ 0 ] )
|
self.addLink( nat, self.switches[ 0 ] )
|
||||||
# set the default route on hosts
|
# Set the default route on hosts
|
||||||
natIP = nat.params[ 'ip' ].split('/')[ 0 ]
|
natIP = nat.params[ 'ip' ].split('/')[ 0 ]
|
||||||
for host in self.hosts:
|
for host in self.hosts:
|
||||||
if host.inNamespace:
|
if host.inNamespace:
|
||||||
@@ -486,7 +497,8 @@ class Mininet( object ):
|
|||||||
info( '*** Stopping %i terms\n' % len( self.terms ) )
|
info( '*** Stopping %i terms\n' % len( self.terms ) )
|
||||||
self.stopXterms()
|
self.stopXterms()
|
||||||
info( '*** Stopping %i switches\n' % len( self.switches ) )
|
info( '*** Stopping %i switches\n' % len( self.switches ) )
|
||||||
for swclass, switches in groupby( sorted( self.switches, key=type ), type ):
|
for swclass, switches in groupby(
|
||||||
|
sorted( self.switches, key=type ), type ):
|
||||||
if hasattr( swclass, 'batchShutdown' ):
|
if hasattr( swclass, 'batchShutdown' ):
|
||||||
swclass.batchShutdown( switches )
|
swclass.batchShutdown( switches )
|
||||||
for switch in self.switches:
|
for switch in self.switches:
|
||||||
@@ -521,13 +533,13 @@ class Mininet( object ):
|
|||||||
if hosts is None:
|
if hosts is None:
|
||||||
hosts = self.hosts
|
hosts = self.hosts
|
||||||
poller = select.poll()
|
poller = select.poll()
|
||||||
Node = hosts[ 0 ] # so we can call class method fdToNode
|
h1 = hosts[ 0 ] # so we can call class method fdToNode
|
||||||
for host in hosts:
|
for host in hosts:
|
||||||
poller.register( host.stdout )
|
poller.register( host.stdout )
|
||||||
while True:
|
while True:
|
||||||
ready = poller.poll( timeoutms )
|
ready = poller.poll( timeoutms )
|
||||||
for fd, event in ready:
|
for fd, event in ready:
|
||||||
host = Node.fdToNode( fd )
|
host = h1.fdToNode( fd )
|
||||||
if event & select.POLLIN:
|
if event & select.POLLIN:
|
||||||
line = host.readline()
|
line = host.readline()
|
||||||
if line is not None:
|
if line is not None:
|
||||||
@@ -574,7 +586,8 @@ class Mininet( object ):
|
|||||||
if timeout:
|
if timeout:
|
||||||
opts = '-W %s' % timeout
|
opts = '-W %s' % timeout
|
||||||
if dest.intfs:
|
if dest.intfs:
|
||||||
result = node.cmd( 'ping -c1 %s %s' % (opts, dest.IP()) )
|
result = node.cmd( 'ping -c1 %s %s' %
|
||||||
|
(opts, dest.IP()) )
|
||||||
sent, received = self._parsePing( result )
|
sent, received = self._parsePing( result )
|
||||||
else:
|
else:
|
||||||
sent, received = 0, 0
|
sent, received = 0, 0
|
||||||
@@ -699,13 +712,13 @@ class Mininet( object ):
|
|||||||
|
|
||||||
# XXX This should be cleaned up
|
# XXX This should be cleaned up
|
||||||
|
|
||||||
def iperf( self, hosts=None, l4Type='TCP', udpBw='10M', format=None,
|
def iperf( self, hosts=None, l4Type='TCP', udpBw='10M', fmt=None,
|
||||||
seconds=5):
|
seconds=5):
|
||||||
"""Run iperf between two hosts.
|
"""Run iperf between two hosts.
|
||||||
hosts: list of hosts; if None, uses opposite hosts
|
hosts: list of hosts; if None, uses first and last hosts
|
||||||
l4Type: string, one of [ TCP, UDP ]
|
l4Type: string, one of [ TCP, UDP ]
|
||||||
udpBw: bandwidth target for UDP test
|
udpBw: bandwidth target for UDP test
|
||||||
format: iperf format argument if any
|
fmt: iperf format argument if any
|
||||||
seconds: iperf time to transmit
|
seconds: iperf time to transmit
|
||||||
returns: two-element array of [ server, client ] speeds
|
returns: two-element array of [ server, client ] speeds
|
||||||
note: send() is buffered, so client rate can be much higher than
|
note: send() is buffered, so client rate can be much higher than
|
||||||
@@ -729,8 +742,8 @@ class Mininet( object ):
|
|||||||
bwArgs = '-b ' + udpBw + ' '
|
bwArgs = '-b ' + udpBw + ' '
|
||||||
elif l4Type != 'TCP':
|
elif l4Type != 'TCP':
|
||||||
raise Exception( 'Unexpected l4 type: %s' % l4Type )
|
raise Exception( 'Unexpected l4 type: %s' % l4Type )
|
||||||
if format:
|
if fmt:
|
||||||
iperfArgs += '-f %s ' %format
|
iperfArgs += '-f %s ' % fmt
|
||||||
server.sendCmd( iperfArgs + '-s', printPid=True )
|
server.sendCmd( iperfArgs + '-s', printPid=True )
|
||||||
servout = ''
|
servout = ''
|
||||||
while server.lastPid is None:
|
while server.lastPid is None:
|
||||||
@@ -755,7 +768,7 @@ class Mininet( object ):
|
|||||||
def runCpuLimitTest( self, cpu, duration=5 ):
|
def runCpuLimitTest( self, cpu, duration=5 ):
|
||||||
"""run CPU limit test with 'while true' processes.
|
"""run CPU limit test with 'while true' processes.
|
||||||
cpu: desired CPU fraction of each host
|
cpu: desired CPU fraction of each host
|
||||||
duration: test duration in seconds
|
duration: test duration in seconds (integer)
|
||||||
returns a single list of measured CPU fractions as floats.
|
returns a single list of measured CPU fractions as floats.
|
||||||
"""
|
"""
|
||||||
cores = int( quietRun( 'nproc' ) )
|
cores = int( quietRun( 'nproc' ) )
|
||||||
@@ -776,12 +789,14 @@ class Mininet( object ):
|
|||||||
# get the initial cpu time for each host
|
# get the initial cpu time for each host
|
||||||
for host in hosts:
|
for host in hosts:
|
||||||
outputs[ host ] = []
|
outputs[ host ] = []
|
||||||
with open( '/sys/fs/cgroup/cpuacct/%s/cpuacct.usage' % host, 'r' ) as f:
|
with open( '/sys/fs/cgroup/cpuacct/%s/cpuacct.usage' %
|
||||||
|
host, 'r' ) as f:
|
||||||
time[ host ] = float( f.read() )
|
time[ host ] = float( f.read() )
|
||||||
for _ in range( 5 ):
|
for _ in range( duration ):
|
||||||
sleep( 1 )
|
sleep( 1 )
|
||||||
for host in hosts:
|
for host in hosts:
|
||||||
with open( '/sys/fs/cgroup/cpuacct/%s/cpuacct.usage' % host, 'r' ) as f:
|
with open( '/sys/fs/cgroup/cpuacct/%s/cpuacct.usage' %
|
||||||
|
host, 'r' ) as f:
|
||||||
readTime = float( f.read() )
|
readTime = float( f.read() )
|
||||||
outputs[ host ].append( ( ( readTime - time[ host ] )
|
outputs[ host ].append( ( ( readTime - time[ host ] )
|
||||||
/ 1000000000 ) / cores * 100 )
|
/ 1000000000 ) / cores * 100 )
|
||||||
|
|||||||
+43
-24
@@ -189,6 +189,8 @@ class Node( object ):
|
|||||||
"""Internal method: spawn and return a process
|
"""Internal method: spawn and return a process
|
||||||
cmd: command to run (list)
|
cmd: command to run (list)
|
||||||
params: parameters to Popen()"""
|
params: parameters to Popen()"""
|
||||||
|
# Leave this is as an instance method for now
|
||||||
|
assert self
|
||||||
return Popen( cmd, **params )
|
return Popen( cmd, **params )
|
||||||
|
|
||||||
def cleanup( self ):
|
def cleanup( self ):
|
||||||
@@ -240,8 +242,11 @@ class Node( object ):
|
|||||||
os.killpg( self.shell.pid, signal.SIGHUP )
|
os.killpg( self.shell.pid, signal.SIGHUP )
|
||||||
self.cleanup()
|
self.cleanup()
|
||||||
|
|
||||||
def stop( self ):
|
def stop( self, deleteIntfs=False ):
|
||||||
"Stop node."
|
"""Stop node.
|
||||||
|
deleteIntfs: delete interfaces? (False)"""
|
||||||
|
if deleteIntfs:
|
||||||
|
self.deleteIntfs()
|
||||||
self.terminate()
|
self.terminate()
|
||||||
|
|
||||||
def waitReadable( self, timeoutms=None ):
|
def waitReadable( self, timeoutms=None ):
|
||||||
@@ -324,7 +329,7 @@ class Node( object ):
|
|||||||
log = info if verbose else debug
|
log = info if verbose else debug
|
||||||
output = ''
|
output = ''
|
||||||
while self.waiting:
|
while self.waiting:
|
||||||
data = self.monitor()
|
data = self.monitor( findPid=findPid )
|
||||||
output += data
|
output += data
|
||||||
log( data )
|
log( data )
|
||||||
return output
|
return output
|
||||||
@@ -421,7 +426,7 @@ class Node( object ):
|
|||||||
warn( '*** defaultIntf: warning:', self.name,
|
warn( '*** defaultIntf: warning:', self.name,
|
||||||
'has no interfaces\n' )
|
'has no interfaces\n' )
|
||||||
|
|
||||||
def intf( self, intf='' ):
|
def intf( self, intf=None ):
|
||||||
"""Return our interface object with given string name,
|
"""Return our interface object with given string name,
|
||||||
default intf if name is falsy (None, empty string, etc).
|
default intf if name is falsy (None, empty string, etc).
|
||||||
or the input intf arg.
|
or the input intf arg.
|
||||||
@@ -682,8 +687,8 @@ class CPULimitedHost( Host ):
|
|||||||
if int( self.cgroupGet( 'rt_runtime_us', 'cpu' ) ) <= 0:
|
if int( self.cgroupGet( 'rt_runtime_us', 'cpu' ) ) <= 0:
|
||||||
mncmd += [ '-r', str( self.rtprio ) ]
|
mncmd += [ '-r', str( self.rtprio ) ]
|
||||||
else:
|
else:
|
||||||
debug( '*** error: not enough cpu time available for %s.' % self.name,
|
debug( '*** error: not enough cpu time available for %s.' %
|
||||||
'Using cfs scheduler for subprocess\n' )
|
self.name, 'Using cfs scheduler for subprocess\n' )
|
||||||
return Host.popen( self, *args, mncmd=mncmd, **kwargs )
|
return Host.popen( self, *args, mncmd=mncmd, **kwargs )
|
||||||
|
|
||||||
def cleanup( self ):
|
def cleanup( self ):
|
||||||
@@ -698,9 +703,11 @@ class CPULimitedHost( Host ):
|
|||||||
"Check (Ubuntu,Debian) kernel config for CONFIG_RT_GROUP_SCHED for RT"
|
"Check (Ubuntu,Debian) kernel config for CONFIG_RT_GROUP_SCHED for RT"
|
||||||
if not cls._rtGroupSched:
|
if not cls._rtGroupSched:
|
||||||
release = quietRun( 'uname -r' ).strip('\r\n')
|
release = quietRun( 'uname -r' ).strip('\r\n')
|
||||||
output = quietRun( 'grep CONFIG_RT_GROUP_SCHED /boot/config-%s' % release )
|
output = quietRun( 'grep CONFIG_RT_GROUP_SCHED /boot/config-%s' %
|
||||||
|
release )
|
||||||
if output == '# CONFIG_RT_GROUP_SCHED is not set\n':
|
if output == '# CONFIG_RT_GROUP_SCHED is not set\n':
|
||||||
error( '\n*** error: please enable RT_GROUP_SCHED in your kernel\n' )
|
error( '\n*** error: please enable RT_GROUP_SCHED'
|
||||||
|
'in your kernel\n' )
|
||||||
exit( 1 )
|
exit( 1 )
|
||||||
cls._rtGroupSched = True
|
cls._rtGroupSched = True
|
||||||
|
|
||||||
@@ -755,8 +762,8 @@ class CPULimitedHost( Host ):
|
|||||||
sched = self.sched
|
sched = self.sched
|
||||||
if sched == 'rt':
|
if sched == 'rt':
|
||||||
if not f or f < 0:
|
if not f or f < 0:
|
||||||
raise Exception( 'Please set a positive CPU fraction for sched=rt\n' )
|
raise Exception( 'Please set a positive CPU fraction'
|
||||||
return
|
' for sched=rt\n' )
|
||||||
pstr, qstr, period, quota = self.rtInfo( f )
|
pstr, qstr, period, quota = self.rtInfo( f )
|
||||||
elif sched == 'cfs':
|
elif sched == 'cfs':
|
||||||
pstr, qstr, period, quota = self.cfsInfo( f )
|
pstr, qstr, period, quota = self.cfsInfo( f )
|
||||||
@@ -881,7 +888,8 @@ class Switch( Node ):
|
|||||||
|
|
||||||
def connected( self ):
|
def connected( self ):
|
||||||
"Is the switch connected to a controller? (override this method)"
|
"Is the switch connected to a controller? (override this method)"
|
||||||
return False and self # satisfy pylint
|
raise NotImplementedError( "connected() needs to be implemented in"
|
||||||
|
" Switch subclass %s" % self.__class__ )
|
||||||
|
|
||||||
def __repr__( self ):
|
def __repr__( self ):
|
||||||
"More informative string representation"
|
"More informative string representation"
|
||||||
@@ -890,6 +898,7 @@ class Switch( Node ):
|
|||||||
return '<%s %s: %s pid=%s> ' % (
|
return '<%s %s: %s pid=%s> ' % (
|
||||||
self.__class__.__name__, self.name, intfs, self.pid )
|
self.__class__.__name__, self.name, intfs, self.pid )
|
||||||
|
|
||||||
|
|
||||||
class UserSwitch( Switch ):
|
class UserSwitch( Switch ):
|
||||||
"User-space switch."
|
"User-space switch."
|
||||||
|
|
||||||
@@ -982,7 +991,8 @@ class UserSwitch( Switch ):
|
|||||||
self.TCReapply( intf )
|
self.TCReapply( intf )
|
||||||
|
|
||||||
def stop( self, deleteIntfs=True ):
|
def stop( self, deleteIntfs=True ):
|
||||||
"Stop OpenFlow reference user datapath."
|
"""Stop OpenFlow reference user datapath.
|
||||||
|
deleteIntfs: delete interfaces? (True)"""
|
||||||
self.cmd( 'kill %ofdatapath' )
|
self.cmd( 'kill %ofdatapath' )
|
||||||
self.cmd( 'kill %ofprotocol' )
|
self.cmd( 'kill %ofprotocol' )
|
||||||
if deleteIntfs:
|
if deleteIntfs:
|
||||||
@@ -1033,7 +1043,8 @@ class OVSLegacyKernelSwitch( Switch ):
|
|||||||
self.execed = False
|
self.execed = False
|
||||||
|
|
||||||
def stop( self, deleteIntfs=True ):
|
def stop( self, deleteIntfs=True ):
|
||||||
"Terminate kernel datapath."
|
"""Terminate kernel datapath."
|
||||||
|
deleteIntfs: delete interfaces? (True)"""
|
||||||
quietRun( 'ovs-dpctl del-dp ' + self.dp )
|
quietRun( 'ovs-dpctl del-dp ' + self.dp )
|
||||||
self.cmd( 'kill %ovs-openflowd' )
|
self.cmd( 'kill %ovs-openflowd' )
|
||||||
if deleteIntfs:
|
if deleteIntfs:
|
||||||
@@ -1075,11 +1086,12 @@ class OVSSwitch( Switch ):
|
|||||||
'You may wish to try '
|
'You may wish to try '
|
||||||
'"service openvswitch-switch start".\n' )
|
'"service openvswitch-switch start".\n' )
|
||||||
exit( 1 )
|
exit( 1 )
|
||||||
info = quietRun( 'ovs-vsctl --version' )
|
version = quietRun( 'ovs-vsctl --version' )
|
||||||
cls.OVSVersion = findall( '\d+\.\d+', info )[ 0 ]
|
cls.OVSVersion = findall( r'\d+\.\d+', version )[ 0 ]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def isOldOVS( cls ):
|
def isOldOVS( cls ):
|
||||||
|
"Is OVS ersion < 1.10?"
|
||||||
return ( StrictVersion( cls.OVSVersion ) <
|
return ( StrictVersion( cls.OVSVersion ) <
|
||||||
StrictVersion( '1.10' ) )
|
StrictVersion( '1.10' ) )
|
||||||
|
|
||||||
@@ -1186,7 +1198,8 @@ class OVSSwitch( Switch ):
|
|||||||
|
|
||||||
|
|
||||||
def stop( self, deleteIntfs=True ):
|
def stop( self, deleteIntfs=True ):
|
||||||
"Terminate OVS switch."
|
"""Terminate OVS switch.
|
||||||
|
deleteIntfs: delete interfaces? (True)"""
|
||||||
self.cmd( 'ovs-vsctl del-br', self )
|
self.cmd( 'ovs-vsctl del-br', self )
|
||||||
if self.datapath == 'user':
|
if self.datapath == 'user':
|
||||||
self.cmd( 'ip link del', self )
|
self.cmd( 'ip link del', self )
|
||||||
@@ -1255,7 +1268,8 @@ class IVSSwitch( Switch ):
|
|||||||
self.cmd( ' '.join(args) + ' >' + logfile + ' 2>&1 </dev/null &' )
|
self.cmd( ' '.join(args) + ' >' + logfile + ' 2>&1 </dev/null &' )
|
||||||
|
|
||||||
def stop( self, deleteIntfs=True ):
|
def stop( self, deleteIntfs=True ):
|
||||||
"Terminate IVS switch."
|
"""Terminate IVS switch.
|
||||||
|
deleteIntfs: delete interfaces? (True)"""
|
||||||
self.cmd( 'kill %ivs' )
|
self.cmd( 'kill %ivs' )
|
||||||
self.cmd( 'wait' )
|
self.cmd( 'wait' )
|
||||||
if deleteIntfs:
|
if deleteIntfs:
|
||||||
@@ -1276,6 +1290,10 @@ class IVSSwitch( Switch ):
|
|||||||
return self.cmd( 'ovs-ofctl ' + ' '.join( args ) +
|
return self.cmd( 'ovs-ofctl ' + ' '.join( args ) +
|
||||||
' tcp:127.0.0.1:%i' % self.listenPort )
|
' tcp:127.0.0.1:%i' % self.listenPort )
|
||||||
|
|
||||||
|
def connected( self ):
|
||||||
|
"For now, return True since we can't tell if we're connected"
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
class Controller( Node ):
|
class Controller( Node ):
|
||||||
"""A Controller is a Node that is running (or has execed?) an
|
"""A Controller is a Node that is running (or has execed?) an
|
||||||
@@ -1323,11 +1341,11 @@ class Controller( Node ):
|
|||||||
' 1>' + cout + ' 2>' + cout + ' &' )
|
' 1>' + cout + ' 2>' + cout + ' &' )
|
||||||
self.execed = False
|
self.execed = False
|
||||||
|
|
||||||
def stop( self ):
|
def stop( self, *args, **kwargs ):
|
||||||
"Stop controller."
|
"Stop controller."
|
||||||
self.cmd( 'kill %' + self.command )
|
self.cmd( 'kill %' + self.command )
|
||||||
self.cmd( 'wait %' + self.command )
|
self.cmd( 'wait %' + self.command )
|
||||||
self.terminate()
|
super( Controller, self ).stop( *args, **kwargs )
|
||||||
|
|
||||||
def IP( self, intf=None ):
|
def IP( self, intf=None ):
|
||||||
"Return IP address of the Controller"
|
"Return IP address of the Controller"
|
||||||
@@ -1343,7 +1361,8 @@ class Controller( Node ):
|
|||||||
self.__class__.__name__, self.name,
|
self.__class__.__name__, self.name,
|
||||||
self.IP(), self.port, self.pid )
|
self.IP(), self.port, self.pid )
|
||||||
@classmethod
|
@classmethod
|
||||||
def isAvailable( self ):
|
def isAvailable( cls ):
|
||||||
|
"Is controller available?"
|
||||||
return quietRun( 'which controller' )
|
return quietRun( 'which controller' )
|
||||||
|
|
||||||
class OVSController( Controller ):
|
class OVSController( Controller ):
|
||||||
@@ -1353,8 +1372,9 @@ class OVSController( Controller ):
|
|||||||
command = 'test-controller'
|
command = 'test-controller'
|
||||||
Controller.__init__( self, name, command=command, **kwargs )
|
Controller.__init__( self, name, command=command, **kwargs )
|
||||||
@classmethod
|
@classmethod
|
||||||
def isAvailable( self ):
|
def isAvailable( cls ):
|
||||||
return quietRun( 'which ovs-controller' ) or quietRun( 'which test-controller' )
|
return ( quietRun( 'which ovs-controller' ) or
|
||||||
|
quietRun( 'which test-controller' ) )
|
||||||
|
|
||||||
class NOX( Controller ):
|
class NOX( Controller ):
|
||||||
"Controller to run a NOX application."
|
"Controller to run a NOX application."
|
||||||
@@ -1432,7 +1452,7 @@ class RemoteController( Controller ):
|
|||||||
" at %s:%d\n" % ( self.ip, self.port ) )
|
" at %s:%d\n" % ( self.ip, self.port ) )
|
||||||
|
|
||||||
|
|
||||||
DefaultControllers = [ Controller, OVSController ]
|
DefaultControllers = ( Controller, OVSController )
|
||||||
|
|
||||||
def findController( controllers=DefaultControllers ):
|
def findController( controllers=DefaultControllers ):
|
||||||
"Return first available controller from list, if any"
|
"Return first available controller from list, if any"
|
||||||
@@ -1446,4 +1466,3 @@ def DefaultController( name, controllers=DefaultControllers, **kwargs ):
|
|||||||
if not controller:
|
if not controller:
|
||||||
raise Exception( 'Could not find a default OpenFlow controller' )
|
raise Exception( 'Could not find a default OpenFlow controller' )
|
||||||
return controller( name, **kwargs )
|
return controller( name, **kwargs )
|
||||||
|
|
||||||
|
|||||||
+22
-15
@@ -33,7 +33,7 @@ class LinuxBridge( Switch ):
|
|||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def start( self, controllers ):
|
def start( self, _controllers ):
|
||||||
"Start Linux bridge"
|
"Start Linux bridge"
|
||||||
self.cmd( 'ifconfig', self, 'down' )
|
self.cmd( 'ifconfig', self, 'down' )
|
||||||
self.cmd( 'brctl delbr', self )
|
self.cmd( 'brctl delbr', self )
|
||||||
@@ -62,21 +62,22 @@ class LinuxBridge( Switch ):
|
|||||||
|
|
||||||
|
|
||||||
class NAT( Node ):
|
class NAT( Node ):
|
||||||
"""NAT: Provides connectivity to external network"""
|
"NAT: Provides connectivity to external network"
|
||||||
|
|
||||||
def __init__( self, name, inetIntf=None, subnet='10.0/8', localIntf=None, **params):
|
|
||||||
super( NAT, self ).__init__( name, **params )
|
|
||||||
|
|
||||||
|
def __init__( self, name, inetIntf=None, subnet='10.0/8',
|
||||||
|
localIntf=None, **params):
|
||||||
"""Start NAT/forwarding between Mininet and external network
|
"""Start NAT/forwarding between Mininet and external network
|
||||||
inetIntf: interface for internet access
|
inetIntf: interface for internet access
|
||||||
subnet: Mininet subnet (default 10.0/8)="""
|
subnet: Mininet subnet (default 10.0/8)="""
|
||||||
|
super( NAT, self ).__init__( name, **params )
|
||||||
|
|
||||||
self.inetIntf = inetIntf if inetIntf else self.getGatewayIntf()
|
self.inetIntf = inetIntf if inetIntf else self.getGatewayIntf()
|
||||||
self.subnet = subnet
|
self.subnet = subnet
|
||||||
self.localIntf = localIntf
|
self.localIntf = localIntf
|
||||||
|
|
||||||
def config( self, **params ):
|
def config( self, **params ):
|
||||||
super( NAT, self).config( **params )
|
|
||||||
"""Configure the NAT and iptables"""
|
"""Configure the NAT and iptables"""
|
||||||
|
super( NAT, self).config( **params )
|
||||||
|
|
||||||
if not self.localIntf:
|
if not self.localIntf:
|
||||||
self.localIntf = self.defaultIntf()
|
self.localIntf = self.defaultIntf()
|
||||||
@@ -94,10 +95,14 @@ class NAT( Node ):
|
|||||||
self.cmd( 'iptables -P FORWARD DROP' )
|
self.cmd( 'iptables -P FORWARD DROP' )
|
||||||
|
|
||||||
# Configure NAT
|
# Configure NAT
|
||||||
self.cmd( 'iptables -I FORWARD -i', self.localIntf, '-d', self.subnet, '-j DROP' )
|
self.cmd( 'iptables -I FORWARD',
|
||||||
self.cmd( 'iptables -A FORWARD -i', self.localIntf, '-s', self.subnet, '-j ACCEPT' )
|
'-i', self.localIntf, '-d', self.subnet, '-j DROP' )
|
||||||
self.cmd( 'iptables -A FORWARD -i', self.inetIntf, '-d', self.subnet, '-j ACCEPT' )
|
self.cmd( 'iptables -A FORWARD',
|
||||||
self.cmd( 'iptables -t nat -A POSTROUTING -o ', self.inetIntf, '-s', self.subnet, '-j MASQUERADE' )
|
'-i', self.localIntf, '-s', self.subnet, '-j ACCEPT' )
|
||||||
|
self.cmd( 'iptables -A FORWARD',
|
||||||
|
'-i', self.inetIntf, '-d', self.subnet, '-j ACCEPT' )
|
||||||
|
self.cmd( 'iptables -t nat -A POSTROUTING',
|
||||||
|
'-o', self.inetIntf, '-s', self.subnet, '-j MASQUERADE' )
|
||||||
|
|
||||||
# Instruct the kernel to perform forwarding
|
# Instruct the kernel to perform forwarding
|
||||||
self.cmd( 'sysctl net.ipv4.ip_forward=1' )
|
self.cmd( 'sysctl net.ipv4.ip_forward=1' )
|
||||||
@@ -116,14 +121,17 @@ class NAT( Node ):
|
|||||||
# hopefully this won't disconnect you
|
# hopefully this won't disconnect you
|
||||||
self.cmd( 'service network-manager restart' )
|
self.cmd( 'service network-manager restart' )
|
||||||
|
|
||||||
def getGatewayIntf( self ):
|
def getGatewayIntf( self, fallback='eth0' ):
|
||||||
|
"""Return gateway interface name
|
||||||
|
fallback: default device to fall back to"""
|
||||||
routes = self.cmd( 'ip route show' )
|
routes = self.cmd( 'ip route show' )
|
||||||
match = re.search('default via \S+ dev (\S+)', routes )
|
match = re.search( r'default via \S+ dev (\S+)', routes )
|
||||||
if match:
|
if match:
|
||||||
return match.group( 1 )
|
return match.group( 1 )
|
||||||
else:
|
else:
|
||||||
warn( 'There is no default route set. Using eth0 as gateway interface...\n' )
|
warn( 'There is no default route set.',
|
||||||
return 'eth0'
|
'Using', fallback, 'as gateway interface...\n' )
|
||||||
|
return fallback
|
||||||
|
|
||||||
def terminate( self ):
|
def terminate( self ):
|
||||||
"""Stop NAT/forwarding between Mininet and external network"""
|
"""Stop NAT/forwarding between Mininet and external network"""
|
||||||
@@ -136,4 +144,3 @@ class NAT( Node ):
|
|||||||
self.cmd( 'sysctl net.ipv4.ip_forward=0' )
|
self.cmd( 'sysctl net.ipv4.ip_forward=0' )
|
||||||
|
|
||||||
super( NAT, self ).terminate()
|
super( NAT, self ).terminate()
|
||||||
|
|
||||||
|
|||||||
+11
-5
@@ -111,7 +111,8 @@ class Topo( object ):
|
|||||||
self.hopts = params.pop( 'hopts', {} )
|
self.hopts = params.pop( 'hopts', {} )
|
||||||
self.sopts = params.pop( 'sopts', {} )
|
self.sopts = params.pop( 'sopts', {} )
|
||||||
self.lopts = params.pop( 'lopts', {} )
|
self.lopts = params.pop( 'lopts', {} )
|
||||||
self.ports = {} # ports[src][dst][sport] is port on dst that connects to src
|
# ports[src][dst][sport] is port on dst that connects to src
|
||||||
|
self.ports = {}
|
||||||
self.build( *args, **params )
|
self.build( *args, **params )
|
||||||
|
|
||||||
def build( self, *args, **params ):
|
def build( self, *args, **params ):
|
||||||
@@ -187,7 +188,7 @@ class Topo( object ):
|
|||||||
withKeys: return link keys
|
withKeys: return link keys
|
||||||
withInfo: return link info
|
withInfo: return link info
|
||||||
returns: list of ( src, dst [,key, info ] )"""
|
returns: list of ( src, dst [,key, info ] )"""
|
||||||
for src, dst, key, info in self.g.edges_iter( data=True, keys=True ):
|
for _src, _dst, key, info in self.g.edges_iter( data=True, keys=True ):
|
||||||
node1, node2 = info[ 'node1' ], info[ 'node2' ]
|
node1, node2 = info[ 'node1' ], info[ 'node2' ]
|
||||||
if withKeys:
|
if withKeys:
|
||||||
if withInfo:
|
if withInfo:
|
||||||
@@ -207,7 +208,7 @@ class Topo( object ):
|
|||||||
withInfo: return link info
|
withInfo: return link info
|
||||||
returns: list of ( src, dst [,key, info ] )"""
|
returns: list of ( src, dst [,key, info ] )"""
|
||||||
links = list( self.iterLinks( withKeys, withInfo ) )
|
links = list( self.iterLinks( withKeys, withInfo ) )
|
||||||
if not sorted:
|
if not sort:
|
||||||
return links
|
return links
|
||||||
# Ignore info when sorting
|
# Ignore info when sorting
|
||||||
tupleSize = 3 if withKeys else 2
|
tupleSize = 3 if withKeys else 2
|
||||||
@@ -287,10 +288,13 @@ class Topo( object ):
|
|||||||
return sorted( items, key=natural )
|
return sorted( items, key=natural )
|
||||||
|
|
||||||
|
|
||||||
|
# Our idiom defines additional parameters in build(param...)
|
||||||
|
# pylint: disable=arguments-differ, attribute-defined-outside-init
|
||||||
|
|
||||||
class SingleSwitchTopo( Topo ):
|
class SingleSwitchTopo( Topo ):
|
||||||
"Single switch connected to k hosts."
|
"Single switch connected to k hosts."
|
||||||
|
|
||||||
def build( self, k=2, **opts ):
|
def build( self, k=2, **_opts ):
|
||||||
"k: number of hosts"
|
"k: number of hosts"
|
||||||
self.k = k
|
self.k = k
|
||||||
switch = self.addSwitch( 's1' )
|
switch = self.addSwitch( 's1' )
|
||||||
@@ -317,7 +321,7 @@ class SingleSwitchReversedTopo( Topo ):
|
|||||||
class LinearTopo( Topo ):
|
class LinearTopo( Topo ):
|
||||||
"Linear topology of k switches, with n hosts per switch."
|
"Linear topology of k switches, with n hosts per switch."
|
||||||
|
|
||||||
def build( self, k=2, n=1, **opts):
|
def build( self, k=2, n=1, **_opts):
|
||||||
"""k: number of switches
|
"""k: number of switches
|
||||||
n: number of hosts per switch"""
|
n: number of hosts per switch"""
|
||||||
self.k = k
|
self.k = k
|
||||||
@@ -340,3 +344,5 @@ class LinearTopo( Topo ):
|
|||||||
if lastSwitch:
|
if lastSwitch:
|
||||||
self.addLink( switch, lastSwitch )
|
self.addLink( switch, lastSwitch )
|
||||||
lastSwitch = switch
|
lastSwitch = switch
|
||||||
|
|
||||||
|
# pylint: enable=arguments-differ, attribute-defined-outside-init
|
||||||
|
|||||||
+6
-3
@@ -3,6 +3,9 @@
|
|||||||
from mininet.topo import Topo
|
from mininet.topo import Topo
|
||||||
from mininet.net import Mininet
|
from mininet.net import Mininet
|
||||||
|
|
||||||
|
# The build() method is expected to do both of these things:
|
||||||
|
# pylint: disable=attribute-defined-outside-init, arguments-differ
|
||||||
|
|
||||||
class TreeTopo( Topo ):
|
class TreeTopo( Topo ):
|
||||||
"Topology for a tree network with a given depth and fanout."
|
"Topology for a tree network with a given depth and fanout."
|
||||||
|
|
||||||
@@ -53,7 +56,8 @@ class TorusTopo( Topo ):
|
|||||||
loc = '%dx%d' % ( i + 1, j + 1 )
|
loc = '%dx%d' % ( i + 1, j + 1 )
|
||||||
# dpid cannot be zero for OVS
|
# dpid cannot be zero for OVS
|
||||||
dpid = ( i + 1 ) * 256 + ( j + 1 )
|
dpid = ( i + 1 ) * 256 + ( j + 1 )
|
||||||
switch = switches[ i, j ] = self.addSwitch( 's' + loc, dpid='%016x' % dpid )
|
switch = switches[ i, j ] = self.addSwitch(
|
||||||
|
's' + loc, dpid='%016x' % dpid )
|
||||||
host = hosts[ i, j ] = self.addHost( 'h' + loc )
|
host = hosts[ i, j ] = self.addHost( 'h' + loc )
|
||||||
self.addLink( host, switch )
|
self.addLink( host, switch )
|
||||||
# Connect switches
|
# Connect switches
|
||||||
@@ -65,5 +69,4 @@ class TorusTopo( Topo ):
|
|||||||
self.addLink( sw1, sw2 )
|
self.addLink( sw1, sw2 )
|
||||||
self.addLink( sw1, sw3 )
|
self.addLink( sw1, sw3 )
|
||||||
|
|
||||||
|
# pylint: enable=attribute-defined-outside-init, arguments-differ
|
||||||
|
|
||||||
|
|||||||
+14
-14
@@ -25,7 +25,7 @@ def checkRun( cmd ):
|
|||||||
return check_call( cmd.split( ' ' ) )
|
return check_call( cmd.split( ' ' ) )
|
||||||
|
|
||||||
# pylint doesn't understand explicit type checking
|
# pylint doesn't understand explicit type checking
|
||||||
# pylint: disable-msg=E1103
|
# pylint: disable=E1103
|
||||||
|
|
||||||
def oldQuietRun( *cmd ):
|
def oldQuietRun( *cmd ):
|
||||||
"""Run a command, routing stderr to stdout, and return the output.
|
"""Run a command, routing stderr to stdout, and return the output.
|
||||||
@@ -119,8 +119,8 @@ def quietRun( cmd, **kwargs ):
|
|||||||
"Run a command and return merged stdout and stderr"
|
"Run a command and return merged stdout and stderr"
|
||||||
return errRun( cmd, stderr=STDOUT, **kwargs )[ 0 ]
|
return errRun( cmd, stderr=STDOUT, **kwargs )[ 0 ]
|
||||||
|
|
||||||
# pylint: enable-msg=E1103
|
# pylint: enable=E1103
|
||||||
# pylint: disable-msg=E1101
|
# pylint: disable=E1101
|
||||||
|
|
||||||
def isShellBuiltin( cmd ):
|
def isShellBuiltin( cmd ):
|
||||||
"Return True if cmd is a bash builtin."
|
"Return True if cmd is a bash builtin."
|
||||||
@@ -133,7 +133,7 @@ def isShellBuiltin( cmd ):
|
|||||||
|
|
||||||
isShellBuiltin.builtIns = None
|
isShellBuiltin.builtIns = None
|
||||||
|
|
||||||
# pylint: enable-msg=E1101
|
# pylint: enable=E1101
|
||||||
|
|
||||||
# Interface management
|
# Interface management
|
||||||
#
|
#
|
||||||
@@ -148,22 +148,22 @@ isShellBuiltin.builtIns = None
|
|||||||
# live in the root namespace and thus do not have to be
|
# live in the root namespace and thus do not have to be
|
||||||
# explicitly moved.
|
# explicitly moved.
|
||||||
|
|
||||||
def makeIntfPair( intf1, intf2, addr1=None, addr2=None, run=quietRun ):
|
def makeIntfPair( intf1, intf2, addr1=None, addr2=None, runCmd=quietRun ):
|
||||||
"""Make a veth pair connecting intf1 and intf2.
|
"""Make a veth pair connecting intf1 and intf2.
|
||||||
intf1: string, interface
|
intf1: string, interface
|
||||||
intf2: string, interface
|
intf2: string, interface
|
||||||
node: node to run on or None (default)
|
runCmd: function to run shell commands (quietRun)
|
||||||
returns: ip link add result"""
|
returns: ip link add result"""
|
||||||
# Delete any old interfaces with the same names
|
# Delete any old interfaces with the same names
|
||||||
run( 'ip link del ' + intf1 )
|
runCmd( 'ip link del ' + intf1 )
|
||||||
run( 'ip link del ' + intf2 )
|
runCmd( 'ip link del ' + intf2 )
|
||||||
# Create new pair
|
# Create new pair
|
||||||
if addr1 is None and addr2 is None:
|
if addr1 is None and addr2 is None:
|
||||||
cmd = 'ip link add name ' + intf1 + ' type veth peer name ' + intf2
|
cmd = 'ip link add name ' + intf1 + ' type veth peer name ' + intf2
|
||||||
else:
|
else:
|
||||||
cmd = ( 'ip link add name ' + intf1 + ' address ' + addr1 +
|
cmd = ( 'ip link add name ' + intf1 + ' address ' + addr1 +
|
||||||
' type veth peer name ' + intf2 + ' address ' + addr2 )
|
' type veth peer name ' + intf2 + ' address ' + addr2 )
|
||||||
cmdOutput = run( cmd )
|
cmdOutput = runCmd( cmd )
|
||||||
if cmdOutput == '':
|
if cmdOutput == '':
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
@@ -202,7 +202,7 @@ def moveIntfNoRetry( intf, dstNode, printError=False ):
|
|||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def moveIntf( intf, dstNode, srcNode=None, printError=True,
|
def moveIntf( intf, dstNode, printError=True,
|
||||||
retries=3, delaySecs=0.001 ):
|
retries=3, delaySecs=0.001 ):
|
||||||
"""Move interface to node, retrying on failure.
|
"""Move interface to node, retrying on failure.
|
||||||
intf: string, interface
|
intf: string, interface
|
||||||
@@ -296,7 +296,7 @@ def ipAdd( i, prefixLen=8, ipBaseNum=0x0a000000 ):
|
|||||||
def ipParse( ip ):
|
def ipParse( ip ):
|
||||||
"Parse an IP address and return an unsigned int."
|
"Parse an IP address and return an unsigned int."
|
||||||
args = [ int( arg ) for arg in ip.split( '.' ) ]
|
args = [ int( arg ) for arg in ip.split( '.' ) ]
|
||||||
while ( len(args) < 4 ):
|
while len(args) < 4:
|
||||||
args.append( 0 )
|
args.append( 0 )
|
||||||
return ipNum( *args )
|
return ipNum( *args )
|
||||||
|
|
||||||
@@ -427,7 +427,7 @@ def fixLimits():
|
|||||||
sysctlTestAndSet( 'net.ipv4.route.max_size', 32768 )
|
sysctlTestAndSet( 'net.ipv4.route.max_size', 32768 )
|
||||||
#Increase number of PTYs for nodes
|
#Increase number of PTYs for nodes
|
||||||
sysctlTestAndSet( 'kernel.pty.max', 20000 )
|
sysctlTestAndSet( 'kernel.pty.max', 20000 )
|
||||||
except:
|
except Exception:
|
||||||
warn( "*** Error setting resource limits. "
|
warn( "*** Error setting resource limits. "
|
||||||
"Mininet's performance may be affected.\n" )
|
"Mininet's performance may be affected.\n" )
|
||||||
|
|
||||||
@@ -545,9 +545,9 @@ def ensureRoot():
|
|||||||
def waitListening( client=None, server='127.0.0.1', port=80, timeout=None ):
|
def waitListening( client=None, server='127.0.0.1', port=80, timeout=None ):
|
||||||
"""Wait until server is listening on port.
|
"""Wait until server is listening on port.
|
||||||
returns True if server is listening"""
|
returns True if server is listening"""
|
||||||
run = ( client.cmd if client else
|
runCmd = ( client.cmd if client else
|
||||||
partial( quietRun, shell=True ) )
|
partial( quietRun, shell=True ) )
|
||||||
if not run( 'which telnet' ):
|
if not runCmd( 'which telnet' ):
|
||||||
raise Exception('Could not find telnet' )
|
raise Exception('Could not find telnet' )
|
||||||
serverIP = server if isinstance( server, basestring ) else server.IP()
|
serverIP = server if isinstance( server, basestring ) else server.IP()
|
||||||
cmd = ( 'sh -c "echo A | telnet -e A %s %s"' %
|
cmd = ( 'sh -c "echo A | telnet -e A %s %s"' %
|
||||||
|
|||||||
Reference in New Issue
Block a user