diff --git a/pym/cl_template.py b/pym/cl_template.py index 66dde02..bd2711e 100644 --- a/pym/cl_template.py +++ b/pym/cl_template.py @@ -3148,7 +3148,7 @@ re.M|re.S) def createDir(self, dirName, mode=False, uid=False, gid=False): """Создает директорию""" if os.access(dirName, os.F_OK): - return [dirName] + return True else: dMode = False prevDir, tmpSubdir = os.path.split(dirName) @@ -3186,8 +3186,8 @@ re.M|re.S) os.chown(dirName, dUid, dGid) createDirs.append(dirName) except: - self.setError(_("Can not create dir: " ) + dirName) - return False + self.setError(_("Can not create dir: " ) + dirName) + return False return createDirs def applyVarsTemplate(self, textTemplate, nameTemplate): @@ -3492,9 +3492,12 @@ re.M|re.S) newDir = os.path.join(self._baseDir, path.partition(prefix)[2][1:]) newDir = "/".join(map(lambda x:x.split("?")[0], newDir.split("/"))) # Применяем шаблон - pathDir, objHeadDir = self.__getApplyHeadDir(newDir, dirInfoFile, opt) + pathDir, objHeadDir, createdDirs =\ + self.__getApplyHeadDir(newDir, dirInfoFile, opt) + if createdDirs: + self.createdDirs += createdDirs if objHeadDir: - self.createdDirs += [pathDir] + return pathDir, objHeadDir else: if self.getError(): return False @@ -3502,7 +3505,6 @@ re.M|re.S) if path in self.dictTemplates.keys(): self.numberProcessTempl += self.dictTemplates[path] return None - return pathDir, objHeadDir def __getApplyHeadDir(self, newDir, templateDirFile, optDir): """Применяет шаблон к директории (права, владелец, и.т. д)""" @@ -3545,11 +3547,15 @@ re.M|re.S) # Фильтрация шаблонов по названию директории realPath = os.path.join("/",applyDir.partition(self._baseDir)[2]) if realPath in self.dirsFilter: - return (applyDir, False) + return ("", False, []) # Создаем директорию если необходимо - if not self.createDir(applyDir, False, self.uid, self.gid): - return False - return (applyDir, True) + crDirs = self.createDir(applyDir, False, self.uid, self.gid) + if not crDirs: + return ("", False, []) + if crDirs is True: + return (applyDir, True, []) + else: + return (applyDir, True, crDirs) try: FD = open(templateDirFile) textTemplate = FD.read() @@ -3557,7 +3563,7 @@ re.M|re.S) except: self.setError(_("Error open template") + ": " +\ templateDirFile) - return (applyDir, False) + return ("", False, []) # Заменяем переменные на их значения textTemplate = self.applyVarsTemplate(textTemplate, templateDirFile) @@ -3572,12 +3578,12 @@ re.M|re.S) if objHead.getError(): self.setError(_("Incorrect template") + ": " +\ templateDirFile) - return (applyDir, False) + return ("", False, []) # Пропускаем директорию if objHead.typeAppend == "skip": applyDir = path - return (applyDir, objHead) + return (applyDir, objHead, []) # Изменяем название родительской директории if "path" in objHead.params: @@ -3589,7 +3595,7 @@ re.M|re.S) elif not path or path and path[0] != "/": self.setError(_("False value 'path' in template") + ": " +\ templateDirFile) - return (applyDir, False) + return ("", False, []) else: path = os.path.join(self._baseDir, path[1:]) @@ -3599,7 +3605,7 @@ re.M|re.S) if "/" in nameDir or nameDir == ".." or nameDir == ".": self.setError(_("False value 'name' in template") + ": " +\ templateDirFile) - return (applyDir, False) + return ("", False, []) # Новый путь к директории applyDir = os.path.join(path, nameDir) else: @@ -3608,7 +3614,7 @@ re.M|re.S) # Фильтрация шаблонов по названию директории realPath = os.path.join("/",applyDir.partition(self._baseDir)[2]) if realPath in self.dirsFilter: - return (applyDir, False) + return ("", False, []) # Удаляем директорию if objHead.typeAppend == "remove": if os.path.isdir(applyDir): @@ -3618,21 +3624,26 @@ re.M|re.S) except: self.setError(_("Can not delete dir: " ) +\ applyDir) - return (applyDir, False) + return ("", False, []) + # Созданные директории + createdDirs = [] # chmod - изменяем права if "chmod" in objHead.params: mode = self.__octToInt(objHead.params['chmod']) if mode: if not os.path.exists(applyDir): - if not self.createDir(applyDir, mode): - return False + crDirs = self.createDir(applyDir, mode, self.uid, self.gid) + if not crDirs: + return ("", False, []) + if not crDirs is True: + createdDirs += crDirs else: os.chmod(applyDir, mode) else: self.setError(_("False value 'chmod' in template") + ": " +\ templateDirFile) - return (applyDir, False) + return ("", False, []) # chown - изменяем владельца и группу if "chown" in objHead.params: owner = objHead.params['chown'] @@ -3646,7 +3657,7 @@ re.M|re.S) self.setError(_("Not user in this system: ") + strUid) self.setError(_("False value 'chown' in template")+\ ": " + templateDirFile) - return (applyDir, False) + return ("", False, []) try: import grp gid = grp.getgrnam(strGid).gr_gid @@ -3654,23 +3665,26 @@ re.M|re.S) self.setError(_("Not group in this system: ")+strGid) self.setError(_("False value 'chown' in template") +\ ": "+ templateDirFile) - return (applyDir, False) + return ("", False, []) if not os.path.exists(applyDir): - if not self.createDir(applyDir, False, uid, gid): - return (applyDir, False) + crDirs = self.createDir(applyDir, False, uid, gid) + if not crDirs: + return ("", False, []) + if not crDirs is True: + createdDirs += crDirs else: if not chownConfDir(applyDir, uid, gid, templateDirFile): - return (applyDir, False) + return ("", False, []) else: self.setError(_("False value 'chown' in template") + ": " +\ templateDirFile) - return (applyDir, False) + return ("", False, []) else: self.setError(_("False value 'chown' in template") + ": " +\ templateDirFile) - return (applyDir, False) + return ("", False, []) else: # Устанавливаем владельцем директории, пользователя по умолчанию # (переменная шаблона ur_login) @@ -3679,11 +3693,16 @@ re.M|re.S) if (self.uid, self.gid) != (tUid, tGid): if not chownConfDir(applyDir, self.uid, self.gid, templateDirFile): - return (applyDir, False) + return ("", False, []) else: - if not self.createDir(applyDir, False, self.uid, self.gid): - return False - return (applyDir, objHead) + crDirs = self.createDir(applyDir, False, self.uid, self.gid) + if not crDirs: + return ("", False, []) + if not crDirs is True: + createdDirs += crDirs + if not objHead: + applyDir = "" + return (applyDir, objHead, createdDirs) def __getApplyHeadTemplate(self, nameFileTemplate, nameFileConfig, templateFileType, optFile): @@ -3761,7 +3780,7 @@ re.M|re.S) if objHeadNew.getError(): self.setError(_("Incorrect template") + ": " +\ nameFileTemplate) - return (applyFiles, False) + return ([], False) pathProg = "" # Родительская директория @@ -3776,7 +3795,7 @@ re.M|re.S) elif not path or path and path[0] != "/": self.setError(_("False value 'path' in template") + ": " +\ nameFileTemplate) - return (applyFiles, False) + return ([], False) else: path = os.path.join(self._baseDir, path[1:]) @@ -3787,7 +3806,7 @@ re.M|re.S) if "/" in nameFile or nameFile == ".." or nameFile == ".": self.setError(_("False value 'name' in template") + ": " +\ nameFileTemplate) - return (applyFiles, False) + return ([], False) # Новый путь к оригинальному файлу pathOldFile = os.path.join(path,nameFile) else: @@ -3797,7 +3816,7 @@ re.M|re.S) # Фильтрация шаблонов по названию файла realPath = os.path.join("/",pathOldFile.partition(self._baseDir)[2]) if realPath in self.filesFilter: - return (applyFiles, False) + return ([], False) typeAppendTemplate = objHeadNew.typeAppend # Удаляем оригинальный файл if typeAppendTemplate == "remove": @@ -3810,6 +3829,7 @@ re.M|re.S) nameFileTemplate) self.setError(_("Can not delete link") + ": " +\ pathOldFile) + return ([], False) if os.path.isfile(pathOldFile): # удаляем файл try: @@ -3819,15 +3839,16 @@ re.M|re.S) nameFileTemplate) self.setError(_("Can not delete file") + ": " +\ pathOldFile) + return ([], False) return (applyFiles, False) # Пропускаем обработку шаблона elif typeAppendTemplate == "skip": - return (applyFiles, False) + return ([], False) # Создаем директорию для файла если ее нет if not os.path.exists(path): if not self.createDir(path): - return (applyFiles, False) + return ([], False) # В случае force if objHeadNew.params.has_key("force"): if os.path.islink(pathOldFile): @@ -3839,7 +3860,7 @@ re.M|re.S) nameFileTemplate) self.setError(_("Can not delete link") + ": " +\ pathOldFile) - return (applyFiles, False) + return ([], False) if os.path.isfile(pathOldFile): # удаляем файл try: @@ -3849,7 +3870,7 @@ re.M|re.S) nameFileTemplate) self.setError(_("Can not delete file") + ": " +\ pathOldFile) - return (applyFiles, False) + return ([], False) flagSymlink = False flagForce = False @@ -3866,9 +3887,9 @@ re.M|re.S) nameFileTemplate) self.setError(_("Can not delete file") + ": " +\ pathOldFile) - return (applyFiles, False) + return ([], False) elif not os.path.exists(pathOldFile): - return (applyFiles, False) + return ([], False) # Если есть указатель на файл шаблона (link) if objHeadNew.params.has_key("link") and\ not objHeadNew.params.has_key("symbolic"): @@ -3885,7 +3906,7 @@ re.M|re.S) nameFileTemplate) self.setError(_("Can not open file") + ": " +\ templateFile) - return (applyFiles, False) + return ([], False) if os.path.exists(pathOldFile): try: os.remove(pathOldFile) @@ -3894,7 +3915,7 @@ re.M|re.S) nameFileTemplate) self.setError(_("Can not delete file") + ": " +\ pathOldFile) - return (applyFiles, False) + return ([], False) if foundTemplateFile: try: FD = open(pathOldFile, "w+") @@ -3905,13 +3926,13 @@ re.M|re.S) nameFileTemplate) self.setError(_("Can not create file") + " '%s'"\ %pathOldFile) - return (applyFiles, False) + return ([], False) oMode = getModeFile(pathOldFile, mode="mode") # Если права не совпадают, меняем права if fMode != oMode: if not chmodConfFile(pathOldFile, fMode, nameFileTemplate, checkExists=False): - return (applyFiles, False) + return ([], False) # Если символическая ссылка if objHeadNew.params.has_key("symbolic"): @@ -3928,18 +3949,18 @@ re.M|re.S) nameFileTemplate) self.setError(_("Can not change the current directory to")+\ " " + pathLink) - return (applyFiles, False) + return ([], False) # chmod - изменяем права if objHeadNew.params.has_key("chmod"): mode = self.__octToInt(objHeadNew.params['chmod']) if mode: if not chmodConfFile(pathOldFile, mode, nameFileTemplate): - return (applyFiles, False) + return ([], False) else: self.setError(_("False value 'chmod' in template") + ": " +\ nameFileTemplate) - return (applyFiles, False) + return ([], False) # chown - изменяем владельца и группу if objHeadNew.params.has_key("chown"): owner = objHeadNew.params['chown'] @@ -3953,7 +3974,7 @@ re.M|re.S) self.setError(_("Not user in this system: ") + strUid) self.setError(_("False value 'chown' in template") +\ ": "+ nameFileTemplate) - return (applyFiles, False) + return ([], False) try: import grp gid = grp.getgrnam(strGid).gr_gid @@ -3961,18 +3982,18 @@ re.M|re.S) self.setError(_("Not group in this system: ")+strGid) self.setError(_("False value 'chown' in template") +\ ": "+ nameFileTemplate) - return (applyFiles, False) + return ([], False) # Изменяем владельца файла if not chownConfFile(pathOldFile,uid,gid,nameFileTemplate): - return (applyFiles, False) + return ([], False) else: self.setError(_("False value 'chown' in template") + ": " +\ nameFileTemplate) - return (applyFiles, False) + return ([], False) else: self.setError(_("False value 'chown' in template") + ": " +\ nameFileTemplate) - return (applyFiles, False) + return ([], False) self.openFiles(nameFileTemplate, pathOldFile) if not objHeadNew.params.has_key("chown"): @@ -3983,7 +4004,7 @@ re.M|re.S) # Изменяем владельца файла if not chownConfFile(pathOldFile, self.uid, self.gid, nameFileTemplate, checkExists=False): - return (applyFiles, False) + return ([], False) if flagSymlink: if os.path.exists(prevOldFile) or os.path.islink(prevOldFile): try: @@ -3998,7 +4019,7 @@ re.M|re.S) nameFileTemplate) self.setError(_("Can not delete file") + ": " +\ prevOldFile) - return (applyFiles, False) + return ([], False) if not "/" == pathOldFile[0]: applyFiles = [prevOldFile,os.path.join(pathLink,pathOldFile)] else: @@ -4010,9 +4031,9 @@ re.M|re.S) nameFileTemplate) self.setError(_("Can not create symbolic link") + " :" +\ "%s -> %s"%(prevOldFile, pathOldFile)) - return (applyFiles, False) + return ([], False) if not objHeadNew.body.strip(): - return (applyFiles, False) + return ([], False) else: applyFiles = [pathOldFile] if pathProg: @@ -4021,7 +4042,7 @@ re.M|re.S) if typeAppendTemplate == "replace" and\ not objHeadNew.params.has_key("symbolic") and\ objHeadNew.params.has_key("link"): - return (applyFiles, False) + return ([], False) if not pathOldFile in self.dictProcessedTemplates: self.dictProcessedTemplates[pathOldFile] = [] self.dictProcessedTemplates[pathOldFile].append(nameFileTemplate) diff --git a/pym/update_config/cl_update_config.py b/pym/update_config/cl_update_config.py index edabfd9..0ea0a01 100644 --- a/pym/update_config/cl_update_config.py +++ b/pym/update_config/cl_update_config.py @@ -24,6 +24,7 @@ import cl_datavars import cl_template from cl_print import color_print as old_color_print from cl_utils import runOsCommand +import cl_overriding import cl_lang # Перевод модуля @@ -31,6 +32,8 @@ tr = cl_lang.lang() tr.setLocalDomain('cl_lib') tr.setLanguage(sys.modules[__name__]) +cl_overriding.printERROR = lambda x:filter(lambda y:color_print().printERROR(y), + str(x).splitlines()) packagePath = "/usr/lib/calculate-2.2" for path in os.listdir(packagePath): @@ -83,7 +86,6 @@ class color_print(old_color_print, writeLog): self.logger.error(arg[0]) self._printObj.printNotOK(*arg, **argv) - class DataVarsObject(cl_datavars.DataVars): """Класс переменных для десктопа""" def __init__(self, section): @@ -109,22 +111,6 @@ class shareUpdateConfigs(color_print, writeLog): '/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): @@ -152,7 +138,7 @@ class shareUpdateConfigs(color_print, writeLog): else: searchObj = self.patternBelongName.search(textFile) if searchObj: - ret = searchObj.grpoup(1) + ret = searchObj.group(1) if ret == nameProgram: ret = True break @@ -185,10 +171,28 @@ class updateUserConfigs(shareUpdateConfigs): 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 + def _getUserTemplateDirs(self, scanDir, userTemplDirs=[], flagDir=False): + """Находит в директории scanDir директории шаблонов для пользователя + + выдает найденные директории. + """ + 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 "cl_pass_action==desktop" in textFile: + userTemplDirs.append(scanDir) + break + elif stat.S_ISDIR(statInfo): + self._getUserTemplateDirs(absPath, userTemplDirs, True) + return userTemplDirs + + + def updateConfig(self, nameProgram, xUsers): + """Обновление конфигурационных файлов у пользователей""" + if not os.path.exists(self.firstEnvFile): self.printWARNING(_("File '%s' does not exist")%self.firstEnvFile) return True @@ -207,37 +211,66 @@ class updateUserConfigs(shareUpdateConfigs): 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 + for foundUserPath in self._getUserTemplateDirs(fullPath): + if self._isApplyTemplateDir(foundUserPath, 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]))) + for userName in xUsers: + clVars = DataVarsObject(section) + clVars.importDataObject() + clVars.Set("ur_login", userName, True) + clVars.Set("cl_pass_action", section, True) + clVars.Set("cl_belong_pkg", nameProgram, True) + clTempl = cl_template.template(clVars) + dirsFiles = clTempl.applyTemplates() + if dirsFiles is False: + self.printERROR(\ + _("Error using templates for the user %s")%userName) + for errMess in clTempl.getError().splitlines(): + self.printERROR(errMess) + return False + if dirsFiles and dirsFiles[1]: + nameAndVerPkg = clVars.Get("cl_name")+"-"+\ + clVars.Get("cl_ver") + if not nameAndVerPkg in dictPakkages: + dictPakkages[nameAndVerPkg] = [] + dictPakkages[nameAndVerPkg].append((userName, + 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) + self.printWARNING(_("Package %s has changed files")\ + %calcPkg+":") + for userName, configFiles in dictPakkages[calcPkg]: + self.printWARNING(" "*2 + _("User %s")%userName + ":") + for nameConfigFile in configFiles: + self.printWARNING(" "*5 + nameConfigFile) return True - class updateSystemConfigs(shareUpdateConfigs): """Обновление системных конфигурационных файлов""" + 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) @@ -270,8 +303,15 @@ class updateSystemConfigs(shareUpdateConfigs): clVars.Set("cl_belong_pkg",nameProgram, True) clTempl = cl_template.template(clVars) dirsFiles = clTempl.applyTemplates() + nameAndVerPkg = clVars.Get("cl_name")+"-"+clVars.Get("cl_ver") + if dirsFiles is False: + self.printERROR(_("Error template in a package %s")\ + %nameAndVerPkg) + for errMess in clTempl.getError().splitlines(): + self.printERROR(errMess) + return False if dirsFiles and dirsFiles[1]: - dictPakkages[clVars.Get("cl_name")+"-"+clVars.Get("cl_ver")] =\ + dictPakkages[nameAndVerPkg] =\ sorted(list(set(dirsFiles[1]))) if dictPakkages: self.logger.info(_("Package %s") %nameProgram) diff --git a/pym/update_config/cl_update_config_cmd.py b/pym/update_config/cl_update_config_cmd.py index b74eb3e..5768f71 100644 --- a/pym/update_config/cl_update_config_cmd.py +++ b/pym/update_config/cl_update_config_cmd.py @@ -39,13 +39,13 @@ 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")}] +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): @@ -81,7 +81,7 @@ class update_cmd: errMsg = _("incorrect argument") + ":" + " %s" %" ".join(args) self.optobj.error(errMsg) return False - if not optObj.path: + if optObj.system and not optObj.path: errMsg = _("no such option") + ":" + " --path" self.optobj.error(errMsg) return False @@ -104,6 +104,15 @@ class update_cmd: return False return True - def updateUserConfig(self): + def updateUserConfig(self, nameProgram): """Обновление конфигурационных файлов для пользователей в X сеансах""" - print self.logicUserObj.getXUsers() \ No newline at end of file + # Пользователи в X сессии + xUsers = self.logicUserObj.getXUsers() + if not xUsers: + self.logicUserObj.logger.info(_("Package %s") %nameProgram) + self.logicUserObj.logger.warn(_("Not found X sessions users")) + return True + # Обновление конфигурационных файлов + if not self.logicUserObj.updateConfig(nameProgram, xUsers): + return False + return True \ No newline at end of file diff --git a/scripts/cl-update-config b/scripts/cl-update-config index d253512..e76cc95 100644 --- a/scripts/cl-update-config +++ b/scripts/cl-update-config @@ -39,6 +39,6 @@ if __name__ == "__main__": if not obj.updateSystemConfig(programName, opts.path): sys.exit(1) if opts.desktop: - if not obj.updateUserConfig(): + if not obj.updateUserConfig(programName): sys.exit(1) sys.exit(0)