From 29ce48b580bf0ebd0f3a13070f83fa88a1e519ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=B0=D0=BC=D0=BE=D1=83=D0=BA=D0=B8=D0=BD=20=D0=90?= =?UTF-8?q?=D0=BB=D0=B5=D0=BA=D1=81=D0=B5=D0=B9?= Date: Wed, 20 Oct 2010 17:46:18 +0400 Subject: [PATCH] Added api module cl_api. Added template function module(). Deleted template functions clget() and clvar(). --- pym/cl_abstract.py | 41 ++++--- pym/cl_api.py | 251 +++++++++++++++++++++++++++++++++++++++++ pym/cl_template.py | 87 +++++++------- pym/server/services.py | 27 +++-- 4 files changed, 337 insertions(+), 69 deletions(-) create mode 100644 pym/cl_api.py diff --git a/pym/cl_abstract.py b/pym/cl_abstract.py index dfba43f..b4bf146 100644 --- a/pym/cl_abstract.py +++ b/pym/cl_abstract.py @@ -1,17 +1,32 @@ # -*- coding: utf-8 -*- from abc import ABCMeta, abstractmethod -class abs_api: +class abs_min: __metaclass__ = ABCMeta - @abstractmethod - def getServiceName(self): - '''Get name service''' - @abstractmethod def isSetup(self): '''Is setup service (True/False)''' + @abstractmethod + def getPrioritet(self): + '''Get prioritet 0-100 + users 50-70 + ''' + + @abstractmethod + def getVars(self): + '''Get Service vars + ''' + + +class abs_api(abs_min): + __metaclass__ = ABCMeta + + @abstractmethod + def getServiceName(self): + '''Get name service''' + @abstractmethod def isStart(self): '''Is run server (True/False)''' @@ -40,12 +55,6 @@ class abs_api: def delRunlevel(self): '''Add daemon to runlevel''' - @abstractmethod - def getRunPrioritet(self): - '''Get run daemon prioritet 0-100 - users 50-70 - ''' - @abstractmethod def delVarsFromEnv(self): '''Delete template vars in env files @@ -56,12 +65,12 @@ class abs_api: '''Get Service information ''' - @abstractmethod - def getVars(self): - '''Get Service vars - ''' - @abstractmethod def getPkgName(self): '''Get package name ''' + + @abstractmethod + def applyTemplates(self): + '''Apply package templates + ''' \ No newline at end of file diff --git a/pym/cl_api.py b/pym/cl_api.py new file mode 100644 index 0000000..5fc2753 --- /dev/null +++ b/pym/cl_api.py @@ -0,0 +1,251 @@ +#-*- coding: utf-8 -*- + +# Copyright 2008-2010 Calculate Ltd. http://www.calculate-linux.org +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import os,sys + + +from cl_print import color_print + +# translate language +import cl_lang +tr = cl_lang.lang() +tr.setLocalDomain('cl_lib') +tr.setLanguage(sys.modules[__name__]) + +from cl_datavars import DataVars + +class APIError(Exception): + """Класс ошибок""" + pass + +class libVars: + + clLibVars = False + + def createClLibVars(self, clLibVars=False): + """Создает объект библиотечных переменных""" + if not clLibVars: + clLibVars = DataVars() + # Заменяем значения переменных переменными из env файлов + clLibVars.flIniFile() + # Устанавливаем у объекта атрибут объект переменных + self.clLibVars = clLibVars + return True + +class _services(color_print, libVars): + apiObjs = {} + + def getApiClass(self, apiFile): + importPath, moduleName = os.path.split(apiFile) + moduleName = moduleName.rpartition(".py")[0] + if not importPath in sys.path: + sys.path.insert(0, importPath) + try: + className = getattr(__import__(moduleName, + globals(), locals(), + ['serviceAPI']), + 'serviceAPI') + except (ImportError, AttributeError): + self.printERROR(_("Can not import module %s")% apiFile) + cl_overriding.exit(1) + return className + + def getPkgApi(self, pkgName): + """get package api""" + if not pkgName in self.apiObjs: + self.createClLibVars(clLibVars=self.clLibVars) + apiDict = self.clLibVars.Get('cl_api') + if not apiDict or not type(apiDict) is dict: + return None + if not pkgName in apiDict: + return None + apiFile = apiDict[pkgName] + className = self.getApiClass(apiFile) + try: + apiObject = className() + except: + self.printERROR(_("Can not create API object")) + self.printERROR(_("Module %s")% apiFile) + cl_overriding.exit(1) + self.apiObjs[pkgName] = apiObject + return apiObject + else: + return self.apiObjs[pkgName] + + def getAllPkgApi(self): + """get all packages api objects""" + self.createClLibVars(clLibVars=self.clLibVars) + apiDict = self.clLibVars.Get('cl_api') + if not apiDict or not type(apiDict) is dict: + return [] + apiFiles = apiDict.values() + apiObjects = [] + for apiFile in apiFiles: + className = self.getApiClass(apiFile) + try: + apiObjects.append(className()) + except: + self.printERROR(_("Can not create API object")) + self.printERROR(_("Module %s")% apiFile) + cl_overriding.exit(1) + return apiObjects + + def runMethodToPkg(self, pkgName, methodName, argv=[]): + """Execute method from pkg""" + pkgObj = self.getPkgApi(pkgName) + if pkgObj is None: + return "" + if not hasattr(pkgObj, methodName) or\ + not callable(getattr(pkgObj, methodName)): + self.printERROR(_("Can not found method %(method)s in \ +API object service %(service)s") %{'method':methodName, + 'service':pkgObj.getServiceName()}) + cl_overriding.exit(1) + if argv: + res = getattr(pkgObj, methodName)(*argv) + else: + res = getattr(pkgObj, methodName)() + return res + +class attribute(object): + def __init__(self, clVars): + self._varsObj=clVars + + + def __getattribute__(self, attr): + if attr.startswith("__"): + value = object.__getattribute__(self, attr) + else: + try: + value = object.__getattribute__(self,'_varsObj').Get(attr) + except Exception, e: + #value = "" + raise APIError(str(e).strip()) + object.__setattr__(self, attr, value) + return value + + def __setattr__(self, attr, value): + if attr.startswith("__") or attr=="_varsObj": + object.__setattr__(self, attr, value) + else: + try: + varObj = object.__getattribute__(self,'_varsObj') + if varObj.Set(attr, value) is False: + raise AttributeError(attr) + except: + raise AttributeError(attr) + +class _pkgAPI(object): + + def __init__(self, pkgName): + services = _services() + self.var = False + varObj = services.runMethodToPkg(pkgName, 'getVars') + if varObj: + self.var = attribute(varObj) + pkgObj = services.getPkgApi(pkgName) + for attr in dir(pkgObj): + if not attr.startswith("_") and callable(getattr(pkgObj, attr)) and\ + getattr(pkgObj, attr).im_func.func_code.co_varnames==('self',): + setattr(self, attr, getattr(pkgObj, attr)) + + def __getattribute__(self, attr): + if attr.startswith("__") or attr in ('var','all'): + value = object.__getattribute__(self, attr) + else: + try: + value = object.__getattribute__(self,attr)() + except: + raise APIError(_("Can not found method %s")%attr) + object.__setattr__(self, attr, value) + return value + +class _allPkg(object): + + def __init__(self, listPkgObj): + def smpPrioritetReverse(objectA, objectB): + '''Comparison of the run priorities of objects + + to sort in descending order + ''' + prioritetA = objectA.getPrioritet() + prioritetB = objectB.getPrioritet() + if prioritetA == prioritetB: + return 0 + elif prioritetA < prioritetB: + return 1 + else: + return -1 + + def smpPrioritetNormal(objectA, objectB): + '''Comparison of the run priorities of objects + + to sort in descending order + ''' + prioritetA = objectA.getPrioritet() + prioritetB = objectB.getPrioritet() + if prioritetA == prioritetB: + return 0 + elif prioritetA > prioritetB: + return 1 + else: + return -1 + + self._listPkgObjNormal = listPkgObj[:] + self._listPkgObjNormal.sort(smpPrioritetNormal) + self._listPkgObjReverse = listPkgObj[:] + self._listPkgObjReverse.sort(smpPrioritetReverse) + + + def __getattribute__(self, attr): + if attr.startswith("__") or\ + attr in ('_listPkgObjNormal','_listPkgObjReverse'): + value = object.__getattribute__(self, attr) + else: + if attr.startswith('stop') or attr.startswith('del'): + listObi = object.__getattribute__(self, '_listPkgObjReverse') + else: + listObi = object.__getattribute__(self,'_listPkgObjNormal') + listValues = [] + for pkgObj in listObi: + try: + val = object.__getattribute__(pkgObj, attr)() + except Exception, e: + continue + listValues.append(val) + if filter(lambda x: set(listValues) == set(x), + ([True],[False],[True,False])): + if False in listValues: + return False + else: + return True + listValues = filter(lambda x: x, listValues) + listValues = map(lambda x: '1' if x is True else x, listValues) + value = "\n".join(listValues) + object.__setattr__(self, attr, value) + return value + +class packagesAPI: + + def __init__(self): + objLibVars = libVars() + objLibVars.createClLibVars() + apiDict = objLibVars.clLibVars.Get('cl_api') + listPkgObj = [] + for pkgName in apiDict.keys(): + pkgAPIObj = _pkgAPI(pkgName) + setattr(self, pkgName.replace('-','_'), pkgAPIObj) + listPkgObj.append(pkgAPIObj) + setattr(self, 'all', _allPkg(listPkgObj)) diff --git a/pym/cl_template.py b/pym/cl_template.py index e230f50..3fc447f 100644 --- a/pym/cl_template.py +++ b/pym/cl_template.py @@ -101,6 +101,7 @@ class _terms(_error, _shareTermsFunction): (объект для работы с переменными) function - функция для для обработки функций в заголовке блока """ + rpl = lambda x: x.replace("@@"," ") trm = {"&&":"@@and@@","||":"@@or@@"} rule = ["==", "!=", ">=", "<=", ">", "<"] listEqual = [] @@ -142,19 +143,19 @@ class _terms(_error, _shareTermsFunction): flagError = False flagFunction = True if flagError: - self.setError("'%s'"%term + " " + _("incorrect")) + self.setError("'%s'"%rpl(term)+" "+ _("incorrect")) self.setError(textError) return False #проверка на допустимость значения if self._reDenyValue.search(vals[1]): - self.setError("'%s'"%term + " " + _("incorrect")) + self.setError("'%s'"%rpl(term) + " " + _("incorrect")) self.setError(textError) return False flagIntTypeVar = None if flagFunction: valVars = function("#-%s-#"%vals[0]) if valVars is False: - self.setError("'%s'"%term + " " + _("incorrect")) + self.setError("'%s'"%rpl(term)+" "+ _("incorrect")) self.setError(textError) return False if "load" == searchFunct.group(1) and\ @@ -163,7 +164,7 @@ class _terms(_error, _shareTermsFunction): try: valVars = int(valVars) except: - self.setError("'%s'"%term + " " + \ + self.setError("'%s'"%rpl(term) + " " + \ _("incorrect")) self.setError(textError) return False @@ -210,12 +211,14 @@ class _terms(_error, _shareTermsFunction): re.search("\(\s*ver\s*,",vals[0]))): # Проверка значения на версию if self._re_not_Version.search(vals[1]): - self.setError("'%s'"%term+" "+_("incorrect")) + self.setError("'%s'"%rpl(term)+" "+\ + _("incorrect")) self.setError(_("Value is not version")) return False # Проверка значения функции на версию if self._re_not_Version.search(valVars): - self.setError("'%s'"%term+" "+_("incorrect")) + self.setError("'%s'"%rpl(term)+" "+\ + _("incorrect")) self.setError(\ _("Value function is not version")) return False @@ -240,7 +243,7 @@ class _terms(_error, _shareTermsFunction): try: valFile = int(vals[1]) except: - self.setError("'%s'"%term +" "+\ + self.setError("'%s'"%rpl(term) +" "+\ _("incorrect")) self.setError(textError) return False @@ -266,7 +269,7 @@ class _terms(_error, _shareTermsFunction): if not flagNotEmptyVals: listEqual.append(False) else: - self.setError("'%s'"%term + " "\ + self.setError("'%s'"%rpl(term) + " "\ + _("incorrect")) self.setError(textError) return False @@ -277,7 +280,7 @@ class _terms(_error, _shareTermsFunction): else: listEqual = [True] else: - self.setError("'%s'"%term + " " + _("incorrect")) + self.setError("'%s'"%rpl(term) + " " + _("incorrect")) self.setError(textError) return False if not (listEqual == [] or False in listEqual): @@ -285,8 +288,6 @@ class _terms(_error, _shareTermsFunction): if listEqual == [] or False in listEqual: return False return True - #exec("res=(%s)"%("".join(listEqual))) - #return res class fileHeader(_terms): """Обработка заголовков шаблонов и конфигурационных файлов @@ -2272,8 +2273,9 @@ class templateFunction(_error, _shareTemplate, _shareTermsFunction): def __init__(self, objVar): # Если не определен словарь функций шаблона # import services api - from server.services import services - self.services = services + from cl_api import packagesAPI, APIError + self.packagesAPI = packagesAPI + self.APIError = APIError if not self.templateFunction: # префикс функций шаблона pref = "func" @@ -3128,45 +3130,40 @@ os_disk_install not found mount point '\' and '\%s'")%mountPoint) textTemplateTmp[resS.end():] return textTemplateTmp - def funcClGet(self, funArgv, resS, localVars, textTemplateTmp): - """Функция шаблона clget(), выдает данные пакета или всех пакетов. + def funcModule(self, funArgv, resS, localVars, textTemplateTmp): + """Функция шаблона module(), выдает значение аттрибута api. - первый аргумент: - 'all' - все пакеты, - имя_пакета - данный пакет - второй аргумент: - строка запроса данных + аргумент: + путь_к_атрибуту - путь к аттрибуту + + возможные пути: + имя_пакета.var.имя_переменной - получаем значение переменной + имя_пакета.имя_метода_api - выполнение метода, получение результата + all.имя_метода_api - выполнение метода для всех пакетов с api """ terms = funArgv.replace(" ","").split(",") - if not terms[0].strip() or\ - (len(terms)==2 and not terms[1].strip()) or len(terms)!=2: + if len(terms)!=1: self.printErrTemplate() cl_overriding.exit(1) - pkgName = terms[0] - request = terms[1] - servApiObj = self.services() - replace = servApiObj.clGet(pkgName, request) - textTemplateTmp = textTemplateTmp[:resS.start()] + replace +\ - textTemplateTmp[resS.end():] - return textTemplateTmp - - def funcClVar(self, funArgv, resS, localVars, textTemplateTmp): - """Функция шаблона clvar(), выдает значение переменной пакета. - - первый аргумент: - имя_пакета - данный пакет - второй аргумент: - название переменной - """ - terms = funArgv.replace(" ","").split(",") - if not terms[0].strip() or\ - (len(terms)==2 and not terms[1].strip()) or len(terms)!=2: + pathObj = terms[0] + if not '.' in pathObj: self.printErrTemplate() cl_overriding.exit(1) - pkgName = terms[0] - varName = terms[1] - servApiObj = self.services() - replace = servApiObj.clGetVar(pkgName, varName) + pkgApiObj = self.packagesAPI() + try: + value = eval('pkgApiObj.%s'%pathObj) + except self.APIError, e: + cl_overriding.printERROR(str(e)) + self.printErrTemplate() + cl_overriding.exit(1) + except Exception, e: + value = "" + if value is True: + replace = '1' + elif value in (False, None): + replace = '' + else: + replace = str(value) textTemplateTmp = textTemplateTmp[:resS.start()] + replace +\ textTemplateTmp[resS.end():] return textTemplateTmp diff --git a/pym/server/services.py b/pym/server/services.py index b30a333..825c072 100644 --- a/pym/server/services.py +++ b/pym/server/services.py @@ -109,8 +109,8 @@ API object service %(service)s") %{'method':methodName, to sort in descending order ''' - prioritetA = objectA.getRunPrioritet() - prioritetB = objectB.getRunPrioritet() + prioritetA = objectA.getPrioritet() + prioritetB = objectB.getPrioritet() if prioritetA == prioritetB: return 0 elif prioritetA < prioritetB: @@ -123,8 +123,8 @@ API object service %(service)s") %{'method':methodName, to sort in descending order ''' - prioritetA = objectA.getRunPrioritet() - prioritetB = objectB.getRunPrioritet() + prioritetA = objectA.getPrioritet() + prioritetB = objectB.getPrioritet() if prioritetA == prioritetB: return 0 elif prioritetA > prioritetB: @@ -172,16 +172,16 @@ API object service %(service)s") %{'method':methodName, def delRunlevelAllServices(self): """Delete all services that were setup from runlevel""" return self.runMethodFromAllServices("delRunlevel", - sortedServices="reverse") + sortedServices="reverse") def delVarsFromAllServices(self): """Delete template vars from all services""" return self.runMethodFromAllServices("delVarsFromEnv", - sortedServices="reverse") + sortedServices="reverse") def getInfoFromAllServices(self, request): """Get info from all services""" return self.runMethodFromAllServices("getServiceInfo", argv=[request], - result='list') + result='list') def clGetVar(self, pkgName, varName): """Get variable value from pkg""" clVars = self.runMethodToPkg(pkgName, 'getVars') @@ -209,4 +209,15 @@ API object service %(service)s") %{'method':methodName, argv=[request]) if not res: res = "" - return res \ No newline at end of file + return res + + def applyTemplates(self, pkgNameOrAll): + """Apply templates from service or all services""" + res = "" + if pkgNameOrAll == "all": + if self.runMethodFromAllServices("applyTemplates") is False: + return False + else: + if self.runMethodToPkg(pkgNameOrAll, "applyTemplates") is False: + return False + return True \ No newline at end of file