diff --git a/examples/cluster.py b/examples/cluster.py index b6128a6..54c95df 100755 --- a/examples/cluster.py +++ b/examples/cluster.py @@ -123,7 +123,8 @@ class RemoteMixin( object ): **kwargs: see Node()""" # We connect to servers by IP address self.server = server if server else 'localhost' - self.serverIP = serverIP if serverIP else self.findServerIP( self.server ) + self.serverIP = ( serverIP if serverIP + else self.findServerIP( self.server ) ) self.user = user if user else self.findUser() if controlPath is True: # Set a default control path for shared SSH connections @@ -143,21 +144,20 @@ class RemoteMixin( object ): self.dest = None self.sshcmd = [] self.isRemote = False + # Satisfy pylint + self.shell, self.pid, self.cmd = None, None, None super( RemoteMixin, self ).__init__( name, **kwargs ) @staticmethod def findUser(): "Try to return logged-in (usually non-root) user" - try: + return ( # If we're running sudo - return os.environ[ 'SUDO_USER' ] - except: - try: - # Logged-in user (if we have a tty) - return quietRun( 'who am i' ).split()[ 0 ] - except: - # Give up and return effective user - return quietRun( 'whoami' ) + os.environ.get( 'SUDO_USER', False ) or + # Logged-in user (if we have a tty) + ( quietRun( 'who am i' ).split() or [ False ] )[ 0 ] or + # Give up and return effective user + quietRun( 'whoami' ) ) # Determine IP address of local host _ipMatchRegex = re.compile( r'\d+\.\d+\.\d+\.\d+' ) @@ -187,6 +187,8 @@ class RemoteMixin( object ): self.pid = int( self.cmd( 'echo $$' ) ) def finishInit( self ): + "Wait for split initialization to complete" + assert self # please pylint self.pid = int( self.waitOutput() ) def rpopen( self, *cmd, **opts ): @@ -282,7 +284,8 @@ 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( r'\d+\.\d+', vers )[ 0 ] + cls.OVSVersions[ self.server ] = re.findall( + r'\d+\.\d+', vers )[ 0 ] return ( StrictVersion( cls.OVSVersions[ self.server ] ) < StrictVersion( '1.10' ) ) @@ -301,6 +304,7 @@ class RemoteLink( Link ): self.tunnel = None kwargs.setdefault( 'params1', {} ) kwargs.setdefault( 'params2', {} ) + self.cmd = None # satisfy pylint Link.__init__( self, node1, node2, **kwargs ) def stop( self ): @@ -324,9 +328,10 @@ class RemoteLink( Link ): elif server1 == server2: # Remote link on same remote server return makeIntfPair( intfname1, intfname2, addr1, addr2, - run=node1.rcmd ) + runCmd=node1.rcmd ) # Otherwise, make a tunnel - self.tunnel = self.makeTunnel( node1, node2, intfname1, intfname2, addr1, addr2 ) + self.tunnel = self.makeTunnel( node1, node2, intfname1, intfname2, + addr1, addr2 ) return self.tunnel @staticmethod @@ -340,7 +345,7 @@ class RemoteLink( Link ): cmd = 'ip link set %s netns %s' % ( intf, node.pid ) node.rcmd( cmd ) links = node.cmd( 'ip link show' ) - if not ( ' %s:' % intf ) in links: + if not ' %s:' % intf in links: if printError: error( '*** Error: RemoteLink.moveIntf: ' + intf + ' not successfully moved to ' + node.name + '\n' ) @@ -442,8 +447,9 @@ class Placer( object ): def place( self, node ): "Return server for a given node" + assert self, node # satisfy pylint # Default placement: run locally - return None + return 'localhost' class RandomPlacer( Placer ): @@ -451,6 +457,7 @@ class RandomPlacer( Placer ): def place( self, nodename ): """Random placement function nodename: node name""" + assert nodename # please pylint # This may be slow with lots of servers return self.servers[ randrange( 0, len( self.servers ) ) ] @@ -467,6 +474,7 @@ class RoundRobinPlacer( Placer ): def place( self, nodename ): """Round-robin placement function nodename: node name""" + assert nodename # please pylint # This may be slow with lots of servers server = self.servers[ self.next ] self.next = ( self.next + 1 ) % len( self.servers ) @@ -626,6 +634,7 @@ class MininetCluster( Mininet ): def popen( self, cmd ): "Popen() for server connections" + assert self # please pylint old = signal( SIGINT, SIG_IGN ) conn = Popen( cmd, stdin=PIPE, stdout=PIPE, close_fds=True ) signal( SIGINT, old ) @@ -649,7 +658,7 @@ class MininetCluster( Mininet ): cmd = [ 'sudo', '-E', '-u', self.user ] cmd += self.sshcmd + [ '-n', dest, 'sudo true' ] debug( ' '.join( cmd ), '\n' ) - out, err, code = errRun( cmd ) + _out, _err, code = errRun( cmd ) if code != 0: error( '\nstartConnection: server connection check failed ' 'to %s using command:\n%s\n' @@ -665,6 +674,7 @@ class MininetCluster( Mininet ): def modifiedaddHost( self, *args, **kwargs ): "Slightly modify addHost" + assert self # please pylint kwargs[ 'splitInit' ] = True return Mininet.addHost( *args, **kwargs ) diff --git a/examples/clustercli.py b/examples/clustercli.py index bf6d423..9f532e3 100644 --- a/examples/clustercli.py +++ b/examples/clustercli.py @@ -5,6 +5,7 @@ from mininet.cli import CLI from mininet.log import output, error +# pylint: disable=global-statement nx, graphviz_layout, plt = None, None, None # Will be imported on demand @@ -23,17 +24,19 @@ class ClusterCLI( CLI ): colors = colors[ 0 : slen ] return colors - def do_plot( self, line ): + def do_plot( self, _line ): "Plot topology colored by node placement" # Import networkx if needed global nx, plt if not nx: try: - import networkx as nx - import matplotlib.pyplot as plt + import networkx + nx = networkx # satisfy pylint + from matplotlib import pyplot + plt = pyplot # satisfiy pylint import pygraphviz assert pygraphviz # silence pyflakes - except: + except ImportError: error( 'plot requires networkx, matplotlib and pygraphviz - ' 'please install them and try again\n' ) return @@ -53,10 +56,13 @@ class ClusterCLI( CLI ): pos = nx.graphviz_layout( g ) opts = { 'ax': None, 'font_weight': 'bold', 'width': 2, 'edge_color': 'darkblue' } - hcolors = [ color[ getattr( h, 'server', 'localhost' ) ] for h in hosts ] - scolors = [ color[ getattr( s, 'server', 'localhost' ) ] for s in switches ] - nx.draw_networkx( g, pos=pos, nodelist=hosts, node_size=800, label='host', - node_color=hcolors, node_shape='s', **opts ) + hcolors = [ color[ getattr( h, 'server', 'localhost' ) ] + for h in hosts ] + scolors = [ color[ getattr( s, 'server', 'localhost' ) ] + for s in switches ] + nx.draw_networkx( g, pos=pos, nodelist=hosts, node_size=800, + label='host', node_color=hcolors, node_shape='s', + **opts ) nx.draw_networkx( g, pos=pos, nodelist=switches, node_size=1000, node_color=scolors, node_shape='o', **opts ) # Get rid of axes, add title, and show @@ -68,7 +74,7 @@ class ClusterCLI( CLI ): plt.title( 'Node Placement', fontweight='bold' ) plt.show() - def do_status( self, line ): + def do_status( self, _line ): "Report on node shell status" nodes = self.mn.hosts + self.mn.switches for node in nodes: @@ -83,7 +89,7 @@ class ClusterCLI( CLI ): output( 'All nodes are still running.\n' ) - def do_placement( self, line ): + def do_placement( self, _line ): "Describe node placement" mn = self.mn nodes = mn.hosts + mn.switches + mn.controllers diff --git a/examples/limit.py b/examples/limit.py index 4984bb9..4db88ac 100755 --- a/examples/limit.py +++ b/examples/limit.py @@ -27,9 +27,11 @@ def limit( bw=10, cpu=.1 ): info( '*** Testing with', sched, 'bandwidth limiting\n' ) if sched == 'rt': 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': - info( '*** RT Scheduler is not enabled in your kernel. Skipping this test\n' ) + info( '*** RT Scheduler is not enabled in your kernel. ' + 'Skipping this test\n' ) continue host = custom( CPULimitedHost, sched=sched, cpu=cpu ) net = Mininet( topo=myTopo, intf=intf, host=host ) diff --git a/examples/linuxrouter.py b/examples/linuxrouter.py index 8d0de5b..3fc5e68 100755 --- a/examples/linuxrouter.py +++ b/examples/linuxrouter.py @@ -44,16 +44,23 @@ class LinuxRouter( Node ): class NetworkTopo( Topo ): "A simple topology of a router with three subnets (one host in each)." - def build( self, n=2, h=1, **opts ): + def build( self, **opts ): router = self.addNode( 'r0', cls=LinuxRouter, ip='192.168.1.1/24' ) - h1 = self.addHost( 'h1', ip='192.168.1.100/24', defaultRoute='via 192.168.1.1' ) - h2 = self.addHost( 'h2', ip='172.16.0.100/12', defaultRoute='via 172.16.0.1' ) - h3 = self.addHost( 'h3', ip='10.0.0.100/8', defaultRoute='via 10.0.0.1' ) - self.addLink( h1, router, intfName2='r0-eth1', params2={ 'ip' : '192.168.1.1/24' } ) - self.addLink( h2, router, intfName2='r0-eth2', params2={ 'ip' : '172.16.0.1/12' } ) - self.addLink( h3, router, intfName2='r0-eth3', params2={ 'ip' : '10.0.0.1/8' } ) + h1 = self.addHost( 'h1', ip='192.168.1.100/24', + defaultRoute='via 192.168.1.1' ) + h2 = self.addHost( 'h2', ip='172.16.0.100/12', + defaultRoute='via 172.16.0.1' ) + h3 = self.addHost( 'h3', ip='10.0.0.100/8', + defaultRoute='via 10.0.0.1' ) + self.addLink( h1, router, intfName2='r0-eth1', + params2={ 'ip' : '192.168.1.1/24' } ) + self.addLink( h2, router, intfName2='r0-eth2', + params2={ 'ip' : '172.16.0.1/12' } ) + self.addLink( h3, router, intfName2='r0-eth3', + params2={ 'ip' : '10.0.0.1/8' } ) def run(): + "Test linux router" topo = NetworkTopo() net = Mininet( topo=topo, controller=None ) # no controller needed net.start() diff --git a/examples/miniedit.py b/examples/miniedit.py index 9ba6a8b..be2bce9 100755 --- a/examples/miniedit.py +++ b/examples/miniedit.py @@ -13,6 +13,9 @@ Controller icon from http://semlabs.co.uk/ OpenFlow icon from https://www.opennetworking.org/ """ +# For now, tolerate long lines and long module +# pylint: disable=line-too-long,too-many-lines + MINIEDIT_VERSION = '2.2.0.1' from optparse import OptionParser @@ -83,34 +86,38 @@ HOSTS = { 'proc': Host, class InbandController( RemoteController ): - + "RemoteController that ignores checkListening" def checkListening( self ): "Overridden to do nothing." return class CustomUserSwitch(UserSwitch): + "Customized UserSwitch" def __init__( self, name, dpopts='--no-slicing', **kwargs ): UserSwitch.__init__( self, name, **kwargs ) self.switchIP = None def getSwitchIP(self): + "Return management IP address" return self.switchIP def setSwitchIP(self, ip): + "Set management IP address" self.switchIP = ip def start( self, controllers ): + "Start and set management IP address" # Call superclass constructor UserSwitch.start( self, controllers ) # Set Switch IP address - if (self.switchIP is not None): + if self.switchIP is not None: if not self.inNamespace: self.cmd( 'ifconfig', self, self.switchIP ) else: self.cmd( 'ifconfig lo', self.switchIP ) class LegacyRouter( Node ): - + "Simple IP router" def __init__( self, name, inNamespace=True, **params ): Node.__init__( self, name, inNamespace, **params ) @@ -122,76 +129,550 @@ class LegacyRouter( Node ): return r class LegacySwitch(OVSSwitch): - + "OVS switch in standalone/bridge mode" def __init__( self, name, **params ): OVSSwitch.__init__( self, name, failMode='standalone', **params ) self.switchIP = None class customOvs(OVSSwitch): + "Customized OVS switch" def __init__( self, name, failMode='secure', datapath='kernel', **params ): OVSSwitch.__init__( self, name, failMode=failMode, datapath=datapath, **params ) self.switchIP = None def getSwitchIP(self): + "Return management IP address" return self.switchIP def setSwitchIP(self, ip): + "Set management IP address" self.switchIP = ip def start( self, controllers ): + "Start and set management IP address" # Call superclass constructor OVSSwitch.start( self, controllers ) # Set Switch IP address - if (self.switchIP is not None): + if self.switchIP is not None: self.cmd( 'ifconfig', self, self.switchIP ) class PrefsDialog(tkSimpleDialog.Dialog): + "Preferences dialog" - def __init__(self, parent, title, prefDefaults): + def __init__(self, parent, title, prefDefaults): - self.prefValues = prefDefaults + self.prefValues = prefDefaults - tkSimpleDialog.Dialog.__init__(self, parent, title) + tkSimpleDialog.Dialog.__init__(self, parent, title) - def body(self, master): - self.rootFrame = master - self.leftfieldFrame = Frame(self.rootFrame, padx=5, pady=5) - self.leftfieldFrame.grid(row=0, column=0, sticky='nswe', columnspan=2) - self.rightfieldFrame = Frame(self.rootFrame, padx=5, pady=5) - self.rightfieldFrame.grid(row=0, column=2, sticky='nswe', columnspan=2) + def body(self, master): + "Create dialog body" + self.rootFrame = master + self.leftfieldFrame = Frame(self.rootFrame, padx=5, pady=5) + self.leftfieldFrame.grid(row=0, column=0, sticky='nswe', columnspan=2) + self.rightfieldFrame = Frame(self.rootFrame, padx=5, pady=5) + self.rightfieldFrame.grid(row=0, column=2, sticky='nswe', columnspan=2) + + # Field for Base IP + Label(self.leftfieldFrame, text="IP Base:").grid(row=0, sticky=E) + self.ipEntry = Entry(self.leftfieldFrame) + self.ipEntry.grid(row=0, column=1) + ipBase = self.prefValues['ipBase'] + self.ipEntry.insert(0, ipBase) + + # Selection of terminal type + Label(self.leftfieldFrame, text="Default Terminal:").grid(row=1, sticky=E) + self.terminalVar = StringVar(self.leftfieldFrame) + self.terminalOption = OptionMenu(self.leftfieldFrame, self.terminalVar, "xterm", "gterm") + self.terminalOption.grid(row=1, column=1, sticky=W) + terminalType = self.prefValues['terminalType'] + self.terminalVar.set(terminalType) + + # Field for CLI + Label(self.leftfieldFrame, text="Start CLI:").grid(row=2, sticky=E) + self.cliStart = IntVar() + self.cliButton = Checkbutton(self.leftfieldFrame, variable=self.cliStart) + self.cliButton.grid(row=2, column=1, sticky=W) + if self.prefValues['startCLI'] == '0': + self.cliButton.deselect() + else: + self.cliButton.select() + + # Selection of switch type + Label(self.leftfieldFrame, text="Default Switch:").grid(row=3, sticky=E) + self.switchType = StringVar(self.leftfieldFrame) + self.switchTypeMenu = OptionMenu(self.leftfieldFrame, self.switchType, "Open vSwitch Kernel Mode", "Indigo Virtual Switch", "Userspace Switch", "Userspace Switch inNamespace") + self.switchTypeMenu.grid(row=3, column=1, sticky=W) + switchTypePref = self.prefValues['switchType'] + if switchTypePref == 'ivs': + self.switchType.set("Indigo Virtual Switch") + elif switchTypePref == 'userns': + self.switchType.set("Userspace Switch inNamespace") + elif switchTypePref == 'user': + self.switchType.set("Userspace Switch") + else: + self.switchType.set("Open vSwitch Kernel Mode") - # Field for Base IP - Label(self.leftfieldFrame, text="IP Base:").grid(row=0, sticky=E) - self.ipEntry = Entry(self.leftfieldFrame) - self.ipEntry.grid(row=0, column=1) - ipBase = self.prefValues['ipBase'] - self.ipEntry.insert(0, ipBase) + # Fields for OVS OpenFlow version + ovsFrame= LabelFrame(self.leftfieldFrame, text='Open vSwitch', padx=5, pady=5) + ovsFrame.grid(row=4, column=0, columnspan=2, sticky=EW) + Label(ovsFrame, text="OpenFlow 1.0:").grid(row=0, sticky=E) + Label(ovsFrame, text="OpenFlow 1.1:").grid(row=1, sticky=E) + Label(ovsFrame, text="OpenFlow 1.2:").grid(row=2, sticky=E) + Label(ovsFrame, text="OpenFlow 1.3:").grid(row=3, sticky=E) - # Selection of terminal type - Label(self.leftfieldFrame, text="Default Terminal:").grid(row=1, sticky=E) - self.terminalVar = StringVar(self.leftfieldFrame) - self.terminalOption = OptionMenu(self.leftfieldFrame, self.terminalVar, "xterm", "gterm") - self.terminalOption.grid(row=1, column=1, sticky=W) - terminalType = self.prefValues['terminalType'] - self.terminalVar.set(terminalType) + self.ovsOf10 = IntVar() + self.covsOf10 = Checkbutton(ovsFrame, variable=self.ovsOf10) + self.covsOf10.grid(row=0, column=1, sticky=W) + if self.prefValues['openFlowVersions']['ovsOf10'] == '0': + self.covsOf10.deselect() + else: + self.covsOf10.select() - # Field for CLI - Label(self.leftfieldFrame, text="Start CLI:").grid(row=2, sticky=E) - self.cliStart = IntVar() - self.cliButton = Checkbutton(self.leftfieldFrame, variable=self.cliStart) - self.cliButton.grid(row=2, column=1, sticky=W) - if self.prefValues['startCLI'] == '0': - self.cliButton.deselect() + self.ovsOf11 = IntVar() + self.covsOf11 = Checkbutton(ovsFrame, variable=self.ovsOf11) + self.covsOf11.grid(row=1, column=1, sticky=W) + if self.prefValues['openFlowVersions']['ovsOf11'] == '0': + self.covsOf11.deselect() + else: + self.covsOf11.select() + + self.ovsOf12 = IntVar() + self.covsOf12 = Checkbutton(ovsFrame, variable=self.ovsOf12) + self.covsOf12.grid(row=2, column=1, sticky=W) + if self.prefValues['openFlowVersions']['ovsOf12'] == '0': + self.covsOf12.deselect() + else: + self.covsOf12.select() + + self.ovsOf13 = IntVar() + self.covsOf13 = Checkbutton(ovsFrame, variable=self.ovsOf13) + self.covsOf13.grid(row=3, column=1, sticky=W) + if self.prefValues['openFlowVersions']['ovsOf13'] == '0': + self.covsOf13.deselect() + else: + self.covsOf13.select() + + # Field for DPCTL listen port + Label(self.leftfieldFrame, text="dpctl port:").grid(row=5, sticky=E) + self.dpctlEntry = Entry(self.leftfieldFrame) + self.dpctlEntry.grid(row=5, column=1) + if 'dpctl' in self.prefValues: + self.dpctlEntry.insert(0, self.prefValues['dpctl']) + + # sFlow + sflowValues = self.prefValues['sflow'] + self.sflowFrame= LabelFrame(self.rightfieldFrame, text='sFlow Profile for Open vSwitch', padx=5, pady=5) + self.sflowFrame.grid(row=0, column=0, columnspan=2, sticky=EW) + + Label(self.sflowFrame, text="Target:").grid(row=0, sticky=E) + self.sflowTarget = Entry(self.sflowFrame) + self.sflowTarget.grid(row=0, column=1) + self.sflowTarget.insert(0, sflowValues['sflowTarget']) + + Label(self.sflowFrame, text="Sampling:").grid(row=1, sticky=E) + self.sflowSampling = Entry(self.sflowFrame) + self.sflowSampling.grid(row=1, column=1) + self.sflowSampling.insert(0, sflowValues['sflowSampling']) + + Label(self.sflowFrame, text="Header:").grid(row=2, sticky=E) + self.sflowHeader = Entry(self.sflowFrame) + self.sflowHeader.grid(row=2, column=1) + self.sflowHeader.insert(0, sflowValues['sflowHeader']) + + Label(self.sflowFrame, text="Polling:").grid(row=3, sticky=E) + self.sflowPolling = Entry(self.sflowFrame) + self.sflowPolling.grid(row=3, column=1) + self.sflowPolling.insert(0, sflowValues['sflowPolling']) + + # NetFlow + nflowValues = self.prefValues['netflow'] + self.nFrame= LabelFrame(self.rightfieldFrame, text='NetFlow Profile for Open vSwitch', padx=5, pady=5) + self.nFrame.grid(row=1, column=0, columnspan=2, sticky=EW) + + Label(self.nFrame, text="Target:").grid(row=0, sticky=E) + self.nflowTarget = Entry(self.nFrame) + self.nflowTarget.grid(row=0, column=1) + self.nflowTarget.insert(0, nflowValues['nflowTarget']) + + Label(self.nFrame, text="Active Timeout:").grid(row=1, sticky=E) + self.nflowTimeout = Entry(self.nFrame) + self.nflowTimeout.grid(row=1, column=1) + self.nflowTimeout.insert(0, nflowValues['nflowTimeout']) + + Label(self.nFrame, text="Add ID to Interface:").grid(row=2, sticky=E) + self.nflowAddId = IntVar() + self.nflowAddIdButton = Checkbutton(self.nFrame, variable=self.nflowAddId) + self.nflowAddIdButton.grid(row=2, column=1, sticky=W) + if nflowValues['nflowAddId'] == '0': + self.nflowAddIdButton.deselect() + else: + self.nflowAddIdButton.select() + + # initial focus + return self.ipEntry + + def apply(self): + ipBase = self.ipEntry.get() + terminalType = self.terminalVar.get() + startCLI = str(self.cliStart.get()) + sw = self.switchType.get() + dpctl = self.dpctlEntry.get() + + ovsOf10 = str(self.ovsOf10.get()) + ovsOf11 = str(self.ovsOf11.get()) + ovsOf12 = str(self.ovsOf12.get()) + ovsOf13 = str(self.ovsOf13.get()) + + sflowValues = {'sflowTarget':self.sflowTarget.get(), + 'sflowSampling':self.sflowSampling.get(), + 'sflowHeader':self.sflowHeader.get(), + 'sflowPolling':self.sflowPolling.get()} + nflowvalues = {'nflowTarget':self.nflowTarget.get(), + 'nflowTimeout':self.nflowTimeout.get(), + 'nflowAddId':str(self.nflowAddId.get())} + self.result = {'ipBase':ipBase, + 'terminalType':terminalType, + 'dpctl':dpctl, + 'sflow':sflowValues, + 'netflow':nflowvalues, + 'startCLI':startCLI} + if sw == 'Indigo Virtual Switch': + self.result['switchType'] = 'ivs' + if StrictVersion(MININET_VERSION) < StrictVersion('2.1'): + self.ovsOk = False + showerror(title="Error", + message='MiniNet version 2.1+ required. You have '+VERSION+'.') + elif sw == 'Userspace Switch': + self.result['switchType'] = 'user' + elif sw == 'Userspace Switch inNamespace': + self.result['switchType'] = 'userns' + else: + self.result['switchType'] = 'ovs' + + self.ovsOk = True + if ovsOf11 == "1": + ovsVer = self.getOvsVersion() + if StrictVersion(ovsVer) < StrictVersion('2.0'): + self.ovsOk = False + showerror(title="Error", + message='Open vSwitch version 2.0+ required. You have '+ovsVer+'.') + if ovsOf12 == "1" or ovsOf13 == "1": + ovsVer = self.getOvsVersion() + if StrictVersion(ovsVer) < StrictVersion('1.10'): + self.ovsOk = False + showerror(title="Error", + message='Open vSwitch version 1.10+ required. You have '+ovsVer+'.') + + if self.ovsOk: + self.result['openFlowVersions']={'ovsOf10':ovsOf10, + 'ovsOf11':ovsOf11, + 'ovsOf12':ovsOf12, + 'ovsOf13':ovsOf13} + else: + self.result = None + + def getOvsVersion(self): + "Return OVS version" + outp = quietRun("ovs-vsctl show") + r = r'ovs_version: "(.*)"' + m = re.search(r, outp) + if m is None: + print 'Version check failed' + return None + else: + print 'Open vSwitch version is '+m.group(1) + return m.group(1) + + +class CustomDialog(object): + + # TODO: Fix button placement and Title and window focus lock + def __init__(self, master, title): + self.top=Toplevel(master) + + self.bodyFrame = Frame(self.top) + self.bodyFrame.grid(row=0, column=0, sticky='nswe') + self.body(self.bodyFrame) + + #return self.b # initial focus + buttonFrame = Frame(self.top, relief='ridge', bd=3, bg='lightgrey') + buttonFrame.grid(row=1 , column=0, sticky='nswe') + + okButton = Button(buttonFrame, width=8, text='OK', relief='groove', + bd=4, command=self.okAction) + okButton.grid(row=0, column=0, sticky=E) + + canlceButton = Button(buttonFrame, width=8, text='Cancel', relief='groove', + bd=4, command=self.cancelAction) + canlceButton.grid(row=0, column=1, sticky=W) + + def body(self, master): + self.rootFrame = master + + def apply(self): + self.top.destroy() + + def cancelAction(self): + self.top.destroy() + + def okAction(self): + self.apply() + self.top.destroy() + +class HostDialog(CustomDialog): + + def __init__(self, master, title, prefDefaults): + + self.prefValues = prefDefaults + self.result = None + + CustomDialog.__init__(self, master, title) + + def body(self, master): + self.rootFrame = master + n = Notebook(self.rootFrame) + self.propFrame = Frame(n) + self.vlanFrame = Frame(n) + self.interfaceFrame = Frame(n) + self.mountFrame = Frame(n) + n.add(self.propFrame, text='Properties') + n.add(self.vlanFrame, text='VLAN Interfaces') + n.add(self.interfaceFrame, text='External Interfaces') + n.add(self.mountFrame, text='Private Directories') + n.pack() + + ### TAB 1 + # Field for Hostname + Label(self.propFrame, text="Hostname:").grid(row=0, sticky=E) + self.hostnameEntry = Entry(self.propFrame) + self.hostnameEntry.grid(row=0, column=1) + if 'hostname' in self.prefValues: + self.hostnameEntry.insert(0, self.prefValues['hostname']) + + # Field for Switch IP + Label(self.propFrame, text="IP Address:").grid(row=1, sticky=E) + self.ipEntry = Entry(self.propFrame) + self.ipEntry.grid(row=1, column=1) + if 'ip' in self.prefValues: + self.ipEntry.insert(0, self.prefValues['ip']) + + # Field for default route + Label(self.propFrame, text="Default Route:").grid(row=2, sticky=E) + self.routeEntry = Entry(self.propFrame) + self.routeEntry.grid(row=2, column=1) + if 'defaultRoute' in self.prefValues: + self.routeEntry.insert(0, self.prefValues['defaultRoute']) + + # Field for CPU + Label(self.propFrame, text="Amount CPU:").grid(row=3, sticky=E) + self.cpuEntry = Entry(self.propFrame) + self.cpuEntry.grid(row=3, column=1) + if 'cpu' in self.prefValues: + self.cpuEntry.insert(0, str(self.prefValues['cpu'])) + # Selection of Scheduler + if 'sched' in self.prefValues: + sched = self.prefValues['sched'] + else: + sched = 'host' + self.schedVar = StringVar(self.propFrame) + self.schedOption = OptionMenu(self.propFrame, self.schedVar, "host", "cfs", "rt") + self.schedOption.grid(row=3, column=2, sticky=W) + self.schedVar.set(sched) + + # Selection of Cores + Label(self.propFrame, text="Cores:").grid(row=4, sticky=E) + self.coreEntry = Entry(self.propFrame) + self.coreEntry.grid(row=4, column=1) + if 'cores' in self.prefValues: + self.coreEntry.insert(1, self.prefValues['cores']) + + # Start command + Label(self.propFrame, text="Start Command:").grid(row=5, sticky=E) + self.startEntry = Entry(self.propFrame) + self.startEntry.grid(row=5, column=1, sticky='nswe', columnspan=3) + if 'startCommand' in self.prefValues: + self.startEntry.insert(0, str(self.prefValues['startCommand'])) + # Stop command + Label(self.propFrame, text="Stop Command:").grid(row=6, sticky=E) + self.stopEntry = Entry(self.propFrame) + self.stopEntry.grid(row=6, column=1, sticky='nswe', columnspan=3) + if 'stopCommand' in self.prefValues: + self.stopEntry.insert(0, str(self.prefValues['stopCommand'])) + + ### TAB 2 + # External Interfaces + self.externalInterfaces = 0 + Label(self.interfaceFrame, text="External Interface:").grid(row=0, column=0, sticky=E) + self.b = Button( self.interfaceFrame, text='Add', command=self.addInterface) + self.b.grid(row=0, column=1) + + self.interfaceFrame = VerticalScrolledTable(self.interfaceFrame, rows=0, columns=1, title='External Interfaces') + self.interfaceFrame.grid(row=1, column=0, sticky='nswe', columnspan=2) + self.tableFrame = self.interfaceFrame.interior + self.tableFrame.addRow(value=['Interface Name'], readonly=True) + + # Add defined interfaces + externalInterfaces = [] + if 'externalInterfaces' in self.prefValues: + externalInterfaces = self.prefValues['externalInterfaces'] + + for externalInterface in externalInterfaces: + self.tableFrame.addRow(value=[externalInterface]) + + ### TAB 3 + # VLAN Interfaces + self.vlanInterfaces = 0 + Label(self.vlanFrame, text="VLAN Interface:").grid(row=0, column=0, sticky=E) + self.vlanButton = Button( self.vlanFrame, text='Add', command=self.addVlanInterface) + self.vlanButton.grid(row=0, column=1) + + self.vlanFrame = VerticalScrolledTable(self.vlanFrame, rows=0, columns=2, title='VLAN Interfaces') + self.vlanFrame.grid(row=1, column=0, sticky='nswe', columnspan=2) + self.vlanTableFrame = self.vlanFrame.interior + self.vlanTableFrame.addRow(value=['IP Address','VLAN ID'], readonly=True) + + vlanInterfaces = [] + if 'vlanInterfaces' in self.prefValues: + vlanInterfaces = self.prefValues['vlanInterfaces'] + for vlanInterface in vlanInterfaces: + self.vlanTableFrame.addRow(value=vlanInterface) + + ### TAB 4 + # Private Directories + self.privateDirectories = 0 + Label(self.mountFrame, text="Private Directory:").grid(row=0, column=0, sticky=E) + self.mountButton = Button( self.mountFrame, text='Add', command=self.addDirectory) + self.mountButton.grid(row=0, column=1) + + self.mountFrame = VerticalScrolledTable(self.mountFrame, rows=0, columns=2, title='Directories') + self.mountFrame.grid(row=1, column=0, sticky='nswe', columnspan=2) + self.mountTableFrame = self.mountFrame.interior + self.mountTableFrame.addRow(value=['Mount','Persistent Directory'], readonly=True) + + directoryList = [] + if 'privateDirectory' in self.prefValues: + directoryList = self.prefValues['privateDirectory'] + for privateDir in directoryList: + if isinstance( privateDir, tuple ): + self.mountTableFrame.addRow(value=privateDir) else: - self.cliButton.select() + self.mountTableFrame.addRow(value=[privateDir,'']) - # Selection of switch type - Label(self.leftfieldFrame, text="Default Switch:").grid(row=3, sticky=E) - self.switchType = StringVar(self.leftfieldFrame) - self.switchTypeMenu = OptionMenu(self.leftfieldFrame, self.switchType, "Open vSwitch Kernel Mode", "Indigo Virtual Switch", "Userspace Switch", "Userspace Switch inNamespace") - self.switchTypeMenu.grid(row=3, column=1, sticky=W) + + def addDirectory( self ): + self.mountTableFrame.addRow() + + def addVlanInterface( self ): + self.vlanTableFrame.addRow() + + def addInterface( self ): + self.tableFrame.addRow() + + def apply(self): + externalInterfaces = [] + for row in range(self.tableFrame.rows): + if (len(self.tableFrame.get(row, 0)) > 0 and + row > 0): + externalInterfaces.append(self.tableFrame.get(row, 0)) + vlanInterfaces = [] + for row in range(self.vlanTableFrame.rows): + if (len(self.vlanTableFrame.get(row, 0)) > 0 and + len(self.vlanTableFrame.get(row, 1)) > 0 and + row > 0): + vlanInterfaces.append([self.vlanTableFrame.get(row, 0), self.vlanTableFrame.get(row, 1)]) + privateDirectories = [] + for row in range(self.mountTableFrame.rows): + if len(self.mountTableFrame.get(row, 0)) > 0 and row > 0: + if len(self.mountTableFrame.get(row, 1)) > 0: + privateDirectories.append((self.mountTableFrame.get(row, 0), self.mountTableFrame.get(row, 1))) + else: + privateDirectories.append(self.mountTableFrame.get(row, 0)) + + results = {'cpu': self.cpuEntry.get(), + 'cores':self.coreEntry.get(), + 'sched':self.schedVar.get(), + 'hostname':self.hostnameEntry.get(), + 'ip':self.ipEntry.get(), + 'defaultRoute':self.routeEntry.get(), + 'startCommand':self.startEntry.get(), + 'stopCommand':self.stopEntry.get(), + 'privateDirectory':privateDirectories, + 'externalInterfaces':externalInterfaces, + 'vlanInterfaces':vlanInterfaces} + self.result = results + +class SwitchDialog(CustomDialog): + + def __init__(self, master, title, prefDefaults): + + self.prefValues = prefDefaults + self.result = None + CustomDialog.__init__(self, master, title) + + def body(self, master): + self.rootFrame = master + self.leftfieldFrame = Frame(self.rootFrame) + self.rightfieldFrame = Frame(self.rootFrame) + self.leftfieldFrame.grid(row=0, column=0, sticky='nswe') + self.rightfieldFrame.grid(row=0, column=1, sticky='nswe') + + rowCount = 0 + externalInterfaces = [] + if 'externalInterfaces' in self.prefValues: + externalInterfaces = self.prefValues['externalInterfaces'] + + # Field for Hostname + Label(self.leftfieldFrame, text="Hostname:").grid(row=rowCount, sticky=E) + self.hostnameEntry = Entry(self.leftfieldFrame) + self.hostnameEntry.grid(row=rowCount, column=1) + self.hostnameEntry.insert(0, self.prefValues['hostname']) + rowCount+=1 + + # Field for DPID + Label(self.leftfieldFrame, text="DPID:").grid(row=rowCount, sticky=E) + self.dpidEntry = Entry(self.leftfieldFrame) + self.dpidEntry.grid(row=rowCount, column=1) + if 'dpid' in self.prefValues: + self.dpidEntry.insert(0, self.prefValues['dpid']) + rowCount+=1 + + # Field for Netflow + Label(self.leftfieldFrame, text="Enable NetFlow:").grid(row=rowCount, sticky=E) + self.nflow = IntVar() + self.nflowButton = Checkbutton(self.leftfieldFrame, variable=self.nflow) + self.nflowButton.grid(row=rowCount, column=1, sticky=W) + if 'netflow' in self.prefValues: + if self.prefValues['netflow'] == '0': + self.nflowButton.deselect() + else: + self.nflowButton.select() + else: + self.nflowButton.deselect() + rowCount+=1 + + # Field for sflow + Label(self.leftfieldFrame, text="Enable sFlow:").grid(row=rowCount, sticky=E) + self.sflow = IntVar() + self.sflowButton = Checkbutton(self.leftfieldFrame, variable=self.sflow) + self.sflowButton.grid(row=rowCount, column=1, sticky=W) + if 'sflow' in self.prefValues: + if self.prefValues['sflow'] == '0': + self.sflowButton.deselect() + else: + self.sflowButton.select() + else: + self.sflowButton.deselect() + rowCount+=1 + + # Selection of switch type + Label(self.leftfieldFrame, text="Switch Type:").grid(row=rowCount, sticky=E) + self.switchType = StringVar(self.leftfieldFrame) + self.switchTypeMenu = OptionMenu(self.leftfieldFrame, self.switchType, "Default", "Open vSwitch Kernel Mode", "Indigo Virtual Switch", "Userspace Switch", "Userspace Switch inNamespace") + self.switchTypeMenu.grid(row=rowCount, column=1, sticky=W) + if 'switchType' in self.prefValues: switchTypePref = self.prefValues['switchType'] if switchTypePref == 'ivs': self.switchType.set("Indigo Virtual Switch") @@ -199,583 +680,115 @@ class PrefsDialog(tkSimpleDialog.Dialog): self.switchType.set("Userspace Switch inNamespace") elif switchTypePref == 'user': self.switchType.set("Userspace Switch") - else: + elif switchTypePref == 'ovs': self.switchType.set("Open vSwitch Kernel Mode") - - - # Fields for OVS OpenFlow version - ovsFrame= LabelFrame(self.leftfieldFrame, text='Open vSwitch', padx=5, pady=5) - ovsFrame.grid(row=4, column=0, columnspan=2, sticky=EW) - Label(ovsFrame, text="OpenFlow 1.0:").grid(row=0, sticky=E) - Label(ovsFrame, text="OpenFlow 1.1:").grid(row=1, sticky=E) - Label(ovsFrame, text="OpenFlow 1.2:").grid(row=2, sticky=E) - Label(ovsFrame, text="OpenFlow 1.3:").grid(row=3, sticky=E) - - self.ovsOf10 = IntVar() - self.covsOf10 = Checkbutton(ovsFrame, variable=self.ovsOf10) - self.covsOf10.grid(row=0, column=1, sticky=W) - if self.prefValues['openFlowVersions']['ovsOf10'] == '0': - self.covsOf10.deselect() - else: - self.covsOf10.select() - - self.ovsOf11 = IntVar() - self.covsOf11 = Checkbutton(ovsFrame, variable=self.ovsOf11) - self.covsOf11.grid(row=1, column=1, sticky=W) - if self.prefValues['openFlowVersions']['ovsOf11'] == '0': - self.covsOf11.deselect() - else: - self.covsOf11.select() - - self.ovsOf12 = IntVar() - self.covsOf12 = Checkbutton(ovsFrame, variable=self.ovsOf12) - self.covsOf12.grid(row=2, column=1, sticky=W) - if self.prefValues['openFlowVersions']['ovsOf12'] == '0': - self.covsOf12.deselect() - else: - self.covsOf12.select() - - self.ovsOf13 = IntVar() - self.covsOf13 = Checkbutton(ovsFrame, variable=self.ovsOf13) - self.covsOf13.grid(row=3, column=1, sticky=W) - if self.prefValues['openFlowVersions']['ovsOf13'] == '0': - self.covsOf13.deselect() - else: - self.covsOf13.select() - - # Field for DPCTL listen port - Label(self.leftfieldFrame, text="dpctl port:").grid(row=5, sticky=E) - self.dpctlEntry = Entry(self.leftfieldFrame) - self.dpctlEntry.grid(row=5, column=1) - if 'dpctl' in self.prefValues: - self.dpctlEntry.insert(0, self.prefValues['dpctl']) - - # sFlow - sflowValues = self.prefValues['sflow'] - self.sflowFrame= LabelFrame(self.rightfieldFrame, text='sFlow Profile for Open vSwitch', padx=5, pady=5) - self.sflowFrame.grid(row=0, column=0, columnspan=2, sticky=EW) - - Label(self.sflowFrame, text="Target:").grid(row=0, sticky=E) - self.sflowTarget = Entry(self.sflowFrame) - self.sflowTarget.grid(row=0, column=1) - self.sflowTarget.insert(0, sflowValues['sflowTarget']) - - Label(self.sflowFrame, text="Sampling:").grid(row=1, sticky=E) - self.sflowSampling = Entry(self.sflowFrame) - self.sflowSampling.grid(row=1, column=1) - self.sflowSampling.insert(0, sflowValues['sflowSampling']) - - Label(self.sflowFrame, text="Header:").grid(row=2, sticky=E) - self.sflowHeader = Entry(self.sflowFrame) - self.sflowHeader.grid(row=2, column=1) - self.sflowHeader.insert(0, sflowValues['sflowHeader']) - - Label(self.sflowFrame, text="Polling:").grid(row=3, sticky=E) - self.sflowPolling = Entry(self.sflowFrame) - self.sflowPolling.grid(row=3, column=1) - self.sflowPolling.insert(0, sflowValues['sflowPolling']) - - # NetFlow - nflowValues = self.prefValues['netflow'] - self.nFrame= LabelFrame(self.rightfieldFrame, text='NetFlow Profile for Open vSwitch', padx=5, pady=5) - self.nFrame.grid(row=1, column=0, columnspan=2, sticky=EW) - - Label(self.nFrame, text="Target:").grid(row=0, sticky=E) - self.nflowTarget = Entry(self.nFrame) - self.nflowTarget.grid(row=0, column=1) - self.nflowTarget.insert(0, nflowValues['nflowTarget']) - - Label(self.nFrame, text="Active Timeout:").grid(row=1, sticky=E) - self.nflowTimeout = Entry(self.nFrame) - self.nflowTimeout.grid(row=1, column=1) - self.nflowTimeout.insert(0, nflowValues['nflowTimeout']) - - Label(self.nFrame, text="Add ID to Interface:").grid(row=2, sticky=E) - self.nflowAddId = IntVar() - self.nflowAddIdButton = Checkbutton(self.nFrame, variable=self.nflowAddId) - self.nflowAddIdButton.grid(row=2, column=1, sticky=W) - if nflowValues['nflowAddId'] == '0': - self.nflowAddIdButton.deselect() - else: - self.nflowAddIdButton.select() - - # initial focus - return self.ipEntry - - def apply(self): - ipBase = self.ipEntry.get() - terminalType = self.terminalVar.get() - startCLI = str(self.cliStart.get()) - sw = self.switchType.get() - dpctl = self.dpctlEntry.get() - - ovsOf10 = str(self.ovsOf10.get()) - ovsOf11 = str(self.ovsOf11.get()) - ovsOf12 = str(self.ovsOf12.get()) - ovsOf13 = str(self.ovsOf13.get()) - - sflowValues = {'sflowTarget':self.sflowTarget.get(), - 'sflowSampling':self.sflowSampling.get(), - 'sflowHeader':self.sflowHeader.get(), - 'sflowPolling':self.sflowPolling.get()} - nflowvalues = {'nflowTarget':self.nflowTarget.get(), - 'nflowTimeout':self.nflowTimeout.get(), - 'nflowAddId':str(self.nflowAddId.get())} - self.result = {'ipBase':ipBase, - 'terminalType':terminalType, - 'dpctl':dpctl, - 'sflow':sflowValues, - 'netflow':nflowvalues, - 'startCLI':startCLI} - if sw == 'Indigo Virtual Switch': - self.result['switchType'] = 'ivs' - if StrictVersion(MININET_VERSION) < StrictVersion('2.1'): - self.ovsOk = False - showerror(title="Error", - message='MiniNet version 2.1+ required. You have '+VERSION+'.') - elif sw == 'Userspace Switch': - self.result['switchType'] = 'user' - elif sw == 'Userspace Switch inNamespace': - self.result['switchType'] = 'userns' - else: - self.result['switchType'] = 'ovs' - - self.ovsOk = True - if ovsOf11 == "1": - ovsVer = self.getOvsVersion() - if StrictVersion(ovsVer) < StrictVersion('2.0'): - self.ovsOk = False - showerror(title="Error", - message='Open vSwitch version 2.0+ required. You have '+ovsVer+'.') - if ovsOf12 == "1" or ovsOf13 == "1": - ovsVer = self.getOvsVersion() - if StrictVersion(ovsVer) < StrictVersion('1.10'): - self.ovsOk = False - showerror(title="Error", - message='Open vSwitch version 1.10+ required. You have '+ovsVer+'.') - - if self.ovsOk: - self.result['openFlowVersions']={'ovsOf10':ovsOf10, - 'ovsOf11':ovsOf11, - 'ovsOf12':ovsOf12, - 'ovsOf13':ovsOf13} - else: - self.result = None - - def getOvsVersion(self): - outp = quietRun("ovs-vsctl show") - r = r'ovs_version: "(.*)"' - m = re.search(r, outp) - if m is None: - print 'Version check failed' - return None - else: - print 'Open vSwitch version is '+m.group(1) - return m.group(1) - - -class CustomDialog(object): - - # TODO: Fix button placement and Title and window focus lock - def __init__(self, master, title): - self.top=Toplevel(master) - - self.bodyFrame = Frame(self.top) - self.bodyFrame.grid(row=0, column=0, sticky='nswe') - self.body(self.bodyFrame) - - #return self.b # initial focus - buttonFrame = Frame(self.top, relief='ridge', bd=3, bg='lightgrey') - buttonFrame.grid(row=1 , column=0, sticky='nswe') - - okButton = Button(buttonFrame, width=8, text='OK', relief='groove', - bd=4, command=self.okAction) - okButton.grid(row=0, column=0, sticky=E) - - canlceButton = Button(buttonFrame, width=8, text='Cancel', relief='groove', - bd=4, command=self.cancelAction) - canlceButton.grid(row=0, column=1, sticky=W) - - def body(self, master): - self.rootFrame = master - - def apply(self): - self.top.destroy() - - def cancelAction(self): - self.top.destroy() - - def okAction(self): - self.apply() - self.top.destroy() - -class HostDialog(CustomDialog): - - def __init__(self, master, title, prefDefaults): - - self.prefValues = prefDefaults - self.result = None - - CustomDialog.__init__(self, master, title) - - def body(self, master): - self.rootFrame = master - n = Notebook(self.rootFrame) - self.propFrame = Frame(n) - self.vlanFrame = Frame(n) - self.interfaceFrame = Frame(n) - self.mountFrame = Frame(n) - n.add(self.propFrame, text='Properties') - n.add(self.vlanFrame, text='VLAN Interfaces') - n.add(self.interfaceFrame, text='External Interfaces') - n.add(self.mountFrame, text='Private Directories') - n.pack() - - ### TAB 1 - # Field for Hostname - Label(self.propFrame, text="Hostname:").grid(row=0, sticky=E) - self.hostnameEntry = Entry(self.propFrame) - self.hostnameEntry.grid(row=0, column=1) - if 'hostname' in self.prefValues: - self.hostnameEntry.insert(0, self.prefValues['hostname']) - - # Field for Switch IP - Label(self.propFrame, text="IP Address:").grid(row=1, sticky=E) - self.ipEntry = Entry(self.propFrame) - self.ipEntry.grid(row=1, column=1) - if 'ip' in self.prefValues: - self.ipEntry.insert(0, self.prefValues['ip']) - - # Field for default route - Label(self.propFrame, text="Default Route:").grid(row=2, sticky=E) - self.routeEntry = Entry(self.propFrame) - self.routeEntry.grid(row=2, column=1) - if 'defaultRoute' in self.prefValues: - self.routeEntry.insert(0, self.prefValues['defaultRoute']) - - # Field for CPU - Label(self.propFrame, text="Amount CPU:").grid(row=3, sticky=E) - self.cpuEntry = Entry(self.propFrame) - self.cpuEntry.grid(row=3, column=1) - if 'cpu' in self.prefValues: - self.cpuEntry.insert(0, str(self.prefValues['cpu'])) - # Selection of Scheduler - if 'sched' in self.prefValues: - sched = self.prefValues['sched'] - else: - sched = 'host' - self.schedVar = StringVar(self.propFrame) - self.schedOption = OptionMenu(self.propFrame, self.schedVar, "host", "cfs", "rt") - self.schedOption.grid(row=3, column=2, sticky=W) - self.schedVar.set(sched) - - # Selection of Cores - Label(self.propFrame, text="Cores:").grid(row=4, sticky=E) - self.coreEntry = Entry(self.propFrame) - self.coreEntry.grid(row=4, column=1) - if 'cores' in self.prefValues: - self.coreEntry.insert(1, self.prefValues['cores']) - - # Start command - Label(self.propFrame, text="Start Command:").grid(row=5, sticky=E) - self.startEntry = Entry(self.propFrame) - self.startEntry.grid(row=5, column=1, sticky='nswe', columnspan=3) - if 'startCommand' in self.prefValues: - self.startEntry.insert(0, str(self.prefValues['startCommand'])) - # Stop command - Label(self.propFrame, text="Stop Command:").grid(row=6, sticky=E) - self.stopEntry = Entry(self.propFrame) - self.stopEntry.grid(row=6, column=1, sticky='nswe', columnspan=3) - if 'stopCommand' in self.prefValues: - self.stopEntry.insert(0, str(self.prefValues['stopCommand'])) - - ### TAB 2 - # External Interfaces - self.externalInterfaces = 0 - Label(self.interfaceFrame, text="External Interface:").grid(row=0, column=0, sticky=E) - self.b = Button( self.interfaceFrame, text='Add', command=self.addInterface) - self.b.grid(row=0, column=1) - - self.interfaceFrame = VerticalScrolledTable(self.interfaceFrame, rows=0, columns=1, title='External Interfaces') - self.interfaceFrame.grid(row=1, column=0, sticky='nswe', columnspan=2) - self.tableFrame = self.interfaceFrame.interior - self.tableFrame.addRow(value=['Interface Name'], readonly=True) - - # Add defined interfaces - externalInterfaces = [] - if 'externalInterfaces' in self.prefValues: - externalInterfaces = self.prefValues['externalInterfaces'] - - for externalInterface in externalInterfaces: - self.tableFrame.addRow(value=[externalInterface]) - - ### TAB 3 - # VLAN Interfaces - self.vlanInterfaces = 0 - Label(self.vlanFrame, text="VLAN Interface:").grid(row=0, column=0, sticky=E) - self.vlanButton = Button( self.vlanFrame, text='Add', command=self.addVlanInterface) - self.vlanButton.grid(row=0, column=1) - - self.vlanFrame = VerticalScrolledTable(self.vlanFrame, rows=0, columns=2, title='VLAN Interfaces') - self.vlanFrame.grid(row=1, column=0, sticky='nswe', columnspan=2) - self.vlanTableFrame = self.vlanFrame.interior - self.vlanTableFrame.addRow(value=['IP Address','VLAN ID'], readonly=True) - - vlanInterfaces = [] - if 'vlanInterfaces' in self.prefValues: - vlanInterfaces = self.prefValues['vlanInterfaces'] - for vlanInterface in vlanInterfaces: - self.vlanTableFrame.addRow(value=vlanInterface) - - ### TAB 4 - # Private Directories - self.privateDirectories = 0 - Label(self.mountFrame, text="Private Directory:").grid(row=0, column=0, sticky=E) - self.mountButton = Button( self.mountFrame, text='Add', command=self.addDirectory) - self.mountButton.grid(row=0, column=1) - - self.mountFrame = VerticalScrolledTable(self.mountFrame, rows=0, columns=2, title='Directories') - self.mountFrame.grid(row=1, column=0, sticky='nswe', columnspan=2) - self.mountTableFrame = self.mountFrame.interior - self.mountTableFrame.addRow(value=['Mount','Persistent Directory'], readonly=True) - - directoryList = [] - if 'privateDirectory' in self.prefValues: - directoryList = self.prefValues['privateDirectory'] - for privateDir in directoryList: - if isinstance( privateDir, tuple ): - self.mountTableFrame.addRow(value=privateDir) - else: - self.mountTableFrame.addRow(value=[privateDir,'']) - - - def addDirectory( self ): - self.mountTableFrame.addRow() - - def addVlanInterface( self ): - self.vlanTableFrame.addRow() - - def addInterface( self ): - self.tableFrame.addRow() - - def apply(self): - externalInterfaces = [] - for row in range(self.tableFrame.rows): - if (len(self.tableFrame.get(row, 0)) > 0 and - row > 0): - externalInterfaces.append(self.tableFrame.get(row, 0)) - vlanInterfaces = [] - for row in range(self.vlanTableFrame.rows): - if (len(self.vlanTableFrame.get(row, 0)) > 0 and - len(self.vlanTableFrame.get(row, 1)) > 0 and - row > 0): - vlanInterfaces.append([self.vlanTableFrame.get(row, 0), self.vlanTableFrame.get(row, 1)]) - privateDirectories = [] - for row in range(self.mountTableFrame.rows): - if (len(self.mountTableFrame.get(row, 0)) > 0 and row > 0): - if(len(self.mountTableFrame.get(row, 1)) > 0): - privateDirectories.append((self.mountTableFrame.get(row, 0), self.mountTableFrame.get(row, 1))) - else: - privateDirectories.append(self.mountTableFrame.get(row, 0)) - - results = {'cpu': self.cpuEntry.get(), - 'cores':self.coreEntry.get(), - 'sched':self.schedVar.get(), - 'hostname':self.hostnameEntry.get(), - 'ip':self.ipEntry.get(), - 'defaultRoute':self.routeEntry.get(), - 'startCommand':self.startEntry.get(), - 'stopCommand':self.stopEntry.get(), - 'privateDirectory':privateDirectories, - 'externalInterfaces':externalInterfaces, - 'vlanInterfaces':vlanInterfaces} - self.result = results - -class SwitchDialog(CustomDialog): - - def __init__(self, master, title, prefDefaults): - - self.prefValues = prefDefaults - self.result = None - CustomDialog.__init__(self, master, title) - - def body(self, master): - self.rootFrame = master - self.leftfieldFrame = Frame(self.rootFrame) - self.rightfieldFrame = Frame(self.rootFrame) - self.leftfieldFrame.grid(row=0, column=0, sticky='nswe') - self.rightfieldFrame.grid(row=0, column=1, sticky='nswe') - - rowCount = 0 - externalInterfaces = [] - if 'externalInterfaces' in self.prefValues: - externalInterfaces = self.prefValues['externalInterfaces'] - - # Field for Hostname - Label(self.leftfieldFrame, text="Hostname:").grid(row=rowCount, sticky=E) - self.hostnameEntry = Entry(self.leftfieldFrame) - self.hostnameEntry.grid(row=rowCount, column=1) - self.hostnameEntry.insert(0, self.prefValues['hostname']) - rowCount+=1 - - # Field for DPID - Label(self.leftfieldFrame, text="DPID:").grid(row=rowCount, sticky=E) - self.dpidEntry = Entry(self.leftfieldFrame) - self.dpidEntry.grid(row=rowCount, column=1) - if 'dpid' in self.prefValues: - self.dpidEntry.insert(0, self.prefValues['dpid']) - rowCount+=1 - - # Field for Netflow - Label(self.leftfieldFrame, text="Enable NetFlow:").grid(row=rowCount, sticky=E) - self.nflow = IntVar() - self.nflowButton = Checkbutton(self.leftfieldFrame, variable=self.nflow) - self.nflowButton.grid(row=rowCount, column=1, sticky=W) - if 'netflow' in self.prefValues: - if self.prefValues['netflow'] == '0': - self.nflowButton.deselect() - else: - self.nflowButton.select() - else: - self.nflowButton.deselect() - rowCount+=1 - - # Field for sflow - Label(self.leftfieldFrame, text="Enable sFlow:").grid(row=rowCount, sticky=E) - self.sflow = IntVar() - self.sflowButton = Checkbutton(self.leftfieldFrame, variable=self.sflow) - self.sflowButton.grid(row=rowCount, column=1, sticky=W) - if 'sflow' in self.prefValues: - if self.prefValues['sflow'] == '0': - self.sflowButton.deselect() - else: - self.sflowButton.select() - else: - self.sflowButton.deselect() - rowCount+=1 - - # Selection of switch type - Label(self.leftfieldFrame, text="Switch Type:").grid(row=rowCount, sticky=E) - self.switchType = StringVar(self.leftfieldFrame) - self.switchTypeMenu = OptionMenu(self.leftfieldFrame, self.switchType, "Default", "Open vSwitch Kernel Mode", "Indigo Virtual Switch", "Userspace Switch", "Userspace Switch inNamespace") - self.switchTypeMenu.grid(row=rowCount, column=1, sticky=W) - if 'switchType' in self.prefValues: - switchTypePref = self.prefValues['switchType'] - if switchTypePref == 'ivs': - self.switchType.set("Indigo Virtual Switch") - elif switchTypePref == 'userns': - self.switchType.set("Userspace Switch inNamespace") - elif switchTypePref == 'user': - self.switchType.set("Userspace Switch") - elif switchTypePref == 'ovs': - self.switchType.set("Open vSwitch Kernel Mode") - else: - self.switchType.set("Default") else: self.switchType.set("Default") - rowCount+=1 + else: + self.switchType.set("Default") + rowCount+=1 - # Field for Switch IP - Label(self.leftfieldFrame, text="IP Address:").grid(row=rowCount, sticky=E) - self.ipEntry = Entry(self.leftfieldFrame) - self.ipEntry.grid(row=rowCount, column=1) - if 'switchIP' in self.prefValues: - self.ipEntry.insert(0, self.prefValues['switchIP']) - rowCount+=1 + # Field for Switch IP + Label(self.leftfieldFrame, text="IP Address:").grid(row=rowCount, sticky=E) + self.ipEntry = Entry(self.leftfieldFrame) + self.ipEntry.grid(row=rowCount, column=1) + if 'switchIP' in self.prefValues: + self.ipEntry.insert(0, self.prefValues['switchIP']) + rowCount+=1 - # Field for DPCTL port - Label(self.leftfieldFrame, text="DPCTL port:").grid(row=rowCount, sticky=E) - self.dpctlEntry = Entry(self.leftfieldFrame) - self.dpctlEntry.grid(row=rowCount, column=1) - if 'dpctl' in self.prefValues: - self.dpctlEntry.insert(0, self.prefValues['dpctl']) - rowCount+=1 + # Field for DPCTL port + Label(self.leftfieldFrame, text="DPCTL port:").grid(row=rowCount, sticky=E) + self.dpctlEntry = Entry(self.leftfieldFrame) + self.dpctlEntry.grid(row=rowCount, column=1) + if 'dpctl' in self.prefValues: + self.dpctlEntry.insert(0, self.prefValues['dpctl']) + rowCount+=1 - # External Interfaces - Label(self.rightfieldFrame, text="External Interface:").grid(row=0, sticky=E) - self.b = Button( self.rightfieldFrame, text='Add', command=self.addInterface) - self.b.grid(row=0, column=1) + # External Interfaces + Label(self.rightfieldFrame, text="External Interface:").grid(row=0, sticky=E) + self.b = Button( self.rightfieldFrame, text='Add', command=self.addInterface) + self.b.grid(row=0, column=1) - self.interfaceFrame = VerticalScrolledTable(self.rightfieldFrame, rows=0, columns=1, title='External Interfaces') - self.interfaceFrame.grid(row=1, column=0, sticky='nswe', columnspan=2) - self.tableFrame = self.interfaceFrame.interior + self.interfaceFrame = VerticalScrolledTable(self.rightfieldFrame, rows=0, columns=1, title='External Interfaces') + self.interfaceFrame.grid(row=1, column=0, sticky='nswe', columnspan=2) + self.tableFrame = self.interfaceFrame.interior - # Add defined interfaces - for externalInterface in externalInterfaces: - self.tableFrame.addRow(value=[externalInterface]) + # Add defined interfaces + for externalInterface in externalInterfaces: + self.tableFrame.addRow(value=[externalInterface]) - self.commandFrame = Frame(self.rootFrame) - self.commandFrame.grid(row=1, column=0, sticky='nswe', columnspan=2) - self.commandFrame.columnconfigure(1, weight=1) - # Start command - Label(self.commandFrame, text="Start Command:").grid(row=0, column=0, sticky=W) - self.startEntry = Entry(self.commandFrame) - self.startEntry.grid(row=0, column=1, sticky='nsew') - if 'startCommand' in self.prefValues: - self.startEntry.insert(0, str(self.prefValues['startCommand'])) - # Stop command - Label(self.commandFrame, text="Stop Command:").grid(row=1, column=0, sticky=W) - self.stopEntry = Entry(self.commandFrame) - self.stopEntry.grid(row=1, column=1, sticky='nsew') - if 'stopCommand' in self.prefValues: - self.stopEntry.insert(0, str(self.prefValues['stopCommand'])) + self.commandFrame = Frame(self.rootFrame) + self.commandFrame.grid(row=1, column=0, sticky='nswe', columnspan=2) + self.commandFrame.columnconfigure(1, weight=1) + # Start command + Label(self.commandFrame, text="Start Command:").grid(row=0, column=0, sticky=W) + self.startEntry = Entry(self.commandFrame) + self.startEntry.grid(row=0, column=1, sticky='nsew') + if 'startCommand' in self.prefValues: + self.startEntry.insert(0, str(self.prefValues['startCommand'])) + # Stop command + Label(self.commandFrame, text="Stop Command:").grid(row=1, column=0, sticky=W) + self.stopEntry = Entry(self.commandFrame) + self.stopEntry.grid(row=1, column=1, sticky='nsew') + if 'stopCommand' in self.prefValues: + self.stopEntry.insert(0, str(self.prefValues['stopCommand'])) - def addInterface( self ): - self.tableFrame.addRow() + def addInterface( self ): + self.tableFrame.addRow() - def defaultDpid( self ,name): - "Derive dpid from switch name, s1 -> 1" - try: - dpid = int( re.findall( r'\d+', name )[ 0 ] ) - dpid = hex( dpid )[ 2: ] - return dpid - except IndexError: - return None - #raise Exception( 'Unable to derive default datapath ID - ' - # 'please either specify a dpid or use a ' - # 'canonical switch name such as s23.' ) + def defaultDpid( self ,name): + "Derive dpid from switch name, s1 -> 1" + try: + dpid = int( re.findall( r'\d+', name )[ 0 ] ) + dpid = hex( dpid )[ 2: ] + return dpid + except IndexError: + return None + #raise Exception( 'Unable to derive default datapath ID - ' + # 'please either specify a dpid or use a ' + # 'canonical switch name such as s23.' ) - def apply(self): - externalInterfaces = [] - for row in range(self.tableFrame.rows): - #print 'Interface is ' + self.tableFrame.get(row, 0) - if (len(self.tableFrame.get(row, 0)) > 0): - externalInterfaces.append(self.tableFrame.get(row, 0)) + def apply(self): + externalInterfaces = [] + for row in range(self.tableFrame.rows): + #print 'Interface is ' + self.tableFrame.get(row, 0) + if len(self.tableFrame.get(row, 0)) > 0: + externalInterfaces.append(self.tableFrame.get(row, 0)) - dpid = self.dpidEntry.get() - if (self.defaultDpid(self.hostnameEntry.get()) is None - and len(dpid) == 0): + dpid = self.dpidEntry.get() + if (self.defaultDpid(self.hostnameEntry.get()) is None + and len(dpid) == 0): + showerror(title="Error", + message= 'Unable to derive default datapath ID - ' + 'please either specify a DPID or use a ' + 'canonical switch name such as s23.' ) + + + results = {'externalInterfaces':externalInterfaces, + 'hostname':self.hostnameEntry.get(), + 'dpid':dpid, + 'startCommand':self.startEntry.get(), + 'stopCommand':self.stopEntry.get(), + 'sflow':str(self.sflow.get()), + 'netflow':str(self.nflow.get()), + 'dpctl':self.dpctlEntry.get(), + 'switchIP':self.ipEntry.get()} + sw = self.switchType.get() + if sw == 'Indigo Virtual Switch': + results['switchType'] = 'ivs' + if StrictVersion(MININET_VERSION) < StrictVersion('2.1'): + self.ovsOk = False showerror(title="Error", - message= 'Unable to derive default datapath ID - ' - 'please either specify a DPID or use a ' - 'canonical switch name such as s23.' ) - - - results = {'externalInterfaces':externalInterfaces, - 'hostname':self.hostnameEntry.get(), - 'dpid':dpid, - 'startCommand':self.startEntry.get(), - 'stopCommand':self.stopEntry.get(), - 'sflow':str(self.sflow.get()), - 'netflow':str(self.nflow.get()), - 'dpctl':self.dpctlEntry.get(), - 'switchIP':self.ipEntry.get()} - sw = self.switchType.get() - if sw == 'Indigo Virtual Switch': - results['switchType'] = 'ivs' - if StrictVersion(MININET_VERSION) < StrictVersion('2.1'): - self.ovsOk = False - showerror(title="Error", - message='MiniNet version 2.1+ required. You have '+VERSION+'.') - elif sw == 'Userspace Switch inNamespace': - results['switchType'] = 'userns' - elif sw == 'Userspace Switch': - results['switchType'] = 'user' - elif sw == 'Open vSwitch Kernel Mode': - results['switchType'] = 'ovs' - else: - results['switchType'] = 'default' - self.result = results + message='MiniNet version 2.1+ required. You have '+VERSION+'.') + elif sw == 'Userspace Switch inNamespace': + results['switchType'] = 'userns' + elif sw == 'Userspace Switch': + results['switchType'] = 'user' + elif sw == 'Open vSwitch Kernel Mode': + results['switchType'] = 'ovs' + else: + results['switchType'] = 'default' + self.result = results class VerticalScrolledTable(LabelFrame): @@ -809,11 +822,11 @@ class VerticalScrolledTable(LabelFrame): # track changes to the canvas and frame width and sync them, # also updating the scrollbar def _configure_interior(event): - # update the scrollbars to match the size of the inner frame + # update the scrollbars to match the size of the inner frame size = (interior.winfo_reqwidth(), interior.winfo_reqheight()) canvas.config(scrollregion="0 0 %s %s" % size) if interior.winfo_reqwidth() != canvas.winfo_width(): - # update the canvas's width to fit the inner frame + # update the canvas's width to fit the inner frame canvas.config(width=interior.winfo_reqwidth()) interior.bind('', _configure_interior) @@ -856,7 +869,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 == True: label.configure(state='readonly') current_row.append(label) self._widgets.append(current_row) @@ -865,159 +878,159 @@ class TableFrame(Frame): class LinkDialog(tkSimpleDialog.Dialog): - def __init__(self, parent, title, linkDefaults): + def __init__(self, parent, title, linkDefaults): - self.linkValues = linkDefaults + self.linkValues = linkDefaults - tkSimpleDialog.Dialog.__init__(self, parent, title) + tkSimpleDialog.Dialog.__init__(self, parent, title) - def body(self, master): + def body(self, master): - self.var = StringVar(master) - Label(master, text="Bandwidth:").grid(row=0, sticky=E) - self.e1 = Entry(master) - self.e1.grid(row=0, column=1) - Label(master, text="Mbit").grid(row=0, column=2, sticky=W) - if 'bw' in self.linkValues: - self.e1.insert(0,str(self.linkValues['bw'])) + self.var = StringVar(master) + Label(master, text="Bandwidth:").grid(row=0, sticky=E) + self.e1 = Entry(master) + self.e1.grid(row=0, column=1) + Label(master, text="Mbit").grid(row=0, column=2, sticky=W) + if 'bw' in self.linkValues: + self.e1.insert(0,str(self.linkValues['bw'])) - Label(master, text="Delay:").grid(row=1, sticky=E) - self.e2 = Entry(master) - self.e2.grid(row=1, column=1) - if 'delay' in self.linkValues: - self.e2.insert(0, self.linkValues['delay']) + Label(master, text="Delay:").grid(row=1, sticky=E) + self.e2 = Entry(master) + self.e2.grid(row=1, column=1) + if 'delay' in self.linkValues: + self.e2.insert(0, self.linkValues['delay']) - Label(master, text="Loss:").grid(row=2, sticky=E) - self.e3 = Entry(master) - self.e3.grid(row=2, column=1) - Label(master, text="%").grid(row=2, column=2, sticky=W) - if 'loss' in self.linkValues: - self.e3.insert(0, str(self.linkValues['loss'])) + Label(master, text="Loss:").grid(row=2, sticky=E) + self.e3 = Entry(master) + self.e3.grid(row=2, column=1) + Label(master, text="%").grid(row=2, column=2, sticky=W) + if 'loss' in self.linkValues: + self.e3.insert(0, str(self.linkValues['loss'])) - Label(master, text="Max Queue size:").grid(row=3, sticky=E) - self.e4 = Entry(master) - self.e4.grid(row=3, column=1) - if 'max_queue_size' in self.linkValues: - self.e4.insert(0, str(self.linkValues['max_queue_size'])) + Label(master, text="Max Queue size:").grid(row=3, sticky=E) + self.e4 = Entry(master) + self.e4.grid(row=3, column=1) + if 'max_queue_size' in self.linkValues: + self.e4.insert(0, str(self.linkValues['max_queue_size'])) - Label(master, text="Jitter:").grid(row=4, sticky=E) - self.e5 = Entry(master) - self.e5.grid(row=4, column=1) - if 'jitter' in self.linkValues: - self.e5.insert(0, self.linkValues['jitter']) + Label(master, text="Jitter:").grid(row=4, sticky=E) + self.e5 = Entry(master) + self.e5.grid(row=4, column=1) + if 'jitter' in self.linkValues: + self.e5.insert(0, self.linkValues['jitter']) - Label(master, text="Speedup:").grid(row=5, sticky=E) - self.e6 = Entry(master) - self.e6.grid(row=5, column=1) - if 'speedup' in self.linkValues: - self.e6.insert(0, str(self.linkValues['speedup'])) + Label(master, text="Speedup:").grid(row=5, sticky=E) + self.e6 = Entry(master) + self.e6.grid(row=5, column=1) + if 'speedup' in self.linkValues: + self.e6.insert(0, str(self.linkValues['speedup'])) - return self.e1 # initial focus + return self.e1 # initial focus - def apply(self): - self.result = {} - if (len(self.e1.get()) > 0): - self.result['bw'] = int(self.e1.get()) - if (len(self.e2.get()) > 0): - self.result['delay'] = self.e2.get() - if (len(self.e3.get()) > 0): - self.result['loss'] = int(self.e3.get()) - if (len(self.e4.get()) > 0): - self.result['max_queue_size'] = int(self.e4.get()) - if (len(self.e5.get()) > 0): - self.result['jitter'] = self.e5.get() - if (len(self.e6.get()) > 0): - self.result['speedup'] = int(self.e6.get()) + def apply(self): + self.result = {} + if len(self.e1.get()) > 0: + self.result['bw'] = int(self.e1.get()) + if len(self.e2.get()) > 0: + self.result['delay'] = self.e2.get() + if len(self.e3.get()) > 0: + self.result['loss'] = int(self.e3.get()) + if len(self.e4.get()) > 0: + self.result['max_queue_size'] = int(self.e4.get()) + if len(self.e5.get()) > 0: + self.result['jitter'] = self.e5.get() + if len(self.e6.get()) > 0: + self.result['speedup'] = int(self.e6.get()) class ControllerDialog(tkSimpleDialog.Dialog): - def __init__(self, parent, title, ctrlrDefaults=None): + def __init__(self, parent, title, ctrlrDefaults=None): - if ctrlrDefaults: - self.ctrlrValues = ctrlrDefaults + if ctrlrDefaults: + self.ctrlrValues = ctrlrDefaults - tkSimpleDialog.Dialog.__init__(self, parent, title) + tkSimpleDialog.Dialog.__init__(self, parent, title) - def body(self, master): + def body(self, master): - self.var = StringVar(master) - self.protcolvar = StringVar(master) + self.var = StringVar(master) + self.protcolvar = StringVar(master) - rowCount=0 - # Field for Hostname - Label(master, text="Name:").grid(row=rowCount, sticky=E) - self.hostnameEntry = Entry(master) - self.hostnameEntry.grid(row=rowCount, column=1) - self.hostnameEntry.insert(0, self.ctrlrValues['hostname']) - rowCount+=1 + rowCount=0 + # Field for Hostname + Label(master, text="Name:").grid(row=rowCount, sticky=E) + self.hostnameEntry = Entry(master) + self.hostnameEntry.grid(row=rowCount, column=1) + self.hostnameEntry.insert(0, self.ctrlrValues['hostname']) + rowCount+=1 - # Field for Remove Controller Port - Label(master, text="Controller Port:").grid(row=rowCount, sticky=E) - self.e2 = Entry(master) - self.e2.grid(row=rowCount, column=1) - self.e2.insert(0, self.ctrlrValues['remotePort']) - rowCount+=1 + # Field for Remove Controller Port + Label(master, text="Controller Port:").grid(row=rowCount, sticky=E) + self.e2 = Entry(master) + self.e2.grid(row=rowCount, column=1) + self.e2.insert(0, self.ctrlrValues['remotePort']) + rowCount+=1 - # Field for Controller Type - Label(master, text="Controller Type:").grid(row=rowCount, sticky=E) - controllerType = self.ctrlrValues['controllerType'] - self.o1 = OptionMenu(master, self.var, "Remote Controller", "In-Band Controller", "OpenFlow Reference", "OVS Controller") - self.o1.grid(row=rowCount, column=1, sticky=W) - if controllerType == 'ref': - self.var.set("OpenFlow Reference") - elif controllerType == 'inband': - self.var.set("In-Band Controller") - elif controllerType == 'remote': - self.var.set("Remote Controller") - else: - self.var.set("OVS Controller") - rowCount+=1 + # Field for Controller Type + Label(master, text="Controller Type:").grid(row=rowCount, sticky=E) + controllerType = self.ctrlrValues['controllerType'] + self.o1 = OptionMenu(master, self.var, "Remote Controller", "In-Band Controller", "OpenFlow Reference", "OVS Controller") + self.o1.grid(row=rowCount, column=1, sticky=W) + if controllerType == 'ref': + self.var.set("OpenFlow Reference") + elif controllerType == 'inband': + self.var.set("In-Band Controller") + elif controllerType == 'remote': + self.var.set("Remote Controller") + else: + self.var.set("OVS Controller") + rowCount+=1 - # Field for Controller Protcol - Label(master, text="Protocol:").grid(row=rowCount, sticky=E) - if 'controllerProtocol' in self.ctrlrValues: - controllerProtocol = self.ctrlrValues['controllerProtocol'] - else: - controllerProtocol = 'tcp' - self.protcol = OptionMenu(master, self.protcolvar, "TCP", "SSL") - self.protcol.grid(row=rowCount, column=1, sticky=W) - if controllerProtocol == 'ssl': - self.protcolvar.set("SSL") - else: - self.protcolvar.set("TCP") - rowCount+=1 + # Field for Controller Protcol + Label(master, text="Protocol:").grid(row=rowCount, sticky=E) + if 'controllerProtocol' in self.ctrlrValues: + controllerProtocol = self.ctrlrValues['controllerProtocol'] + else: + controllerProtocol = 'tcp' + self.protcol = OptionMenu(master, self.protcolvar, "TCP", "SSL") + self.protcol.grid(row=rowCount, column=1, sticky=W) + if controllerProtocol == 'ssl': + self.protcolvar.set("SSL") + else: + self.protcolvar.set("TCP") + rowCount+=1 - # Field for Remove Controller IP - remoteFrame= LabelFrame(master, text='Remote/In-Band Controller', padx=5, pady=5) - remoteFrame.grid(row=rowCount, column=0, columnspan=2, sticky=W) + # Field for Remove Controller IP + remoteFrame= LabelFrame(master, text='Remote/In-Band Controller', padx=5, pady=5) + remoteFrame.grid(row=rowCount, column=0, columnspan=2, sticky=W) - Label(remoteFrame, text="IP Address:").grid(row=0, sticky=E) - self.e1 = Entry(remoteFrame) - self.e1.grid(row=0, column=1) - self.e1.insert(0, self.ctrlrValues['remoteIP']) - rowCount+=1 + Label(remoteFrame, text="IP Address:").grid(row=0, sticky=E) + self.e1 = Entry(remoteFrame) + self.e1.grid(row=0, column=1) + self.e1.insert(0, self.ctrlrValues['remoteIP']) + rowCount+=1 - return self.hostnameEntry # initial focus + return self.hostnameEntry # initial focus - def apply(self): - self.result = { 'hostname': self.hostnameEntry.get(), - 'remoteIP': self.e1.get(), - 'remotePort': int(self.e2.get())} + def apply(self): + self.result = { 'hostname': self.hostnameEntry.get(), + 'remoteIP': self.e1.get(), + 'remotePort': int(self.e2.get())} - controllerType = self.var.get() - if controllerType == 'Remote Controller': - self.result['controllerType'] = 'remote' - elif controllerType == 'In-Band Controller': - self.result['controllerType'] = 'inband' - elif controllerType == 'OpenFlow Reference': - self.result['controllerType'] = 'ref' - else: - self.result['controllerType'] = 'ovsc' - controllerProtocol = self.protcolvar.get() - if controllerProtocol == 'SSL': - self.result['controllerProtocol'] = 'ssl' - else: - self.result['controllerProtocol'] = 'tcp' + controllerType = self.var.get() + if controllerType == 'Remote Controller': + self.result['controllerType'] = 'remote' + elif controllerType == 'In-Band Controller': + self.result['controllerType'] = 'inband' + elif controllerType == 'OpenFlow Reference': + self.result['controllerType'] = 'ref' + else: + self.result['controllerType'] = 'ovsc' + controllerProtocol = self.protcolvar.get() + if controllerProtocol == 'SSL': + self.result['controllerProtocol'] = 'ssl' + else: + self.result['controllerProtocol'] = 'tcp' class ToolTip(object): @@ -1427,8 +1440,8 @@ class MiniEdit( Frame ): self.appPrefs["netflow"] = self.nflowDefaults # Load controllers - if ('controllers' in loadedTopology): - if (loadedTopology['version'] == '1'): + if 'controllers' in loadedTopology: + if loadedTopology['version'] == '1': # This is old location of controller info hostname = 'c0' self.controllers = {} @@ -1509,7 +1522,7 @@ class MiniEdit( Frame ): self.switchOpts[hostname] = switch['opts'] # create links to controllers - if (int(loadedTopology['version']) > 1): + if int(loadedTopology['version']) > 1: controllers = self.switchOpts[hostname]['controllers'] for controller in controllers: dest = self.findWidgetByName(controller) @@ -1774,7 +1787,7 @@ class MiniEdit( Frame ): if 'dpid' in opts: f.write(", dpid='"+opts['dpid']+"'") f.write(")\n") - if ('externalInterfaces' in opts): + if 'externalInterfaces' in opts: for extInterface in opts['externalInterfaces']: f.write(" Intf( '"+extInterface+"', node="+name+" )\n") @@ -1806,7 +1819,7 @@ class MiniEdit( Frame ): f.write(" "+name+".setCPUFrac(f="+str(opts['cpu'])+", sched='"+opts['sched']+"')\n") else: f.write(" "+name+" = net.addHost('"+name+"', cls=Host, ip='"+ip+"', defaultRoute="+defaultRoute+")\n") - if ('externalInterfaces' in opts): + if 'externalInterfaces' in opts: for extInterface in opts['externalInterfaces']: f.write(" Intf( '"+extInterface+"', node="+name+" )\n") f.write("\n") @@ -1814,56 +1827,56 @@ class MiniEdit( Frame ): # Save Links f.write(" info( '*** Add links\\n')\n") for key,linkDetail in self.links.iteritems(): - tags = self.canvas.gettags(key) - if 'data' in tags: - optsExist = False - src = linkDetail['src'] - dst = linkDetail['dest'] - linkopts = linkDetail['linkOpts'] - srcName, dstName = src[ 'text' ], dst[ 'text' ] - bw = '' - # delay = '' - # loss = '' - # max_queue_size = '' - linkOpts = "{" - if 'bw' in linkopts: - bw = linkopts['bw'] - linkOpts = linkOpts + "'bw':"+str(bw) - optsExist = True - if 'delay' in linkopts: - # delay = linkopts['delay'] - if optsExist: - linkOpts = linkOpts + "," - linkOpts = linkOpts + "'delay':'"+linkopts['delay']+"'" - optsExist = True - if 'loss' in linkopts: - if optsExist: - linkOpts = linkOpts + "," - linkOpts = linkOpts + "'loss':"+str(linkopts['loss']) - optsExist = True - if 'max_queue_size' in linkopts: - if optsExist: - linkOpts = linkOpts + "," - linkOpts = linkOpts + "'max_queue_size':"+str(linkopts['max_queue_size']) - optsExist = True - if 'jitter' in linkopts: - if optsExist: - linkOpts = linkOpts + "," - linkOpts = linkOpts + "'jitter':'"+linkopts['jitter']+"'" - optsExist = True - if 'speedup' in linkopts: - if optsExist: - linkOpts = linkOpts + "," - linkOpts = linkOpts + "'speedup':"+str(linkopts['speedup']) - optsExist = True + tags = self.canvas.gettags(key) + if 'data' in tags: + optsExist = False + src = linkDetail['src'] + dst = linkDetail['dest'] + linkopts = linkDetail['linkOpts'] + srcName, dstName = src[ 'text' ], dst[ 'text' ] + bw = '' + # delay = '' + # loss = '' + # max_queue_size = '' + linkOpts = "{" + if 'bw' in linkopts: + bw = linkopts['bw'] + linkOpts = linkOpts + "'bw':"+str(bw) + optsExist = True + if 'delay' in linkopts: + # delay = linkopts['delay'] + if optsExist: + linkOpts = linkOpts + "," + linkOpts = linkOpts + "'delay':'"+linkopts['delay']+"'" + optsExist = True + if 'loss' in linkopts: + if optsExist: + linkOpts = linkOpts + "," + linkOpts = linkOpts + "'loss':"+str(linkopts['loss']) + optsExist = True + if 'max_queue_size' in linkopts: + if optsExist: + linkOpts = linkOpts + "," + linkOpts = linkOpts + "'max_queue_size':"+str(linkopts['max_queue_size']) + optsExist = True + if 'jitter' in linkopts: + if optsExist: + linkOpts = linkOpts + "," + linkOpts = linkOpts + "'jitter':'"+linkopts['jitter']+"'" + optsExist = True + if 'speedup' in linkopts: + if optsExist: + linkOpts = linkOpts + "," + linkOpts = linkOpts + "'speedup':"+str(linkopts['speedup']) + optsExist = True - linkOpts = linkOpts + "}" - if optsExist: - f.write(" "+srcName+dstName+" = "+linkOpts+"\n") - f.write(" net.addLink("+srcName+", "+dstName) - if optsExist: - f.write(", cls=TCLink , **"+srcName+dstName) - f.write(")\n") + linkOpts = linkOpts + "}" + if optsExist: + f.write(" "+srcName+dstName+" = "+linkOpts+"\n") + f.write(" net.addLink("+srcName+", "+dstName) + if optsExist: + f.write(", cls=TCLink , **"+srcName+dstName) + f.write(")\n") f.write("\n") f.write(" info( '*** Starting network\\n')\n") @@ -1893,28 +1906,28 @@ class MiniEdit( Frame ): opts = self.switchOpts[name] if opts['switchType'] == 'default': if self.appPrefs['switchType'] == 'user': - if ('switchIP' in opts): - if (len(opts['switchIP'])>0): + if 'switchIP' in opts: + if len(opts['switchIP']) > 0: f.write(" "+name+".cmd('ifconfig "+name+" "+opts['switchIP']+"')\n") elif self.appPrefs['switchType'] == 'userns': - if ('switchIP' in opts): - if (len(opts['switchIP'])>0): + if 'switchIP' in opts: + if len(opts['switchIP']) > 0: f.write(" "+name+".cmd('ifconfig lo "+opts['switchIP']+"')\n") elif self.appPrefs['switchType'] == 'ovs': - if ('switchIP' in opts): - if (len(opts['switchIP'])>0): + if 'switchIP' in opts: + if len(opts['switchIP']) > 0: f.write(" "+name+".cmd('ifconfig "+name+" "+opts['switchIP']+"')\n") elif opts['switchType'] == 'user': - if ('switchIP' in opts): - if (len(opts['switchIP'])>0): + if 'switchIP' in opts: + if len(opts['switchIP']) > 0: f.write(" "+name+".cmd('ifconfig "+name+" "+opts['switchIP']+"')\n") elif opts['switchType'] == 'userns': - if ('switchIP' in opts): - if (len(opts['switchIP'])>0): + if 'switchIP' in opts: + if len(opts['switchIP']) > 0: f.write(" "+name+".cmd('ifconfig lo "+opts['switchIP']+"')\n") elif opts['switchType'] == 'ovs': - if ('switchIP' in opts): - if (len(opts['switchIP'])>0): + if 'switchIP' in opts: + if len(opts['switchIP']) > 0: f.write(" "+name+".cmd('ifconfig "+name+" "+opts['switchIP']+"')\n") for widget in self.widgetToItem: name = widget[ 'text' ] @@ -1922,17 +1935,17 @@ class MiniEdit( Frame ): if 'Host' in tags: opts = self.hostOpts[name] # Attach vlan interfaces - if ('vlanInterfaces' in opts): + if 'vlanInterfaces' in opts: for vlanInterface in opts['vlanInterfaces']: f.write(" "+name+".cmd('vconfig add "+name+"-eth0 "+vlanInterface[1]+"')\n") f.write(" "+name+".cmd('ifconfig "+name+"-eth0."+vlanInterface[1]+" "+vlanInterface[0]+"')\n") # Run User Defined Start Command - if ('startCommand' in opts): + if 'startCommand' in opts: f.write(" "+name+".cmdPrint('"+opts['startCommand']+"')\n") if 'Switch' in tags: opts = self.switchOpts[name] # Run User Defined Start Command - if ('startCommand' in opts): + if 'startCommand' in opts: f.write(" "+name+".cmdPrint('"+opts['startCommand']+"')\n") # Configure NetFlow @@ -1987,12 +2000,12 @@ class MiniEdit( Frame ): if 'Host' in tags: opts = self.hostOpts[name] # Run User Defined Stop Command - if ('stopCommand' in opts): + if 'stopCommand' in opts: f.write(" "+name+".cmdPrint('"+opts['stopCommand']+"')\n") if 'Switch' in tags: opts = self.switchOpts[name] # Run User Defined Stop Command - if ('stopCommand' in opts): + if 'stopCommand' in opts: f.write(" "+name+".cmdPrint('"+opts['stopCommand']+"')\n") f.write(" net.stop()\n") @@ -2598,7 +2611,7 @@ class MiniEdit( Frame ): if name not in self.net.nameToNode: return if 'Switch' in tags or 'LegacySwitch' in tags: - call(["xterm -T 'Bridge Details' -sb -sl 2000 -e 'ovs-vsctl list bridge " + name + "; read -p \"Press Enter to close\"' &"], shell=True) + call(["xterm -T 'Bridge Details' -sb -sl 2000 -e 'ovs-vsctl list bridge " + name + "; read -p \"Press Enter to close\"' &"], shell=True) def ovsShow( self, _ignore=None ): call(["xterm -T 'OVS Summary' -sb -sl 2000 -e 'ovs-vsctl show; read -p \"Press Enter to close\"' &"], shell=True) @@ -2725,19 +2738,19 @@ class MiniEdit( Frame ): # Some post startup config if switchClass == CustomUserSwitch: - if ('switchIP' in opts): - if (len(opts['switchIP']) > 0): + if 'switchIP' in opts: + if len(opts['switchIP']) > 0: newSwitch.setSwitchIP(opts['switchIP']) if switchClass == customOvs: - if ('switchIP' in opts): - if (len(opts['switchIP']) > 0): + if 'switchIP' in opts: + if len(opts['switchIP']) > 0: newSwitch.setSwitchIP(opts['switchIP']) # Attach external interfaces - if ('externalInterfaces' in opts): + if 'externalInterfaces' in opts: for extInterface in opts['externalInterfaces']: if self.checkIntf(extInterface): - Intf( extInterface, node=newSwitch ) + Intf( extInterface, node=newSwitch ) elif 'LegacySwitch' in tags: newSwitch = net.addSwitch( name , cls=LegacySwitch) @@ -2759,13 +2772,13 @@ class MiniEdit( Frame ): # Create the correct host class if 'cores' in opts or 'cpu' in opts: - if ('privateDirectory' in opts): + if 'privateDirectory' in opts: hostCls = partial( CPULimitedHost, privateDirs=opts['privateDirectory'] ) else: hostCls=CPULimitedHost else: - if ('privateDirectory' in opts): + if 'privateDirectory' in opts: hostCls = partial( Host, privateDirs=opts['privateDirectory'] ) else: @@ -2784,11 +2797,11 @@ class MiniEdit( Frame ): newHost.setCPUFrac(f=opts['cpu'], sched=opts['sched']) # Attach external interfaces - if ('externalInterfaces' in opts): + if 'externalInterfaces' in opts: for extInterface in opts['externalInterfaces']: if self.checkIntf(extInterface): - Intf( extInterface, node=newHost ) - if ('vlanInterfaces' in opts): + Intf( extInterface, node=newHost ) + if 'vlanInterfaces' in opts: if len(opts['vlanInterfaces']) > 0: print 'Checking that OS is VLAN prepared' self.pathCheck('vconfig', moduleName='vlan package') @@ -2894,18 +2907,18 @@ class MiniEdit( Frame ): newHost = self.net.get(name) opts = self.hostOpts[name] # Attach vlan interfaces - if ('vlanInterfaces' in opts): + if 'vlanInterfaces' in opts: for vlanInterface in opts['vlanInterfaces']: print 'adding vlan interface '+vlanInterface[1] newHost.cmdPrint('ifconfig '+name+'-eth0.'+vlanInterface[1]+' '+vlanInterface[0]) # Run User Defined Start Command - if ('startCommand' in opts): + if 'startCommand' in opts: newHost.cmdPrint(opts['startCommand']) if 'Switch' in tags: newNode = self.net.get(name) opts = self.switchOpts[name] # Run User Defined Start Command - if ('startCommand' in opts): + if 'startCommand' in opts: newNode.cmdPrint(opts['startCommand']) @@ -3018,13 +3031,13 @@ class MiniEdit( Frame ): newHost = self.net.get(name) opts = self.hostOpts[name] # Run User Defined Stop Command - if ('stopCommand' in opts): + if 'stopCommand' in opts: newHost.cmdPrint(opts['stopCommand']) if 'Switch' in tags: newNode = self.net.get(name) opts = self.switchOpts[name] # Run User Defined Stop Command - if ('stopCommand' in opts): + if 'stopCommand' in opts: newNode.cmdPrint(opts['stopCommand']) self.net.stop() @@ -3033,7 +3046,7 @@ class MiniEdit( Frame ): def do_linkPopup(self, event): # display the popup menu - if ( self.net is None ): + if self.net is None: try: self.linkPopup.tk_popup(event.x_root, event.y_root, 0) finally: @@ -3048,7 +3061,7 @@ class MiniEdit( Frame ): def do_controllerPopup(self, event): # display the popup menu - if ( self.net is None ): + if self.net is None: try: self.controllerPopup.tk_popup(event.x_root, event.y_root, 0) finally: @@ -3057,7 +3070,7 @@ class MiniEdit( Frame ): def do_legacyRouterPopup(self, event): # display the popup menu - if ( self.net is not None ): + if self.net is not None: try: self.legacyRouterRunPopup.tk_popup(event.x_root, event.y_root, 0) finally: @@ -3066,7 +3079,7 @@ class MiniEdit( Frame ): def do_hostPopup(self, event): # display the popup menu - if ( self.net is None ): + if self.net is None: try: self.hostPopup.tk_popup(event.x_root, event.y_root, 0) finally: @@ -3081,7 +3094,7 @@ class MiniEdit( Frame ): def do_legacySwitchPopup(self, event): # display the popup menu - if ( self.net is not None ): + if self.net is not None: try: self.switchRunPopup.tk_popup(event.x_root, event.y_root, 0) finally: @@ -3090,7 +3103,7 @@ class MiniEdit( Frame ): def do_switchPopup(self, event): # display the popup menu - if ( self.net is None ): + if self.net is None: try: self.switchPopup.tk_popup(event.x_root, event.y_root, 0) finally: diff --git a/examples/multilink.py b/examples/multilink.py index 90d070a..469bddb 100755 --- a/examples/multilink.py +++ b/examples/multilink.py @@ -11,7 +11,7 @@ from mininet.net import Mininet from mininet.topo import Topo def runMultiLink(): - + "Create and run multiple link network" topo = simpleMultiLinkTopo( n=2 ) net = Mininet( topo=topo ) net.start() @@ -19,6 +19,7 @@ def runMultiLink(): net.stop() class simpleMultiLinkTopo( Topo ): + "Simple topology with multiple links" def __init__( self, n, **kwargs ): Topo.__init__( self, **kwargs ) diff --git a/examples/natnet.py b/examples/natnet.py index ece1de4..33e4df3 100755 --- a/examples/natnet.py +++ b/examples/natnet.py @@ -27,7 +27,7 @@ from mininet.util import irange class InternetTopo(Topo): "Single switch connected to n hosts." - def __init__(self, n=2, h=1, **opts): + def __init__(self, n=2, **opts): Topo.__init__(self, **opts) # set up inet switch @@ -67,4 +67,3 @@ def run(): if __name__ == '__main__': setLogLevel('info') run() - diff --git a/examples/numberedports.py b/examples/numberedports.py index 2d4a231..68f5aaa 100755 --- a/examples/numberedports.py +++ b/examples/numberedports.py @@ -20,9 +20,12 @@ def validatePort( switch, intf ): else: return 1 -def net(): +def testPortNumbering(): - "Create a network with 5 hosts." + """Test port numbering: + Create a network with 5 hosts (using Mininet's + mid-level API) and check that implicit and + explicit port numbering works as expected.""" net = Mininet( controller=Controller ) @@ -45,18 +48,21 @@ def net(): net.addLink( h2, s1 ) net.addLink( h3, s1 ) net.addLink( h4, s1 ) - net.addLink( h5, s1, port1 = 1, port2 = 9 ) # specify a different port to connect host 5 to on the switch. + # specify a different port to connect host 5 to on the switch. + net.addLink( h5, s1, port1=1, port2= 9) info( '*** Starting network\n' ) net.start() # print the interfaces and their port numbers - info( '\n*** printing and validating the ports running on each interface\n' ) + info( '\n*** printing and validating the ports ' + 'running on each interface\n' ) for intfs in s1.intfList(): if not intfs.name == "lo": info( intfs, ': ', s1.ports[intfs], '\n' ) - info ( 'Validating that', intfs, 'is actually on port', s1.ports[intfs], '... ' ) + info ( 'Validating that', intfs, + 'is actually on port', s1.ports[intfs], '... ' ) if validatePort( s1, intfs ): info( 'Validated.\n' ) print '\n' @@ -70,5 +76,4 @@ def net(): if __name__ == '__main__': setLogLevel( 'info' ) - net() - + testPortNumbering() diff --git a/examples/sshd.py b/examples/sshd.py index 02d82a9..39107ec 100755 --- a/examples/sshd.py +++ b/examples/sshd.py @@ -81,6 +81,6 @@ if __name__ == '__main__': net = TreeNet( depth=1, fanout=4 ) # get sshd args from the command line or use default args # useDNS=no -u0 to avoid reverse DNS lookup timeout - opts = ' '.join( sys.argv[ 1: ] ) if len( sys.argv ) > 1 else ( + argvopts = ' '.join( sys.argv[ 1: ] ) if len( sys.argv ) > 1 else ( '-D -o UseDNS=no -u0' ) - sshd( net, opts=opts ) + sshd( net, opts=argvopts ) diff --git a/examples/vlanhost.py b/examples/vlanhost.py index 0ded83c..11d3831 100755 --- a/examples/vlanhost.py +++ b/examples/vlanhost.py @@ -35,7 +35,7 @@ class VLANHost( Host ): """Configure VLANHost according to (optional) parameters: vlan: VLAN ID for default interface""" - r = super( Host, self ).config( **params ) + r = super( VLANHost, self ).config( **params ) intf = self.defaultIntf() # remove IP from default, "physical" interface diff --git a/mininet/net.py b/mininet/net.py index 6e17184..832199f 100755 --- a/mininet/net.py +++ b/mininet/net.py @@ -727,10 +727,8 @@ class Mininet( object ): if not quietRun( 'which telnet' ): error( 'Cannot find telnet in $PATH - required for iperf test' ) return - if not hosts: - hosts = [ self.hosts[ 0 ], self.hosts[ -1 ] ] - else: - assert len( hosts ) == 2 + hosts = hosts or [ self.hosts[ 0 ], self.hosts[ -1 ] ] + assert len( hosts ) == 2 client, server = hosts output( '*** Iperf: testing ' + l4Type + ' bandwidth between ' ) output( "%s and %s\n" % ( client.name, server.name ) ) diff --git a/mininet/node.py b/mininet/node.py index 2cf2a4c..428a72d 100644 --- a/mininet/node.py +++ b/mininet/node.py @@ -888,8 +888,9 @@ class Switch( Node ): def connected( self ): "Is the switch connected to a controller? (override this method)" - raise NotImplementedError( "connected() needs to be implemented in" - " Switch subclass %s" % self.__class__ ) + warn( "Warning: connected() needs to be implemented in" + " Switch subclass %s\n" % self.__class__ ) + return True def __repr__( self ): "More informative string representation" @@ -1290,10 +1291,6 @@ 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 diff --git a/mininet/test/runner.py b/mininet/test/runner.py index b034f55..dcfff66 100755 --- a/mininet/test/runner.py +++ b/mininet/test/runner.py @@ -26,6 +26,6 @@ def runTests( testDir, verbosity=1 ): if __name__ == '__main__': setLogLevel( 'warning' ) # get the directory containing example tests - testDir = os.path.dirname( os.path.realpath( __file__ ) ) - verbosity = 2 if '-v' in sys.argv else 1 - runTests( testDir, verbosity ) + thisdir = os.path.dirname( os.path.realpath( __file__ ) ) + vlevel = 2 if '-v' in sys.argv else 1 + runTests( testDir=thisdir, verbosity=vlevel ) diff --git a/mininet/test/test_hifi.py b/mininet/test/test_hifi.py index c314630..dace8a6 100755 --- a/mininet/test/test_hifi.py +++ b/mininet/test/test_hifi.py @@ -42,7 +42,8 @@ class testOptionsTopoCommon( object ): switchClass = None # overridden in subclasses - def tearDown( self ): + @staticmethod + def tearDown(): "Clean up if necessary" if sys.exc_info != ( None, None, None ): cleanup() @@ -151,7 +152,7 @@ class testOptionsTopoCommon( object ): # As long as the kernel doesn't wait a long time before # delivering bytes to the iperf server, its reported data rate # should be close to the actual receive rate. - serverRate, clientRate = bw_strs + serverRate, _clientRate = bw_strs bw = float( serverRate.split(' ')[0] ) self.assertWithinTolerance( bw, BW, BW_TOLERANCE, msg ) diff --git a/mininet/test/test_nets.py b/mininet/test/test_nets.py index 97c4148..5b44207 100755 --- a/mininet/test/test_nets.py +++ b/mininet/test/test_nets.py @@ -23,7 +23,8 @@ class testSingleSwitchCommon( object ): switchClass = None # overridden in subclasses - def tearDown( self ): + @staticmethod + def tearDown(): "Clean up if necessary" if sys.exc_info != ( None, None, None ): cleanup() @@ -74,7 +75,8 @@ class testLinearCommon( object ): def testLinear5( self ): "Ping test on a 5-switch topology" - mn = Mininet( LinearTopo( k=5 ), self.switchClass, Host, Controller, waitConnected=True ) + mn = Mininet( LinearTopo( k=5 ), self.switchClass, Host, + Controller, waitConnected=True ) dropped = mn.run( mn.ping ) self.assertEqual( dropped, 0 ) diff --git a/mininet/test/test_walkthrough.py b/mininet/test/test_walkthrough.py index f7f143a..cf7194d 100755 --- a/mininet/test/test_walkthrough.py +++ b/mininet/test/test_walkthrough.py @@ -19,6 +19,9 @@ def tsharkVersion(): versionMatch = re.findall( r'TShark \d+.\d+.\d+', versionStr )[0] return versionMatch.split()[ 1 ] +# pylint doesn't understand pexpect.match, unfortunately! +# pylint:disable=maybe-no-member + class testWalkthrough( unittest.TestCase ): "Test Mininet walkthrough" @@ -33,7 +36,7 @@ class testWalkthrough( unittest.TestCase ): def testWireshark( self ): "Use tshark to test the of dissector" - # Satisfy pylint: + # Satisfy pylint assert self if StrictVersion( tsharkVersion() ) < StrictVersion( '1.12.0' ): tshark = pexpect.spawn( 'tshark -i lo -R of' ) @@ -78,7 +81,8 @@ class testWalkthrough( unittest.TestCase ): node = p.match.group( 1 ) actual.append( node ) p.expect( '\n' ) - self.assertEqual( actual.sort(), nodes.sort(), '"nodes" and "dump" differ' ) + self.assertEqual( actual.sort(), nodes.sort(), + '"nodes" and "dump" differ' ) p.expect( self.prompt ) p.sendline( 'exit' ) p.wait() @@ -202,7 +206,8 @@ class testWalkthrough( unittest.TestCase ): p.expect( self.prompt ) # test delay p.sendline( 'h1 ping -c 4 h2' ) - p.expect( r'rtt min/avg/max/mdev = ([\d\.]+)/([\d\.]+)/([\d\.]+)/([\d\.]+) ms' ) + p.expect( r'rtt min/avg/max/mdev = ' + r'([\d\.]+)/([\d\.]+)/([\d\.]+)/([\d\.]+) ms' ) delay = float( p.match.group( 2 ) ) self.assertTrue( delay > 40, 'Delay < 40ms' ) self.assertTrue( delay < 45, 'Delay > 40ms' ) @@ -226,10 +231,13 @@ class testWalkthrough( unittest.TestCase ): def testCustomTopo( self ): "Start Mininet using a custom topo, then run pingall" + # Satisfy pylint + assert self custom = os.path.dirname( os.path.realpath( __file__ ) ) custom = os.path.join( custom, '../../custom/topo-2sw-2host.py' ) custom = os.path.normpath( custom ) - p = pexpect.spawn( 'mn --custom %s --topo mytopo --test pingall' % custom ) + p = pexpect.spawn( + 'mn --custom %s --topo mytopo --test pingall' % custom ) p.expect( '0% dropped' ) p.expect( pexpect.EOF ) @@ -331,11 +339,15 @@ class testWalkthrough( unittest.TestCase ): 'Github is not reachable; cannot download Pox' ) def testRemoteController( self ): "Test Mininet using Pox controller" + # Satisfy pylint + assert self if not os.path.exists( '/tmp/pox' ): - p = pexpect.spawn( 'git clone https://github.com/noxrepo/pox.git /tmp/pox' ) + p = pexpect.spawn( + 'git clone https://github.com/noxrepo/pox.git /tmp/pox' ) p.expect( pexpect.EOF ) pox = pexpect.spawn( '/tmp/pox/pox.py forwarding.l2_learning' ) - net = pexpect.spawn( 'mn --controller=remote,ip=127.0.0.1,port=6633 --test pingall' ) + net = pexpect.spawn( + 'mn --controller=remote,ip=127.0.0.1,port=6633 --test pingall' ) net.expect( '0% dropped' ) net.expect( pexpect.EOF ) pox.sendintr() diff --git a/mininet/util.py b/mininet/util.py index 6334649..32aa591 100644 --- a/mininet/util.py +++ b/mininet/util.py @@ -427,6 +427,7 @@ def fixLimits(): sysctlTestAndSet( 'net.ipv4.route.max_size', 32768 ) #Increase number of PTYs for nodes sysctlTestAndSet( 'kernel.pty.max', 20000 ) + # pylint: disable=broad-except except Exception: warn( "*** Error setting resource limits. " "Mininet's performance may be affected.\n" ) @@ -549,6 +550,7 @@ def waitListening( client=None, server='127.0.0.1', port=80, timeout=None ): partial( quietRun, shell=True ) ) if not runCmd( 'which telnet' ): raise Exception('Could not find telnet' ) + # pylint: disable=maybe-no-member serverIP = server if isinstance( server, basestring ) else server.IP() cmd = ( 'sh -c "echo A | telnet -e A %s %s"' % ( serverIP, port ) )