Pass pylint.
This commit is contained in:
+1
-1
@@ -23,7 +23,7 @@ def sh( cmd ):
|
||||
def cleanup():
|
||||
"""Clean up junk which might be left over from old runs;
|
||||
do fast stuff before slow dp and link removal!"""
|
||||
|
||||
|
||||
info("*** Removing excess controllers/ofprotocols/ofdatapaths/pings/noxes"
|
||||
"\n")
|
||||
zombies = 'controller ofprotocol ofdatapath ping nox_core lt-nox_core '
|
||||
|
||||
+23
-17
@@ -29,18 +29,18 @@ from subprocess import call
|
||||
from cmd import Cmd
|
||||
from os import isatty
|
||||
from select import poll, POLLIN
|
||||
from sys import stdin
|
||||
import sys
|
||||
|
||||
from mininet.log import info, output, error
|
||||
from mininet.term import makeTerms
|
||||
from mininet.util import quietRun, isShellBuiltin
|
||||
|
||||
|
||||
class CLI( Cmd ):
|
||||
"Simple command-line interface to talk to nodes."
|
||||
|
||||
prompt = 'mininet> '
|
||||
|
||||
def __init__( self, mininet, stdin=stdin ):
|
||||
def __init__( self, mininet, stdin=sys.stdin ):
|
||||
self.mn = mininet
|
||||
self.nodelist = self.mn.controllers + self.mn.switches + self.mn.hosts
|
||||
self.nodemap = {} # map names to Node objects
|
||||
@@ -75,7 +75,7 @@ class CLI( Cmd ):
|
||||
# must have the same interface
|
||||
# pylint: disable-msg=W0613,R0201
|
||||
|
||||
helpStr = (
|
||||
helpStr = (
|
||||
'You may also send a command to a node using:\n'
|
||||
' <node> command {args}\n'
|
||||
'For example:\n'
|
||||
@@ -110,7 +110,9 @@ class CLI( Cmd ):
|
||||
for switch in self.mn.switches:
|
||||
output( switch.name, '<->' )
|
||||
for intf in switch.intfs.values():
|
||||
node, name = switch.connection.get( intf, ( None, 'Unknown ' ) )
|
||||
# Ugly, but pylint wants it
|
||||
name = switch.connection.get( intf,
|
||||
( None, 'Unknown ' ) )[ 1 ]
|
||||
output( ' %s' % name )
|
||||
output( '\n' )
|
||||
|
||||
@@ -209,7 +211,7 @@ class CLI( Cmd ):
|
||||
def isatty( self ):
|
||||
"Is our standard input a tty?"
|
||||
return isatty( self.stdin.fileno() )
|
||||
|
||||
|
||||
def do_noecho( self, line ):
|
||||
"Run an interactive command with echoing turned off."
|
||||
if self.isatty():
|
||||
@@ -236,20 +238,16 @@ class CLI( Cmd ):
|
||||
for arg in rest ]
|
||||
rest = ' '.join( rest )
|
||||
# Run cmd on node:
|
||||
node.sendCmd( rest )
|
||||
self.waitForNode( node, isShellBuiltin( first ) )
|
||||
builtin = isShellBuiltin( first )
|
||||
print "builtin =", builtin
|
||||
node.sendCmd( rest, printPid=( not builtin ) )
|
||||
self.waitForNode( node )
|
||||
else:
|
||||
error( '*** Unknown command: %s\n' % first )
|
||||
|
||||
# pylint: enable-msg=W0613,R0201
|
||||
|
||||
def isReadable( self, poller ):
|
||||
"Check whether a single polled object is readable."
|
||||
for fd, mask in poller.poll( 0 ):
|
||||
if mask & POLLIN:
|
||||
return True
|
||||
|
||||
def waitForNode( self, node, isShellBuiltin=False ):
|
||||
def waitForNode( self, node ):
|
||||
"Wait for a node to finish, and print its output."
|
||||
# Pollers
|
||||
nodePoller = poll()
|
||||
@@ -264,10 +262,10 @@ class CLI( Cmd ):
|
||||
while True:
|
||||
try:
|
||||
bothPoller.poll()
|
||||
if self.isReadable( self.inPoller ):
|
||||
if isReadable( self.inPoller ):
|
||||
key = self.stdin.read( 1 )
|
||||
node.write( key )
|
||||
if self.isReadable( nodePoller ):
|
||||
if isReadable( nodePoller ):
|
||||
data = node.monitor()
|
||||
output( data )
|
||||
if not node.waiting:
|
||||
@@ -275,3 +273,11 @@ class CLI( Cmd ):
|
||||
except KeyboardInterrupt:
|
||||
node.sendInt()
|
||||
|
||||
# Helper functions
|
||||
|
||||
def isReadable( poller ):
|
||||
"Check whether a Poll object has a readable fd."
|
||||
for fdmask in poller.poll( 0 ):
|
||||
mask = fdmask[ 1 ]
|
||||
if mask & POLLIN:
|
||||
return True
|
||||
|
||||
+28
-24
@@ -100,26 +100,6 @@ from mininet.util import quietRun, fixLimits
|
||||
from mininet.util import createLink, macColonHex, ipStr, ipParse
|
||||
from mininet.term import cleanUpScreens, makeTerms
|
||||
|
||||
DATAPATHS = [ 'kernel' ] # [ 'user', 'kernel' ]
|
||||
|
||||
|
||||
def init():
|
||||
"Initialize Mininet."
|
||||
if init.inited:
|
||||
return
|
||||
if os.getuid() != 0:
|
||||
# Note: this script must be run as root
|
||||
# Perhaps we should do so automatically!
|
||||
print "*** Mininet must run as root."
|
||||
exit( 1 )
|
||||
# If which produces no output, then mnexec is not in the path.
|
||||
# May want to loosen this to handle mnexec in the current dir.
|
||||
if not quietRun( 'which mnexec' ):
|
||||
raise Exception( "Could not find mnexec - check $PATH" )
|
||||
fixLimits()
|
||||
|
||||
init.inited = False
|
||||
|
||||
class Mininet( object ):
|
||||
"Network emulation with hosts spawned in network namespaces."
|
||||
|
||||
@@ -167,7 +147,7 @@ class Mininet( object ):
|
||||
if topo and build:
|
||||
self.build()
|
||||
|
||||
|
||||
|
||||
def addHost( self, name, mac=None, ip=None ):
|
||||
"""Add host.
|
||||
name: name of host to add
|
||||
@@ -195,13 +175,13 @@ class Mininet( object ):
|
||||
self.nameToNode[ name ] = sw
|
||||
return sw
|
||||
|
||||
def addController( self, controller ):
|
||||
def addController( self, name='c0', **kwargs ):
|
||||
"""Add controller.
|
||||
controller: Controller class"""
|
||||
controller_new = self.controller( 'c0' )
|
||||
controller_new = self.controller( name, **kwargs )
|
||||
if controller_new: # allow controller-less setups
|
||||
self.controllers.append( controller_new )
|
||||
self.nameToNode[ 'c0' ] = controller_new
|
||||
self.nameToNode[ name ] = controller_new
|
||||
|
||||
# Control network support:
|
||||
#
|
||||
@@ -558,3 +538,27 @@ class Mininet( object ):
|
||||
result = CLI( self )
|
||||
self.stop()
|
||||
return result
|
||||
|
||||
|
||||
# pylint thinks inited is unused
|
||||
# pylint: disable-msg=W0612
|
||||
|
||||
def init():
|
||||
"Initialize Mininet."
|
||||
if init.inited:
|
||||
return
|
||||
if os.getuid() != 0:
|
||||
# Note: this script must be run as root
|
||||
# Perhaps we should do so automatically!
|
||||
print "*** Mininet must run as root."
|
||||
exit( 1 )
|
||||
# If which produces no output, then mnexec is not in the path.
|
||||
# May want to loosen this to handle mnexec in the current dir.
|
||||
if not quietRun( 'which mnexec' ):
|
||||
raise Exception( "Could not find mnexec - check $PATH" )
|
||||
fixLimits()
|
||||
init.inited = True
|
||||
|
||||
init.inited = False
|
||||
|
||||
# pylint: enable-msg=W0612
|
||||
|
||||
+8
-14
@@ -95,6 +95,8 @@ class Node( object ):
|
||||
self.lastPid = None
|
||||
self.readbuf = ''
|
||||
self.waiting = False
|
||||
# Stash additional information as desired
|
||||
self.args = kwargs
|
||||
|
||||
@classmethod
|
||||
def fdToNode( cls, fd ):
|
||||
@@ -186,7 +188,7 @@ class Node( object ):
|
||||
if self.lastPid:
|
||||
try:
|
||||
os.kill( self.lastPid, sig )
|
||||
except Exception:
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
def monitor( self, timeoutms=None ):
|
||||
@@ -301,7 +303,7 @@ class Node( object ):
|
||||
if port1 is None:
|
||||
port1 = node1.newPort()
|
||||
if port2 is None:
|
||||
port2 = node2.newPort()
|
||||
port2 = node2.newPort()
|
||||
intf1 = node1.intfName( port1 )
|
||||
intf2 = node2.intfName( port2 )
|
||||
makeIntfPair( intf1, intf2 )
|
||||
@@ -410,14 +412,6 @@ class Switch( Node ):
|
||||
error( '*** Error: %s has execed and cannot accept commands' %
|
||||
self.name )
|
||||
|
||||
def monitor( self, *args, **kwargs ):
|
||||
"Monitor a switch."
|
||||
if not self.execed:
|
||||
return Node.monitor( self, *args, **kwargs )
|
||||
else:
|
||||
return True, ''
|
||||
|
||||
|
||||
class UserSwitch( Switch ):
|
||||
"User-space switch."
|
||||
|
||||
@@ -458,7 +452,7 @@ class UserSwitch( Switch ):
|
||||
class KernelSwitch( Switch ):
|
||||
"""Kernel-space switch.
|
||||
Currently only works in root namespace."""
|
||||
|
||||
|
||||
def __init__( self, name, dp=None, **kwargs ):
|
||||
"""Init.
|
||||
name: name for switch
|
||||
@@ -496,7 +490,7 @@ class KernelSwitch( Switch ):
|
||||
# Run protocol daemon
|
||||
controller = controllers[ 0 ]
|
||||
self.cmd( 'ofprotocol ' + self.dp +
|
||||
' tcp:%s:%d' % ( controller.IP(), controller.port ) +
|
||||
' tcp:%s:%d' % ( controller.IP(), controller.port ) +
|
||||
' --fail=closed ' + self.opts +
|
||||
' 1> ' + ofplog + ' 2>' + ofplog + ' &' )
|
||||
self.execed = False
|
||||
@@ -550,8 +544,8 @@ class OVSKernelSwitch( Switch ):
|
||||
# Run protocol daemon
|
||||
controller = controllers[ 0 ]
|
||||
self.cmd( 'ovs-openflowd ' + self.dp +
|
||||
' tcp:%s:%i' % ( controller.IP(), controller.port ) +
|
||||
' --fail=closed ' + self.opts +
|
||||
' tcp:%s:%i' % ( controller.IP(), controller.port ) +
|
||||
' --fail=closed ' + self.opts +
|
||||
' 1>' + ofplog + ' 2>' + ofplog + '&' )
|
||||
self.execed = False
|
||||
|
||||
|
||||
+3
-3
@@ -15,7 +15,7 @@ from mininet.util import quietRun
|
||||
def quoteArg( arg ):
|
||||
"Quote an argument if it contains spaces."
|
||||
return repr( arg ) if ' ' in arg else arg
|
||||
|
||||
|
||||
def makeTerm( node, title='Node', term='xterm' ):
|
||||
"""Run screen on a node, and hook up a terminal.
|
||||
node: Node object
|
||||
@@ -38,9 +38,9 @@ def makeTerm( node, title='Node', term='xterm' ):
|
||||
else:
|
||||
args = [ 'sh', '-c', 'exec tail -f /tmp/' + node.name + '*.log' ]
|
||||
if term == 'gterm':
|
||||
# Compress these for gnome-terminal, which expects one token
|
||||
# Compress these for gnome-terminal, which expects one token
|
||||
# to follow the -e option
|
||||
args = [ ' '.join( [ quoteArg( arg ) for arg in args ] ) ]
|
||||
args = [ ' '.join( [ quoteArg( arg ) for arg in args ] ) ]
|
||||
return Popen( cmds[ term ] + args )
|
||||
|
||||
def cleanUpScreens():
|
||||
|
||||
+33
-21
@@ -5,7 +5,9 @@ from resource import setrlimit, RLIMIT_NPROC, RLIMIT_NOFILE
|
||||
import select
|
||||
from subprocess import call, check_call, Popen, PIPE, STDOUT
|
||||
|
||||
from mininet.log import lg
|
||||
from mininet.log import error
|
||||
|
||||
# Command execution support
|
||||
|
||||
def run( cmd ):
|
||||
"""Simple interface to subprocess.call()
|
||||
@@ -17,13 +19,16 @@ def checkRun( cmd ):
|
||||
cmd: list of command params"""
|
||||
return check_call( cmd.split( ' ' ) )
|
||||
|
||||
# pylint doesn't understand explicit type checking
|
||||
# pylint: disable-msg=E1103
|
||||
|
||||
def quietRun( *cmd ):
|
||||
"""Run a command, routing stderr to stdout, and return the output.
|
||||
cmd: list of command params"""
|
||||
if len( cmd ) == 1:
|
||||
cmd = cmd[ 0 ]
|
||||
if isinstance( cmd, str ):
|
||||
cmd = cmd.split( ' ' )
|
||||
if isinstance( cmd, str ):
|
||||
cmd = cmd.split( ' ' )
|
||||
popen = Popen( cmd, stdout=PIPE, stderr=STDOUT )
|
||||
# We can't use Popen.communicate() because it uses
|
||||
# select(), which can't handle
|
||||
@@ -42,6 +47,22 @@ def quietRun( *cmd ):
|
||||
break
|
||||
return output
|
||||
|
||||
# pylint: enable-msg=E1103
|
||||
# pylint: disable-msg=E1101,W0612
|
||||
|
||||
def isShellBuiltin( cmd ):
|
||||
"Return True if cmd is a bash builtin."
|
||||
if isShellBuiltin.builtIns is None:
|
||||
isShellBuiltin.builtIns = quietRun( 'bash -c enable' )
|
||||
space = cmd.find( ' ' )
|
||||
if space > 0:
|
||||
cmd = cmd[ :space]
|
||||
return cmd in isShellBuiltin.builtIns
|
||||
|
||||
isShellBuiltin.builtIns = None
|
||||
|
||||
# pylint: enable-msg=E1101,W0612
|
||||
|
||||
# Interface management
|
||||
#
|
||||
# Interfaces are managed as strings which are simply the
|
||||
@@ -78,7 +99,7 @@ def retry( retries, delaySecs, fn, *args, **keywords ):
|
||||
sleep( delaySecs )
|
||||
tries += 1
|
||||
if tries >= retries:
|
||||
lg.error( "*** gave up after %i retries\n" % tries )
|
||||
error( "*** gave up after %i retries\n" % tries )
|
||||
exit( 1 )
|
||||
|
||||
def moveIntfNoRetry( intf, node, printError=False ):
|
||||
@@ -91,7 +112,7 @@ def moveIntfNoRetry( intf, node, printError=False ):
|
||||
links = node.cmd( 'ip link show' )
|
||||
if not ( ' %s:' % intf ) in links:
|
||||
if printError:
|
||||
lg.error( '*** Error: moveIntf: ' + intf +
|
||||
error( '*** Error: moveIntf: ' + intf +
|
||||
' not successfully moved to ' + node.name + '\n' )
|
||||
return False
|
||||
return True
|
||||
@@ -112,10 +133,8 @@ def createLink( node1, node2, port1=None, port2=None ):
|
||||
returns: intf1 name, intf2 name"""
|
||||
return node1.linkTo( node2, port1, port2 )
|
||||
|
||||
def fixLimits():
|
||||
"Fix ridiculously small resource limits."
|
||||
setrlimit( RLIMIT_NPROC, ( 4096, 8192 ) )
|
||||
setrlimit( RLIMIT_NOFILE, ( 16384, 32768 ) )
|
||||
|
||||
# IP and Mac address formatting and parsing
|
||||
|
||||
def _colonHex( val, bytes ):
|
||||
"""Generate colon-hex string.
|
||||
@@ -181,17 +200,10 @@ def makeNumeric( s ):
|
||||
else:
|
||||
return s
|
||||
|
||||
# pylint: disable-msg=E1101,W0612
|
||||
|
||||
def isShellBuiltin( cmd ):
|
||||
"Return True if cmd is a bash builtin."
|
||||
if isShellBuiltin.builtIns is None:
|
||||
isShellBuiltin.builtIns = quietRun( 'bash -c enable' )
|
||||
space = cmd.find( ' ' )
|
||||
if space > 0:
|
||||
cmd = cmd[ :space]
|
||||
return cmd in isShellBuiltin.builtIns
|
||||
# Other stuff we use
|
||||
|
||||
isShellBuiltin.builtIns = None
|
||||
|
||||
# pylint: enable-msg=E1101,W0612
|
||||
def fixLimits():
|
||||
"Fix ridiculously small resource limits."
|
||||
setrlimit( RLIMIT_NPROC, ( 4096, 8192 ) )
|
||||
setrlimit( RLIMIT_NOFILE, ( 16384, 32768 ) )
|
||||
|
||||
Reference in New Issue
Block a user