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