Revision b1ec912d mininet/node.py

View differences:

mininet/node.py
189 189
        """Internal method: spawn and return a process
190 190
            cmd: command to run (list)
191 191
            params: parameters to Popen()"""
192
        # Leave this is as an instance method for now
193
        assert self
192 194
        return Popen( cmd, **params )
193 195

  
194 196
    def cleanup( self ):
......
240 242
                os.killpg( self.shell.pid, signal.SIGHUP )
241 243
        self.cleanup()
242 244

  
243
    def stop( self ):
244
        "Stop node."
245
    def stop( self, deleteIntfs=False ):
246
        """Stop node.
247
           deleteIntfs: delete interfaces? (False)"""
248
        if deleteIntfs:
249
            self.deleteIntfs()
245 250
        self.terminate()
246 251

  
247 252
    def waitReadable( self, timeoutms=None ):
......
324 329
        log = info if verbose else debug
325 330
        output = ''
326 331
        while self.waiting:
327
            data = self.monitor()
332
            data = self.monitor( findPid=findPid )
328 333
            output += data
329 334
            log( data )
330 335
        return output
......
421 426
            warn( '*** defaultIntf: warning:', self.name,
422 427
                  'has no interfaces\n' )
423 428

  
424
    def intf( self, intf='' ):
429
    def intf( self, intf=None ):
425 430
        """Return our interface object with given string name,
426 431
           default intf if name is falsy (None, empty string, etc).
427 432
           or the input intf arg.
......
682 687
            if int( self.cgroupGet( 'rt_runtime_us', 'cpu' ) ) <= 0:
683 688
                mncmd += [ '-r', str( self.rtprio ) ]
684 689
            else:
685
                debug( '*** error: not enough cpu time available for %s.' % self.name,
686
                      'Using cfs scheduler for subprocess\n' )
690
                debug( '*** error: not enough cpu time available for %s.' %
691
                       self.name, 'Using cfs scheduler for subprocess\n' )
687 692
        return Host.popen( self, *args, mncmd=mncmd, **kwargs )
688 693

  
689 694
    def cleanup( self ):
......
698 703
        "Check (Ubuntu,Debian) kernel config for CONFIG_RT_GROUP_SCHED for RT"
699 704
        if not cls._rtGroupSched:
700 705
            release = quietRun( 'uname -r' ).strip('\r\n')
701
            output = quietRun( 'grep CONFIG_RT_GROUP_SCHED /boot/config-%s' % release )
706
            output = quietRun( 'grep CONFIG_RT_GROUP_SCHED /boot/config-%s' %
707
                               release )
702 708
            if output == '# CONFIG_RT_GROUP_SCHED is not set\n':
703
                error( '\n*** error: please enable RT_GROUP_SCHED in your kernel\n' )
709
                error( '\n*** error: please enable RT_GROUP_SCHED'
710
                       'in your kernel\n' )
704 711
                exit( 1 )
705 712
            cls._rtGroupSched = True
706 713

  
......
755 762
            sched = self.sched
756 763
        if sched == 'rt':
757 764
            if not f or f < 0:
758
                raise Exception( 'Please set a positive CPU fraction for sched=rt\n' )
759
                return
765
                raise Exception( 'Please set a positive CPU fraction'
766
                                 ' for sched=rt\n' )
760 767
            pstr, qstr, period, quota = self.rtInfo( f )
761 768
        elif sched == 'cfs':
762 769
            pstr, qstr, period, quota = self.cfsInfo( f )
......
881 888

  
882 889
    def connected( self ):
883 890
        "Is the switch connected to a controller? (override this method)"
884
        return False and self  # satisfy pylint
891
        raise NotImplementedError( "connected() needs to be implemented in"
892
                                   " Switch subclass %s" % self.__class__ )
885 893

  
886 894
    def __repr__( self ):
887 895
        "More informative string representation"
......
890 898
        return '<%s %s: %s pid=%s> ' % (
891 899
            self.__class__.__name__, self.name, intfs, self.pid )
892 900

  
901

  
893 902
class UserSwitch( Switch ):
894 903
    "User-space switch."
895 904

  
......
982 991
                    self.TCReapply( intf )
983 992

  
984 993
    def stop( self, deleteIntfs=True ):
985
        "Stop OpenFlow reference user datapath."
994
        """Stop OpenFlow reference user datapath.
995
           deleteIntfs: delete interfaces? (True)"""
986 996
        self.cmd( 'kill %ofdatapath' )
987 997
        self.cmd( 'kill %ofprotocol' )
988 998
        if deleteIntfs:
......
1033 1043
        self.execed = False
1034 1044

  
1035 1045
    def stop( self, deleteIntfs=True ):
1036
        "Terminate kernel datapath."
1046
        """Terminate kernel datapath."
1047
           deleteIntfs: delete interfaces? (True)"""
1037 1048
        quietRun( 'ovs-dpctl del-dp ' + self.dp )
1038 1049
        self.cmd( 'kill %ovs-openflowd' )
1039 1050
        if deleteIntfs:
......
1075 1086
                   'You may wish to try '
1076 1087
                   '"service openvswitch-switch start".\n' )
1077 1088
            exit( 1 )
1078
        info = quietRun( 'ovs-vsctl --version' )
1079
        cls.OVSVersion =  findall( '\d+\.\d+', info )[ 0 ]
1089
        version = quietRun( 'ovs-vsctl --version' )
1090
        cls.OVSVersion =  findall( r'\d+\.\d+', version )[ 0 ]
1080 1091

  
1081 1092
    @classmethod
1082 1093
    def isOldOVS( cls ):
1094
        "Is OVS ersion < 1.10?"
1083 1095
        return ( StrictVersion( cls.OVSVersion ) <
1084 1096
             StrictVersion( '1.10' ) )
1085 1097

  
......
1186 1198

  
1187 1199

  
1188 1200
    def stop( self, deleteIntfs=True ):
1189
        "Terminate OVS switch."
1201
        """Terminate OVS switch.
1202
           deleteIntfs: delete interfaces? (True)"""
1190 1203
        self.cmd( 'ovs-vsctl del-br', self )
1191 1204
        if self.datapath == 'user':
1192 1205
            self.cmd( 'ip link del', self )
......
1255 1268
        self.cmd( ' '.join(args) + ' >' + logfile + ' 2>&1 </dev/null &' )
1256 1269

  
1257 1270
    def stop( self, deleteIntfs=True ):
1258
        "Terminate IVS switch."
1271
        """Terminate IVS switch.
1272
           deleteIntfs: delete interfaces? (True)"""
1259 1273
        self.cmd( 'kill %ivs' )
1260 1274
        self.cmd( 'wait' )
1261 1275
        if deleteIntfs:
......
1276 1290
        return self.cmd( 'ovs-ofctl ' + ' '.join( args ) +
1277 1291
                         ' tcp:127.0.0.1:%i' % self.listenPort )
1278 1292

  
1293
    def connected( self ):
1294
        "For now, return True since we can't tell if we're connected"
1295
        return True
1296

  
1279 1297

  
1280 1298
class Controller( Node ):
1281 1299
    """A Controller is a Node that is running (or has execed?) an
......
1323 1341
                  ' 1>' + cout + ' 2>' + cout + ' &' )
1324 1342
        self.execed = False
1325 1343

  
1326
    def stop( self ):
1344
    def stop( self, *args, **kwargs ):
1327 1345
        "Stop controller."
1328 1346
        self.cmd( 'kill %' + self.command )
1329 1347
        self.cmd( 'wait %' + self.command )
1330
        self.terminate()
1348
        super( Controller, self ).stop( *args, **kwargs )
1331 1349

  
1332 1350
    def IP( self, intf=None ):
1333 1351
        "Return IP address of the Controller"
......
1343 1361
            self.__class__.__name__, self.name,
1344 1362
            self.IP(), self.port, self.pid )
1345 1363
    @classmethod
1346
    def isAvailable( self ):
1364
    def isAvailable( cls ):
1365
        "Is controller available?"
1347 1366
        return quietRun( 'which controller' )
1348 1367

  
1349 1368
class OVSController( Controller ):
......
1353 1372
            command = 'test-controller'
1354 1373
        Controller.__init__( self, name, command=command, **kwargs )
1355 1374
    @classmethod
1356
    def isAvailable( self ):
1357
        return quietRun( 'which ovs-controller' ) or quietRun( 'which test-controller' )
1375
    def isAvailable( cls ):
1376
        return ( quietRun( 'which ovs-controller' ) or
1377
                 quietRun( 'which test-controller' ) )
1358 1378

  
1359 1379
class NOX( Controller ):
1360 1380
    "Controller to run a NOX application."
......
1432 1452
                  " at %s:%d\n" % ( self.ip, self.port ) )
1433 1453

  
1434 1454

  
1435
DefaultControllers = [ Controller, OVSController ]
1455
DefaultControllers = ( Controller, OVSController )
1436 1456

  
1437 1457
def findController( controllers=DefaultControllers ):
1438 1458
    "Return first available controller from list, if any"
......
1446 1466
    if not controller:
1447 1467
        raise Exception( 'Could not find a default OpenFlow controller' )
1448 1468
    return controller( name, **kwargs )
1449

  

Also available in: Unified diff