Newer
Older
"""
Mininet runner
author: Brandon Heller (brandonh@stanford.edu)
To see options:
sudo mn -h
Example to pull custom params (topo, switch, etc.) from a file:
sudo mn --custom ~/mininet/custom/custom_example.py
from optparse import OptionParser
from mininet.net import Mininet, init
from mininet.node import KernelSwitch, Host, Controller, ControllerParams, NOX
from mininet.node import RemoteController, UserSwitch, OVSKernelSwitch
from mininet.topo import SingleSwitchTopo, LinearTopo, SingleSwitchReversedTopo
# built in topologies, created only when run
TOPODEF = 'minimal'
TOPOS = { 'minimal': ( lambda: SingleSwitchTopo( k=2 ) ),
'reversed': ( lambda: SingleSwitchReversedTopo( k=2 ) ),
'single4': ( lambda: SingleSwitchTopo( k=4 ) ),
'single100': ( lambda: SingleSwitchTopo( k=100 ) ),
'linear2': ( lambda: LinearTopo( k=2 ) ),
'linear100': ( lambda: LinearTopo( k=100 ) ) }
SWITCHDEF = 'kernel'
SWITCHES = { 'kernel': KernelSwitch,
HOSTDEF = 'process'
HOSTS = { 'process': Host }
# a and b are the name and inNamespace params.
CONTROLLERS = { 'ref': Controller,
'nox_dump': lambda a, b: NOX( a, b, 'packetdump' ),
'nox_pysw': lambda a, b: NOX( a, b, 'pyswitch' ),
'remote': lambda a, b: None,
TESTS = [ 'cli', 'build', 'pingAll', 'pingPair', 'iperf', 'all', 'iperfUdp' ]
def addDictOption( opts, choicesDict, default, name, helpStr=None ):
"""Convenience function to add choices dicts to OptionParser.
opts: OptionParser instance
choicesDict: dictionary of valid choices, must include default
default: default choice key
name: long option name
help: string"""
if default not in choicesDict:
raise Exception( 'Invalid default %s for choices dict: %s' %
( default, name ) )
if not helpStr:
helpStr = '[' + ' '.join( choicesDict.keys() ) + ']'
opts.add_option( '--' + name,
type='choice',
choices=choicesDict.keys(),
class MininetRunner( object ):
"Build, setup, and run Mininet."
def setCustom( self, name, value ):
print "got", self, name, value
if name in ( 'topos', 'switches', 'hosts', 'controllers' ):
# Update dictionaries
param = name.upper()
globals()[ param ].update( value )
elif name == 'validate':
# Add custom validate function
self.validate = value
else:
# Add or modify global variable or class
globals()[ name ] = value
def parseCustomFile( self, fileName ):
"Parse custom file and add params before parsing cmd-line options."
custom = {}
if os.path.isfile( fileName ):
execfile( fileName, custom, custom )
for name in custom:
self.setCustom( name, custom[ name ] )
raise Exception( 'could not find custom file: %s' % fileName )
def parseArgs( self ):
"""Parse command-line args and return options object.
returns: opts parse options dict"""
if '--custom' in sys.argv:
print "custom in sys.argv"
index = sys.argv.index( '--custom' )
if len( sys.argv ) > index + 1:
custom = sys.argv[ index + 1 ]
self.parseCustomFile( custom )
else:
raise Exception( 'Custom file name not found' )
addDictOption( opts, TOPOS, TOPODEF, 'topo' )
addDictOption( opts, SWITCHES, SWITCHDEF, 'switch' )
addDictOption( opts, HOSTS, HOSTDEF, 'host' )
addDictOption( opts, CONTROLLERS, CONTROLLERDEF, 'controller' )
opts.add_option( '--custom', type='string', default=None,
help='read custom topo and node params from .py file' )
opts.add_option( '--test', type='choice', choices=TESTS,
default=TESTS[ 0 ],
help='[' + ' '.join( TESTS ) + ']' )
opts.add_option( '--xterms', '-x', action='store_true',
default=False, help='spawn xterms for each node' )
opts.add_option( '--mac', action='store_true',
default=False, help='set MACs equal to DPIDs' )
opts.add_option( '--arp', action='store_true',
default=False, help='set all-pairs ARP entries' )
opts.add_option( '--verbosity', '-v', type='choice',
choices=LEVELS.keys(), default = 'info',
help = '[' + ' '.join( LEVELS.keys() ) + ']' )
opts.add_option( '--ip', type='string', default='127.0.0.1',
help='[ip address as a dotted decimal string for a'
'remote controller]' )
opts.add_option( '--port', type='string', default=6633,
help='[port integer for a listening remote'
' controller]' )
opts.add_option( '--inNamespace', action='store_true',
default=False, help='sw and ctrl in namespace?' )
self.options = opts.parse_args()[ 0 ]
def setup( self ):
"Setup and validate environment."
lg.setLogLevel( self.options.verbosity )
# validate environment setup
init()
def begin( self ):
"Create and run mininet."
topo = TOPOS[ self.options.topo ]() # build topology object
switch = SWITCHES[ self.options.switch ]
host = HOSTS[ self.options.host ]
controller = CONTROLLERS[ self.options.controller ]
if self.options.controller == 'remote':
controller = lambda a, b: RemoteController( a, b,
ipAddress=self.options.ip,
port=self.options.port )
self.validate( self.options )
controllerParams = ControllerParams( 0x0a000000, 8 ) # 10.0.0.0/8
inNamespace = self.options.inNamespace
mac = self.options.mac
arp = self.options.arp
mn = Mininet( topo, switch, host, controller, controllerParams,
inNamespace=inNamespace,
xterms=xterms, autoSetMacs=mac,
autoStaticArp=arp )
test = self.options.test
if test != 'build':
if test == 'cli':
elif test == 'all':
mn.start()
mn.ping()
mn.iperf()
elapsed = float( time.time() - start )
print ( 'completed in %0.3f seconds' % elapsed )
if __name__ == "__main__":