###########################################################
#
# Daemon configuration
#
###########################################################
import logging as log
import pickle
import hashlib
import os
import imp
import re
from ConfigParser import ConfigParser
import filters
import statespaces
class DynamicModuleCfg:
"""Dynamic module manager"""
modSubDir = None
CHECKSUM_FILE = 'checksums'
CHECKSUM_SECTION = 'SHA-1_CHECKSUMS'
def __init__(self, modSubDir):
self.modSubDir = modSubDir
self.checkSumFile = modSubDir + '/' + self.CHECKSUM_FILE
if not os.path.exists(self.checkSumFile):
self.__createCsumsFile()
def loadModule(self, className):
pFileName = os.getcwd() + '/' + self.modSubDir + '/' + className + '.p'
log.debug('Reading from ' + pFileName)
fp = open(pFileName, 'r')
p = pickle.Unpickler(fp)
loadedMod = p.load()
fp.close()
if not self.__verifyCheckSum(className, pFileName):
print 'Invalid checksum'
return None
else:
return loadedMod
def loadModules(self, config = None):
subDirFiles = os.listdir(os.getcwd() + '/' + self.modSubDir)
p = re.compile('.p$', re.IGNORECASE)
modFiles = [elem for elem in subDirFiles if p.search(elem) is not None]
modNames = []
for mfName in modFiles:
modNames.append(mfName.split('.')[0])
log.debug('Found modules: ' + str(modNames))
myMods = {}
for mName in modNames:
classObj = self.loadModule(mName)
if classObj is not None:
myMods[mName] = classObj
return myMods
def saveModule(self, className, classObj):
pFileName = os.getcwd() + '/' + self.modSubDir + '/' + className + '.p'
log.debug('Writing to ' + pFileName)
fp = open(pFileName, 'w')
p = pickle.Pickler(fp)
p.dump(classObj)
fp.close()
self.__writeCheckSum(className, pFileName)
def __doCheckSum(self, filename):
f = open(filename, 'r')
data = f.read()
f.close()
hasher = hashlib.sha1()
hasher.update(data)
digest = hasher.hexdigest()
return digest
def __createCsumsFile(self):
csumsfile = open(self.checkSumFile, 'w')
csumsfile.write('[' + self.CHECKSUM_SECTION + ']\n')
csumsfile.close()
def __writeCheckSum(self, entryname, filename):
csumsfile = open(self.checkSumFile, 'r+')
csumcfg = ConfigParser()
csumcfg.readfp(csumsfile)
digest = self.__doCheckSum(filename)
csumcfg.set(self.CHECKSUM_SECTION, entryname, digest)
csumsfile.seek(0)
csumcfg.write(csumsfile)
def __verifyCheckSum(self, entryname, filename):
csumsfile = open(self.checkSumFile, 'r')
csumcfg = ConfigParser()
csumcfg.readfp(csumsfile)
digest = csumcfg.get(self.CHECKSUM_SECTION, entryname)
cur_digest = self.__doCheckSum(filename)
log.debug('Old checksum ' + digest + '\nNew checksum: ' + cur_digest)
if cur_digest == digest:
return True
return False
def importModule(self, className, requiredAttributes):
"""Imports a given class from the module with the same name """
codeFile = os.getcwd() + '/' + self.modSubDir + '/' + className + '.py'
mod = imp.load_source(self.modSubDir + '.' + className, codeFile)
newClass = eval('mod.' + className)()
for ra in requiredAttributes:
if not hasattr(newClass, ra):
print className, ': missing required symbol \"' + ra + '\"'
return None
self.saveModule(className, newClass)
return newClass
class FilterCfg:
"""Filter resource manager"""
REQUIRED_ATTRIBUTES = ['ASSOCIATED_SPACES', 'DESCRIPTIVE_NAME',
'attach', 'detach', 'filter']
dynamicModuleCfg = None
FILTER_SUBDIR = 'filters'
filterModules = {}
def __init__(self):
self.dynamicModuleCfg = DynamicModuleCfg(self.FILTER_SUBDIR)
def loadFilter(self, name):
newFilt = self.dynamicModuleCfg.loadModule(name)
if newFilt is not None:
filterModules[name] = newFilt
return True
else:
return False
def loadFilters(self, config = None):
self.filterModules = self.dynamicModuleCfg.loadModules()
for fM in self.filterModules:
log.debug(fM)
def __saveFilter(self, className, classObj):
self.dynamicModuleCfg.saveModule(className, classObj)
def saveFilters(self):
for className in self.filterModules:
self.__saveFilter(className, self.filterModules[className])
def importFilter(self, className):
"""Imports a given filter definition """
classObj = self.dynamicModuleCfg.importModule(className, self.REQUIRED_ATTRIBUTES)
if classObj is not None:
print 'Imported: ' + classObj.DESCRIPTIVE_NAME
return True
else:
return False
class StateSpaceCfg:
"""State space resource manager"""
REQUIRED_ATTRIBUTES = ['DESCRIPTIVE_NAME',
'load', 'reset', 'run', 'unload']
dynamicModuleCfg = None
FILTER_SUBDIR = 'statespaces'
spaceModules = {}
def __init__(self):
self.dynamicModuleCfg = DynamicModuleCfg(self.FILTER_SUBDIR)
def loadSpace(self, name):
newSpace = self.dynamicModuleCfg.loadModule(name)
if newSpace is not None:
spaceModules[name] = newFilt
return True
else:
return False
def loadSpaces(self, config = None):
self.spaceModules = self.dynamicModuleCfg.loadModules()
for sM in self.spaceModules:
log.debug(sM)
def __saveSpace(self, className, classObj):
self.dynamicModuleCfg.saveModule(className, classObj)
def saveSpaces(self):
for className in self.spaceModules:
self.__saveSpace(className, self.spaceModules[className])
def importSpace(self, name):
"""Imports a given state space definition file """
classObj = self.dynamicModuleCfg.importModule(name, self.REQUIRED_ATTRIBUTES)
if classObj is not None:
print 'Imported: ' + classObj.DESCRIPTIVE_NAME
return True
else:
return False
class DaemonConfig:
stateSpaceCfg = None
filterCfg = None
filterChain = []
def __init__ (self):
self.filterCfg = FilterCfg()
self.stateSpaceCfg = StateSpaceCfg()
def setupFilterChain(self):
self.filterChain = ['DefaultFilter']
def setupFilterBindings(self):
for f in self.filterCfg.filterModules.values():
assocSpaces = []
for s in f.ASSOCIATED_SPACES:
if self.stateSpaceCfg.spaceModules.has_key(s):
assocSpaces.append(self.stateSpaceCfg.spaceModules[s])
else:
print 'WARNING: Reference to undefined state space: ' + s
setattr(f, '__ASSOCIATED_SPACES__', assocSpaces)