Added script cl-update-config

develop
Самоукин Алексей 14 years ago
parent 6dac597c23
commit b07681e60b

@ -0,0 +1,209 @@
#-*- coding: utf-8 -*-
# Copyright 2010 Mir 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.
__version__ = "2.2.0.0"
__app__ = "calculate-lib"
import sys, os, stat, re
from cl_log import log
import cl_datavars
import cl_template
from cl_print import color_print as old_color_print
import cl_lang
# Перевод модуля
tr = cl_lang.lang()
tr.setLocalDomain('cl_lib')
tr.setLanguage(sys.modules[__name__])
packagePath = "/usr/lib/calculate-2.2"
for path in os.listdir(packagePath):
realPath = os.path.join(packagePath,path)
if os.path.isdir(realPath):
pymPath = os.path.join(realPath,"pym")
if len(filter(lambda x:x.startswith("cl_vars_") and\
x.endswith(".py") or x.startswith("cl_fill_") and\
x.endswith(".py"), os.listdir(pymPath)))==2:
sys.path.insert(0, os.path.abspath(pymPath))
class writeLog:
"""Класс логгирования"""
logger = log("apply-templates",
filename="/var/log/calculate/update_config.log",
formatter="%(asctime)s - %(levelname)s - %(message)s")
class color_print(old_color_print, writeLog):
"""Класс для переопределения печати сообщений"""
_printObj = old_color_print()
def printERROR(self, *arg, **argv):
"""Вывод на печать ошибки"""
# Запись в log ошибки
self.logger.error(arg[0])
self._printObj.printERROR(*arg, **argv)
def printSUCCESS(self, *arg, **argv):
"""Вывод на печать в случае успеха без [ok] справа"""
# Запись в log информации
self.logger.info(arg[0])
self._printObj.printSUCCESS(*arg, **argv)
def printWARNING(self, *arg, **argv):
"""Вывод на печать предупреждения"""
# Запись в log предупреждения
self.logger.warn(arg[0])
self._printObj.printWARNING(*arg, **argv)
def printOK(self, *arg, **argv):
"""Вывод на печать в случае успеха с [ok] справа"""
# Запись в log информации
self.logger.info(arg[0])
self._printObj.printOK(*arg, **argv)
def printNotOK(self, *arg, **argv):
"""Вывод на печать в случае сбоя"""
# Запись в log предупреждения
self.logger.error(arg[0])
self._printObj.printNotOK(*arg, **argv)
class DataVarsObject(cl_datavars.DataVars):
"""Класс переменных для десктопа"""
def __init__(self, section):
cl_datavars.DataVars.__init__(self)
self.section=section
def importDataObject(self, **args):
'''Заполнить конфигурацию переменных, для десктопа'''
# Имя секции в calculate.env
#envSection = "calculate-desktop"
# заполнить переменные окружения алгоритмом по умолнанию
self.importData(self.section, ('cl_vars_%s' %self.section,
'cl_fill_%s' %self.section))
self.flIniFile()
class updateSystemConfigs(color_print, writeLog):
"""Апдейт системных конфигурационных файлов"""
patternBelongDir = re.compile("belong\(\)")
patternBelongName = re.compile("belong\(([^\(\)]+)\)")
patternSect = re.compile("^\s*\[([^\[\]]+)\]\s*")
templatePaths = ['/usr/share/calculate-2.2/templates',
'/var/calculate/templates',
'/var/calculate/remote/templates']
firstEnvFile = "/etc/calculate/calculate2.env"
def _isApplyTemplateDir(self, scanDir, nameProgram, flagDir=False):
"""Есть ли шаблоны в директории scanDir для пакета nameProgram
выдает True, False
"""
ret = False
if flagDir or stat.S_ISDIR(os.stat(scanDir)[stat.ST_MODE]):
for fileOrDir in sorted(os.listdir(scanDir)):
absPath = os.path.join(scanDir,fileOrDir)
#print absPath
statInfo = os.stat(absPath)[stat.ST_MODE]
if stat.S_ISREG(statInfo):
textFile = open(absPath).read()
if "cl_pass_action==desktop" in textFile:
break
if self.patternBelongDir.search(textFile):
ret = os.path.basename(os.path.dirname(absPath))
if ret == nameProgram:
ret = True
break
else:
ret = False
else:
searchObj = self.patternBelongName.search(textFile)
if searchObj:
ret = searchObj.grpoup(1)
if ret == nameProgram:
ret = True
break
else:
ret = False
elif stat.S_ISDIR(statInfo):
ret = self._isApplyTemplateDir(absPath, nameProgram, True)
if ret:
break
return ret
def isExistsProtectFiles(self, configPath):
"""Есть ли в защищенных директориях конфигурационные файлы"""
if not "CONFIG_PROTECT" in os.environ:
self.printERROR(_("Missing environment variable CONFIG_PROTECT"))
exit(1)
protectPaths = ["/etc"] + map(lambda x: x.strip(),
os.environ["CONFIG_PROTECT"].split(" "))
flagFoundProtect = False
for pPath in protectPaths:
fPath = os.path.join(configPath, pPath[1:])
if os.path.exists(fPath) and os.listdir(fPath):
flagFoundProtect = True
break
if not flagFoundProtect:
return False
return True
def updateConfig(self, nameProgram, configPath):
if not os.path.exists(configPath):
self.printERROR(_("Path '%s' does not exist")%configPath)
return False
if not os.path.exists(self.firstEnvFile):
self.printWARNING(_("File '%s' does not exist")%self.firstEnvFile)
return True
if not os.access(self.firstEnvFile, os.R_OK):
self.printWARNING(_("Permission denied: '%s'")%self.firstEnvFile)
return True
sections = []
sectionsWork = []
for line in open(self.firstEnvFile).readlines():
sRet = self.patternSect.search(line)
if sRet:
sectionsWork.append(sRet.group(1))
#sectionsWork = os.listdir(self.templatePaths[0])
for sectName in sectionsWork:
for templatePath in self.templatePaths:
fullPath = os.path.join(templatePath,sectName)
if not sectName in sections and os.path.isdir(fullPath):
if self._isApplyTemplateDir(fullPath, nameProgram):
sections.append(sectName)
dictPakkages = {}
for sectName in sections:
clVars = DataVarsObject(sectName)
clVars.importDataObject()
clVars.Set("cl_root_path",configPath, True)
clVars.Set("cl_belong_pkg",nameProgram, True)
clTempl = cl_template.template(clVars)
dirsFiles = clTempl.applyTemplates()
if dirsFiles and dirsFiles[1]:
dictPakkages[clVars.Get("cl_name")+"-"+clVars.Get("cl_ver")] =\
sorted(list(set(dirsFiles[1])))
if dictPakkages:
self.logger.info(_("Package %s") %nameProgram)
for calcPkg in dictPakkages:
self.printWARNING(_("Package %s has changed files")%calcPkg+":")
for nameF in dictPakkages[calcPkg]:
nameFile = nameF.partition(configPath)[2]
if nameFile[:1] != "/":
nameFile = "/" + nameFile
self.printWARNING(" "*5 + nameFile)
return True

@ -0,0 +1,103 @@
#-*- coding: utf-8 -*-
# Copyright 2010 Mir 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.
from update_config.cl_update_config import updateSystemConfigs, color_print,\
__app__, __version__
from cl_print import color_print as old_color_print
from cl_opt import opt
import sys
import cl_lang
# Перевод модуля
tr = cl_lang.lang()
tr.setLocalDomain('cl_lib')
tr.setLanguage(sys.modules[__name__])
# Использование программы
USAGE = _("%prog [options] package_name")
# Коментарии к использованию программы
COMMENT_EXAMPLES = _("Update configuration files of package nss_ldap")
# Пример использования программы
EXAMPLES = _("%prog --system --path / nss_ldap")
# Описание программы (что делает программа)
DESCRIPTION = _("Update configuration files package installed")
# Опции командной строки
CMD_OPTIONS = [{'longOption':"system",
'help':_("update system configuration files")},
{'longOption':"desktop",
'help':_("update desktop (user) configuration files")},
{'longOption':"path",
'optVal':"PATH",
'help':_("root path for saving the updated configuration files")}]
class update_cmd:
def __init__(self):
# Объект опций командной строки
self.optobj = opt(\
package=__app__,
version=__version__,
usage=USAGE,
examples=EXAMPLES,
comment_examples=COMMENT_EXAMPLES,
description=DESCRIPTION,
option_list=CMD_OPTIONS + opt.color_control,
check_values=self.checkOpts)
# Создаем объект логики
self.logicObj = updateSystemConfigs()
def setPrintNoColor(self, optObj):
"""Установка печати сообщений без цвета"""
if optObj.color and optObj.color=="never":
old_color_print.colorPrint = lambda *arg: \
sys.stdout.write(arg[-1]) or\
sys.stdout.flush()
def checkOpts(self, optObj, args):
"""Проверка опций командной строки"""
if not args:
errMsg = _("no such argument") + ":" + " %s" %USAGE.split(" ")[-1]
self.optobj.error(errMsg)
return False
if len(args)>1:
errMsg = _("incorrect argument") + ":" + " %s" %" ".join(args)
self.optobj.error(errMsg)
return False
if not optObj.path:
errMsg = _("no such option") + ":" + " --path"
self.optobj.error(errMsg)
return False
if not filter(lambda x: x, [optObj.system, optObj.desktop]):
errMsg = _("no such options") + ":" + " --system " + _("or") +\
" --desktop"
self.optobj.error(errMsg)
return False
return optObj, args
def updateSystemConfig(self, nameProgram, configPath):
"""Обновление системных конфигурационных файлов"""
# Проверка есть ли в пакете защищенные конфигурационные файлы
if not self.logicObj.isExistsProtectFiles(configPath):
self.logicObj.logger.info(_("Package %s") %nameProgram)
self.logicObj.logger.warn(_("Not found protected files"))
return True
# Обновление конфигурационных файлов
if not self.logicObj.updateConfig(nameProgram, configPath):
return False
return True

@ -0,0 +1,43 @@
#!/usr/bin/python
#-*- coding: utf-8 -*-
# Copyright 2010 Mir 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 sys
import os
sys.path.insert(0,os.path.abspath('/usr/lib/calculate-2.2/calculate-lib/pym'))
from update_config.cl_update_config_cmd import update_cmd
import cl_lang
# Перевод модуля
tr = cl_lang.lang()
tr.setLocalDomain('cl_lib')
tr.setLanguage(sys.modules[__name__])
if __name__ == "__main__":
obj = update_cmd()
ret = obj.optobj.parse_args()
if ret is False:
sys.exit(1)
opts, args = ret
programName = args[0]
# Установка цвета печати сообщений
obj.setPrintNoColor(opts)
# Выполняем логику программы
if opts.system:
if not obj.updateSystemConfig(programName, opts.path):
sys.exit(1)
if opts.desktop:
pass
sys.exit(0)

@ -1,4 +1,5 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*-
# setup.py --- Setup script for calculate-lib # setup.py --- Setup script for calculate-lib
@ -16,14 +17,47 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import sys, os
import sys
from distutils.core import setup from distutils.core import setup
from distutils.command.build_scripts import build_scripts
from distutils.command.install_scripts import install_scripts
__version__ = "2.2.0.0"
__app__ = "calculate-lib"
class cl_build_scripts(build_scripts):
"""Class for build scripts"""
def run (self):
scripts = ['./scripts/cl-update-config']
backup_build_dir = self.build_dir
backup_scripts = filter(lambda x: not x in scripts, self.scripts)
self.scripts = scripts
self.build_dir = self.build_dir + "-bin"
build_scripts.run(self)
if backup_scripts:
self.scripts = backup_scripts
self.build_dir = backup_build_dir
build_scripts.run(self)
class cl_install_scripts(install_scripts):
"""Class for install scripts"""
def run (self):
backup_install_dir = self.install_dir
backup_build_dir = self.build_dir
cl_cmd_obj = self.distribution.get_command_obj("install")
self.build_dir = self.build_dir + "-bin"
self.install_dir = os.path.join(cl_cmd_obj.install_platlib, __app__,
"bin")
install_scripts.run(self)
if os.path.exists(backup_build_dir):
self.build_dir = backup_build_dir
self.install_dir = backup_install_dir
install_scripts.run(self)
setup( setup(
name = 'calculate-lib', name = __app__,
version = "2.2.0.0", version = __version__,
description = "The library for Calculate 2", description = "The library for Calculate 2",
author = "Mir Calculate Ltd.", author = "Mir Calculate Ltd.",
author_email = "support@calculate.ru", author_email = "support@calculate.ru",
@ -33,7 +67,11 @@ setup(
packages = ['calculate-lib.pym', packages = ['calculate-lib.pym',
'calculate-lib.pym.format', 'calculate-lib.pym.format',
'calculate-lib.pym.server', 'calculate-lib.pym.server',
'calculate-lib.pym.client'], 'calculate-lib.pym.client',
'calculate-lib.pym.update_config'],
data_files = [("/usr/share/calculate-2.2/i18n",['i18n/cl_lib_ru.mo']), data_files = [("/usr/share/calculate-2.2/i18n",['i18n/cl_lib_ru.mo']),
("/var/calculate/remote",[])], ("/var/calculate/remote",[])],
scripts=["./scripts/cl-update-config"],
cmdclass={'build_scripts':cl_build_scripts,
'install_scripts':cl_install_scripts},
) )

Loading…
Cancel
Save