Bob Lantz
Committed by Bob Lantz

Enable --custom files to import ONOSCLI

Since --custom files are execed, subsequently importing them
actually creates duplicate classes. This wouldn't be a problem
except that we depend on isinstance(). As a workaround, we allow
the class name to match if isinstance() fails, assuming it will
be a class that is compatible with ONOSCluster or ONOSNode.

Example: env PYTHONPATH=. mn --custom onos.py,mytest.py

where mytest.py imports onos

Change-Id: Ib4cda82fbdd612420de1e113ab768e2f137d5213
...@@ -210,6 +210,25 @@ def RenamedTopo( topo, *args, **kwargs ): ...@@ -210,6 +210,25 @@ def RenamedTopo( topo, *args, **kwargs ):
210 return RenamedTopoCls( *args, **kwargs ) 210 return RenamedTopoCls( *args, **kwargs )
211 211
212 212
213 +# We accept objects that "claim" to be a particular class,
214 +# since the class definitions can be both execed (--custom) and
215 +# imported (in another custom file), which breaks isinstance().
216 +# In order for this to work properly, a class should not be
217 +# renamed so as to inappropriately omit or include the class
218 +# name text. Note that mininet.util.specialClass renames classes
219 +# by adding the specialized parameter names and values.
220 +
221 +def isONOSNode( obj ):
222 + "Does obj claim to be some kind of ONOSNode?"
223 + return ( isinstance( obj, ONOSNode) or
224 + 'ONOSNode' in type( obj ).__name__ )
225 +
226 +def isONOSCluster( obj ):
227 + "Does obj claim to be some kind of ONOSCluster?"
228 + return ( isinstance( obj, ONOSCluster ) or
229 + 'ONOSCluster' in type( obj ).__name__ )
230 +
231 +
213 class ONOSNode( Controller ): 232 class ONOSNode( Controller ):
214 "ONOS cluster node" 233 "ONOS cluster node"
215 234
...@@ -448,7 +467,7 @@ class ONOSCluster( Controller ): ...@@ -448,7 +467,7 @@ class ONOSCluster( Controller ):
448 467
449 def nodes( self ): 468 def nodes( self ):
450 "Return list of ONOS nodes" 469 "Return list of ONOS nodes"
451 - return [ h for h in self.net.hosts if isinstance( h, ONOSNode ) ] 470 + return [ h for h in self.net.hosts if isONOSNode( h ) ]
452 471
453 def configPortForwarding( self, ports=[], action='A' ): 472 def configPortForwarding( self, ports=[], action='A' ):
454 """Start or stop port forwarding (any intf) for all nodes 473 """Start or stop port forwarding (any intf) for all nodes
...@@ -471,7 +490,7 @@ class ONOSSwitchMixin( object ): ...@@ -471,7 +490,7 @@ class ONOSSwitchMixin( object ):
471 "Connect to ONOSCluster" 490 "Connect to ONOSCluster"
472 self.controllers = controllers 491 self.controllers = controllers
473 assert ( len( controllers ) is 1 and 492 assert ( len( controllers ) is 1 and
474 - isinstance( controllers[ 0 ], ONOSCluster ) ) 493 + isONOSCluster( controllers[ 0 ] ) )
475 clist = controllers[ 0 ].nodes() 494 clist = controllers[ 0 ].nodes()
476 return super( ONOSSwitchMixin, self ).start( clist ) 495 return super( ONOSSwitchMixin, self ).start( clist )
477 496
...@@ -517,7 +536,7 @@ class ONOSCLI( OldCLI ): ...@@ -517,7 +536,7 @@ class ONOSCLI( OldCLI ):
517 536
518 def __init__( self, net, **kwargs ): 537 def __init__( self, net, **kwargs ):
519 c0 = net.controllers[ 0 ] 538 c0 = net.controllers[ 0 ]
520 - if isinstance( c0, ONOSCluster ): 539 + if isONOSCluster( c0 ):
521 net = MininetFacade( net, cnet=c0.net ) 540 net = MininetFacade( net, cnet=c0.net )
522 OldCLI.__init__( self, net, **kwargs ) 541 OldCLI.__init__( self, net, **kwargs )
523 542
...@@ -528,7 +547,7 @@ class ONOSCLI( OldCLI ): ...@@ -528,7 +547,7 @@ class ONOSCLI( OldCLI ):
528 def do_onos( self, line ): 547 def do_onos( self, line ):
529 "Send command to ONOS CLI" 548 "Send command to ONOS CLI"
530 c0 = self.mn.controllers[ 0 ] 549 c0 = self.mn.controllers[ 0 ]
531 - if isinstance( c0, ONOSCluster ): 550 + if isONOSCluster( c0 ):
532 # cmdLoop strips off command name 'onos' 551 # cmdLoop strips off command name 'onos'
533 if line.startswith( ':' ): 552 if line.startswith( ':' ):
534 line = 'onos' + line 553 line = 'onos' + line
...@@ -556,9 +575,9 @@ class ONOSCLI( OldCLI ): ...@@ -556,9 +575,9 @@ class ONOSCLI( OldCLI ):
556 def do_status( self, line ): 575 def do_status( self, line ):
557 "Return status of ONOS cluster(s)" 576 "Return status of ONOS cluster(s)"
558 for c in self.mn.controllers: 577 for c in self.mn.controllers:
559 - if isinstance( c, ONOSCluster ): 578 + if isONOSCluster( c ):
560 for node in c.net.hosts: 579 for node in c.net.hosts:
561 - if isinstance( node, ONOSNode ): 580 + if isONOSNode( node ):
562 errors, warnings = node.checkLog() 581 errors, warnings = node.checkLog()
563 running = ( 'Running' if node.isRunning() 582 running = ( 'Running' if node.isRunning()
564 else 'Exited' ) 583 else 'Exited' )
......