Revision 18aab5b7

View differences:

examples/cluster.py
123 123
           **kwargs: see Node()"""
124 124
        # We connect to servers by IP address
125 125
        self.server = server if server else 'localhost'
126
        self.serverIP = serverIP if serverIP else self.findServerIP( self.server )
126
        self.serverIP = ( serverIP if serverIP
127
                          else self.findServerIP( self.server ) )
127 128
        self.user = user if user else self.findUser()
128 129
        if controlPath is True:
129 130
            # Set a default control path for shared SSH connections
......
143 144
            self.dest = None
144 145
            self.sshcmd = []
145 146
            self.isRemote = False
147
        # Satisfy pylint
148
        self.shell, self.pid, self.cmd = None, None, None
146 149
        super( RemoteMixin, self ).__init__( name, **kwargs )
147 150

  
148 151
    @staticmethod
149 152
    def findUser():
150 153
        "Try to return logged-in (usually non-root) user"
151
        try:
154
        return (
152 155
            # If we're running sudo
153
            return os.environ[ 'SUDO_USER' ]
154
        except:
155
            try:
156
                # Logged-in user (if we have a tty)
157
                return quietRun( 'who am i' ).split()[ 0 ]
158
            except:
159
                # Give up and return effective user
160
                return quietRun( 'whoami' )
156
            os.environ.get( 'SUDO_USER', False ) or
157
            # Logged-in user (if we have a tty)
158
            ( quietRun( 'who am i' ).split() or [ False ] )[ 0 ] or
159
            # Give up and return effective user
160
            quietRun( 'whoami' ) )
161 161

  
162 162
    # Determine IP address of local host
163 163
    _ipMatchRegex = re.compile( r'\d+\.\d+\.\d+\.\d+' )
......
187 187
            self.pid = int( self.cmd( 'echo $$' ) )
188 188

  
189 189
    def finishInit( self ):
190
        "Wait for split initialization to complete"
191
        assert self  # please pylint
190 192
        self.pid = int( self.waitOutput() )
191 193

  
192 194
    def rpopen( self, *cmd, **opts ):
......
282 284
        cls = type( self )
283 285
        if self.server not in cls.OVSVersions:
284 286
            vers = self.cmd( 'ovs-vsctl --version' )
285
            cls.OVSVersions[ self.server ] = re.findall( r'\d+\.\d+', vers )[ 0 ]
287
            cls.OVSVersions[ self.server ] = re.findall(
288
                r'\d+\.\d+', vers )[ 0 ]
286 289
        return ( StrictVersion( cls.OVSVersions[ self.server ] ) <
287 290
                StrictVersion( '1.10' ) )
288 291

  
......
301 304
        self.tunnel = None
302 305
        kwargs.setdefault( 'params1', {} )
303 306
        kwargs.setdefault( 'params2', {} )
307
        self.cmd = None  # satisfy pylint
304 308
        Link.__init__( self, node1, node2, **kwargs )
305 309

  
306 310
    def stop( self ):
......
324 328
        elif server1 == server2:
325 329
            # Remote link on same remote server
326 330
            return makeIntfPair( intfname1, intfname2, addr1, addr2,
327
                                 run=node1.rcmd )
331
                                 runCmd=node1.rcmd )
328 332
        # Otherwise, make a tunnel
329
        self.tunnel = self.makeTunnel( node1, node2, intfname1, intfname2, addr1, addr2 )
333
        self.tunnel = self.makeTunnel( node1, node2, intfname1, intfname2,
334
                                       addr1, addr2 )
330 335
        return self.tunnel
331 336

  
332 337
    @staticmethod
......
340 345
        cmd = 'ip link set %s netns %s' % ( intf, node.pid )
341 346
        node.rcmd( cmd )
342 347
        links = node.cmd( 'ip link show' )
343
        if not ( ' %s:' % intf ) in links:
348
        if not ' %s:' % intf in links:
344 349
            if printError:
345 350
                error( '*** Error: RemoteLink.moveIntf: ' + intf +
346 351
                      ' not successfully moved to ' + node.name + '\n' )
......
442 447

  
443 448
    def place( self, node ):
444 449
        "Return server for a given node"
450
        assert self, node  # satisfy pylint
445 451
        # Default placement: run locally
446
        return None
452
        return 'localhost'
447 453

  
448 454

  
449 455
class RandomPlacer( Placer ):
......
451 457
    def place( self, nodename ):
452 458
        """Random placement function
453 459
            nodename: node name"""
460
        assert nodename  # please pylint
454 461
        # This may be slow with lots of servers
455 462
        return self.servers[ randrange( 0, len( self.servers ) ) ]
456 463

  
......
467 474
    def place( self, nodename ):
468 475
        """Round-robin placement function
469 476
            nodename: node name"""
477
        assert nodename  # please pylint
470 478
        # This may be slow with lots of servers
471 479
        server = self.servers[ self.next ]
472 480
        self.next = ( self.next + 1 ) % len( self.servers )
......
626 634

  
627 635
    def popen( self, cmd ):
628 636
        "Popen() for server connections"
637
        assert self  # please pylint
629 638
        old = signal( SIGINT, SIG_IGN )
630 639
        conn = Popen( cmd, stdin=PIPE, stdout=PIPE, close_fds=True )
631 640
        signal( SIGINT, old )
......
649 658
            cmd = [ 'sudo', '-E', '-u', self.user ]
650 659
            cmd += self.sshcmd + [ '-n', dest, 'sudo true' ]
651 660
            debug( ' '.join( cmd ), '\n' )
652
            out, err, code = errRun( cmd )
661
            _out, _err, code = errRun( cmd )
653 662
            if code != 0:
654 663
                error( '\nstartConnection: server connection check failed '
655 664
                       'to %s using command:\n%s\n'
......
665 674

  
666 675
    def modifiedaddHost( self, *args, **kwargs ):
667 676
        "Slightly modify addHost"
677
        assert self  # please pylint
668 678
        kwargs[ 'splitInit' ] = True
669 679
        return Mininet.addHost( *args, **kwargs )
670 680

  
examples/clustercli.py
5 5
from mininet.cli import CLI
6 6
from mininet.log import output, error
7 7

  
8
# pylint: disable=global-statement
8 9
nx, graphviz_layout, plt = None, None, None  # Will be imported on demand
9 10

  
10 11

  
......
23 24
        colors = colors[ 0 : slen ]
24 25
        return colors
25 26

  
26
    def do_plot( self, line ):
27
    def do_plot( self, _line ):
27 28
        "Plot topology colored by node placement"
28 29
        # Import networkx if needed
29 30
        global nx, plt
30 31
        if not nx:
31 32
            try:
32
                import networkx as nx
33
                import matplotlib.pyplot as plt
33
                import networkx
34
                nx = networkx  # satisfy pylint
35
                from matplotlib import pyplot
36
                plt = pyplot   # satisfiy pylint
34 37
                import pygraphviz
35 38
                assert pygraphviz  # silence pyflakes
36
            except:
39
            except ImportError:
37 40
                error( 'plot requires networkx, matplotlib and pygraphviz - '
38 41
                       'please install them and try again\n' )
39 42
                return
......
53 56
        pos = nx.graphviz_layout( g )
54 57
        opts = { 'ax': None, 'font_weight': 'bold',
55 58
		 'width': 2, 'edge_color': 'darkblue' }
56
        hcolors = [ color[ getattr( h, 'server', 'localhost' ) ] for h in hosts ]
57
        scolors = [ color[ getattr( s, 'server', 'localhost' ) ] for s in switches ]
58
        nx.draw_networkx( g, pos=pos, nodelist=hosts, node_size=800, label='host',
59
                          node_color=hcolors, node_shape='s', **opts )
59
        hcolors = [ color[ getattr( h, 'server', 'localhost' ) ]
60
                    for h in hosts ]
61
        scolors = [ color[ getattr( s, 'server', 'localhost' ) ]
62
                    for s in switches ]
63
        nx.draw_networkx( g, pos=pos, nodelist=hosts, node_size=800,
64
                          label='host', node_color=hcolors, node_shape='s',
65
                          **opts )
60 66
        nx.draw_networkx( g, pos=pos, nodelist=switches, node_size=1000,
61 67
                          node_color=scolors, node_shape='o', **opts )
62 68
        # Get rid of axes, add title, and show
......
68 74
        plt.title( 'Node Placement', fontweight='bold' )
69 75
        plt.show()
70 76

  
71
    def do_status( self, line ):
77
    def do_status( self, _line ):
72 78
        "Report on node shell status"
73 79
        nodes = self.mn.hosts + self.mn.switches
74 80
        for node in nodes:
......
83 89
            output( 'All nodes are still running.\n' )
84 90

  
85 91

  
86
    def do_placement( self, line ):
92
    def do_placement( self, _line ):
87 93
        "Describe node placement"
88 94
        mn = self.mn
89 95
        nodes = mn.hosts + mn.switches + mn.controllers
examples/limit.py
27 27
        info( '*** Testing with', sched, 'bandwidth limiting\n' )
28 28
        if sched == 'rt':
29 29
            release = quietRun( 'uname -r' ).strip('\r\n')
30
            output = quietRun( 'grep CONFIG_RT_GROUP_SCHED /boot/config-%s' % release )
30
            output = quietRun( 'grep CONFIG_RT_GROUP_SCHED /boot/config-%s'
31
                               % release )
31 32
            if output == '# CONFIG_RT_GROUP_SCHED is not set\n':
32
                info( '*** RT Scheduler is not enabled in your kernel. Skipping this test\n' )
33
                info( '*** RT Scheduler is not enabled in your kernel. '
34
                      'Skipping this test\n' )
33 35
                continue
34 36
        host = custom( CPULimitedHost, sched=sched, cpu=cpu )
35 37
        net = Mininet( topo=myTopo, intf=intf, host=host )
examples/linuxrouter.py
44 44
class NetworkTopo( Topo ):
45 45
    "A simple topology of a router with three subnets (one host in each)."
46 46

  
47
    def build( self, n=2, h=1, **opts ):
47
    def build( self, **opts ):
48 48
        router = self.addNode( 'r0', cls=LinuxRouter, ip='192.168.1.1/24' )
49
        h1 = self.addHost( 'h1', ip='192.168.1.100/24', defaultRoute='via 192.168.1.1' )
50
        h2 = self.addHost( 'h2', ip='172.16.0.100/12', defaultRoute='via 172.16.0.1' )
51
        h3 = self.addHost( 'h3', ip='10.0.0.100/8', defaultRoute='via 10.0.0.1' )
52
        self.addLink( h1, router, intfName2='r0-eth1', params2={ 'ip' : '192.168.1.1/24' } )
53
        self.addLink( h2, router, intfName2='r0-eth2', params2={ 'ip' : '172.16.0.1/12' } )
54
        self.addLink( h3, router, intfName2='r0-eth3', params2={ 'ip' : '10.0.0.1/8' } )
49
        h1 = self.addHost( 'h1', ip='192.168.1.100/24',
50
                           defaultRoute='via 192.168.1.1' )
51
        h2 = self.addHost( 'h2', ip='172.16.0.100/12',
52
                           defaultRoute='via 172.16.0.1' )
53
        h3 = self.addHost( 'h3', ip='10.0.0.100/8',
54
                           defaultRoute='via 10.0.0.1' )
55
        self.addLink( h1, router, intfName2='r0-eth1',
56
                      params2={ 'ip' : '192.168.1.1/24' } )
57
        self.addLink( h2, router, intfName2='r0-eth2',
58
                      params2={ 'ip' : '172.16.0.1/12' } )
59
        self.addLink( h3, router, intfName2='r0-eth3',
60
                      params2={ 'ip' : '10.0.0.1/8' } )
55 61

  
56 62
def run():
63
    "Test linux router"
57 64
    topo = NetworkTopo()
58 65
    net = Mininet( topo=topo, controller=None ) # no controller needed
59 66
    net.start()
examples/miniedit.py
13 13
OpenFlow icon from https://www.opennetworking.org/
14 14
"""
15 15

  
16
# For now, tolerate long lines and long module
17
# pylint: disable=line-too-long,too-many-lines
18

  
16 19
MINIEDIT_VERSION = '2.2.0.1'
17 20

  
18 21
from optparse import OptionParser
......
83 86

  
84 87

  
85 88
class InbandController( RemoteController ):
86

  
89
    "RemoteController that ignores checkListening"
87 90
    def checkListening( self ):
88 91
        "Overridden to do nothing."
89 92
        return
90 93

  
91 94
class CustomUserSwitch(UserSwitch):
95
    "Customized UserSwitch"
92 96
    def __init__( self, name, dpopts='--no-slicing', **kwargs ):
93 97
        UserSwitch.__init__( self, name, **kwargs )
94 98
        self.switchIP = None
95 99

  
96 100
    def getSwitchIP(self):
101
        "Return management IP address"
97 102
        return self.switchIP
98 103

  
99 104
    def setSwitchIP(self, ip):
105
        "Set management IP address"
100 106
        self.switchIP = ip
101 107

  
102 108
    def start( self, controllers ):
109
        "Start and set management IP address"
103 110
        # Call superclass constructor
104 111
        UserSwitch.start( self, controllers )
105 112
        # Set Switch IP address
106
        if (self.switchIP is not None):
113
        if self.switchIP is not None:
107 114
            if not self.inNamespace:
108 115
                self.cmd( 'ifconfig', self, self.switchIP )
109 116
            else:
110 117
                self.cmd( 'ifconfig lo', self.switchIP )
111 118

  
112 119
class LegacyRouter( Node ):
113

  
120
    "Simple IP router"
114 121
    def __init__( self, name, inNamespace=True, **params ):
115 122
        Node.__init__( self, name, inNamespace, **params )
116 123

  
......
122 129
        return r
123 130

  
124 131
class LegacySwitch(OVSSwitch):
125

  
132
    "OVS switch in standalone/bridge mode"
126 133
    def __init__( self, name, **params ):
127 134
        OVSSwitch.__init__( self, name, failMode='standalone', **params )
128 135
        self.switchIP = None
129 136

  
130 137
class customOvs(OVSSwitch):
138
    "Customized OVS switch"
131 139

  
132 140
    def __init__( self, name, failMode='secure', datapath='kernel', **params ):
133 141
        OVSSwitch.__init__( self, name, failMode=failMode, datapath=datapath, **params )
134 142
        self.switchIP = None
135 143

  
136 144
    def getSwitchIP(self):
145
        "Return management IP address"
137 146
        return self.switchIP
138 147

  
139 148
    def setSwitchIP(self, ip):
149
        "Set management IP address"
140 150
        self.switchIP = ip
141 151

  
142 152
    def start( self, controllers ):
153
        "Start and set management IP address"
143 154
        # Call superclass constructor
144 155
        OVSSwitch.start( self, controllers )
145 156
        # Set Switch IP address
146
        if (self.switchIP is not None):
157
        if self.switchIP is not None:
147 158
            self.cmd( 'ifconfig', self, self.switchIP )
148 159

  
149 160
class PrefsDialog(tkSimpleDialog.Dialog):
161
    "Preferences dialog"
162

  
163
    def __init__(self, parent, title, prefDefaults):
164

  
165
        self.prefValues = prefDefaults
166

  
167
        tkSimpleDialog.Dialog.__init__(self, parent, title)
168

  
169
    def body(self, master):
170
        "Create dialog body"
171
        self.rootFrame = master
172
        self.leftfieldFrame = Frame(self.rootFrame, padx=5, pady=5)
173
        self.leftfieldFrame.grid(row=0, column=0, sticky='nswe', columnspan=2)
174
        self.rightfieldFrame = Frame(self.rootFrame, padx=5, pady=5)
175
        self.rightfieldFrame.grid(row=0, column=2, sticky='nswe', columnspan=2)
176

  
177
        # Field for Base IP
178
        Label(self.leftfieldFrame, text="IP Base:").grid(row=0, sticky=E)
179
        self.ipEntry = Entry(self.leftfieldFrame)
180
        self.ipEntry.grid(row=0, column=1)
181
        ipBase =  self.prefValues['ipBase']
182
        self.ipEntry.insert(0, ipBase)
183

  
184
        # Selection of terminal type
185
        Label(self.leftfieldFrame, text="Default Terminal:").grid(row=1, sticky=E)
186
        self.terminalVar = StringVar(self.leftfieldFrame)
187
        self.terminalOption = OptionMenu(self.leftfieldFrame, self.terminalVar, "xterm", "gterm")
188
        self.terminalOption.grid(row=1, column=1, sticky=W)
189
        terminalType = self.prefValues['terminalType']
190
        self.terminalVar.set(terminalType)
191

  
192
        # Field for CLI
193
        Label(self.leftfieldFrame, text="Start CLI:").grid(row=2, sticky=E)
194
        self.cliStart = IntVar()
195
        self.cliButton = Checkbutton(self.leftfieldFrame, variable=self.cliStart)
196
        self.cliButton.grid(row=2, column=1, sticky=W)
197
        if self.prefValues['startCLI'] == '0':
198
            self.cliButton.deselect()
199
        else:
200
            self.cliButton.select()
201

  
202
        # Selection of switch type
203
        Label(self.leftfieldFrame, text="Default Switch:").grid(row=3, sticky=E)
204
        self.switchType = StringVar(self.leftfieldFrame)
205
        self.switchTypeMenu = OptionMenu(self.leftfieldFrame, self.switchType, "Open vSwitch Kernel Mode", "Indigo Virtual Switch", "Userspace Switch", "Userspace Switch inNamespace")
206
        self.switchTypeMenu.grid(row=3, column=1, sticky=W)
207
        switchTypePref = self.prefValues['switchType']
208
        if switchTypePref == 'ivs':
209
            self.switchType.set("Indigo Virtual Switch")
210
        elif switchTypePref == 'userns':
211
            self.switchType.set("Userspace Switch inNamespace")
212
        elif switchTypePref == 'user':
213
            self.switchType.set("Userspace Switch")
214
        else:
215
            self.switchType.set("Open vSwitch Kernel Mode")
216

  
217

  
218
        # Fields for OVS OpenFlow version
219
        ovsFrame= LabelFrame(self.leftfieldFrame, text='Open vSwitch', padx=5, pady=5)
220
        ovsFrame.grid(row=4, column=0, columnspan=2, sticky=EW)
221
        Label(ovsFrame, text="OpenFlow 1.0:").grid(row=0, sticky=E)
222
        Label(ovsFrame, text="OpenFlow 1.1:").grid(row=1, sticky=E)
223
        Label(ovsFrame, text="OpenFlow 1.2:").grid(row=2, sticky=E)
224
        Label(ovsFrame, text="OpenFlow 1.3:").grid(row=3, sticky=E)
225

  
226
        self.ovsOf10 = IntVar()
227
        self.covsOf10 = Checkbutton(ovsFrame, variable=self.ovsOf10)
228
        self.covsOf10.grid(row=0, column=1, sticky=W)
229
        if self.prefValues['openFlowVersions']['ovsOf10'] == '0':
230
            self.covsOf10.deselect()
231
        else:
232
            self.covsOf10.select()
150 233

  
151
        def __init__(self, parent, title, prefDefaults):
152

  
153
            self.prefValues = prefDefaults
154

  
155
            tkSimpleDialog.Dialog.__init__(self, parent, title)
156

  
157
        def body(self, master):
158
            self.rootFrame = master
159
            self.leftfieldFrame = Frame(self.rootFrame, padx=5, pady=5)
160
            self.leftfieldFrame.grid(row=0, column=0, sticky='nswe', columnspan=2)
161
            self.rightfieldFrame = Frame(self.rootFrame, padx=5, pady=5)
162
            self.rightfieldFrame.grid(row=0, column=2, sticky='nswe', columnspan=2)
163

  
164

  
165
            # Field for Base IP
166
            Label(self.leftfieldFrame, text="IP Base:").grid(row=0, sticky=E)
167
            self.ipEntry = Entry(self.leftfieldFrame)
168
            self.ipEntry.grid(row=0, column=1)
169
            ipBase =  self.prefValues['ipBase']
170
            self.ipEntry.insert(0, ipBase)
171

  
172
            # Selection of terminal type
173
            Label(self.leftfieldFrame, text="Default Terminal:").grid(row=1, sticky=E)
174
            self.terminalVar = StringVar(self.leftfieldFrame)
175
            self.terminalOption = OptionMenu(self.leftfieldFrame, self.terminalVar, "xterm", "gterm")
176
            self.terminalOption.grid(row=1, column=1, sticky=W)
177
            terminalType = self.prefValues['terminalType']
178
            self.terminalVar.set(terminalType)
179

  
180
            # Field for CLI
181
            Label(self.leftfieldFrame, text="Start CLI:").grid(row=2, sticky=E)
182
            self.cliStart = IntVar()
183
            self.cliButton = Checkbutton(self.leftfieldFrame, variable=self.cliStart)
184
            self.cliButton.grid(row=2, column=1, sticky=W)
185
            if self.prefValues['startCLI'] == '0':
186
                self.cliButton.deselect()
187
            else:
188
                self.cliButton.select()
189

  
190
            # Selection of switch type
191
            Label(self.leftfieldFrame, text="Default Switch:").grid(row=3, sticky=E)
192
            self.switchType = StringVar(self.leftfieldFrame)
193
            self.switchTypeMenu = OptionMenu(self.leftfieldFrame, self.switchType, "Open vSwitch Kernel Mode", "Indigo Virtual Switch", "Userspace Switch", "Userspace Switch inNamespace")
194
            self.switchTypeMenu.grid(row=3, column=1, sticky=W)
195
            switchTypePref = self.prefValues['switchType']
196
            if switchTypePref == 'ivs':
197
                self.switchType.set("Indigo Virtual Switch")
198
            elif switchTypePref == 'userns':
199
                self.switchType.set("Userspace Switch inNamespace")
200
            elif switchTypePref == 'user':
201
                self.switchType.set("Userspace Switch")
202
            else:
203
                self.switchType.set("Open vSwitch Kernel Mode")
204

  
234
        self.ovsOf11 = IntVar()
235
        self.covsOf11 = Checkbutton(ovsFrame, variable=self.ovsOf11)
236
        self.covsOf11.grid(row=1, column=1, sticky=W)
237
        if self.prefValues['openFlowVersions']['ovsOf11'] == '0':
238
            self.covsOf11.deselect()
239
        else:
240
            self.covsOf11.select()
205 241

  
206
            # Fields for OVS OpenFlow version
207
            ovsFrame= LabelFrame(self.leftfieldFrame, text='Open vSwitch', padx=5, pady=5)
208
            ovsFrame.grid(row=4, column=0, columnspan=2, sticky=EW)
209
            Label(ovsFrame, text="OpenFlow 1.0:").grid(row=0, sticky=E)
210
            Label(ovsFrame, text="OpenFlow 1.1:").grid(row=1, sticky=E)
211
            Label(ovsFrame, text="OpenFlow 1.2:").grid(row=2, sticky=E)
212
            Label(ovsFrame, text="OpenFlow 1.3:").grid(row=3, sticky=E)
242
        self.ovsOf12 = IntVar()
243
        self.covsOf12 = Checkbutton(ovsFrame, variable=self.ovsOf12)
244
        self.covsOf12.grid(row=2, column=1, sticky=W)
245
        if self.prefValues['openFlowVersions']['ovsOf12'] == '0':
246
            self.covsOf12.deselect()
247
        else:
248
            self.covsOf12.select()
213 249

  
214
            self.ovsOf10 = IntVar()
215
            self.covsOf10 = Checkbutton(ovsFrame, variable=self.ovsOf10)
216
            self.covsOf10.grid(row=0, column=1, sticky=W)
217
            if self.prefValues['openFlowVersions']['ovsOf10'] == '0':
218
                self.covsOf10.deselect()
219
            else:
220
                self.covsOf10.select()
250
        self.ovsOf13 = IntVar()
251
        self.covsOf13 = Checkbutton(ovsFrame, variable=self.ovsOf13)
252
        self.covsOf13.grid(row=3, column=1, sticky=W)
253
        if self.prefValues['openFlowVersions']['ovsOf13'] == '0':
254
            self.covsOf13.deselect()
255
        else:
256
            self.covsOf13.select()
257

  
258
        # Field for DPCTL listen port
259
        Label(self.leftfieldFrame, text="dpctl port:").grid(row=5, sticky=E)
260
        self.dpctlEntry = Entry(self.leftfieldFrame)
261
        self.dpctlEntry.grid(row=5, column=1)
262
        if 'dpctl' in self.prefValues:
263
            self.dpctlEntry.insert(0, self.prefValues['dpctl'])
264

  
265
        # sFlow
266
        sflowValues = self.prefValues['sflow']
267
        self.sflowFrame= LabelFrame(self.rightfieldFrame, text='sFlow Profile for Open vSwitch', padx=5, pady=5)
268
        self.sflowFrame.grid(row=0, column=0, columnspan=2, sticky=EW)
269

  
270
        Label(self.sflowFrame, text="Target:").grid(row=0, sticky=E)
271
        self.sflowTarget = Entry(self.sflowFrame)
272
        self.sflowTarget.grid(row=0, column=1)
273
        self.sflowTarget.insert(0, sflowValues['sflowTarget'])
274

  
275
        Label(self.sflowFrame, text="Sampling:").grid(row=1, sticky=E)
276
        self.sflowSampling = Entry(self.sflowFrame)
277
        self.sflowSampling.grid(row=1, column=1)
278
        self.sflowSampling.insert(0, sflowValues['sflowSampling'])
279

  
280
        Label(self.sflowFrame, text="Header:").grid(row=2, sticky=E)
281
        self.sflowHeader = Entry(self.sflowFrame)
282
        self.sflowHeader.grid(row=2, column=1)
283
        self.sflowHeader.insert(0, sflowValues['sflowHeader'])
284

  
285
        Label(self.sflowFrame, text="Polling:").grid(row=3, sticky=E)
286
        self.sflowPolling = Entry(self.sflowFrame)
287
        self.sflowPolling.grid(row=3, column=1)
288
        self.sflowPolling.insert(0, sflowValues['sflowPolling'])
289

  
290
        # NetFlow
291
        nflowValues = self.prefValues['netflow']
292
        self.nFrame= LabelFrame(self.rightfieldFrame, text='NetFlow Profile for Open vSwitch', padx=5, pady=5)
293
        self.nFrame.grid(row=1, column=0, columnspan=2, sticky=EW)
294

  
295
        Label(self.nFrame, text="Target:").grid(row=0, sticky=E)
296
        self.nflowTarget = Entry(self.nFrame)
297
        self.nflowTarget.grid(row=0, column=1)
298
        self.nflowTarget.insert(0, nflowValues['nflowTarget'])
299

  
300
        Label(self.nFrame, text="Active Timeout:").grid(row=1, sticky=E)
301
        self.nflowTimeout = Entry(self.nFrame)
302
        self.nflowTimeout.grid(row=1, column=1)
303
        self.nflowTimeout.insert(0, nflowValues['nflowTimeout'])
304

  
305
        Label(self.nFrame, text="Add ID to Interface:").grid(row=2, sticky=E)
306
        self.nflowAddId = IntVar()
307
        self.nflowAddIdButton = Checkbutton(self.nFrame, variable=self.nflowAddId)
308
        self.nflowAddIdButton.grid(row=2, column=1, sticky=W)
309
        if nflowValues['nflowAddId'] == '0':
310
            self.nflowAddIdButton.deselect()
311
        else:
312
            self.nflowAddIdButton.select()
313

  
314
        # initial focus
315
        return self.ipEntry
316

  
317
    def apply(self):
318
        ipBase = self.ipEntry.get()
319
        terminalType = self.terminalVar.get()
320
        startCLI = str(self.cliStart.get())
321
        sw = self.switchType.get()
322
        dpctl = self.dpctlEntry.get()
323

  
324
        ovsOf10 = str(self.ovsOf10.get())
325
        ovsOf11 = str(self.ovsOf11.get())
326
        ovsOf12 = str(self.ovsOf12.get())
327
        ovsOf13 = str(self.ovsOf13.get())
328

  
329
        sflowValues = {'sflowTarget':self.sflowTarget.get(),
330
                       'sflowSampling':self.sflowSampling.get(),
331
                       'sflowHeader':self.sflowHeader.get(),
332
                       'sflowPolling':self.sflowPolling.get()}
333
        nflowvalues = {'nflowTarget':self.nflowTarget.get(),
334
                       'nflowTimeout':self.nflowTimeout.get(),
335
                       'nflowAddId':str(self.nflowAddId.get())}
336
        self.result = {'ipBase':ipBase,
337
                       'terminalType':terminalType,
338
                       'dpctl':dpctl,
339
                       'sflow':sflowValues,
340
                       'netflow':nflowvalues,
341
                       'startCLI':startCLI}
342
        if sw == 'Indigo Virtual Switch':
343
            self.result['switchType'] = 'ivs'
344
            if StrictVersion(MININET_VERSION) < StrictVersion('2.1'):
345
                self.ovsOk = False
346
                showerror(title="Error",
347
                          message='MiniNet version 2.1+ required. You have '+VERSION+'.')
348
        elif sw == 'Userspace Switch':
349
            self.result['switchType'] = 'user'
350
        elif sw == 'Userspace Switch inNamespace':
351
            self.result['switchType'] = 'userns'
352
        else:
353
            self.result['switchType'] = 'ovs'
221 354

  
222
            self.ovsOf11 = IntVar()
223
            self.covsOf11 = Checkbutton(ovsFrame, variable=self.ovsOf11)
224
            self.covsOf11.grid(row=1, column=1, sticky=W)
225
            if self.prefValues['openFlowVersions']['ovsOf11'] == '0':
226
                self.covsOf11.deselect()
227
            else:
228
                self.covsOf11.select()
355
        self.ovsOk = True
356
        if ovsOf11 == "1":
357
            ovsVer = self.getOvsVersion()
358
            if StrictVersion(ovsVer) < StrictVersion('2.0'):
359
                self.ovsOk = False
360
                showerror(title="Error",
361
                          message='Open vSwitch version 2.0+ required. You have '+ovsVer+'.')
362
        if ovsOf12 == "1" or ovsOf13 == "1":
363
            ovsVer = self.getOvsVersion()
364
            if StrictVersion(ovsVer) < StrictVersion('1.10'):
365
                self.ovsOk = False
366
                showerror(title="Error",
367
                          message='Open vSwitch version 1.10+ required. You have '+ovsVer+'.')
229 368

  
230
            self.ovsOf12 = IntVar()
231
            self.covsOf12 = Checkbutton(ovsFrame, variable=self.ovsOf12)
232
            self.covsOf12.grid(row=2, column=1, sticky=W)
233
            if self.prefValues['openFlowVersions']['ovsOf12'] == '0':
234
                self.covsOf12.deselect()
235
            else:
236
                self.covsOf12.select()
369
        if self.ovsOk:
370
            self.result['openFlowVersions']={'ovsOf10':ovsOf10,
371
                                             'ovsOf11':ovsOf11,
372
                                             'ovsOf12':ovsOf12,
373
                                             'ovsOf13':ovsOf13}
374
        else:
375
            self.result = None
237 376

  
238
            self.ovsOf13 = IntVar()
239
            self.covsOf13 = Checkbutton(ovsFrame, variable=self.ovsOf13)
240
            self.covsOf13.grid(row=3, column=1, sticky=W)
241
            if self.prefValues['openFlowVersions']['ovsOf13'] == '0':
242
                self.covsOf13.deselect()
243
            else:
244
                self.covsOf13.select()
245

  
246
            # Field for DPCTL listen port
247
            Label(self.leftfieldFrame, text="dpctl port:").grid(row=5, sticky=E)
248
            self.dpctlEntry = Entry(self.leftfieldFrame)
249
            self.dpctlEntry.grid(row=5, column=1)
250
            if 'dpctl' in self.prefValues:
251
                self.dpctlEntry.insert(0, self.prefValues['dpctl'])
252

  
253
            # sFlow
254
            sflowValues = self.prefValues['sflow']
255
            self.sflowFrame= LabelFrame(self.rightfieldFrame, text='sFlow Profile for Open vSwitch', padx=5, pady=5)
256
            self.sflowFrame.grid(row=0, column=0, columnspan=2, sticky=EW)
257

  
258
            Label(self.sflowFrame, text="Target:").grid(row=0, sticky=E)
259
            self.sflowTarget = Entry(self.sflowFrame)
260
            self.sflowTarget.grid(row=0, column=1)
261
            self.sflowTarget.insert(0, sflowValues['sflowTarget'])
262

  
263
            Label(self.sflowFrame, text="Sampling:").grid(row=1, sticky=E)
264
            self.sflowSampling = Entry(self.sflowFrame)
265
            self.sflowSampling.grid(row=1, column=1)
266
            self.sflowSampling.insert(0, sflowValues['sflowSampling'])
267

  
268
            Label(self.sflowFrame, text="Header:").grid(row=2, sticky=E)
269
            self.sflowHeader = Entry(self.sflowFrame)
270
            self.sflowHeader.grid(row=2, column=1)
271
            self.sflowHeader.insert(0, sflowValues['sflowHeader'])
272

  
273
            Label(self.sflowFrame, text="Polling:").grid(row=3, sticky=E)
274
            self.sflowPolling = Entry(self.sflowFrame)
275
            self.sflowPolling.grid(row=3, column=1)
276
            self.sflowPolling.insert(0, sflowValues['sflowPolling'])
277

  
278
            # NetFlow
279
            nflowValues = self.prefValues['netflow']
280
            self.nFrame= LabelFrame(self.rightfieldFrame, text='NetFlow Profile for Open vSwitch', padx=5, pady=5)
281
            self.nFrame.grid(row=1, column=0, columnspan=2, sticky=EW)
282

  
283
            Label(self.nFrame, text="Target:").grid(row=0, sticky=E)
284
            self.nflowTarget = Entry(self.nFrame)
285
            self.nflowTarget.grid(row=0, column=1)
286
            self.nflowTarget.insert(0, nflowValues['nflowTarget'])
287

  
288
            Label(self.nFrame, text="Active Timeout:").grid(row=1, sticky=E)
289
            self.nflowTimeout = Entry(self.nFrame)
290
            self.nflowTimeout.grid(row=1, column=1)
291
            self.nflowTimeout.insert(0, nflowValues['nflowTimeout'])
292

  
293
            Label(self.nFrame, text="Add ID to Interface:").grid(row=2, sticky=E)
294
            self.nflowAddId = IntVar()
295
            self.nflowAddIdButton = Checkbutton(self.nFrame, variable=self.nflowAddId)
296
            self.nflowAddIdButton.grid(row=2, column=1, sticky=W)
297
            if nflowValues['nflowAddId'] == '0':
298
                self.nflowAddIdButton.deselect()
299
            else:
300
                self.nflowAddIdButton.select()
301

  
302
            # initial focus
303
            return self.ipEntry
304

  
305
        def apply(self):
306
            ipBase = self.ipEntry.get()
307
            terminalType = self.terminalVar.get()
308
            startCLI = str(self.cliStart.get())
309
            sw = self.switchType.get()
310
            dpctl = self.dpctlEntry.get()
311

  
312
            ovsOf10 = str(self.ovsOf10.get())
313
            ovsOf11 = str(self.ovsOf11.get())
314
            ovsOf12 = str(self.ovsOf12.get())
315
            ovsOf13 = str(self.ovsOf13.get())
316

  
317
            sflowValues = {'sflowTarget':self.sflowTarget.get(),
318
                           'sflowSampling':self.sflowSampling.get(),
319
                           'sflowHeader':self.sflowHeader.get(),
320
                           'sflowPolling':self.sflowPolling.get()}
321
            nflowvalues = {'nflowTarget':self.nflowTarget.get(),
322
                           'nflowTimeout':self.nflowTimeout.get(),
323
                           'nflowAddId':str(self.nflowAddId.get())}
324
            self.result = {'ipBase':ipBase,
325
                           'terminalType':terminalType,
326
                           'dpctl':dpctl,
327
                           'sflow':sflowValues,
328
                           'netflow':nflowvalues,
329
                           'startCLI':startCLI}
330
            if sw == 'Indigo Virtual Switch':
331
                self.result['switchType'] = 'ivs'
332
                if StrictVersion(MININET_VERSION) < StrictVersion('2.1'):
333
                    self.ovsOk = False
334
                    showerror(title="Error",
335
                              message='MiniNet version 2.1+ required. You have '+VERSION+'.')
336
            elif sw == 'Userspace Switch':
337
                self.result['switchType'] = 'user'
338
            elif sw == 'Userspace Switch inNamespace':
339
                self.result['switchType'] = 'userns'
340
            else:
341
                self.result['switchType'] = 'ovs'
342

  
343
            self.ovsOk = True
344
            if ovsOf11 == "1":
345
                ovsVer = self.getOvsVersion()
346
                if StrictVersion(ovsVer) < StrictVersion('2.0'):
347
                    self.ovsOk = False
348
                    showerror(title="Error",
349
                              message='Open vSwitch version 2.0+ required. You have '+ovsVer+'.')
350
            if ovsOf12 == "1" or ovsOf13 == "1":
351
                ovsVer = self.getOvsVersion()
352
                if StrictVersion(ovsVer) < StrictVersion('1.10'):
353
                    self.ovsOk = False
354
                    showerror(title="Error",
355
                              message='Open vSwitch version 1.10+ required. You have '+ovsVer+'.')
356

  
357
            if self.ovsOk:
358
                self.result['openFlowVersions']={'ovsOf10':ovsOf10,
359
                                                 'ovsOf11':ovsOf11,
360
                                                 'ovsOf12':ovsOf12,
361
                                                 'ovsOf13':ovsOf13}
362
            else:
363
                self.result = None
364

  
365
        def getOvsVersion(self):
366
            outp = quietRun("ovs-vsctl show")
367
            r = r'ovs_version: "(.*)"'
368
            m = re.search(r, outp)
369
            if m is None:
370
                print 'Version check failed'
371
                return None
372
            else:
373
                print 'Open vSwitch version is '+m.group(1)
374
                return m.group(1)
377
    def getOvsVersion(self):
378
        "Return OVS version"
379
        outp = quietRun("ovs-vsctl show")
380
        r = r'ovs_version: "(.*)"'
381
        m = re.search(r, outp)
382
        if m is None:
383
            print 'Version check failed'
384
            return None
385
        else:
386
            print 'Open vSwitch version is '+m.group(1)
387
            return m.group(1)
375 388

  
376 389

  
377 390
class CustomDialog(object):
378 391

  
379
        # TODO: Fix button placement and Title and window focus lock
380
        def __init__(self, master, title):
381
            self.top=Toplevel(master)
392
    # TODO: Fix button placement and Title and window focus lock
393
    def __init__(self, master, title):
394
        self.top=Toplevel(master)
382 395

  
383
            self.bodyFrame = Frame(self.top)
384
            self.bodyFrame.grid(row=0, column=0, sticky='nswe')
385
            self.body(self.bodyFrame)
396
        self.bodyFrame = Frame(self.top)
397
        self.bodyFrame.grid(row=0, column=0, sticky='nswe')
398
        self.body(self.bodyFrame)
386 399

  
387
            #return self.b # initial focus
388
            buttonFrame = Frame(self.top, relief='ridge', bd=3, bg='lightgrey')
389
            buttonFrame.grid(row=1 , column=0, sticky='nswe')
400
        #return self.b # initial focus
401
        buttonFrame = Frame(self.top, relief='ridge', bd=3, bg='lightgrey')
402
        buttonFrame.grid(row=1 , column=0, sticky='nswe')
390 403

  
391
            okButton = Button(buttonFrame, width=8, text='OK', relief='groove',
392
                       bd=4, command=self.okAction)
393
            okButton.grid(row=0, column=0, sticky=E)
404
        okButton = Button(buttonFrame, width=8, text='OK', relief='groove',
405
                   bd=4, command=self.okAction)
406
        okButton.grid(row=0, column=0, sticky=E)
394 407

  
395
            canlceButton = Button(buttonFrame, width=8, text='Cancel', relief='groove',
396
                        bd=4, command=self.cancelAction)
397
            canlceButton.grid(row=0, column=1, sticky=W)
408
        canlceButton = Button(buttonFrame, width=8, text='Cancel', relief='groove',
409
                    bd=4, command=self.cancelAction)
410
        canlceButton.grid(row=0, column=1, sticky=W)
398 411

  
399
        def body(self, master):
400
            self.rootFrame = master
412
    def body(self, master):
413
        self.rootFrame = master
401 414

  
402
        def apply(self):
403
            self.top.destroy()
415
    def apply(self):
416
        self.top.destroy()
404 417

  
405
        def cancelAction(self):
406
            self.top.destroy()
418
    def cancelAction(self):
419
        self.top.destroy()
407 420

  
408
        def okAction(self):
409
            self.apply()
410
            self.top.destroy()
421
    def okAction(self):
422
        self.apply()
423
        self.top.destroy()
411 424

  
412 425
class HostDialog(CustomDialog):
413 426

  
414
        def __init__(self, master, title, prefDefaults):
415

  
416
            self.prefValues = prefDefaults
417
            self.result = None
427
    def __init__(self, master, title, prefDefaults):
428

  
429
        self.prefValues = prefDefaults
430
        self.result = None
431

  
432
        CustomDialog.__init__(self, master, title)
433

  
434
    def body(self, master):
435
        self.rootFrame = master
436
        n = Notebook(self.rootFrame)
437
        self.propFrame = Frame(n)
438
        self.vlanFrame = Frame(n)
439
        self.interfaceFrame = Frame(n)
440
        self.mountFrame = Frame(n)
441
        n.add(self.propFrame, text='Properties')
442
        n.add(self.vlanFrame, text='VLAN Interfaces')
443
        n.add(self.interfaceFrame, text='External Interfaces')
444
        n.add(self.mountFrame, text='Private Directories')
445
        n.pack()
446

  
447
        ### TAB 1
448
        # Field for Hostname
449
        Label(self.propFrame, text="Hostname:").grid(row=0, sticky=E)
450
        self.hostnameEntry = Entry(self.propFrame)
451
        self.hostnameEntry.grid(row=0, column=1)
452
        if 'hostname' in self.prefValues:
453
            self.hostnameEntry.insert(0, self.prefValues['hostname'])
418 454

  
419
            CustomDialog.__init__(self, master, title)
420

  
421
        def body(self, master):
422
            self.rootFrame = master
423
            n = Notebook(self.rootFrame)
424
            self.propFrame = Frame(n)
425
            self.vlanFrame = Frame(n)
426
            self.interfaceFrame = Frame(n)
427
            self.mountFrame = Frame(n)
428
            n.add(self.propFrame, text='Properties')
429
            n.add(self.vlanFrame, text='VLAN Interfaces')
430
            n.add(self.interfaceFrame, text='External Interfaces')
431
            n.add(self.mountFrame, text='Private Directories')
432
            n.pack()
433

  
434
            ### TAB 1
435
            # Field for Hostname
436
            Label(self.propFrame, text="Hostname:").grid(row=0, sticky=E)
437
            self.hostnameEntry = Entry(self.propFrame)
438
            self.hostnameEntry.grid(row=0, column=1)
439
            if 'hostname' in self.prefValues:
440
                self.hostnameEntry.insert(0, self.prefValues['hostname'])
441

  
442
            # Field for Switch IP
443
            Label(self.propFrame, text="IP Address:").grid(row=1, sticky=E)
444
            self.ipEntry = Entry(self.propFrame)
445
            self.ipEntry.grid(row=1, column=1)
446
            if 'ip' in self.prefValues:
447
                self.ipEntry.insert(0, self.prefValues['ip'])
448

  
449
            # Field for default route
450
            Label(self.propFrame, text="Default Route:").grid(row=2, sticky=E)
451
            self.routeEntry = Entry(self.propFrame)
452
            self.routeEntry.grid(row=2, column=1)
453
            if 'defaultRoute' in self.prefValues:
454
                self.routeEntry.insert(0, self.prefValues['defaultRoute'])
455

  
456
            # Field for CPU
457
            Label(self.propFrame, text="Amount CPU:").grid(row=3, sticky=E)
458
            self.cpuEntry = Entry(self.propFrame)
459
            self.cpuEntry.grid(row=3, column=1)
460
            if 'cpu' in self.prefValues:
461
                self.cpuEntry.insert(0, str(self.prefValues['cpu']))
462
            # Selection of Scheduler
463
            if 'sched' in self.prefValues:
464
                sched =  self.prefValues['sched']
455
        # Field for Switch IP
456
        Label(self.propFrame, text="IP Address:").grid(row=1, sticky=E)
457
        self.ipEntry = Entry(self.propFrame)
458
        self.ipEntry.grid(row=1, column=1)
459
        if 'ip' in self.prefValues:
460
            self.ipEntry.insert(0, self.prefValues['ip'])
461

  
462
        # Field for default route
463
        Label(self.propFrame, text="Default Route:").grid(row=2, sticky=E)
464
        self.routeEntry = Entry(self.propFrame)
465
        self.routeEntry.grid(row=2, column=1)
466
        if 'defaultRoute' in self.prefValues:
467
            self.routeEntry.insert(0, self.prefValues['defaultRoute'])
468

  
469
        # Field for CPU
470
        Label(self.propFrame, text="Amount CPU:").grid(row=3, sticky=E)
471
        self.cpuEntry = Entry(self.propFrame)
472
        self.cpuEntry.grid(row=3, column=1)
473
        if 'cpu' in self.prefValues:
474
            self.cpuEntry.insert(0, str(self.prefValues['cpu']))
475
        # Selection of Scheduler
476
        if 'sched' in self.prefValues:
477
            sched =  self.prefValues['sched']
478
        else:
479
            sched = 'host'
480
        self.schedVar = StringVar(self.propFrame)
481
        self.schedOption = OptionMenu(self.propFrame, self.schedVar, "host", "cfs", "rt")
482
        self.schedOption.grid(row=3, column=2, sticky=W)
483
        self.schedVar.set(sched)
484

  
485
        # Selection of Cores
486
        Label(self.propFrame, text="Cores:").grid(row=4, sticky=E)
487
        self.coreEntry = Entry(self.propFrame)
488
        self.coreEntry.grid(row=4, column=1)
489
        if 'cores' in self.prefValues:
490
            self.coreEntry.insert(1, self.prefValues['cores'])
491

  
492
        # Start command
493
        Label(self.propFrame, text="Start Command:").grid(row=5, sticky=E)
494
        self.startEntry = Entry(self.propFrame)
495
        self.startEntry.grid(row=5, column=1, sticky='nswe', columnspan=3)
496
        if 'startCommand' in self.prefValues:
497
            self.startEntry.insert(0, str(self.prefValues['startCommand']))
498
        # Stop command
499
        Label(self.propFrame, text="Stop Command:").grid(row=6, sticky=E)
500
        self.stopEntry = Entry(self.propFrame)
501
        self.stopEntry.grid(row=6, column=1, sticky='nswe', columnspan=3)
502
        if 'stopCommand' in self.prefValues:
503
            self.stopEntry.insert(0, str(self.prefValues['stopCommand']))
504

  
505
        ### TAB 2
506
        # External Interfaces
507
        self.externalInterfaces = 0
508
        Label(self.interfaceFrame, text="External Interface:").grid(row=0, column=0, sticky=E)
509
        self.b = Button( self.interfaceFrame, text='Add', command=self.addInterface)
510
        self.b.grid(row=0, column=1)
511

  
512
        self.interfaceFrame = VerticalScrolledTable(self.interfaceFrame, rows=0, columns=1, title='External Interfaces')
513
        self.interfaceFrame.grid(row=1, column=0, sticky='nswe', columnspan=2)
514
        self.tableFrame = self.interfaceFrame.interior
515
        self.tableFrame.addRow(value=['Interface Name'], readonly=True)
516

  
517
        # Add defined interfaces
518
        externalInterfaces = []
519
        if 'externalInterfaces' in self.prefValues:
520
            externalInterfaces = self.prefValues['externalInterfaces']
521

  
522
        for externalInterface in externalInterfaces:
523
            self.tableFrame.addRow(value=[externalInterface])
524

  
525
        ### TAB 3
526
        # VLAN Interfaces
527
        self.vlanInterfaces = 0
528
        Label(self.vlanFrame, text="VLAN Interface:").grid(row=0, column=0, sticky=E)
529
        self.vlanButton = Button( self.vlanFrame, text='Add', command=self.addVlanInterface)
530
        self.vlanButton.grid(row=0, column=1)
531

  
532
        self.vlanFrame = VerticalScrolledTable(self.vlanFrame, rows=0, columns=2, title='VLAN Interfaces')
533
        self.vlanFrame.grid(row=1, column=0, sticky='nswe', columnspan=2)
534
        self.vlanTableFrame = self.vlanFrame.interior
535
        self.vlanTableFrame.addRow(value=['IP Address','VLAN ID'], readonly=True)
536

  
537
        vlanInterfaces = []
538
        if 'vlanInterfaces' in self.prefValues:
539
            vlanInterfaces = self.prefValues['vlanInterfaces']
540
        for vlanInterface in vlanInterfaces:
541
            self.vlanTableFrame.addRow(value=vlanInterface)
542

  
543
        ### TAB 4
544
        # Private Directories
545
        self.privateDirectories = 0
546
        Label(self.mountFrame, text="Private Directory:").grid(row=0, column=0, sticky=E)
547
        self.mountButton = Button( self.mountFrame, text='Add', command=self.addDirectory)
548
        self.mountButton.grid(row=0, column=1)
549

  
550
        self.mountFrame = VerticalScrolledTable(self.mountFrame, rows=0, columns=2, title='Directories')
551
        self.mountFrame.grid(row=1, column=0, sticky='nswe', columnspan=2)
552
        self.mountTableFrame = self.mountFrame.interior
553
        self.mountTableFrame.addRow(value=['Mount','Persistent Directory'], readonly=True)
554

  
555
        directoryList = []
556
        if 'privateDirectory' in self.prefValues:
557
            directoryList = self.prefValues['privateDirectory']
558
        for privateDir in directoryList:
559
            if isinstance( privateDir, tuple ):
560
                self.mountTableFrame.addRow(value=privateDir)
465 561
            else:
466
                sched = 'host'
467
            self.schedVar = StringVar(self.propFrame)
468
            self.schedOption = OptionMenu(self.propFrame, self.schedVar, "host", "cfs", "rt")
469
            self.schedOption.grid(row=3, column=2, sticky=W)
470
            self.schedVar.set(sched)
471

  
472
            # Selection of Cores
473
            Label(self.propFrame, text="Cores:").grid(row=4, sticky=E)
474
            self.coreEntry = Entry(self.propFrame)
475
            self.coreEntry.grid(row=4, column=1)
476
            if 'cores' in self.prefValues:
477
                self.coreEntry.insert(1, self.prefValues['cores'])
478

  
479
            # Start command
480
            Label(self.propFrame, text="Start Command:").grid(row=5, sticky=E)
481
            self.startEntry = Entry(self.propFrame)
482
            self.startEntry.grid(row=5, column=1, sticky='nswe', columnspan=3)
483
            if 'startCommand' in self.prefValues:
484
                self.startEntry.insert(0, str(self.prefValues['startCommand']))
485
            # Stop command
486
            Label(self.propFrame, text="Stop Command:").grid(row=6, sticky=E)
487
            self.stopEntry = Entry(self.propFrame)
488
            self.stopEntry.grid(row=6, column=1, sticky='nswe', columnspan=3)
489
            if 'stopCommand' in self.prefValues:
490
                self.stopEntry.insert(0, str(self.prefValues['stopCommand']))
491

  
492
            ### TAB 2
493
            # External Interfaces
494
            self.externalInterfaces = 0
495
            Label(self.interfaceFrame, text="External Interface:").grid(row=0, column=0, sticky=E)
496
            self.b = Button( self.interfaceFrame, text='Add', command=self.addInterface)
497
            self.b.grid(row=0, column=1)
498

  
499
            self.interfaceFrame = VerticalScrolledTable(self.interfaceFrame, rows=0, columns=1, title='External Interfaces')
500
            self.interfaceFrame.grid(row=1, column=0, sticky='nswe', columnspan=2)
501
            self.tableFrame = self.interfaceFrame.interior
502
            self.tableFrame.addRow(value=['Interface Name'], readonly=True)
503

  
504
            # Add defined interfaces
505
            externalInterfaces = []
506
            if 'externalInterfaces' in self.prefValues:
507
                externalInterfaces = self.prefValues['externalInterfaces']
508

  
509
            for externalInterface in externalInterfaces:
510
                self.tableFrame.addRow(value=[externalInterface])
511

  
512
            ### TAB 3
513
            # VLAN Interfaces
514
            self.vlanInterfaces = 0
515
            Label(self.vlanFrame, text="VLAN Interface:").grid(row=0, column=0, sticky=E)
516
            self.vlanButton = Button( self.vlanFrame, text='Add', command=self.addVlanInterface)
517
            self.vlanButton.grid(row=0, column=1)
518

  
519
            self.vlanFrame = VerticalScrolledTable(self.vlanFrame, rows=0, columns=2, title='VLAN Interfaces')
520
            self.vlanFrame.grid(row=1, column=0, sticky='nswe', columnspan=2)
521
            self.vlanTableFrame = self.vlanFrame.interior
522
            self.vlanTableFrame.addRow(value=['IP Address','VLAN ID'], readonly=True)
523

  
524
            vlanInterfaces = []
525
            if 'vlanInterfaces' in self.prefValues:
526
                vlanInterfaces = self.prefValues['vlanInterfaces']
527
            for vlanInterface in vlanInterfaces:
528
                self.vlanTableFrame.addRow(value=vlanInterface)
529

  
530
            ### TAB 4
531
            # Private Directories
532
            self.privateDirectories = 0
533
            Label(self.mountFrame, text="Private Directory:").grid(row=0, column=0, sticky=E)
534
            self.mountButton = Button( self.mountFrame, text='Add', command=self.addDirectory)
535
            self.mountButton.grid(row=0, column=1)
536

  
537
            self.mountFrame = VerticalScrolledTable(self.mountFrame, rows=0, columns=2, title='Directories')
538
            self.mountFrame.grid(row=1, column=0, sticky='nswe', columnspan=2)
539
            self.mountTableFrame = self.mountFrame.interior
540
            self.mountTableFrame.addRow(value=['Mount','Persistent Directory'], readonly=True)
541

  
542
            directoryList = []
543
            if 'privateDirectory' in self.prefValues:
544
                directoryList = self.prefValues['privateDirectory']
545
            for privateDir in directoryList:
546
                if isinstance( privateDir, tuple ):
547
                    self.mountTableFrame.addRow(value=privateDir)
562
                self.mountTableFrame.addRow(value=[privateDir,''])
563

  
564

  
565
    def addDirectory( self ):
566
        self.mountTableFrame.addRow()
567

  
568
    def addVlanInterface( self ):
569
        self.vlanTableFrame.addRow()
570

  
571
    def addInterface( self ):
572
        self.tableFrame.addRow()
573

  
574
    def apply(self):
575
        externalInterfaces = []
576
        for row in range(self.tableFrame.rows):
577
            if (len(self.tableFrame.get(row, 0)) > 0 and
578
                row > 0):
579
                externalInterfaces.append(self.tableFrame.get(row, 0))
580
        vlanInterfaces = []
581
        for row in range(self.vlanTableFrame.rows):
582
            if (len(self.vlanTableFrame.get(row, 0)) > 0 and
583
                len(self.vlanTableFrame.get(row, 1)) > 0 and
584
                row > 0):
585
                vlanInterfaces.append([self.vlanTableFrame.get(row, 0), self.vlanTableFrame.get(row, 1)])
586
        privateDirectories = []
587
        for row in range(self.mountTableFrame.rows):
588
            if len(self.mountTableFrame.get(row, 0)) > 0 and row > 0:
589
                if len(self.mountTableFrame.get(row, 1)) > 0:
590
                    privateDirectories.append((self.mountTableFrame.get(row, 0), self.mountTableFrame.get(row, 1)))
548 591
                else:
549
                    self.mountTableFrame.addRow(value=[privateDir,''])
550

  
551

  
552
        def addDirectory( self ):
553
            self.mountTableFrame.addRow()
554

  
555
        def addVlanInterface( self ):
556
            self.vlanTableFrame.addRow()
557

  
558
        def addInterface( self ):
559
            self.tableFrame.addRow()
560

  
561
        def apply(self):
562
            externalInterfaces = []
563
            for row in range(self.tableFrame.rows):
564
                if (len(self.tableFrame.get(row, 0)) > 0 and
565
                    row > 0):
566
                    externalInterfaces.append(self.tableFrame.get(row, 0))
567
            vlanInterfaces = []
568
            for row in range(self.vlanTableFrame.rows):
569
                if (len(self.vlanTableFrame.get(row, 0)) > 0 and
570
                    len(self.vlanTableFrame.get(row, 1)) > 0 and
571
                    row > 0):
572
                    vlanInterfaces.append([self.vlanTableFrame.get(row, 0), self.vlanTableFrame.get(row, 1)])
573
            privateDirectories = []
574
            for row in range(self.mountTableFrame.rows):
575
                if (len(self.mountTableFrame.get(row, 0)) > 0 and row > 0):
576
                    if(len(self.mountTableFrame.get(row, 1)) > 0):
577
                        privateDirectories.append((self.mountTableFrame.get(row, 0), self.mountTableFrame.get(row, 1)))
578
                    else:
579
                        privateDirectories.append(self.mountTableFrame.get(row, 0))
580

  
581
            results = {'cpu': self.cpuEntry.get(),
582
                       'cores':self.coreEntry.get(),
583
                       'sched':self.schedVar.get(),
584
                       'hostname':self.hostnameEntry.get(),
585
                       'ip':self.ipEntry.get(),
586
                       'defaultRoute':self.routeEntry.get(),
587
                       'startCommand':self.startEntry.get(),
588
                       'stopCommand':self.stopEntry.get(),
589
                       'privateDirectory':privateDirectories,
590
                       'externalInterfaces':externalInterfaces,
591
                       'vlanInterfaces':vlanInterfaces}
592
            self.result = results
592
                    privateDirectories.append(self.mountTableFrame.get(row, 0))
593

  
594
        results = {'cpu': self.cpuEntry.get(),
595
                   'cores':self.coreEntry.get(),
596
                   'sched':self.schedVar.get(),
597
                   'hostname':self.hostnameEntry.get(),
598
                   'ip':self.ipEntry.get(),
599
                   'defaultRoute':self.routeEntry.get(),
600
                   'startCommand':self.startEntry.get(),
601
                   'stopCommand':self.stopEntry.get(),
602
                   'privateDirectory':privateDirectories,
603
                   'externalInterfaces':externalInterfaces,
604
                   'vlanInterfaces':vlanInterfaces}
605
        self.result = results
593 606

  
594 607
class SwitchDialog(CustomDialog):
595 608

  
596
        def __init__(self, master, title, prefDefaults):
597

  
598
            self.prefValues = prefDefaults
599
            self.result = None
600
            CustomDialog.__init__(self, master, title)
601

  
602
        def body(self, master):
603
            self.rootFrame = master
604
            self.leftfieldFrame = Frame(self.rootFrame)
605
            self.rightfieldFrame = Frame(self.rootFrame)
606
            self.leftfieldFrame.grid(row=0, column=0, sticky='nswe')
607
            self.rightfieldFrame.grid(row=0, column=1, sticky='nswe')
608

  
609
            rowCount = 0
610
            externalInterfaces = []
611
            if 'externalInterfaces' in self.prefValues:
612
                externalInterfaces = self.prefValues['externalInterfaces']
613

  
614
            # Field for Hostname
615
            Label(self.leftfieldFrame, text="Hostname:").grid(row=rowCount, sticky=E)
616
            self.hostnameEntry = Entry(self.leftfieldFrame)
617
            self.hostnameEntry.grid(row=rowCount, column=1)
618
            self.hostnameEntry.insert(0, self.prefValues['hostname'])
619
            rowCount+=1
620

  
621
            # Field for DPID
622
            Label(self.leftfieldFrame, text="DPID:").grid(row=rowCount, sticky=E)
623
            self.dpidEntry = Entry(self.leftfieldFrame)
624
            self.dpidEntry.grid(row=rowCount, column=1)
625
            if 'dpid' in self.prefValues:
626
                self.dpidEntry.insert(0, self.prefValues['dpid'])
627
            rowCount+=1
628

  
629
            # Field for Netflow
630
            Label(self.leftfieldFrame, text="Enable NetFlow:").grid(row=rowCount, sticky=E)
631
            self.nflow = IntVar()
632
            self.nflowButton = Checkbutton(self.leftfieldFrame, variable=self.nflow)
633
            self.nflowButton.grid(row=rowCount, column=1, sticky=W)
634
            if 'netflow' in self.prefValues:
635
                if self.prefValues['netflow'] == '0':
636
                    self.nflowButton.deselect()
637
                else:
638
                    self.nflowButton.select()
639
            else:
609
    def __init__(self, master, title, prefDefaults):
610

  
611
        self.prefValues = prefDefaults
612
        self.result = None
613
        CustomDialog.__init__(self, master, title)
614

  
615
    def body(self, master):
616
        self.rootFrame = master
617
        self.leftfieldFrame = Frame(self.rootFrame)
618
        self.rightfieldFrame = Frame(self.rootFrame)
619
        self.leftfieldFrame.grid(row=0, column=0, sticky='nswe')
620
        self.rightfieldFrame.grid(row=0, column=1, sticky='nswe')
621

  
622
        rowCount = 0
623
        externalInterfaces = []
624
        if 'externalInterfaces' in self.prefValues:
625
            externalInterfaces = self.prefValues['externalInterfaces']
626

  
627
        # Field for Hostname
628
        Label(self.leftfieldFrame, text="Hostname:").grid(row=rowCount, sticky=E)
629
        self.hostnameEntry = Entry(self.leftfieldFrame)
630
        self.hostnameEntry.grid(row=rowCount, column=1)
631
        self.hostnameEntry.insert(0, self.prefValues['hostname'])
632
        rowCount+=1
633

  
634
        # Field for DPID
635
        Label(self.leftfieldFrame, text="DPID:").grid(row=rowCount, sticky=E)
636
        self.dpidEntry = Entry(self.leftfieldFrame)
637
        self.dpidEntry.grid(row=rowCount, column=1)
638
        if 'dpid' in self.prefValues:
639
            self.dpidEntry.insert(0, self.prefValues['dpid'])
640
        rowCount+=1
641

  
642
        # Field for Netflow
643
        Label(self.leftfieldFrame, text="Enable NetFlow:").grid(row=rowCount, sticky=E)
644
        self.nflow = IntVar()
645
        self.nflowButton = Checkbutton(self.leftfieldFrame, variable=self.nflow)
646
        self.nflowButton.grid(row=rowCount, column=1, sticky=W)
647
        if 'netflow' in self.prefValues:
648
            if self.prefValues['netflow'] == '0':
640 649
                self.nflowButton.deselect()
641
            rowCount+=1
642

  
643
            # Field for sflow
644
            Label(self.leftfieldFrame, text="Enable sFlow:").grid(row=rowCount, sticky=E)
645
            self.sflow = IntVar()
646
            self.sflowButton = Checkbutton(self.leftfieldFrame, variable=self.sflow)
647
            self.sflowButton.grid(row=rowCount, column=1, sticky=W)
648
            if 'sflow' in self.prefValues:
649
                if self.prefValues['sflow'] == '0':
650
                    self.sflowButton.deselect()
651
                else:
652
                    self.sflowButton.select()
653 650
            else:
651
                self.nflowButton.select()
652
        else:
653
            self.nflowButton.deselect()
654
        rowCount+=1
655

  
656
        # Field for sflow
657
        Label(self.leftfieldFrame, text="Enable sFlow:").grid(row=rowCount, sticky=E)
658
        self.sflow = IntVar()
659
        self.sflowButton = Checkbutton(self.leftfieldFrame, variable=self.sflow)
660
        self.sflowButton.grid(row=rowCount, column=1, sticky=W)
661
        if 'sflow' in self.prefValues:
662
            if self.prefValues['sflow'] == '0':
654 663
                self.sflowButton.deselect()
655
            rowCount+=1
656

  
657
            # Selection of switch type
658
            Label(self.leftfieldFrame, text="Switch Type:").grid(row=rowCount, sticky=E)
659
            self.switchType = StringVar(self.leftfieldFrame)
660
            self.switchTypeMenu = OptionMenu(self.leftfieldFrame, self.switchType, "Default", "Open vSwitch Kernel Mode", "Indigo Virtual Switch", "Userspace Switch", "Userspace Switch inNamespace")
661
            self.switchTypeMenu.grid(row=rowCount, column=1, sticky=W)
662
            if 'switchType' in self.prefValues:
663
                switchTypePref = self.prefValues['switchType']
664
                if switchTypePref == 'ivs':
665
                    self.switchType.set("Indigo Virtual Switch")
666
                elif switchTypePref == 'userns':
667
                    self.switchType.set("Userspace Switch inNamespace")
668
                elif switchTypePref == 'user':
669
                    self.switchType.set("Userspace Switch")
670
                elif switchTypePref == 'ovs':
671
                    self.switchType.set("Open vSwitch Kernel Mode")
672
                else:
673
                    self.switchType.set("Default")
664
            else:
665
                self.sflowButton.select()
666
        else:
667
            self.sflowButton.deselect()
668
        rowCount+=1
669

  
670
        # Selection of switch type
671
        Label(self.leftfieldFrame, text="Switch Type:").grid(row=rowCount, sticky=E)
672
        self.switchType = StringVar(self.leftfieldFrame)
673
        self.switchTypeMenu = OptionMenu(self.leftfieldFrame, self.switchType, "Default", "Open vSwitch Kernel Mode", "Indigo Virtual Switch", "Userspace Switch", "Userspace Switch inNamespace")
674
        self.switchTypeMenu.grid(row=rowCount, column=1, sticky=W)
675
        if 'switchType' in self.prefValues:
676
            switchTypePref = self.prefValues['switchType']
677
            if switchTypePref == 'ivs':
678
                self.switchType.set("Indigo Virtual Switch")
679
            elif switchTypePref == 'userns':
680
                self.switchType.set("Userspace Switch inNamespace")
681
            elif switchTypePref == 'user':
682
                self.switchType.set("Userspace Switch")
683
            elif switchTypePref == 'ovs':
684
                self.switchType.set("Open vSwitch Kernel Mode")
674 685
            else:
675 686
                self.switchType.set("Default")
676
            rowCount+=1
677

  
678
            # Field for Switch IP
679
            Label(self.leftfieldFrame, text="IP Address:").grid(row=rowCount, sticky=E)
680
            self.ipEntry = Entry(self.leftfieldFrame)
681
            self.ipEntry.grid(row=rowCount, column=1)
682
            if 'switchIP' in self.prefValues:
683
                self.ipEntry.insert(0, self.prefValues['switchIP'])
684
            rowCount+=1
685

  
686
            # Field for DPCTL port
687
            Label(self.leftfieldFrame, text="DPCTL port:").grid(row=rowCount, sticky=E)
688
            self.dpctlEntry = Entry(self.leftfieldFrame)
689
            self.dpctlEntry.grid(row=rowCount, column=1)
690
            if 'dpctl' in self.prefValues:
691
                self.dpctlEntry.insert(0, self.prefValues['dpctl'])
692
            rowCount+=1
693

  
694
            # External Interfaces
695
            Label(self.rightfieldFrame, text="External Interface:").grid(row=0, sticky=E)
696
            self.b = Button( self.rightfieldFrame, text='Add', command=self.addInterface)
697
            self.b.grid(row=0, column=1)
698

  
699
            self.interfaceFrame = VerticalScrolledTable(self.rightfieldFrame, rows=0, columns=1, title='External Interfaces')
700
            self.interfaceFrame.grid(row=1, column=0, sticky='nswe', columnspan=2)
701
            self.tableFrame = self.interfaceFrame.interior
702

  
703
            # Add defined interfaces
704
            for externalInterface in externalInterfaces:
705
                self.tableFrame.addRow(value=[externalInterface])
706

  
707
            self.commandFrame = Frame(self.rootFrame)
708
            self.commandFrame.grid(row=1, column=0, sticky='nswe', columnspan=2)
709
            self.commandFrame.columnconfigure(1, weight=1)
710
            # Start command
711
            Label(self.commandFrame, text="Start Command:").grid(row=0, column=0, sticky=W)
712
            self.startEntry = Entry(self.commandFrame)
713
            self.startEntry.grid(row=0, column=1,  sticky='nsew')
714
            if 'startCommand' in self.prefValues:
715
                self.startEntry.insert(0, str(self.prefValues['startCommand']))
716
            # Stop command
717
            Label(self.commandFrame, text="Stop Command:").grid(row=1, column=0, sticky=W)
718
            self.stopEntry = Entry(self.commandFrame)
719
            self.stopEntry.grid(row=1, column=1, sticky='nsew')
720
            if 'stopCommand' in self.prefValues:
721
                self.stopEntry.insert(0, str(self.prefValues['stopCommand']))
722

  
723
        def addInterface( self ):
724
            self.tableFrame.addRow()
725

  
726
        def defaultDpid( self ,name):
727
            "Derive dpid from switch name, s1 -> 1"
728
            try:
729
                dpid = int( re.findall( r'\d+', name )[ 0 ] )
730
                dpid = hex( dpid )[ 2: ]
731
                return dpid
732
            except IndexError:
733
                return None
734
                #raise Exception( 'Unable to derive default datapath ID - '
735
                #                 'please either specify a dpid or use a '
736
                #                 'canonical switch name such as s23.' )
737

  
738
        def apply(self):
739
            externalInterfaces = []
740
            for row in range(self.tableFrame.rows):
741
                #print 'Interface is ' + self.tableFrame.get(row, 0)
742
                if (len(self.tableFrame.get(row, 0)) > 0):
743
                    externalInterfaces.append(self.tableFrame.get(row, 0))
744

  
745
            dpid = self.dpidEntry.get()
746
            if (self.defaultDpid(self.hostnameEntry.get()) is None
747
               and len(dpid) == 0):
687
        else:
688
            self.switchType.set("Default")
689
        rowCount+=1
690

  
691
        # Field for Switch IP
692
        Label(self.leftfieldFrame, text="IP Address:").grid(row=rowCount, sticky=E)
693
        self.ipEntry = Entry(self.leftfieldFrame)
694
        self.ipEntry.grid(row=rowCount, column=1)
695
        if 'switchIP' in self.prefValues:
696
            self.ipEntry.insert(0, self.prefValues['switchIP'])
697
        rowCount+=1
698

  
699
        # Field for DPCTL port
700
        Label(self.leftfieldFrame, text="DPCTL port:").grid(row=rowCount, sticky=E)
701
        self.dpctlEntry = Entry(self.leftfieldFrame)
702
        self.dpctlEntry.grid(row=rowCount, column=1)
703
        if 'dpctl' in self.prefValues:
704
            self.dpctlEntry.insert(0, self.prefValues['dpctl'])
705
        rowCount+=1
706

  
707
        # External Interfaces
708
        Label(self.rightfieldFrame, text="External Interface:").grid(row=0, sticky=E)
709
        self.b = Button( self.rightfieldFrame, text='Add', command=self.addInterface)
710
        self.b.grid(row=0, column=1)
711

  
712
        self.interfaceFrame = VerticalScrolledTable(self.rightfieldFrame, rows=0, columns=1, title='External Interfaces')
713
        self.interfaceFrame.grid(row=1, column=0, sticky='nswe', columnspan=2)
714
        self.tableFrame = self.interfaceFrame.interior
715

  
716
        # Add defined interfaces
717
        for externalInterface in externalInterfaces:
718
            self.tableFrame.addRow(value=[externalInterface])
719

  
720
        self.commandFrame = Frame(self.rootFrame)
721
        self.commandFrame.grid(row=1, column=0, sticky='nswe', columnspan=2)
722
        self.commandFrame.columnconfigure(1, weight=1)
723
        # Start command
724
        Label(self.commandFrame, text="Start Command:").grid(row=0, column=0, sticky=W)
725
        self.startEntry = Entry(self.commandFrame)
726
        self.startEntry.grid(row=0, column=1,  sticky='nsew')
727
        if 'startCommand' in self.prefValues:
728
            self.startEntry.insert(0, str(self.prefValues['startCommand']))
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff