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
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
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 )
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'))
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' ) )