From 6cb68f26c9488b51e7e454045073f3c162c9a4b1 Mon Sep 17 00:00:00 2001 From: Bob Lantz Date: Mon, 13 Apr 2015 17:27:59 -0700 Subject: [PATCH] Simply use class names as option help The justification for this is that 1) the options are already documented in the API documentation and 2) the class names are fairly self-explanatory, so adding short descriptions doesn't add much. In the future, however, we could add a short description by simply using the first line or sentence of the docstring; note that docstrings would have to be canonicalized, which they aren't now. --- bin/mn | 41 +++++++++++++++++------------------------ mininet/node.py | 6 +++++- mininet/topo.py | 6 ++++++ 3 files changed, 28 insertions(+), 25 deletions(-) diff --git a/bin/mn b/bin/mn index 05c9cb8..b702b8e 100755 --- a/bin/mn +++ b/bin/mn @@ -26,12 +26,13 @@ from mininet.log import lg, LEVELS, info, debug, warn, error from mininet.net import Mininet, MininetWithControlNet, VERSION from mininet.node import ( Host, CPULimitedHost, Controller, OVSController, Ryu, NOX, RemoteController, findController, - DefaultController, + DefaultController, NullController, UserSwitch, OVSSwitch, OVSBridge, IVSSwitch ) from mininet.nodelib import LinuxBridge from mininet.link import Link, TCLink, OVSLink -from mininet.topo import SingleSwitchTopo, LinearTopo, SingleSwitchReversedTopo +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 @@ -49,7 +50,7 @@ PLACEMENT = { 'block': SwitchBinPlacer, 'random': RandomPlacer } # built in topologies, created only when run TOPODEF = 'minimal' -TOPOS = { 'minimal': lambda: SingleSwitchTopo( k=2 ), +TOPOS = { 'minimal': MinimalTopo, 'linear': LinearTopo, 'reversed': SingleSwitchReversedTopo, 'single': SingleSwitchTopo, @@ -65,13 +66,6 @@ SWITCHES = { 'user': UserSwitch, 'ivs': IVSSwitch, 'lxbr': LinuxBridge, 'default': OVSSwitch } -SWITCHESHELP = { 'user': 'OpenFlow reference user-space switch.', - 'ovs': 'Open vSwitch OpenFlow-compatible switch.', - 'ovsbr': 'Open vSwitch as an L2 MAC learning switch.', - 'ovsk': 'Same as the ovs type.', - 'ivs': 'Indigo Virtual Switch.', - 'lxbr': 'Linux Bridge.', - 'default': 'Open vSwitch OpenFlow-compatible switch.'} HOSTDEF = 'proc' HOSTS = { 'proc': Host, @@ -79,13 +73,14 @@ HOSTS = { 'proc': Host, 'cfs': specialClass( CPULimitedHost, defaults=dict( sched='cfs' ) ) } CONTROLLERDEF = 'default' + CONTROLLERS = { 'ref': Controller, 'ovsc': OVSController, 'nox': NOX, 'remote': RemoteController, 'ryu': Ryu, 'default': DefaultController, # Note: replaced below - 'none': lambda name: None } + 'none': NullController } LINKDEF = 'default' LINKS = { 'default': Link, @@ -103,20 +98,18 @@ ALTSPELLING = { 'pingall': 'pingAll', 'iperfUDP': 'iperfUdp' } -def addDictOption( opts, choicesDict, default, name, helpDict=None, **kwargs ): - """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 - helpDict: dictionary describing choices - kwargs: additional arguments to add_option""" +def addDictOption( opts, choicesDict, default, name, **kwargs ): + """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 + kwargs: additional arguments to add_option""" helpStr = ( '|'.join( sorted( choicesDict.keys() ) ) + '[,param=value...]' ) - if helpDict: - helpList = [ k + "=" + helpDict[k] - for k in sorted( helpDict.keys() ) ] - helpStr += " " + ( ' '.join( helpList ) ) + helpList = [ '%s=%s' % ( k, v.__name__ ) + for k, v in choicesDict.items() ] + helpStr += ' ' + ( ' '.join( helpList ) ) params = dict( type='string', default=default, help=helpStr ) params.update( **kwargs ) opts.add_option( '--' + name, **params ) @@ -202,7 +195,7 @@ class MininetRunner( object ): '(type %prog -h for details)' ) opts = OptionParser( description=desc, usage=usage ) - addDictOption( opts, SWITCHES, SWITCHDEF, 'switch', SWITCHESHELP ) + addDictOption( opts, SWITCHES, SWITCHDEF, 'switch' ) addDictOption( opts, HOSTS, HOSTDEF, 'host' ) addDictOption( opts, CONTROLLERS, [], 'controller', action='append' ) addDictOption( opts, LINKS, LINKDEF, 'link' ) diff --git a/mininet/node.py b/mininet/node.py index 872c061..544fae3 100644 --- a/mininet/node.py +++ b/mininet/node.py @@ -906,7 +906,7 @@ class Switch( Node ): deleteIntfs: delete interfaces? (True)""" if deleteIntfs: self.deleteIntfs() - + def __repr__( self ): "More informative string representation" intfs = ( ','.join( [ '%s:%s' % ( i.name, i.IP() ) @@ -1517,3 +1517,7 @@ def DefaultController( name, controllers=DefaultControllers, **kwargs ): if not controller: raise Exception( 'Could not find a default OpenFlow controller' ) return controller( name, **kwargs ) + +def NullController( *_args, **_kwargs ): + "Nonexistent controller - simply returns None" + return None diff --git a/mininet/topo.py b/mininet/topo.py index aea2b67..55c5b59 100644 --- a/mininet/topo.py +++ b/mininet/topo.py @@ -318,6 +318,12 @@ class SingleSwitchReversedTopo( Topo ): port1=0, port2=( k - h + 1 ) ) +class MinimalTopo( SingleSwitchTopo ): + "Minimal topology with two hosts and one switch" + def build( self ): + return SingleSwitchTopo.build( self, k=2 ) + + class LinearTopo( Topo ): "Linear topology of k switches, with n hosts per switch."