You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
calculate-utils-2.2-lib/pym/update_config/cl_update_config.py

286 lines
12 KiB

#-*- 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
from cl_utils import runOsCommand
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 shareUpdateConfigs(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 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 _isApplyTemplateDir(self, scanDir, nameProgram, flagSkipDesktop=True,
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)
statInfo = os.stat(absPath)[stat.ST_MODE]
if stat.S_ISREG(statInfo):
textFile = open(absPath).read()
if flagSkipDesktop and\
"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,
flagSkipDesktop)
if ret:
break
return ret
class updateUserConfigs(shareUpdateConfigs):
"""Обновление пользовательских конфигурационных файлов"""
def getXUsers(self):
"""Имена пользователей в X сессии"""
xSession = 0
foundTwoSession = False
retCode, resWho = runOsCommand("who")
xUsers = []
if retCode==0:
if resWho and type(resWho) == list:
xUsers = map(lambda x: x[0],
filter(lambda x: x[1].startswith(":"),
map(lambda x: filter(lambda y: y,
x.split(" "))[:2] ,resWho)))
else:
self.printERROR(_("Can not execute 'who'"))
return False
return xUsers
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
sectionsWork = []
for line in open(self.firstEnvFile).readlines():
sRet = self.patternSect.search(line)
if sRet:
sectionsWork.append(sRet.group(1))
sectName = "desktop"
# Если установлен calculate-desktop
if sectName in sectionsWork:
section = ""
for templatePath in self.templatePaths:
fullPath = os.path.join(templatePath,sectName)
if os.path.isdir(fullPath):
if self._isApplyTemplateDir(fullPath, nameProgram,
flagSkipDesktop=False):
section = sectName
break
dictPakkages = {}
if section:
clVars = DataVarsObject(section)
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
class updateSystemConfigs(shareUpdateConfigs):
"""Обновление системных конфигурационных файлов"""
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