Pass code check with pylint=2.4.4 (#1012)
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
|
||||
name: code-check
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
code-check:
|
||||
name: Mininet Code Check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Set up Python 3.x
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.x
|
||||
- name: Check out Mininet source
|
||||
uses: actions/checkout@v2
|
||||
- name: Install Mininet code check dependencies
|
||||
run: |
|
||||
PYTHON=`which python` util/install.sh -n
|
||||
python -m pip install pylint==2.4.4
|
||||
- name: Run code check
|
||||
run: make codecheck
|
||||
@@ -24,9 +24,6 @@ jobs:
|
||||
# This seems too slow unfortunately:
|
||||
# sudo apt-get upgrade -y -qq
|
||||
PYTHON=`which python` util/install.sh -nv
|
||||
- name: Run code check (skipping for now)
|
||||
run: |
|
||||
bash -c "if [ `lsb_release -rs` == '14.04' ]; then make codecheck; fi"
|
||||
- name: Sanity test
|
||||
run: |
|
||||
export sudo="sudo env PATH=$PATH"
|
||||
|
||||
@@ -41,10 +41,16 @@ load-plugins=
|
||||
# can either give multiple identifier separated by comma (,) or put this option
|
||||
# multiple time (only on the command line, not in the configuration file where
|
||||
# it should appear only once).
|
||||
#
|
||||
# Note: we may want to re-enable some of these at some point, but many of them
|
||||
# are just style issues rather than errors.
|
||||
#
|
||||
disable=pointless-except, invalid-name, super-init-not-called, fixme, star-args,
|
||||
too-many-instance-attributes, too-few-public-methods, too-many-arguments,
|
||||
too-many-instance-attributes, too-few-public-methods,
|
||||
too-many-locals, too-many-public-methods, duplicate-code, bad-whitespace,
|
||||
locally-disabled, locally-enabled
|
||||
locally-disabled, locally-enabled, bad-continuation,
|
||||
useless-object-inheritance, unnecessary-pass, no-else-return,
|
||||
no-else-raise, no-else-continue, super-with-arguments
|
||||
|
||||
# bad-continuation, wrong-import-order
|
||||
|
||||
|
||||
+4
-7
@@ -3,20 +3,17 @@ sudo: required
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- dist: trusty
|
||||
python: 2.7
|
||||
env: dist="14.04 LTS trusty"
|
||||
- dist: trusty
|
||||
- dist: focal
|
||||
python: 3.6
|
||||
env: dist="14.04 LTS trusty"
|
||||
env: dist="24.04 LTS focal"
|
||||
|
||||
before_install:
|
||||
- sudo apt-get update -qq
|
||||
- sudo apt-get install -qq vlan
|
||||
- sudo apt-get install -qq vlan pyflakes
|
||||
- PYTHON=`which python` util/install.sh -n
|
||||
|
||||
install:
|
||||
- bash -c "if [ `lsb_release -rs` == '14.04' ]; then make codecheck; fi"
|
||||
- make codecheck
|
||||
- pip install pexpect || pip3 install pexpect
|
||||
- util/install.sh -nfvw
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ BIN = $(MN)
|
||||
PYSRC = $(MININET) $(TEST) $(EXAMPLES) $(BIN)
|
||||
MNEXEC = mnexec
|
||||
MANPAGES = mn.1 mnexec.1
|
||||
P8IGN = E251,E201,E302,E202,E126,E127,E203,E226
|
||||
P8IGN = E251,E201,E302,E202,E126,E127,E203,E226,E402,W504,W503,E731
|
||||
PREFIX ?= /usr
|
||||
BINDIR ?= $(PREFIX)/bin
|
||||
MANDIR ?= $(PREFIX)/share/man/man1
|
||||
|
||||
@@ -11,15 +11,20 @@ Example to pull custom params (topo, switch, etc.) from a file:
|
||||
sudo mn --custom ~/mininet/custom/custom_example.py
|
||||
"""
|
||||
|
||||
from optparse import OptionParser
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
from functools import partial
|
||||
from optparse import OptionParser # pylint: disable=deprecated-module
|
||||
from sys import exit # pylint: disable=redefined-builtin
|
||||
|
||||
# Fix setuptools' evil madness, and open up (more?) security holes
|
||||
if 'PYTHONPATH' in os.environ:
|
||||
sys.path = os.environ[ 'PYTHONPATH' ].split( ':' ) + sys.path
|
||||
|
||||
# pylint: disable=wrong-import-position
|
||||
|
||||
from mininet.clean import cleanup
|
||||
import mininet.cli
|
||||
from mininet.log import lg, LEVELS, info, debug, warn, error, output
|
||||
@@ -34,10 +39,7 @@ from mininet.link import Link, TCLink, TCULink, OVSLink
|
||||
from mininet.topo import ( SingleSwitchTopo, LinearTopo,
|
||||
SingleSwitchReversedTopo, MinimalTopo )
|
||||
from mininet.topolib import TreeTopo, TorusTopo
|
||||
from mininet.util import customClass, specialClass, splitArgs
|
||||
from mininet.util import buildTopo
|
||||
|
||||
from functools import partial
|
||||
from mininet.util import customClass, specialClass, splitArgs, buildTopo
|
||||
|
||||
# Experimental! cluster edition prototype
|
||||
from mininet.examples.cluster import ( MininetCluster, RemoteHost,
|
||||
@@ -46,6 +48,7 @@ from mininet.examples.cluster import ( MininetCluster, RemoteHost,
|
||||
ClusterCleanup )
|
||||
from mininet.examples.clustercli import ClusterCLI
|
||||
|
||||
|
||||
PLACEMENT = { 'block': SwitchBinPlacer, 'random': RandomPlacer }
|
||||
|
||||
# built in topologies, created only when run
|
||||
@@ -107,6 +110,7 @@ def nullTest( _net ):
|
||||
"Null 'test' (does nothing)"
|
||||
pass
|
||||
|
||||
|
||||
TESTS.update( all=allTest, none=nullTest, build=nullTest )
|
||||
|
||||
# Map to alternate spellings of Mininet() methods
|
||||
@@ -425,7 +429,7 @@ if __name__ == "__main__":
|
||||
except KeyboardInterrupt:
|
||||
info( "\n\nKeyboard Interrupt. Shutting down and cleaning up...\n\n")
|
||||
cleanup()
|
||||
except Exception:
|
||||
except Exception: # pylint: disable=broad-except
|
||||
# Print exception
|
||||
type_, val_, trace_ = sys.exc_info()
|
||||
errorMsg = ( "-"*80 + "\n" +
|
||||
|
||||
+3
-2
@@ -34,14 +34,14 @@ and '/var/run'. It also has a temporary private directory mounted
|
||||
on '/var/mn'
|
||||
"""
|
||||
|
||||
from functools import partial
|
||||
|
||||
from mininet.net import Mininet
|
||||
from mininet.node import Host
|
||||
from mininet.cli import CLI
|
||||
from mininet.topo import SingleSwitchTopo
|
||||
from mininet.log import setLogLevel, info
|
||||
|
||||
from functools import partial
|
||||
|
||||
|
||||
# Sample usage
|
||||
|
||||
@@ -61,6 +61,7 @@ def testHostWithPrivateDirs():
|
||||
CLI( net )
|
||||
net.stop()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
setLogLevel( 'info' )
|
||||
testHostWithPrivateDirs()
|
||||
|
||||
+38
-28
@@ -74,6 +74,15 @@ Things to do:
|
||||
- hifi support (e.g. delay compensation)
|
||||
"""
|
||||
|
||||
from signal import signal, SIGINT, SIG_IGN
|
||||
from subprocess import Popen, PIPE, STDOUT
|
||||
import os
|
||||
from random import randrange
|
||||
import sys
|
||||
import re
|
||||
from itertools import groupby
|
||||
from operator import attrgetter
|
||||
from distutils.version import StrictVersion
|
||||
|
||||
from mininet.node import Node, Host, OVSSwitch, Controller
|
||||
from mininet.link import Link, Intf
|
||||
@@ -85,15 +94,7 @@ from mininet.examples.clustercli import CLI
|
||||
from mininet.log import setLogLevel, debug, info, error
|
||||
from mininet.clean import addCleanupCallback
|
||||
|
||||
from signal import signal, SIGINT, SIG_IGN
|
||||
from subprocess import Popen, PIPE, STDOUT
|
||||
import os
|
||||
from random import randrange
|
||||
import sys
|
||||
import re
|
||||
from itertools import groupby
|
||||
from operator import attrgetter
|
||||
from distutils.version import StrictVersion
|
||||
# pylint: disable=too-many-arguments
|
||||
|
||||
|
||||
def findUser():
|
||||
@@ -261,7 +262,7 @@ class RemoteMixin( object ):
|
||||
cmd: remote command to run (list)
|
||||
**params: parameters to Popen()
|
||||
returns: Popen() object"""
|
||||
if type( cmd ) is str:
|
||||
if isinstance( cmd, str):
|
||||
cmd = cmd.split()
|
||||
if self.isRemote:
|
||||
if sudo:
|
||||
@@ -289,6 +290,7 @@ class RemoteMixin( object ):
|
||||
def addIntf( self, *args, **kwargs ):
|
||||
"Override: use RemoteLink.moveIntf"
|
||||
# kwargs.update( moveIntfFn=RemoteLink.moveIntf )
|
||||
# pylint: disable=useless-super-delegation
|
||||
return super( RemoteMixin, self).addIntf( *args, **kwargs )
|
||||
|
||||
|
||||
@@ -325,6 +327,7 @@ class RemoteOVSSwitch( RemoteMixin, OVSSwitch ):
|
||||
StrictVersion( '1.10' ) )
|
||||
|
||||
@classmethod
|
||||
# pylint: disable=arguments-differ
|
||||
def batchStartup( cls, switches, **_kwargs ):
|
||||
"Start up switches in per-server batches"
|
||||
key = attrgetter( 'server' )
|
||||
@@ -336,6 +339,7 @@ class RemoteOVSSwitch( RemoteMixin, OVSSwitch ):
|
||||
return switches
|
||||
|
||||
@classmethod
|
||||
# pylint: disable=arguments-differ
|
||||
def batchShutdown( cls, switches, **_kwargs ):
|
||||
"Stop switches in per-server batches"
|
||||
key = attrgetter( 'server' )
|
||||
@@ -413,8 +417,9 @@ class RemoteLink( Link ):
|
||||
# And we can't ssh into this server remotely as 'localhost',
|
||||
# so try again swappping node1 and node2
|
||||
if node2.server == 'localhost':
|
||||
return self.makeTunnel( node2, node1, intfname2, intfname1,
|
||||
addr2, addr1 )
|
||||
return self.makeTunnel( node1=node2, node2=node1,
|
||||
intfname1=intfname2, intfname2=intfname1,
|
||||
addr1=addr2, addr2=addr1 )
|
||||
debug( '\n*** Make SSH tunnel ' + node1.server + ':' + intfname1 +
|
||||
' == ' + node2.server + ':' + intfname2 )
|
||||
# 1. Create tap interfaces
|
||||
@@ -526,8 +531,9 @@ class RemoteGRELink( RemoteLink ):
|
||||
# We should never try to create a tunnel to ourselves!
|
||||
assert node1.server != node2.server
|
||||
if node2.server == 'localhost':
|
||||
return self.makeTunnel( node2, node1, intfname2, intfname1,
|
||||
addr2, addr1 )
|
||||
return self.makeTunnel( node1=node2, node2=node1,
|
||||
intfname1=intfname2, intfname2=intfname1,
|
||||
addr1=addr2, addr2=addr1 )
|
||||
IP1, IP2 = node1.serverIP, node2.serverIP
|
||||
# GRE tunnel needs to be set up with the IP of the local interface
|
||||
# that connects the remote node, NOT '127.0.0.1' of localhost
|
||||
@@ -555,6 +561,7 @@ class RemoteGRELink( RemoteLink ):
|
||||
node.rcmd('ip link set dev %s mtu 1450' % intfname)
|
||||
if not self.moveIntf(intfname, node):
|
||||
raise Exception('interface move failed on node %s' % node)
|
||||
return None # May want to return something useful here
|
||||
|
||||
|
||||
# Some simple placement algorithms for MininetCluster
|
||||
@@ -589,10 +596,10 @@ class Placer( object ):
|
||||
|
||||
class RandomPlacer( Placer ):
|
||||
"Random placement"
|
||||
def place( self, nodename ):
|
||||
def place( self, node ):
|
||||
"""Random placement function
|
||||
nodename: node name"""
|
||||
assert nodename # please pylint
|
||||
node: node"""
|
||||
assert node # please pylint
|
||||
# This may be slow with lots of servers
|
||||
return self.servers[ randrange( 0, len( self.servers ) ) ]
|
||||
|
||||
@@ -606,10 +613,10 @@ class RoundRobinPlacer( Placer ):
|
||||
Placer.__init__( self, *args, **kwargs )
|
||||
self.next = 0
|
||||
|
||||
def place( self, nodename ):
|
||||
def place( self, node ):
|
||||
"""Round-robin placement function
|
||||
nodename: node name"""
|
||||
assert nodename # please pylint
|
||||
node: node"""
|
||||
assert node # please pylint
|
||||
# This may be slow with lots of servers
|
||||
server = self.servers[ self.next ]
|
||||
self.next = ( self.next + 1 ) % len( self.servers )
|
||||
@@ -647,7 +654,7 @@ class SwitchBinPlacer( Placer ):
|
||||
tickets = sum( [ binsizes[ server ] * [ server ]
|
||||
for server in servers ], [] )
|
||||
# And assign one ticket to each node
|
||||
return { node: ticket for node, ticket in zip( nodes, tickets ) }
|
||||
return dict( zip( nodes, tickets ) )
|
||||
|
||||
def calculatePlacement( self ):
|
||||
"Pre-calculate node placement"
|
||||
@@ -704,21 +711,21 @@ class HostSwitchBinPlacer( Placer ):
|
||||
self.cset = frozenset( self.controllers )
|
||||
self.hind, self.sind, self.cind = 0, 0, 0
|
||||
|
||||
def place( self, nodename ):
|
||||
def place( self, node ):
|
||||
"""Simple placement algorithm:
|
||||
place nodes into evenly sized bins"""
|
||||
# Place nodes into bins
|
||||
if nodename in self.hset:
|
||||
if node in self.hset:
|
||||
server = self.servdict[ self.hind / self.hbin ]
|
||||
self.hind += 1
|
||||
elif nodename in self.sset:
|
||||
elif node in self.sset:
|
||||
server = self.servdict[ self.sind / self.sbin ]
|
||||
self.sind += 1
|
||||
elif nodename in self.cset:
|
||||
elif node in self.cset:
|
||||
server = self.servdict[ self.cind / self.cbin ]
|
||||
self.cind += 1
|
||||
else:
|
||||
info( 'warning: unknown node', nodename )
|
||||
info( 'warning: unknown node', node )
|
||||
server = self.servdict[ 0 ]
|
||||
return server
|
||||
|
||||
@@ -764,6 +771,7 @@ class MininetCluster( Mininet ):
|
||||
# Make sure control directory exists
|
||||
self.cdir = os.environ[ 'HOME' ] + '/.ssh/mn'
|
||||
errRun( [ 'mkdir', '-p', self.cdir ] )
|
||||
# pylint: disable=unexpected-keyword-arg
|
||||
Mininet.__init__( self, *args, **params )
|
||||
|
||||
def popen( self, cmd ):
|
||||
@@ -840,18 +848,19 @@ class MininetCluster( Mininet ):
|
||||
if cfile:
|
||||
config.setdefault( 'controlPath', cfile )
|
||||
|
||||
# pylint: disable=arguments-differ,signature-differs
|
||||
def addController( self, *args, **kwargs ):
|
||||
"Patch to update IP address to global IP address"
|
||||
controller = Mininet.addController( self, *args, **kwargs )
|
||||
loopback = '127.0.0.1'
|
||||
if ( not isinstance( controller, Controller ) or
|
||||
controller.IP() != loopback ):
|
||||
return
|
||||
return None
|
||||
# Find route to a different server IP address
|
||||
serverIPs = [ ip for ip in self.serverIP.values()
|
||||
if ip is not controller.IP() ]
|
||||
if not serverIPs:
|
||||
return # no remote servers - loopback is fine
|
||||
return None # no remote servers - loopback is fine
|
||||
remoteIP = serverIPs[ 0 ]
|
||||
# Route should contain 'dev <intfname>'
|
||||
route = controller.cmd( 'ip route get', remoteIP,
|
||||
@@ -865,6 +874,7 @@ class MininetCluster( Mininet ):
|
||||
debug( controller, 'IP address updated to', controller.IP() )
|
||||
return controller
|
||||
|
||||
# pylint: disable=arguments-differ,signature-differs
|
||||
def buildFromTopo( self, *args, **kwargs ):
|
||||
"Start network"
|
||||
info( '*** Placing nodes\n' )
|
||||
|
||||
@@ -17,6 +17,7 @@ def clusterSanity():
|
||||
CLI( net )
|
||||
net.stop()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
setLogLevel( 'info' )
|
||||
clusterSanity()
|
||||
|
||||
@@ -31,6 +31,7 @@ class ClusterCLI( CLI ):
|
||||
if not nx:
|
||||
try:
|
||||
# pylint: disable=import-error,no-member
|
||||
# pylint: disable=import-outside-toplevel
|
||||
import networkx
|
||||
nx = networkx # satisfy pylint
|
||||
from matplotlib import pyplot
|
||||
|
||||
@@ -19,6 +19,7 @@ def demo():
|
||||
CLI( net )
|
||||
net.stop()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
setLogLevel( 'info' )
|
||||
demo()
|
||||
|
||||
@@ -17,6 +17,7 @@ def perf(Link):
|
||||
net.iperf()
|
||||
net.stop()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
setLogLevel('info')
|
||||
perf( RemoteSSHLink )
|
||||
|
||||
@@ -27,6 +27,7 @@ Bob Lantz, April 2010
|
||||
|
||||
import re
|
||||
|
||||
# pylint: disable=import-error
|
||||
from Tkinter import Frame, Button, Label, Text, Scrollbar, Canvas, Wm, READABLE
|
||||
|
||||
from mininet.log import setLogLevel
|
||||
@@ -34,6 +35,9 @@ from mininet.topolib import TreeNet
|
||||
from mininet.term import makeTerms, cleanUpScreens
|
||||
from mininet.util import quietRun
|
||||
|
||||
# pylint: disable=too-many-arguments
|
||||
|
||||
|
||||
class Console( Frame ):
|
||||
"A simple console on a host."
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ class MultiSwitch( OVSSwitch ):
|
||||
def start( self, controllers ):
|
||||
return OVSSwitch.start( self, [ cmap[ self.name ] ] )
|
||||
|
||||
|
||||
topo = TreeTopo( depth=2, fanout=2 )
|
||||
net = Mininet( topo=topo, switch=MultiSwitch, build=False, waitConnected=True )
|
||||
for c in [ c0, c1 ]:
|
||||
|
||||
@@ -58,6 +58,7 @@ def multiControllerNet():
|
||||
info( "*** Stopping network\n" )
|
||||
net.stop()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
setLogLevel( 'info' ) # for CLI output
|
||||
multiControllerNet()
|
||||
|
||||
@@ -66,6 +66,7 @@ class MininetFacade( object ):
|
||||
for net in self.nets:
|
||||
if key in net:
|
||||
return net[ key ]
|
||||
return None
|
||||
|
||||
def __iter__( self ):
|
||||
"Iterate through all nodes in all Mininet objects"
|
||||
@@ -100,6 +101,7 @@ class MininetFacade( object ):
|
||||
|
||||
class ControlNetwork( Topo ):
|
||||
"Control Network Topology"
|
||||
# pylint: disable=arguments-differ
|
||||
def build( self, n, dataController=DataController, **_kwargs ):
|
||||
"""n: number of data network controller nodes
|
||||
dataController: class for data network controllers"""
|
||||
|
||||
+1
-1
@@ -54,7 +54,7 @@ def bwtest( cpuLimits, period_us=100000, seconds=10 ):
|
||||
try:
|
||||
net = Mininet( topo=topo, host=host, waitConnected=True )
|
||||
# pylint: disable=bare-except
|
||||
except:
|
||||
except: # noqa
|
||||
info( '*** Skipping scheduler %s and cleaning up\n' % sched )
|
||||
cleanup()
|
||||
break
|
||||
|
||||
@@ -39,6 +39,7 @@ def emptyNet():
|
||||
info( '*** Stopping network' )
|
||||
net.stop()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
setLogLevel( 'info' )
|
||||
emptyNet()
|
||||
|
||||
@@ -8,6 +8,8 @@ hardware interface) to a network after the network is created.
|
||||
import re
|
||||
import sys
|
||||
|
||||
from sys import exit # pylint: disable=redefined-builtin
|
||||
|
||||
from mininet.cli import CLI
|
||||
from mininet.log import setLogLevel, info, error
|
||||
from mininet.net import Mininet
|
||||
@@ -15,6 +17,7 @@ from mininet.link import Intf
|
||||
from mininet.topolib import TreeTopo
|
||||
from mininet.util import quietRun
|
||||
|
||||
|
||||
def checkIntf( intf ):
|
||||
"Make sure intf exists and is not configured."
|
||||
config = quietRun( 'ifconfig %s 2>/dev/null' % intf, shell=True )
|
||||
@@ -27,6 +30,7 @@ def checkIntf( intf ):
|
||||
'and is probably in use!\n' )
|
||||
exit( 1 )
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
setLogLevel( 'info' )
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ def intfOptions():
|
||||
info( '\n*** Done testing\n' )
|
||||
net.stop()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
setLogLevel( 'info' )
|
||||
intfOptions()
|
||||
|
||||
@@ -55,6 +55,7 @@ def verySimpleLimit( bw=150 ):
|
||||
h2.cmdPrint( 'tc -d class show dev', h2.defaultIntf() )
|
||||
net.stop()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
setLogLevel( 'info' )
|
||||
limit()
|
||||
|
||||
@@ -24,20 +24,24 @@ of switches, this example demonstrates:
|
||||
"""
|
||||
|
||||
|
||||
import sys
|
||||
|
||||
from functools import partial
|
||||
|
||||
from mininet.net import Mininet
|
||||
from mininet.node import UserSwitch, OVSKernelSwitch, Controller
|
||||
from mininet.topo import Topo
|
||||
from mininet.log import lg, info
|
||||
from mininet.util import irange, quietRun
|
||||
from mininet.link import TCLink
|
||||
from functools import partial
|
||||
|
||||
import sys
|
||||
flush = sys.stdout.flush
|
||||
|
||||
|
||||
class LinearTestTopo( Topo ):
|
||||
"Topology for a string of N hosts and N-1 switches."
|
||||
|
||||
# pylint: disable=arguments-differ
|
||||
def build( self, N, **params ):
|
||||
# Create switches and hosts
|
||||
hosts = [ self.addHost( 'h%s' % h )
|
||||
@@ -79,7 +83,7 @@ def linearBandwidthTest( lengths ):
|
||||
output = quietRun( 'sysctl -w net.ipv4.tcp_congestion_control=reno' )
|
||||
assert 'reno' in output
|
||||
|
||||
for datapath in switches.keys():
|
||||
for datapath in switches:
|
||||
info( "*** testing", datapath, "datapath\n" )
|
||||
Switch = switches[ datapath ]
|
||||
results[ datapath ] = []
|
||||
@@ -105,7 +109,7 @@ def linearBandwidthTest( lengths ):
|
||||
results[ datapath ] += [ ( n, serverbw ) ]
|
||||
net.stop()
|
||||
|
||||
for datapath in switches.keys():
|
||||
for datapath in switches:
|
||||
info( "\n*** Linear network results for", datapath, "datapath:\n" )
|
||||
result = results[ datapath ]
|
||||
info( "SwitchCount\tiperf Results\n" )
|
||||
@@ -115,6 +119,7 @@ def linearBandwidthTest( lengths ):
|
||||
info( '\n')
|
||||
info( '\n' )
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
lg.setLogLevel( 'info' )
|
||||
sizes = [ 1, 2, 3, 4 ]
|
||||
|
||||
@@ -38,6 +38,7 @@ from mininet.cli import CLI
|
||||
class LinuxRouter( Node ):
|
||||
"A Node with IP forwarding enabled."
|
||||
|
||||
# pylint: disable=arguments-differ
|
||||
def config( self, **params ):
|
||||
super( LinuxRouter, self).config( **params )
|
||||
# Enable forwarding on the router
|
||||
@@ -51,6 +52,7 @@ class LinuxRouter( Node ):
|
||||
class NetworkTopo( Topo ):
|
||||
"A LinuxRouter connecting three IP subnets"
|
||||
|
||||
# pylint: disable=arguments-differ
|
||||
def build( self, **_opts ):
|
||||
|
||||
defaultIP = '192.168.1.1/24' # IP address for r0-eth1
|
||||
@@ -87,6 +89,7 @@ def run():
|
||||
CLI( net )
|
||||
net.stop()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
setLogLevel( 'info' )
|
||||
run()
|
||||
|
||||
+64
-59
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/python
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
MiniEdit: a simple network editor for Mininet
|
||||
@@ -13,16 +13,30 @@ Controller icon from http://semlabs.co.uk/
|
||||
OpenFlow icon from https://www.opennetworking.org/
|
||||
"""
|
||||
|
||||
# Miniedit needs some work in order to pass pylint...
|
||||
# pylint: disable=line-too-long,too-many-branches
|
||||
# pylint: disable=too-many-statements,attribute-defined-outside-init
|
||||
# pylint: disable=missing-docstring
|
||||
|
||||
MINIEDIT_VERSION = '2.2.0.1'
|
||||
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
from distutils.version import StrictVersion
|
||||
from functools import partial
|
||||
from optparse import OptionParser
|
||||
from subprocess import call
|
||||
from sys import exit # pylint: disable=redefined-builtin
|
||||
|
||||
from mininet.log import info, debug, warn, setLogLevel
|
||||
from mininet.net import Mininet, VERSION
|
||||
from mininet.util import (netParse, ipAdd, quietRun,
|
||||
buildTopo, custom, customClass )
|
||||
from mininet.term import makeTerm, cleanUpScreens
|
||||
from mininet.node import (Controller, RemoteController, NOX, OVSController,
|
||||
CPULimitedHost, Host, Node,
|
||||
OVSSwitch, UserSwitch, IVSSwitch )
|
||||
from mininet.link import TCLink, Intf, Link
|
||||
from mininet.cli import CLI
|
||||
from mininet.moduledeps import moduleDeps
|
||||
from mininet.topo import SingleSwitchTopo, LinearTopo, SingleSwitchReversedTopo
|
||||
from mininet.topolib import TreeTopo
|
||||
|
||||
# pylint: disable=import-error
|
||||
if sys.version_info[0] == 2:
|
||||
@@ -47,38 +61,24 @@ else:
|
||||
from tkinter import font as tkFont
|
||||
from tkinter import simpledialog as tkSimpleDialog
|
||||
from tkinter import filedialog as tkFileDialog
|
||||
# someday: from ttk import *
|
||||
# pylint: enable=import-error
|
||||
|
||||
import re
|
||||
import json
|
||||
from distutils.version import StrictVersion
|
||||
import os
|
||||
from functools import partial
|
||||
|
||||
# Miniedit still needs work in order to pass pylint...
|
||||
# pylint: disable=line-too-long,too-many-branches
|
||||
# pylint: disable=too-many-statements,attribute-defined-outside-init
|
||||
# pylint: disable=missing-docstring,too-many-ancestors
|
||||
# pylint: disable=too-many-nested-blocks,too-many-arguments
|
||||
|
||||
|
||||
MINIEDIT_VERSION = '2.2.0.1'
|
||||
|
||||
if 'PYTHONPATH' in os.environ:
|
||||
sys.path = os.environ[ 'PYTHONPATH' ].split( ':' ) + sys.path
|
||||
|
||||
# someday: from ttk import *
|
||||
|
||||
from mininet.log import info, debug, warn, setLogLevel
|
||||
from mininet.net import Mininet, VERSION
|
||||
from mininet.util import netParse, ipAdd, quietRun
|
||||
from mininet.util import buildTopo
|
||||
from mininet.util import custom, customClass
|
||||
from mininet.term import makeTerm, cleanUpScreens
|
||||
from mininet.node import Controller, RemoteController, NOX, OVSController
|
||||
from mininet.node import CPULimitedHost, Host, Node
|
||||
from mininet.node import OVSSwitch, UserSwitch
|
||||
from mininet.link import TCLink, Intf, Link
|
||||
from mininet.cli import CLI
|
||||
from mininet.moduledeps import moduleDeps
|
||||
from mininet.topo import SingleSwitchTopo, LinearTopo, SingleSwitchReversedTopo
|
||||
from mininet.topolib import TreeTopo
|
||||
|
||||
info( 'MiniEdit running against Mininet '+VERSION, '\n' )
|
||||
MININET_VERSION = re.sub(r'[^\d\.]', '', VERSION)
|
||||
if StrictVersion(MININET_VERSION) > StrictVersion('2.0'):
|
||||
from mininet.node import IVSSwitch
|
||||
|
||||
TOPODEF = 'none'
|
||||
TOPOS = { 'minimal': lambda: SingleSwitchTopo( k=2 ),
|
||||
@@ -138,6 +138,7 @@ class LegacyRouter( Node ):
|
||||
def __init__( self, name, inNamespace=True, **params ):
|
||||
Node.__init__( self, name, inNamespace, **params )
|
||||
|
||||
# pylint: disable=arguments-differ
|
||||
def config( self, **_params ):
|
||||
if self.intfs:
|
||||
self.setParam( _params, 'setIP', ip='0.0.0.0' )
|
||||
@@ -818,8 +819,8 @@ class VerticalScrolledTable(LabelFrame):
|
||||
* This frame only allows vertical scrolling
|
||||
|
||||
"""
|
||||
def __init__(self, parent, rows=2, columns=2, title=None, *args, **kw):
|
||||
LabelFrame.__init__(self, parent, text=title, padx=5, pady=5, *args, **kw)
|
||||
def __init__(self, parent, rows=2, columns=2, title=None, **kw):
|
||||
LabelFrame.__init__(self, parent, text=title, padx=5, pady=5, **kw)
|
||||
|
||||
# create a canvas object and a vertical scrollbar for scrolling it
|
||||
vscrollbar = Scrollbar(self, orient=VERTICAL)
|
||||
@@ -855,8 +856,6 @@ class VerticalScrolledTable(LabelFrame):
|
||||
canvas.itemconfigure(interior_id, width=canvas.winfo_width())
|
||||
canvas.bind('<Configure>', _configure_canvas)
|
||||
|
||||
return
|
||||
|
||||
class TableFrame(Frame):
|
||||
def __init__(self, parent, rows=2, columns=2):
|
||||
|
||||
@@ -888,7 +887,7 @@ class TableFrame(Frame):
|
||||
label.grid(row=self.rows, column=column, sticky="wens", padx=1, pady=1)
|
||||
if value is not None:
|
||||
label.insert(0, value[column])
|
||||
if readonly == True:
|
||||
if readonly:
|
||||
label.configure(state='readonly')
|
||||
current_row.append(label)
|
||||
self._widgets.append(current_row)
|
||||
@@ -1401,11 +1400,11 @@ class MiniEdit( Frame ):
|
||||
|
||||
def addNode( self, node, nodeNum, x, y, name=None):
|
||||
"Add a new node to our canvas."
|
||||
if 'Switch' == node:
|
||||
if node == 'Switch':
|
||||
self.switchCount += 1
|
||||
if 'Host' == node:
|
||||
if node == 'Host':
|
||||
self.hostCount += 1
|
||||
if 'Controller' == node:
|
||||
if node == 'Controller':
|
||||
self.controllerCount += 1
|
||||
if name is None:
|
||||
name = self.nodePrefixes[ node ] + nodeNum
|
||||
@@ -1422,13 +1421,16 @@ class MiniEdit( Frame ):
|
||||
|
||||
def convertJsonUnicode(self, text):
|
||||
"Some part of Mininet don't like Unicode"
|
||||
try:
|
||||
unicode
|
||||
except NameError:
|
||||
return text
|
||||
if isinstance(text, dict):
|
||||
return {self.convertJsonUnicode(key): self.convertJsonUnicode(value) for key, value in text.items()}
|
||||
elif isinstance(text, list):
|
||||
if isinstance(text, list):
|
||||
return [self.convertJsonUnicode(element) for element in text]
|
||||
elif isinstance(text, unicode):
|
||||
if isinstance(text, unicode): # pylint: disable=undefined-variable
|
||||
return text.encode('utf-8')
|
||||
else:
|
||||
return text
|
||||
|
||||
def loadTopology( self ):
|
||||
@@ -1440,7 +1442,7 @@ class MiniEdit( Frame ):
|
||||
('All Files','*'),
|
||||
]
|
||||
f = tkFileDialog.askopenfile(filetypes=myFormats, mode='rb')
|
||||
if f == None:
|
||||
if f is None:
|
||||
return
|
||||
self.newTopology()
|
||||
loadedTopology = self.convertJsonUnicode(json.load(f))
|
||||
@@ -1601,10 +1603,11 @@ class MiniEdit( Frame ):
|
||||
for widget in self.widgetToItem:
|
||||
if name == widget[ 'text' ]:
|
||||
return widget
|
||||
return None
|
||||
|
||||
def newTopology( self ):
|
||||
"New command."
|
||||
for widget in self.widgetToItem.keys():
|
||||
for widget in self.widgetToItem:
|
||||
self.deleteItem( self.widgetToItem[ widget ] )
|
||||
self.hostCount = 0
|
||||
self.switchCount = 0
|
||||
@@ -1725,7 +1728,7 @@ class MiniEdit( Frame ):
|
||||
if controllerType == 'inband':
|
||||
inBandCtrl = True
|
||||
|
||||
if inBandCtrl == True:
|
||||
if inBandCtrl:
|
||||
f.write("\n")
|
||||
f.write("class InbandController( RemoteController ):\n")
|
||||
f.write("\n")
|
||||
@@ -2122,7 +2125,7 @@ class MiniEdit( Frame ):
|
||||
c = self.canvas
|
||||
x, y = c.canvasx( event.x ), c.canvasy( event.y )
|
||||
name = self.nodePrefixes[ node ]
|
||||
if 'Switch' == node:
|
||||
if node == 'Switch':
|
||||
self.switchCount += 1
|
||||
name = self.nodePrefixes[ node ] + str( self.switchCount )
|
||||
self.switchOpts[name] = {}
|
||||
@@ -2130,14 +2133,14 @@ class MiniEdit( Frame ):
|
||||
self.switchOpts[name]['hostname']=name
|
||||
self.switchOpts[name]['switchType']='default'
|
||||
self.switchOpts[name]['controllers']=[]
|
||||
if 'LegacyRouter' == node:
|
||||
if node == 'LegacyRouter':
|
||||
self.switchCount += 1
|
||||
name = self.nodePrefixes[ node ] + str( self.switchCount )
|
||||
self.switchOpts[name] = {}
|
||||
self.switchOpts[name]['nodeNum']=self.switchCount
|
||||
self.switchOpts[name]['hostname']=name
|
||||
self.switchOpts[name]['switchType']='legacyRouter'
|
||||
if 'LegacySwitch' == node:
|
||||
if node == 'LegacySwitch':
|
||||
self.switchCount += 1
|
||||
name = self.nodePrefixes[ node ] + str( self.switchCount )
|
||||
self.switchOpts[name] = {}
|
||||
@@ -2145,13 +2148,13 @@ class MiniEdit( Frame ):
|
||||
self.switchOpts[name]['hostname']=name
|
||||
self.switchOpts[name]['switchType']='legacySwitch'
|
||||
self.switchOpts[name]['controllers']=[]
|
||||
if 'Host' == node:
|
||||
if node == 'Host':
|
||||
self.hostCount += 1
|
||||
name = self.nodePrefixes[ node ] + str( self.hostCount )
|
||||
self.hostOpts[name] = {'sched':'host'}
|
||||
self.hostOpts[name]['nodeNum']=self.hostCount
|
||||
self.hostOpts[name]['hostname']=name
|
||||
if 'Controller' == node:
|
||||
if node == 'Controller':
|
||||
name = self.nodePrefixes[ node ] + str( self.controllerCount )
|
||||
ctrlr = { 'controllerType': 'ref',
|
||||
'hostname': name,
|
||||
@@ -2169,15 +2172,15 @@ class MiniEdit( Frame ):
|
||||
self.itemToWidget[ item ] = icon
|
||||
self.selectItem( item )
|
||||
icon.links = {}
|
||||
if 'Switch' == node:
|
||||
if node == 'Switch':
|
||||
icon.bind('<Button-3>', self.do_switchPopup )
|
||||
if 'LegacyRouter' == node:
|
||||
if node == 'LegacyRouter':
|
||||
icon.bind('<Button-3>', self.do_legacyRouterPopup )
|
||||
if 'LegacySwitch' == node:
|
||||
if node == 'LegacySwitch':
|
||||
icon.bind('<Button-3>', self.do_legacySwitchPopup )
|
||||
if 'Host' == node:
|
||||
if node == 'Host':
|
||||
icon.bind('<Button-3>', self.do_hostPopup )
|
||||
if 'Controller' == node:
|
||||
if node == 'Controller':
|
||||
icon.bind('<Button-3>', self.do_controllerPopup )
|
||||
|
||||
def clickController( self, event ):
|
||||
@@ -2374,6 +2377,8 @@ class MiniEdit( Frame ):
|
||||
# For now, don't allow hosts to be directly linked
|
||||
stags = self.canvas.gettags( self.widgetToItem[ source ] )
|
||||
dtags = self.canvas.gettags( target )
|
||||
# TODO: Make this less confusing
|
||||
# pylint: disable=too-many-boolean-expressions
|
||||
if (('Host' in stags and 'Host' in dtags) or
|
||||
('Controller' in dtags and 'LegacyRouter' in stags) or
|
||||
('Controller' in stags and 'LegacyRouter' in dtags) or
|
||||
@@ -3225,7 +3230,8 @@ class MiniEdit( Frame ):
|
||||
"Parse custom file and add params before parsing cmd-line options."
|
||||
customs = {}
|
||||
if os.path.isfile( fileName ):
|
||||
execfile( fileName, customs, customs )
|
||||
with open( fileName, 'r' ) as f:
|
||||
exec( f.read() ) # pylint: disable=exec-used
|
||||
for name, val in customs.items():
|
||||
self.setCustom( name, val )
|
||||
else:
|
||||
@@ -3592,8 +3598,7 @@ def addDictOption( opts, choicesDict, default, name, helpStr=None ):
|
||||
if __name__ == '__main__':
|
||||
setLogLevel( 'info' )
|
||||
app = MiniEdit()
|
||||
### import topology if specified ###
|
||||
app.parseArgs()
|
||||
### import topology if specified ###
|
||||
app.importTopo()
|
||||
|
||||
app.mainloop()
|
||||
|
||||
@@ -19,14 +19,13 @@ to-do:
|
||||
- think about clearing last hop - why doesn't that work?
|
||||
"""
|
||||
|
||||
from random import randint
|
||||
|
||||
from mininet.net import Mininet
|
||||
from mininet.node import OVSSwitch
|
||||
from mininet.topo import LinearTopo
|
||||
from mininet.log import info, output, warn, setLogLevel
|
||||
|
||||
from random import randint
|
||||
|
||||
|
||||
class MobilitySwitch( OVSSwitch ):
|
||||
"Switch that can reattach and rename interfaces"
|
||||
@@ -38,6 +37,7 @@ class MobilitySwitch( OVSSwitch ):
|
||||
del self.intfs[ port ]
|
||||
del self.nameToIntf[ intf.name ]
|
||||
|
||||
# pylint: disable=arguments-differ
|
||||
def addIntf( self, intf, rename=False, **kwargs ):
|
||||
"Add (and reparent) an interface"
|
||||
OVSSwitch.addIntf( self, intf, **kwargs )
|
||||
@@ -132,6 +132,7 @@ def mobilityTest():
|
||||
old = new
|
||||
net.stop()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
setLogLevel( 'info' )
|
||||
mobilityTest()
|
||||
|
||||
@@ -21,6 +21,7 @@ def runMultiLink():
|
||||
class simpleMultiLinkTopo( Topo ):
|
||||
"Simple topology with multiple links"
|
||||
|
||||
# pylint: disable=arguments-differ
|
||||
def build( self, n, **_kwargs ):
|
||||
h1, h2 = self.addHost( 'h1' ), self.addHost( 'h2' )
|
||||
s1 = self.addSwitch( 's1' )
|
||||
@@ -29,6 +30,7 @@ class simpleMultiLinkTopo( Topo ):
|
||||
self.addLink( s1, h1 )
|
||||
self.addLink( s1, h2 )
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
setLogLevel( 'info' )
|
||||
runMultiLink()
|
||||
|
||||
@@ -8,14 +8,14 @@ multiple hosts and monitor their output interactively for a period=
|
||||
of time.
|
||||
"""
|
||||
|
||||
from select import poll, POLLIN
|
||||
from time import time
|
||||
|
||||
from mininet.net import Mininet
|
||||
from mininet.node import Node
|
||||
from mininet.topo import SingleSwitchTopo
|
||||
from mininet.log import info, setLogLevel
|
||||
|
||||
from select import poll, POLLIN
|
||||
from time import time
|
||||
|
||||
def chunks( l, n ):
|
||||
"Divide list l into chunks of size n - thanks Stackoverflow"
|
||||
|
||||
@@ -6,15 +6,15 @@ monitoring them
|
||||
"""
|
||||
|
||||
|
||||
from time import time
|
||||
from select import poll, POLLIN
|
||||
from subprocess import Popen, PIPE
|
||||
|
||||
from mininet.topo import SingleSwitchTopo
|
||||
from mininet.net import Mininet
|
||||
from mininet.log import info, setLogLevel
|
||||
from mininet.util import decode
|
||||
|
||||
from time import time
|
||||
from select import poll, POLLIN
|
||||
from subprocess import Popen, PIPE
|
||||
|
||||
|
||||
def monitorFiles( outfiles, seconds, timeoutms ):
|
||||
"Monitor set of files and return [(host, line)...]"
|
||||
|
||||
@@ -17,6 +17,7 @@ def ifconfigTest( net ):
|
||||
for host in hosts:
|
||||
info( host.cmd( 'ifconfig' ) )
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
lg.setLogLevel( 'info' )
|
||||
info( "*** Initializing Mininet and kernel modules\n" )
|
||||
|
||||
@@ -27,6 +27,7 @@ from mininet.util import irange
|
||||
|
||||
class InternetTopo(Topo):
|
||||
"Single switch connected to n hosts."
|
||||
# pylint: disable=arguments-differ
|
||||
def build(self, n=2, **_kwargs ):
|
||||
# set up inet switch
|
||||
inetSwitch = self.addSwitch('s0')
|
||||
@@ -62,6 +63,7 @@ def run():
|
||||
CLI(net)
|
||||
net.stop()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
setLogLevel('info')
|
||||
run()
|
||||
|
||||
@@ -75,6 +75,7 @@ def testPortNumbering():
|
||||
info( '*** Stopping network\n' )
|
||||
net.stop()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
setLogLevel( 'info' )
|
||||
testPortNumbering()
|
||||
|
||||
@@ -28,6 +28,7 @@ def monitorhosts( hosts=5 ):
|
||||
# Done
|
||||
net.stop()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
setLogLevel( 'info' )
|
||||
monitorhosts( hosts=5 )
|
||||
|
||||
@@ -2,13 +2,14 @@
|
||||
|
||||
"Monitor multiple hosts using popen()/pmonitor()"
|
||||
|
||||
from time import time
|
||||
from signal import SIGINT
|
||||
|
||||
from mininet.net import Mininet
|
||||
from mininet.topo import SingleSwitchTopo
|
||||
from mininet.util import pmonitor
|
||||
from mininet.log import setLogLevel, info
|
||||
|
||||
from time import time
|
||||
from signal import SIGINT
|
||||
|
||||
def pmonitorTest( N=3, seconds=10 ):
|
||||
"Run pings and monitor multiple hosts using pmonitor"
|
||||
@@ -31,6 +32,7 @@ def pmonitorTest( N=3, seconds=10 ):
|
||||
p.send_signal( SIGINT )
|
||||
net.stop()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
setLogLevel( 'info' )
|
||||
pmonitorTest()
|
||||
|
||||
@@ -8,6 +8,7 @@ but it exposes the configuration details and allows customization.
|
||||
For most tasks, the higher-level API will be preferable.
|
||||
"""
|
||||
|
||||
from time import sleep
|
||||
|
||||
from mininet.net import Mininet
|
||||
from mininet.node import Node
|
||||
@@ -15,7 +16,6 @@ from mininet.link import Link
|
||||
from mininet.log import setLogLevel, info
|
||||
from mininet.util import quietRun
|
||||
|
||||
from time import sleep
|
||||
|
||||
def scratchNet( cname='controller', cargs='-v ptcp:' ):
|
||||
"Create network from scratch using Open vSwitch."
|
||||
@@ -62,6 +62,7 @@ def scratchNet( cname='controller', cargs='-v ptcp:' ):
|
||||
switch.deleteIntfs()
|
||||
info( '\n' )
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
setLogLevel( 'info' )
|
||||
info( '*** Scratch network demo (kernel datapath)\n' )
|
||||
|
||||
@@ -66,6 +66,7 @@ def scratchNetUser( cname='controller', cargs='ptcp:' ):
|
||||
switch.deleteIntfs()
|
||||
info( '\n' )
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
setLogLevel( 'info' )
|
||||
info( '*** Scratch network demo (user datapath)\n' )
|
||||
|
||||
@@ -9,6 +9,7 @@ iperf will hang indefinitely if the TCP handshake fails
|
||||
to complete.
|
||||
"""
|
||||
|
||||
from sys import argv
|
||||
|
||||
from mininet.topo import Topo
|
||||
from mininet.net import Mininet
|
||||
@@ -17,7 +18,6 @@ from mininet.link import TCLink
|
||||
from mininet.util import dumpNodeConnections
|
||||
from mininet.log import setLogLevel, info
|
||||
|
||||
from sys import argv
|
||||
|
||||
# It would be nice if we didn't have to do this:
|
||||
# pylint: disable=arguments-differ
|
||||
@@ -54,6 +54,7 @@ def perfTest( lossy=True ):
|
||||
net.iperf( ( h1, h4 ), l4Type='UDP' )
|
||||
net.stop()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
setLogLevel( 'info' )
|
||||
# Prevent test_simpleperf from failing due to packet loss
|
||||
|
||||
@@ -47,6 +47,7 @@ def connectToRootNS( network, switch, ip, routes ):
|
||||
for route in routes:
|
||||
root.cmd( 'route add -net ' + route + ' dev ' + str( intf ) )
|
||||
|
||||
# pylint: disable=too-many-arguments
|
||||
def sshd( network, cmd='/usr/sbin/sshd', opts='-D',
|
||||
ip='10.123.123.1/32', routes=None, switch=None ):
|
||||
"""Start a network, connect it to root ns, and run sshd on all hosts.
|
||||
@@ -73,6 +74,7 @@ def sshd( network, cmd='/usr/sbin/sshd', opts='-D',
|
||||
host.cmd( 'kill %' + cmd )
|
||||
network.stop()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
lg.setLogLevel( 'info')
|
||||
net = TreeNet( depth=1, fanout=4 )
|
||||
|
||||
@@ -38,6 +38,7 @@ def treePing64():
|
||||
info( "%s: %d%% packet loss\n" % ( name, results[ name ] ) )
|
||||
info( '\n' )
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
setLogLevel( 'info' )
|
||||
treePing64()
|
||||
|
||||
@@ -24,14 +24,18 @@ Usage (example uses VLAN ID=1000):
|
||||
|
||||
"""
|
||||
|
||||
from sys import exit # pylint: disable=redefined-builtin
|
||||
|
||||
from mininet.node import Host
|
||||
from mininet.topo import Topo
|
||||
from mininet.util import quietRun
|
||||
from mininet.log import error
|
||||
|
||||
|
||||
class VLANHost( Host ):
|
||||
"Host connected to VLAN interface"
|
||||
|
||||
# pylint: disable=arguments-differ
|
||||
def config( self, vlan=100, **params ):
|
||||
"""Configure VLANHost according to (optional) parameters:
|
||||
vlan: VLAN ID for default interface"""
|
||||
@@ -54,6 +58,7 @@ class VLANHost( Host ):
|
||||
|
||||
return r
|
||||
|
||||
|
||||
hosts = { 'vlan': VLANHost }
|
||||
|
||||
|
||||
@@ -101,6 +106,7 @@ def exampleCustomTags():
|
||||
CLI( net )
|
||||
net.stop()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
from functools import partial
|
||||
|
||||
+8
-5
@@ -47,7 +47,7 @@ class CLI( Cmd ):
|
||||
prompt = 'mininet> '
|
||||
|
||||
def __init__( self, mininet, stdin=sys.stdin, script=None,
|
||||
*args, **kwargs ):
|
||||
**kwargs ):
|
||||
"""Start and run interactive or batch mode CLI
|
||||
mininet: Mininet network object
|
||||
stdin: standard input for CLI
|
||||
@@ -59,7 +59,7 @@ class CLI( Cmd ):
|
||||
self.inPoller = poll()
|
||||
self.inPoller.register( stdin )
|
||||
self.inputFile = script
|
||||
Cmd.__init__( self, *args, stdin=stdin, **kwargs )
|
||||
Cmd.__init__( self, stdin=stdin, **kwargs )
|
||||
info( '*** Starting CLI:\n' )
|
||||
|
||||
if self.inputFile:
|
||||
@@ -79,6 +79,7 @@ class CLI( Cmd ):
|
||||
return
|
||||
cls.readlineInited = True
|
||||
try:
|
||||
# pylint: disable=import-outside-toplevel
|
||||
from readline import ( read_history_file, write_history_file,
|
||||
set_history_length )
|
||||
except ImportError:
|
||||
@@ -141,7 +142,7 @@ class CLI( Cmd ):
|
||||
' mininet> xterm h2\n\n'
|
||||
)
|
||||
|
||||
def do_help( self, line ):
|
||||
def do_help( self, line ): # pylint: disable=arguments-differ
|
||||
"Describe available CLI commands."
|
||||
Cmd.do_help( self, line )
|
||||
if line == '':
|
||||
@@ -173,6 +174,7 @@ class CLI( Cmd ):
|
||||
"""Evaluate a Python expression.
|
||||
Node names may be used, e.g.: py h1.cmd('ls')"""
|
||||
try:
|
||||
# pylint: disable=eval-used
|
||||
result = eval( line, globals(), self.getLocals() )
|
||||
if not result:
|
||||
return
|
||||
@@ -467,10 +469,10 @@ class CLI( Cmd ):
|
||||
node.sendInt()
|
||||
except select.error as e:
|
||||
# pylint: disable=unpacking-non-sequence
|
||||
# pylint: disable=unbalanced-tuple-unpacking
|
||||
errno_, errmsg = e.args
|
||||
# pylint: enable=unpacking-non-sequence
|
||||
if errno_ != errno.EINTR:
|
||||
error( "select.error: %d, %s" % (errno_, errmsg) )
|
||||
error( "select.error: %s, %s" % (errno_, errmsg) )
|
||||
node.sendInt()
|
||||
|
||||
def precmd( self, line ):
|
||||
@@ -488,3 +490,4 @@ def isReadable( poller ):
|
||||
mask = fdmask[ 1 ]
|
||||
if mask & POLLIN:
|
||||
return True
|
||||
return False
|
||||
|
||||
+14
-3
@@ -24,9 +24,14 @@ TCIntf: interface with bandwidth limiting and delay via tc
|
||||
Link: basic link class for creating veth pairs
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from mininet.log import info, error, debug
|
||||
from mininet.util import makeIntfPair
|
||||
import re
|
||||
|
||||
# Make pylint happy:
|
||||
# pylint: disable=too-many-arguments
|
||||
|
||||
|
||||
class Intf( object ):
|
||||
|
||||
@@ -170,7 +175,7 @@ class Intf( object ):
|
||||
name, value = list( param.items() )[ 0 ]
|
||||
f = getattr( self, method, None )
|
||||
if not f or value is None:
|
||||
return
|
||||
return None
|
||||
if isinstance( value, list ):
|
||||
result = f( *value )
|
||||
elif isinstance( value, dict ):
|
||||
@@ -311,6 +316,7 @@ class TCIntf( Intf ):
|
||||
debug(" *** executing command: %s\n" % c)
|
||||
return self.cmd( c )
|
||||
|
||||
# pylint: disable=arguments-differ
|
||||
def config( self, bw=None, delay=None, jitter=None, loss=None,
|
||||
gro=False, txo=True, rxo=True,
|
||||
speedup=0, use_hfsc=False, use_tbf=False,
|
||||
@@ -351,7 +357,7 @@ class TCIntf( Intf ):
|
||||
# Question: what happens if we want to reset things?
|
||||
if ( bw is None and not delay and not loss
|
||||
and max_queue_size is None ):
|
||||
return
|
||||
return None
|
||||
|
||||
# Clear existing configuration
|
||||
tcoutput = self.tc( '%s qdisc show dev %s' )
|
||||
@@ -533,6 +539,10 @@ class OVSLink( Link ):
|
||||
|
||||
def __init__( self, node1, node2, **kwargs ):
|
||||
"See Link.__init__() for options"
|
||||
try:
|
||||
OVSSwitch
|
||||
except NameError:
|
||||
# pylint: disable=import-outside-toplevel,cyclic-import
|
||||
from mininet.node import OVSSwitch
|
||||
self.isPatchLink = False
|
||||
if ( isinstance( node1, OVSSwitch ) and
|
||||
@@ -541,6 +551,7 @@ class OVSLink( Link ):
|
||||
kwargs.update( cls1=OVSIntf, cls2=OVSIntf )
|
||||
Link.__init__( self, node1, node2, **kwargs )
|
||||
|
||||
# pylint: disable=arguments-differ, signature-differs
|
||||
def makeIntfPair( self, *args, **kwargs ):
|
||||
"Usually delegated to OVSSwitch"
|
||||
if self.isPatchLink:
|
||||
|
||||
+4
-2
@@ -51,7 +51,7 @@ class StreamHandlerNoNewline( logging.StreamHandler ):
|
||||
self.flush()
|
||||
except ( KeyboardInterrupt, SystemExit ):
|
||||
raise
|
||||
except:
|
||||
except: # noqa pylint: disable=bare-except
|
||||
self.handleError( record )
|
||||
|
||||
|
||||
@@ -137,13 +137,14 @@ class MininetLogger( Logger, object ):
|
||||
|
||||
logger.warning("Houston, we have a %s", "cli output", exc_info=1)
|
||||
"""
|
||||
if self.manager.disable >= OUTPUT:
|
||||
if getattr( self.manager, 'disabled', 0 ) >= OUTPUT:
|
||||
return
|
||||
if self.isEnabledFor( OUTPUT ):
|
||||
self._log( OUTPUT, msg, args, kwargs )
|
||||
|
||||
# pylint: enable=method-hidden
|
||||
|
||||
|
||||
lg = MininetLogger()
|
||||
|
||||
# Make things a bit more convenient by adding aliases
|
||||
@@ -168,6 +169,7 @@ def makeListCompatible( fn ):
|
||||
setattr( newfn, '__doc__', fn.__doc__ )
|
||||
return newfn
|
||||
|
||||
|
||||
_loggers = lg.info, lg.output, lg.warn, lg.error, lg.debug
|
||||
_loggers = tuple( makeListCompatible( logger )
|
||||
for logger in _loggers )
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
"Module dependency utility functions for Mininet."
|
||||
|
||||
from os import environ
|
||||
from sys import exit # pylint: disable=redefined-builtin
|
||||
|
||||
from mininet.util import quietRun, BaseString
|
||||
from mininet.log import info, error, debug
|
||||
from os import environ
|
||||
|
||||
|
||||
def lsmod():
|
||||
"Return output of lsmod."
|
||||
@@ -18,6 +21,7 @@ def modprobe( mod ):
|
||||
mod: module string"""
|
||||
return quietRun( [ 'modprobe', mod ] )
|
||||
|
||||
|
||||
OF_KMOD = 'ofdatapath'
|
||||
OVS_KMOD = 'openvswitch_mod' # Renamed 'openvswitch' in OVS 1.7+/Linux 3.5+
|
||||
TUN = 'tun'
|
||||
|
||||
@@ -92,6 +92,7 @@ import select
|
||||
import signal
|
||||
import random
|
||||
|
||||
from sys import exit # pylint: disable=redefined-builtin
|
||||
from time import sleep
|
||||
from itertools import chain, groupby
|
||||
from math import ceil
|
||||
@@ -113,6 +114,7 @@ VERSION = "2.3.0a1"
|
||||
class Mininet( object ):
|
||||
"Network emulation with hosts spawned in network namespaces."
|
||||
|
||||
# pylint: disable=too-many-arguments
|
||||
def __init__( self, topo=None, switch=OVSKernelSwitch, host=Host,
|
||||
controller=DefaultController, link=Link, intf=Intf,
|
||||
build=True, xterms=False, cleanup=False, ipBase='10.0.0.0/8',
|
||||
|
||||
+34
-14
@@ -57,7 +57,10 @@ import pty
|
||||
import re
|
||||
import signal
|
||||
import select
|
||||
from distutils.version import StrictVersion
|
||||
from re import findall
|
||||
from subprocess import Popen, PIPE
|
||||
from sys import exit # pylint: disable=redefined-builtin
|
||||
from time import sleep
|
||||
|
||||
from mininet.log import info, error, warn, debug
|
||||
@@ -66,8 +69,10 @@ from mininet.util import ( quietRun, errRun, errFail, moveIntf, isShellBuiltin,
|
||||
encode, getincrementaldecoder, Python3, which )
|
||||
from mininet.moduledeps import moduleDeps, pathCheck, TUN
|
||||
from mininet.link import Link, Intf, TCIntf, OVSIntf
|
||||
from re import findall
|
||||
from distutils.version import StrictVersion
|
||||
|
||||
|
||||
# pylint: disable=too-many-arguments
|
||||
|
||||
|
||||
class Node( object ):
|
||||
"""A virtual network node is simply a shell in a network namespace.
|
||||
@@ -94,9 +99,13 @@ class Node( object ):
|
||||
# Stash configuration parameters for future reference
|
||||
self.params = params
|
||||
|
||||
self.intfs = {} # dict of port numbers to interfaces
|
||||
self.ports = {} # dict of interfaces to port numbers
|
||||
# replace with Port objects, eventually ?
|
||||
# dict of port numbers to interfacse
|
||||
self.intfs = {}
|
||||
|
||||
# dict of interfaces to port numbers
|
||||
# todo: replace with Port objects, eventually ?
|
||||
self.ports = {}
|
||||
|
||||
self.nameToIntf = {} # dict of interface names to Intfs
|
||||
|
||||
# Make pylint happy
|
||||
@@ -284,6 +293,7 @@ class Node( object ):
|
||||
returns: result of poll()"""
|
||||
if len( self.readbuf ) == 0:
|
||||
return self.pollOut.poll( timeoutms )
|
||||
return None
|
||||
|
||||
def sendCmd( self, *args, **kwargs ):
|
||||
"""Send a command, followed by a command to echo a sentinel,
|
||||
@@ -377,6 +387,7 @@ class Node( object ):
|
||||
return self.waitOutput( verbose )
|
||||
else:
|
||||
warn( '(%s exited - ignoring cmd%s)\n' % ( self, args ) )
|
||||
return None
|
||||
|
||||
def cmdPrint( self, *args):
|
||||
"""Call cmd and printing its output
|
||||
@@ -469,6 +480,7 @@ class Node( object ):
|
||||
else:
|
||||
warn( '*** defaultIntf: warning:', self.name,
|
||||
'has no interfaces\n' )
|
||||
return None
|
||||
|
||||
def intf( self, intf=None ):
|
||||
"""Return our interface object with given string name,
|
||||
@@ -582,10 +594,10 @@ class Node( object ):
|
||||
value may also be list or dict"""
|
||||
name, value = list( param.items() )[ 0 ]
|
||||
if value is None:
|
||||
return
|
||||
return None
|
||||
f = getattr( self, method, None )
|
||||
if not f:
|
||||
return
|
||||
return None
|
||||
if isinstance( value, list ):
|
||||
result = f( *value )
|
||||
elif isinstance( value, dict ):
|
||||
@@ -653,11 +665,12 @@ class Node( object ):
|
||||
@classmethod
|
||||
def checkSetup( cls ):
|
||||
"Make sure our class and superclasses are set up"
|
||||
while cls and not getattr( cls, 'isSetup', True ):
|
||||
cls.setup()
|
||||
cls.isSetup = True
|
||||
clas = cls
|
||||
while clas and not getattr( clas, 'isSetup', True ):
|
||||
clas.setup()
|
||||
clas.isSetup = True
|
||||
# Make pylint happy
|
||||
cls = getattr( type( cls ), '__base__', None )
|
||||
clas = getattr( type( clas ), '__base__', None )
|
||||
|
||||
@classmethod
|
||||
def setup( cls ):
|
||||
@@ -838,6 +851,7 @@ class CPULimitedHost( Host ):
|
||||
errFail( 'cgclassify -g cpuset:/%s %s' % (
|
||||
self.name, self.pid ) )
|
||||
|
||||
# pylint: disable=arguments-differ
|
||||
def config( self, cpu=-1, cores=None, **params ):
|
||||
"""cpu: desired overall system CPU fraction
|
||||
cores: (real) core(s) this host can run on
|
||||
@@ -930,6 +944,7 @@ class Switch( Node ):
|
||||
else:
|
||||
error( '*** Error: %s has execed and cannot accept commands' %
|
||||
self.name )
|
||||
return None
|
||||
|
||||
def connected( self ):
|
||||
"Is the switch connected to a controller? (override this method)"
|
||||
@@ -1115,6 +1130,7 @@ class OVSSwitch( Switch ):
|
||||
if self.batch:
|
||||
cmd = ' '.join( str( arg ).strip() for arg in args )
|
||||
self.commands.append( cmd )
|
||||
return None
|
||||
else:
|
||||
return self.cmd( 'ovs-vsctl', *args, **kwargs )
|
||||
|
||||
@@ -1302,7 +1318,7 @@ class OVSBridge( OVSSwitch ):
|
||||
"Are we forwarding yet?"
|
||||
if self.stp:
|
||||
status = self.dpctl( 'show' )
|
||||
return 'STP_FORWARD' in status and not 'STP_LEARN' in status
|
||||
return 'STP_FORWARD' in status and 'STP_LEARN' not in status
|
||||
else:
|
||||
return True
|
||||
|
||||
@@ -1429,6 +1445,7 @@ class Controller( Node ):
|
||||
' 1>' + cout + ' 2>' + cout + ' &' )
|
||||
self.execed = False
|
||||
|
||||
# pylint: disable=arguments-differ,signature-differs
|
||||
def stop( self, *args, **kwargs ):
|
||||
"Stop controller."
|
||||
self.cmd( 'kill %' + self.command )
|
||||
@@ -1479,7 +1496,7 @@ class NOX( Controller ):
|
||||
warn( 'warning: no NOX modules specified; '
|
||||
'running packetdump only\n' )
|
||||
noxArgs = [ 'packetdump' ]
|
||||
elif type( noxArgs ) not in ( list, tuple ):
|
||||
elif not isinstance( noxArgs, ( list, tuple ) ):
|
||||
noxArgs = [ noxArgs ]
|
||||
|
||||
if 'NOX_CORE_DIR' not in os.environ:
|
||||
@@ -1505,7 +1522,7 @@ class Ryu( Controller ):
|
||||
warn( 'warning: no Ryu modules specified; '
|
||||
'running simple_switch only\n' )
|
||||
ryuArgs = [ ryuCoreDir + 'simple_switch.py' ]
|
||||
elif type( ryuArgs ) not in ( list, tuple ):
|
||||
elif not isinstance( ryuArgs, ( list, tuple ) ):
|
||||
ryuArgs = [ ryuArgs ]
|
||||
|
||||
Controller.__init__( self, name,
|
||||
@@ -1532,6 +1549,7 @@ class RemoteController( Controller ):
|
||||
"Overridden to do nothing."
|
||||
return
|
||||
|
||||
# pylint: disable=arguments-differ
|
||||
def stop( self ):
|
||||
"Overridden to do nothing."
|
||||
return
|
||||
@@ -1563,6 +1581,7 @@ class RemoteController( Controller ):
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
DefaultControllers = ( Controller, OVSController )
|
||||
|
||||
def findController( controllers=DefaultControllers ):
|
||||
@@ -1570,6 +1589,7 @@ def findController( controllers=DefaultControllers ):
|
||||
for controller in controllers:
|
||||
if controller.isAvailable():
|
||||
return controller
|
||||
return None
|
||||
|
||||
def DefaultController( name, controllers=DefaultControllers, **kwargs ):
|
||||
"Find a controller that is available and instantiate it"
|
||||
|
||||
@@ -102,6 +102,7 @@ class NAT( Node ):
|
||||
# hopefully this won't disconnect you
|
||||
self.cmd( 'service network-manager restart || netplan apply' )
|
||||
|
||||
# pylint: disable=arguments-differ
|
||||
def config( self, **params ):
|
||||
"""Configure the NAT and iptables"""
|
||||
|
||||
|
||||
+1
-1
@@ -50,7 +50,7 @@ def makeTerm( node, title='Node', term='xterm', display=None, cmd='bash'):
|
||||
}
|
||||
if term not in cmds:
|
||||
error( 'invalid terminal type: %s' % term )
|
||||
return
|
||||
return None
|
||||
display, tunnel = tunnelX11( node, display )
|
||||
if display is None:
|
||||
return []
|
||||
|
||||
@@ -25,6 +25,7 @@ def runTests( testDir, verbosity=1 ):
|
||||
.run( testSuite ).wasSuccessful() )
|
||||
sys.exit( 0 if success else 1 )
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
setLogLevel( 'warning' )
|
||||
# get the directory containing example tests
|
||||
|
||||
@@ -45,7 +45,7 @@ class testOptionsTopoCommon( object ):
|
||||
@staticmethod
|
||||
def tearDown():
|
||||
"Clean up if necessary"
|
||||
if sys.exc_info != ( None, None, None ):
|
||||
if sys.exc_info() != ( None, None, None ):
|
||||
cleanup()
|
||||
|
||||
def runOptionsTopoTest( self, n, msg, hopts=None, lopts=None ):
|
||||
@@ -263,6 +263,7 @@ class testOptionsTopoUserspace( testOptionsTopoCommon, unittest.TestCase ):
|
||||
longMessage = True
|
||||
switchClass = UserSwitch
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
setLogLevel( 'warning' )
|
||||
unittest.main()
|
||||
|
||||
@@ -26,7 +26,7 @@ class testSingleSwitchCommon( object ):
|
||||
@staticmethod
|
||||
def tearDown():
|
||||
"Clean up if necessary"
|
||||
if sys.exc_info != ( None, None, None ):
|
||||
if sys.exc_info() != ( None, None, None ):
|
||||
cleanup()
|
||||
|
||||
def testMinimal( self ):
|
||||
|
||||
@@ -26,6 +26,7 @@ class TestPtyLeak( unittest.TestCase ):
|
||||
assert ( host.slave, host.master ) == oldptys
|
||||
net.stop()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
cleanup()
|
||||
|
||||
@@ -24,7 +24,7 @@ class TestSwitchDpidAssignmentOVS( unittest.TestCase ):
|
||||
"Clean up if necessary"
|
||||
# satisfy pylint
|
||||
assert self
|
||||
if sys.exc_info != ( None, None, None ):
|
||||
if sys.exc_info() != ( None, None, None ):
|
||||
cleanup()
|
||||
|
||||
def testDefaultDpid( self ):
|
||||
@@ -95,6 +95,7 @@ class testSwitchUserspace( TestSwitchDpidAssignmentOVS ):
|
||||
"Test dpid assignment of Userspace switch."
|
||||
switchClass = UserSwitch
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
setLogLevel( 'warning' )
|
||||
unittest.main()
|
||||
|
||||
@@ -35,5 +35,6 @@ class testQuietRun( unittest.TestCase ):
|
||||
output = quietRun(testQuietRun.getEchoCmd( n ) )
|
||||
self.assertEqual( n, len( output ) )
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
@@ -6,14 +6,16 @@ Tests for the Mininet Walkthrough
|
||||
TODO: missing xterm test
|
||||
"""
|
||||
|
||||
import unittest
|
||||
import os
|
||||
import re
|
||||
from mininet.util import quietRun, pexpect
|
||||
from mininet.clean import cleanup
|
||||
import unittest
|
||||
|
||||
from distutils.version import StrictVersion
|
||||
from sys import stdout
|
||||
|
||||
from mininet.util import quietRun, pexpect
|
||||
from mininet.clean import cleanup
|
||||
|
||||
|
||||
def tsharkVersion():
|
||||
"Return tshark version"
|
||||
@@ -74,7 +76,7 @@ class testWalkthrough( unittest.TestCase ):
|
||||
p.expect( self.prompt )
|
||||
# net command
|
||||
p.sendline( 'net' )
|
||||
expected = [ x for x in nodes ]
|
||||
expected = list( nodes )
|
||||
while len( expected ) > 0:
|
||||
index = p.expect( expected )
|
||||
node = p.match.group( 0 )
|
||||
@@ -110,7 +112,7 @@ class testWalkthrough( unittest.TestCase ):
|
||||
ifcount = 0
|
||||
while True:
|
||||
index = p.expect( interfaces )
|
||||
if index == 0 or index == 3:
|
||||
if index in (0, 3):
|
||||
ifcount += 1
|
||||
elif index == 1:
|
||||
self.fail( 's1 interface displayed in "h1 ifconfig"' )
|
||||
@@ -126,7 +128,7 @@ class testWalkthrough( unittest.TestCase ):
|
||||
index = p.expect( interfaces )
|
||||
if index == 0:
|
||||
self.fail( 'h1 interface displayed in "s1 ifconfig"' )
|
||||
elif index == 1 or index == 2 or index == 3:
|
||||
elif index in (1, 2, 3):
|
||||
ifcount += 1
|
||||
else:
|
||||
break
|
||||
@@ -309,7 +311,7 @@ class testWalkthrough( unittest.TestCase ):
|
||||
ifcount = 0
|
||||
while True:
|
||||
index = p.expect( interfaces )
|
||||
if index == 1 or index == 3:
|
||||
if index in (1, 3):
|
||||
ifcount += 1
|
||||
elif index == 0:
|
||||
self.fail( 'h1 interface displayed in "s1 ifconfig"' )
|
||||
|
||||
@@ -13,6 +13,9 @@ setup for testing, and can even be emulated with the Mininet package.
|
||||
|
||||
from mininet.util import irange, natural, naturalSeq
|
||||
|
||||
# pylint: disable=too-many-arguments
|
||||
|
||||
|
||||
class MultiGraph( object ):
|
||||
"Utility class to track nodes and edges - replaces networkx.MultiGraph"
|
||||
|
||||
|
||||
+15
-11
@@ -1,19 +1,23 @@
|
||||
"Utility functions for Mininet."
|
||||
|
||||
import codecs
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
from mininet.log import output, info, error, warn, debug
|
||||
|
||||
from time import sleep
|
||||
from fcntl import fcntl, F_GETFL, F_SETFL
|
||||
from functools import partial
|
||||
from os import O_NONBLOCK
|
||||
from resource import getrlimit, setrlimit, RLIMIT_NPROC, RLIMIT_NOFILE
|
||||
from select import poll, POLLIN, POLLHUP
|
||||
from subprocess import call, check_call, Popen, PIPE, STDOUT
|
||||
import re
|
||||
from fcntl import fcntl, F_GETFL, F_SETFL
|
||||
from os import O_NONBLOCK
|
||||
import os
|
||||
from functools import partial
|
||||
import sys
|
||||
import codecs
|
||||
from sys import exit # pylint: disable=redefined-builtin
|
||||
from time import sleep
|
||||
|
||||
from mininet.log import output, info, error, warn, debug
|
||||
|
||||
# pylint: disable=too-many-arguments
|
||||
|
||||
|
||||
# Python 2/3 compatibility
|
||||
|
||||
@@ -454,6 +458,7 @@ def pmonitor(popens, timeoutms=500, readline=True,
|
||||
poller.register( fd, POLLIN )
|
||||
flags = fcntl( fd, F_GETFL )
|
||||
fcntl( fd, F_SETFL, flags | O_NONBLOCK )
|
||||
# pylint: disable=too-many-nested-blocks
|
||||
while popens:
|
||||
fds = poller.poll( timeoutms )
|
||||
if fds:
|
||||
@@ -665,7 +670,6 @@ def ensureRoot():
|
||||
if os.getuid() != 0:
|
||||
error( '*** Mininet must run as root.\n' )
|
||||
exit( 1 )
|
||||
return
|
||||
|
||||
def waitListening( client=None, server='127.0.0.1', port=80, timeout=None ):
|
||||
"""Wait until server is listening on port.
|
||||
|
||||
Reference in New Issue
Block a user