Exemplo n.º 1
0
    def importLib(cls, libName, className=None):
        '''Import a user-defined lib from the proper realm.
        
        :param libName: the name of the file (module) located in the code_directry
            and realm directory
        :param className: the name of the attribute (class, func or whatever) from
            the module to be loaded

        :returns: the module or element of the module loaded
        '''
        if '://' in libName:
            # This is an absolute path
            fileName = libName
        else:
            parentGlobals = inspect.currentframe().f_back.f_globals
            realm = parentGlobals.get('_beach_realm', '')
            if libName.startswith('.') or cls._code_directory_root is None:
                # For relative paths we look at the parent's path
                if '_beach_path' not in parentGlobals:
                    if '/' in parentGlobals['__file__']:
                        initPath = 'file://%s' % parentGlobals[
                            '__file__'][:parentGlobals['__file__'].rfind('/')]
                    else:
                        initPath = 'file://.'
                else:
                    initPath = parentGlobals[
                        '_beach_path'][:parentGlobals['_beach_path'].rfind('/'
                                                                           )]
            else:
                # This is a realm-relative path
                initPath = '%s/%s/' % (cls._code_directory_root, realm)

            fileName = '%s/%s.py' % (initPath, libName)

        try:
            mod = loadModuleFrom(fileName, realm)
        except urllib2.URLError:
            if os.path.isfile(fileName):
                raise
            fileName = '%s/%s/__init__.py' % (initPath, libName)
            mod = loadModuleFrom(fileName, realm)

        if className is not None and className != '*':
            mod = getattr(mod, className)

        parentGlobals = inspect.currentframe().f_back.f_globals
        if className is not None and className == '*':
            loadModule = mod
            mod = {}
            for name, val in loadModule.__dict__.iteritems():
                if not name.startswith('_') and type(name) is not ModuleType:
                    parentGlobals[name] = val
                    mod[name] = val
        elif className is not None:
            parentGlobals[className] = mod
        else:
            parentGlobals[libName] = mod

        return mod
Exemplo n.º 2
0
    def importLib( cls, libName, className = None ):
        '''Import a user-defined lib from the proper realm.
        
        :param libName: the name of the file (module) located in the code_directry
            and realm directory
        :param className: the name of the attribute (class, func or whatever) from
            the module to be loaded

        :returns: the module or element of the module loaded
        '''
        if '://' in libName:
            # This is an absolute path
            fileName = libName
        else:
            parentGlobals = inspect.currentframe().f_back.f_globals
            realm = parentGlobals.get( '_beach_realm', '' )
            if libName.startswith( '.' ) or cls._code_directory_root is None:
                # For relative paths we look at the parent's path
                if '_beach_path' not in parentGlobals:
                    if '/' in parentGlobals[ '__file__' ]:
                        initPath = 'file://%s' % parentGlobals[ '__file__' ][ : parentGlobals[ '__file__' ].rfind( '/' ) ]
                    else:
                        initPath = 'file://.'
                else:
                    initPath = parentGlobals[ '_beach_path' ][ : parentGlobals[ '_beach_path' ].rfind( '/' ) ]
            else:
                # This is a realm-relative path
                initPath = '%s/%s/' % ( cls._code_directory_root, realm )
                
            fileName = '%s/%s.py' % ( initPath, libName )

        try:
            mod = loadModuleFrom( fileName, realm )
        except urllib2.URLError:
            if os.path.isfile( fileName ):
                raise
            fileName = '%s/%s/__init__.py' % ( initPath, libName )
            mod = loadModuleFrom( fileName, realm )

        if className is not None and className != '*':
            mod = getattr( mod, className )

        parentGlobals = inspect.currentframe().f_back.f_globals
        if className is not None and className == '*':
            loadModule = mod
            mod = {}
            for name, val in loadModule.__dict__.iteritems():
                if not name.startswith( '_' ) and type( name ) is not ModuleType:
                    parentGlobals[ name ] = val
                    mod[ name ] = val
        elif className is not None:
            parentGlobals[ className ] = mod
        else:
            parentGlobals[ libName ] = mod

        return mod
Exemplo n.º 3
0
    def compileRule( self, ruleRecord ):
        env = { 'False' : False, 
                'True' : True }
        env[ "__name__" ] = None
        env[ "__file__" ] = None
        env[ "__builtins__" ] = None

        try:
            rule = {
                'name' : ruleRecord[ 'name' ], 
                'original' : ruleRecord[ 'rule' ],
            }

            if '://' in ruleRecord[ 'rule' ]:
                url = self.massageUrl( ruleRecord[ 'rule' ] )
                className = ruleRecord[ 'rule' ].split( '/' )[ -1 ]
                if className.endswith( '.py' ):
                    className = className[ 0 : -3 ]
                newClass = getattr( loadModuleFrom( url, 'hcp' ),
                                    className )
                newObj = newClass( self._actor )
                if hasattr( newObj, 'analyze' ):
                    cb = newObj.analyze
                elif hasattr( newObj, 'getDescriptor' ):
                    self.statefulDescriptors[ ruleRecord[ 'name' ] ] = StateMachine( descriptor = newObj.getDescriptor() )
                    self.statefulInstances[ ruleRecord[ 'name' ] ] = {}
                    cb = lambda event, sensor: self.evalStateful( ruleRecord[ 'name' ], event, sensor )
                else:
                    raise Exception( 'unknown file format, missing "analyze" export.' )
                rule[ 'rule' ] = cb
            else:
                rule[ 'rule' ] = eval( 'lambda event, sensor: ( %s )' % ( ruleRecord[ 'rule' ], ), env, env )


            if '://' in ruleRecord[ 'action' ]:
                url = self.massageUrl( ruleRecord[ 'action' ] )
                className = ruleRecord[ 'rule' ].split( '/' )[ -1 ]
                if className.endswith( '.py' ):
                    className = className[ 0 : -3 ]
                newClass = getattr( loadModuleFrom( url, 'hcp' ),
                                    className )
                newObj = newClass( self._actor )
                if hasattr( newObj, 'respond' ):
                    cb = newObj.respond
                else:
                    raise Exception( 'unknown file format, missing "respond" export.' )
                rule[ 'action' ] = cb
            else:
                rule[ 'action' ] = eval( 'lambda event, sensor, context, report, page: ( %s )' % ( ruleRecord[ 'action' ], ), env, env )

            # Test to see if a dummy call to the match and action will result in True
            # this should never occur and is an indicator of a bad rule that always triggers.
            isBad = False
            try:
                if rule[ 'rule' ]( None, None ):
                    isBad = True
            except:
                pass

            if isBad:
                raise Exception( 'matching rule invalid, always returns True' )

            return ( rule, None )
        except:
            exc = traceback.format_exc()
            self._actor.log( "Error compiling rule %s: %s" % ( ruleRecord.get( 'name', '-' ), exc ) )
            return ( None, exc )
Exemplo n.º 4
0
    def svc_receiveTasks(self):
        z = self.opsSocket.getChild()
        while not self.stopEvent.wait(0):
            #self.log( "Waiting for op" )
            data = z.recv()
            if data is not False and data is not None and 'req' in data:
                action = data['req']
                #self.log( "Received new ops request: %s" % action )
                if 'keepalive' == action:
                    z.send(successMessage())
                elif 'start_actor' == action:
                    if not self.isOpen:
                        z.send(errorMessage('draining'))
                    if 'actor_name' not in data or 'port' not in data or 'uid' not in data:
                        z.send(
                            errorMessage('missing information to start actor'))
                    else:
                        actorName = data['actor_name']
                        className = actorName[actorName.rfind('/') + 1:]
                        className = className[:-3] if className.endswith(
                            '.py') else className
                        realm = data.get('realm', 'global')
                        parameters = data.get('parameters', {})
                        resources = data.get('resources', {})
                        ident = data.get('ident', None)
                        trusted = data.get('trusted', [])
                        n_concurrent = data.get('n_concurrent', 1)
                        is_drainable = data.get('is_drainable', False)
                        ip = data['ip']
                        port = data['port']
                        uid = data['uid']
                        log_level = data.get('loglevel', None)
                        log_dest = data.get('logdest', None)
                        if log_level is None:
                            log_level = self._log_level
                        if log_dest is None:
                            log_dest = self._log_dest
                        try:
                            implementation = None
                            if '://' in actorName:
                                actorName = actorName if actorName.endswith(
                                    '.py') else '%s.py' % actorName
                                self.log(
                                    "Starting actor %s/%s at absolute %s" %
                                    (realm, actorName, actorName))
                                implementation = loadModuleFrom(
                                    actorName, realm)
                            else:
                                self.log(
                                    "Starting actor %s/%s at %s/%s/%s.py" %
                                    (realm, actorName, self.codeDirectory,
                                     realm, actorName))
                                implementation = loadModuleFrom(
                                    '%s/%s/%s.py' %
                                    (self.codeDirectory, realm, actorName),
                                    realm)

                            actor = getattr(implementation, className)(
                                self,
                                realm,
                                ip,
                                port,
                                uid,
                                log_level,
                                log_dest,
                                self.configFilePath,
                                parameters=parameters,
                                resources=resources,
                                ident=ident,
                                trusted=trusted,
                                n_concurrent=n_concurrent,
                                private_key=self.private_key,
                                is_drainable=is_drainable)
                        except:
                            actor = None
                            self.logCritical(
                                "Error loading actor %s: %s (%s)" %
                                (actorName, traceback.format_exc(),
                                 dir(implementation)))

                        if actor is not None:
                            self.log("Successfully loaded actor %s/%s" %
                                     (realm, actorName))
                            self.actors[uid] = actor
                            actor.start()
                            z.send(successMessage({'uid': uid}))
                        else:
                            self.logCritical(
                                'Error loading actor %s/%s: %s' %
                                (realm, actorName, traceback.format_exc()))
                            z.send(
                                errorMessage(
                                    'exception',
                                    data={'st': traceback.format_exc()}))
                elif 'kill_actor' == action:
                    if 'uid' not in data:
                        z.send(
                            errorMessage('missing information to stop actor'))
                    else:
                        uid = data['uid']
                        if uid in self.actors:
                            actor = self.actors[uid]
                            del (self.actors[uid])
                            actor.stop()
                            actor.join(timeout=60)
                            info = None
                            if not actor.ready():
                                actor.kill(timeout=60)
                                info = {'error': 'timeout'}
                                self.log("Actor %s timedout while exiting" %
                                         uid)
                            z.send(successMessage(data=info))
                        else:
                            z.send(errorMessage('actor not found'))
                elif 'get_load_info' == action:
                    info = {}
                    for uid, actor in self.actors.items():
                        info[uid] = (actor._n_free_handlers,
                                     actor._n_concurrent, actor.getPending(),
                                     actor._qps, actor._q_avg)
                    z.send(successMessage(data=info))
                elif 'is_drainable' == action:
                    z.send(successMessage({'is_drainable':
                                           self.isDrainable()}))
                elif 'drain' == action:
                    z.send(successMessage({'is_drained': self.drain()}))
                else:
                    z.send(
                        errorMessage('unknown request', data={'req': action}))
            else:
                self.logCritical("Received completely invalid request")
                z.send(errorMessage('invalid request'))
Exemplo n.º 5
0
    def svc_receiveTasks( self ):
        z = self.opsSocket.getChild()
        while not self.stopEvent.wait( 0 ):
            #self.log( "Waiting for op" )
            data = z.recv()
            if data is not False and data is not None and 'req' in data:
                action = data[ 'req' ]
                #self.log( "Received new ops request: %s" % action )
                if 'keepalive' == action:
                    z.send( successMessage() )
                elif 'start_actor' == action:
                    if 'actor_name' not in data or 'port' not in data or 'uid' not in data:
                        z.send( errorMessage( 'missing information to start actor' ) )
                    else:
                        actorName = data[ 'actor_name' ]
                        className = actorName[ actorName.rfind( '/' ) + 1 : ]
                        className = className[ : -3 ] if className.endswith( '.py' ) else className
                        realm = data.get( 'realm', 'global' )
                        parameters = data.get( 'parameters', {} )
                        resources = data.get( 'resources', {} )
                        ident = data.get( 'ident', None )
                        trusted = data.get( 'trusted', [] )
                        n_concurrent = data.get( 'n_concurrent', 1 )
                        ip = data[ 'ip' ]
                        port = data[ 'port' ]
                        uid = data[ 'uid' ]
                        log_level = data.get( 'loglevel', None )
                        log_dest = data.get( 'logdest', None )
                        if log_level is None:
                            log_level = self._log_level
                        if log_dest is None:
                            log_dest = self._log_dest
                        try:
                            implementation = None
                            if '://' in actorName:
                                actorName = actorName if actorName.endswith( '.py' ) else '%s.py' % actorName
                                self.log( "Starting actor %s/%s at absolute %s" % ( realm, actorName, actorName ) )
                                implementation = loadModuleFrom( actorName, realm )
                            else:
                                self.log( "Starting actor %s/%s at %s/%s/%s.py" % ( realm,
                                                                                    actorName,
                                                                                    self.codeDirectory,
                                                                                    realm,
                                                                                    actorName ) )
                                implementation = loadModuleFrom( '%s/%s/%s.py' % ( self.codeDirectory,
                                                                                   realm,
                                                                                   actorName ),
                                                                 realm )

                            actor = getattr( implementation,
                                             className )( self,
                                                          realm,
                                                          ip,
                                                          port,
                                                          uid,
                                                          log_level,
                                                          log_dest,
                                                          self.configFilePath,
                                                          parameters = parameters,
                                                          resources = resources,
                                                          ident = ident,
                                                          trusted = trusted,
                                                          n_concurrent = n_concurrent,
                                                          private_key = self.private_key )
                        except:
                            actor = None
                            self.logCritical( "Error loading actor %s: %s (%s)" % ( actorName, traceback.format_exc(), dir( implementation ) ) )

                        if actor is not None:
                            self.log( "Successfully loaded actor %s/%s" % ( realm, actorName ) )
                            self.actors[ uid ] = actor
                            actor.start()
                            z.send( successMessage( { 'uid' : uid } ) )
                        else:
                            self.logCritical( 'Error loading actor %s/%s: %s' % ( realm,
                                                                                  actorName,
                                                                                  traceback.format_exc() ) )
                            z.send( errorMessage( 'exception',
                                                  data = { 'st' : traceback.format_exc() } ) )
                elif 'kill_actor' == action:
                    if 'uid' not in data:
                        z.send( errorMessage( 'missing information to stop actor' ) )
                    else:
                        uid = data[ 'uid' ]
                        if uid in self.actors:
                            actor = self.actors[ uid ]
                            del( self.actors[ uid ] )
                            actor.stop()
                            actor.join( timeout = 10 )
                            info = None
                            if not actor.ready():
                                actor.kill( timeout = 10 )
                                info = { 'error' : 'timeout' }
                            z.send( successMessage( data = info ) )
                        else:
                            z.send( errorMessage( 'actor not found' ) )
                elif 'get_load_info' == action:
                    info = {}
                    for uid, actor in self.actors.items():
                        info[ uid ] = ( actor._n_free_handlers, actor._n_concurrent, actor.getPending(), actor._qps, actor._q_avg )
                    z.send( successMessage( data = info ) )
                else:
                    z.send( errorMessage( 'unknown request', data = { 'req' : action } ) )
            else:
                self.logCritical( "Received completely invalid request" )
                z.send( errorMessage( 'invalid request' ) )