|
|
|
@ -228,13 +228,13 @@ class _terms(_error):
|
|
|
|
|
exec("res=(%s)"%("".join(listEqual)))
|
|
|
|
|
return res
|
|
|
|
|
|
|
|
|
|
class calcHeader(_terms):
|
|
|
|
|
class fileHeader(_terms):
|
|
|
|
|
"""Обработка заголовков профилей и конфигурационных файлов
|
|
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
# Допустимые параметры заголовка
|
|
|
|
|
allowParam = ["format", "format_conf", "comment", "append", "force",
|
|
|
|
|
"link", "mirror", "symbolic", "chmod","chown"]
|
|
|
|
|
"link", "mirror", "symbolic", "chmod", "chown", "name"]
|
|
|
|
|
# Корректность заголовка
|
|
|
|
|
headerCorrect = True
|
|
|
|
|
|
|
|
|
@ -399,6 +399,111 @@ class calcHeader(_terms):
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class dirHeader(_terms):
|
|
|
|
|
"""Обработка заголовков профилей директорий
|
|
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
# Допустимые параметры заголовка
|
|
|
|
|
allowParam = ["append", "chmod", "chown", "name"]
|
|
|
|
|
# Корректность заголовка
|
|
|
|
|
headerCorrect = True
|
|
|
|
|
|
|
|
|
|
# Тип вставки профиля
|
|
|
|
|
typeAppend = ""
|
|
|
|
|
# Возможные типы вставки профилей
|
|
|
|
|
_fileAppend = "join", "remove"
|
|
|
|
|
# условные операторы
|
|
|
|
|
terms = ('>', '<', '==', '!=', '>=', '<=')
|
|
|
|
|
# параметры без значения
|
|
|
|
|
listParNotVal = ("symbolic", "force")
|
|
|
|
|
# Результат вычисления условия в заголовке
|
|
|
|
|
headerTerm = True
|
|
|
|
|
# Сообщение о ошибке
|
|
|
|
|
errorMessage = ""
|
|
|
|
|
|
|
|
|
|
def __init__(self, text, objVar=False, function=False):
|
|
|
|
|
self.body = text
|
|
|
|
|
# Объект с переменными
|
|
|
|
|
self.objVar=objVar
|
|
|
|
|
# Параметры описанные в заголовке файла профиля
|
|
|
|
|
self.params = {}
|
|
|
|
|
# некорректные параметры
|
|
|
|
|
incorrectParams = set([])
|
|
|
|
|
|
|
|
|
|
textLines = text.splitlines()
|
|
|
|
|
flagErrorBody = False
|
|
|
|
|
if textLines:
|
|
|
|
|
textLine = textLines[0]
|
|
|
|
|
rePar = re.compile("\s*#\s*calculate\s+",re.I)
|
|
|
|
|
reP = rePar.search(textLine)
|
|
|
|
|
if reP:
|
|
|
|
|
reL = False
|
|
|
|
|
reLns = re.compile(r"\A([^\\\n]*\\\n)+[^\n]*\n*",re.M)
|
|
|
|
|
reLs = reLns.search(text)
|
|
|
|
|
if reLs:
|
|
|
|
|
reL = reLs
|
|
|
|
|
paramLine = text[reP.end():reLs.end()]
|
|
|
|
|
paramLine = paramLine.replace("\\"," ")
|
|
|
|
|
else:
|
|
|
|
|
reLn = re.compile("\n")
|
|
|
|
|
reL = reLn.search(text)
|
|
|
|
|
paramLine = textLine[reP.end():]
|
|
|
|
|
if reL:
|
|
|
|
|
self.body = text[reL.end():]
|
|
|
|
|
else:
|
|
|
|
|
self.body = ""
|
|
|
|
|
if self.body.strip():
|
|
|
|
|
self.headerTerm = False
|
|
|
|
|
self.headerCorrect = False
|
|
|
|
|
self.errorMessage = _("incorrect text in profile: '%s'")\
|
|
|
|
|
%self.body
|
|
|
|
|
flagErrorBody = True
|
|
|
|
|
if not flagErrorBody:
|
|
|
|
|
paramList = re.split("\s+",paramLine)
|
|
|
|
|
if paramList:
|
|
|
|
|
for i in paramList:
|
|
|
|
|
foundTerm = False
|
|
|
|
|
for term in self.terms:
|
|
|
|
|
if term in i:
|
|
|
|
|
foundTerm = True
|
|
|
|
|
if function:
|
|
|
|
|
rezTerm = self._equalTerm(i,\
|
|
|
|
|
_("header profile not valid: ") + \
|
|
|
|
|
i,function)
|
|
|
|
|
else:
|
|
|
|
|
rezTerm = self._equalTerm(i,\
|
|
|
|
|
_("header profile not valid: ") + \
|
|
|
|
|
i)
|
|
|
|
|
if not rezTerm:
|
|
|
|
|
self.headerTerm = False
|
|
|
|
|
break
|
|
|
|
|
if not foundTerm:
|
|
|
|
|
par = i.split("=")
|
|
|
|
|
if len(par) == 1:
|
|
|
|
|
if i in self.listParNotVal:
|
|
|
|
|
self.params[i] = "True"
|
|
|
|
|
else:
|
|
|
|
|
if i.strip():
|
|
|
|
|
incorrectParams = set([i])
|
|
|
|
|
elif len(par) == 2:
|
|
|
|
|
self.params[par[0]] = par[1]
|
|
|
|
|
self.typeAppend = self._getAppend()
|
|
|
|
|
if not flagErrorBody:
|
|
|
|
|
if not incorrectParams:
|
|
|
|
|
incorrectParams = set(self.params.keys()) - set(self.allowParam)
|
|
|
|
|
if incorrectParams:
|
|
|
|
|
self.headerTerm = False
|
|
|
|
|
self.headerCorrect = False
|
|
|
|
|
self.errorMessage = _("incorrect header parameters - '%s'")\
|
|
|
|
|
% " ".join(list(incorrectParams))
|
|
|
|
|
|
|
|
|
|
def _getAppend(self):
|
|
|
|
|
"""Выдать тип добавления директории"""
|
|
|
|
|
if self.params.has_key("append") and self.params["append"] in\
|
|
|
|
|
self._fileAppend:
|
|
|
|
|
return self.params["append"]
|
|
|
|
|
else:
|
|
|
|
|
return "join"
|
|
|
|
|
|
|
|
|
|
class objShare:
|
|
|
|
|
"""Общий клас для объектов, наследуем
|
|
|
|
@ -1772,47 +1877,6 @@ class _file(_error):
|
|
|
|
|
break
|
|
|
|
|
return retText
|
|
|
|
|
|
|
|
|
|
def createDir(self, baseProfDir, profDir, baseDirMv):
|
|
|
|
|
"""Создает директорию
|
|
|
|
|
|
|
|
|
|
результат вычитания из profDir baseProfDir
|
|
|
|
|
плюс baseDirMv
|
|
|
|
|
"""
|
|
|
|
|
if baseDirMv and not os.access(baseDirMv, os.F_OK):
|
|
|
|
|
os.makedirs(baseDirMv)
|
|
|
|
|
|
|
|
|
|
baseDir = baseProfDir;
|
|
|
|
|
if baseProfDir[-1] == "/":
|
|
|
|
|
baseDir = baseProfDir[:-1]
|
|
|
|
|
dirMv = profDir.split(baseDir)[1]
|
|
|
|
|
listDirMv = dirMv.split("/")
|
|
|
|
|
lenListDirMv = len(listDirMv) - 2
|
|
|
|
|
# Созданные директории
|
|
|
|
|
createDirs = []
|
|
|
|
|
if lenListDirMv >= 0:
|
|
|
|
|
for i in range(lenListDirMv,-1,-1):
|
|
|
|
|
z = i + 2
|
|
|
|
|
dirTest = baseDirMv + "/".join(listDirMv[:z])
|
|
|
|
|
if os.access(dirTest, os.F_OK):
|
|
|
|
|
break
|
|
|
|
|
start = i
|
|
|
|
|
end = lenListDirMv + 1
|
|
|
|
|
for k in range(start,end):
|
|
|
|
|
z = k + 2
|
|
|
|
|
dirTest = "/".join(listDirMv[:z])
|
|
|
|
|
dirTestMv = baseDirMv + dirTest
|
|
|
|
|
if not os.access(dirTestMv, os.F_OK):
|
|
|
|
|
dirTestProf = baseProfDir + dirTest
|
|
|
|
|
try:
|
|
|
|
|
mode,uid,gid = self.getModeFile(dirTestProf)
|
|
|
|
|
except OSError:
|
|
|
|
|
self.setError (_("not access dir:" ) + profDir)
|
|
|
|
|
return False
|
|
|
|
|
os.mkdir(dirTestMv, mode)
|
|
|
|
|
os.chown(dirTestMv, uid,gid)
|
|
|
|
|
createDirs.append(dirTestMv)
|
|
|
|
|
return createDirs
|
|
|
|
|
|
|
|
|
|
def scanDirs(self, profilesDirs):
|
|
|
|
|
"""Сканирует дерево каталогов выдает два списка: директории, файлы"""
|
|
|
|
|
dirs = []
|
|
|
|
@ -2115,6 +2179,9 @@ class profile(_file, _terms, xmlShare):
|
|
|
|
|
# Версии установленных программ
|
|
|
|
|
installProgVersions = []
|
|
|
|
|
|
|
|
|
|
# Название файла профиля директории
|
|
|
|
|
profDirNameFile = ".calculate_directory"
|
|
|
|
|
|
|
|
|
|
def __init__(self, objVar, servDir=False):
|
|
|
|
|
_file.__init__(self)
|
|
|
|
|
# Словарь для создания объектов новых классов по образцу
|
|
|
|
@ -2170,6 +2237,90 @@ class profile(_file, _terms, xmlShare):
|
|
|
|
|
self.setError (_("Empty oct value"))
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def removeDir(self, rmDir):
|
|
|
|
|
"""Рекурсивное удаление директории
|
|
|
|
|
|
|
|
|
|
входной параметр директория
|
|
|
|
|
"""
|
|
|
|
|
if not os.path.exists(rmDir):
|
|
|
|
|
self.printERROR(_("Not found remove dir %s") %rmDir)
|
|
|
|
|
return False
|
|
|
|
|
fileObj = _file()
|
|
|
|
|
# Сканируем директорию
|
|
|
|
|
scanObjs = fileObj.scanDirs([rmDir])
|
|
|
|
|
for socketRm in scanObjs[0].sockets:
|
|
|
|
|
# Удаляем сокеты
|
|
|
|
|
if os.path.exists(socketRm):
|
|
|
|
|
os.remove(socketRm)
|
|
|
|
|
for linkRm in scanObjs[0].links:
|
|
|
|
|
# Удаляем ссылки
|
|
|
|
|
os.unlink(linkRm[1])
|
|
|
|
|
for fileRm in scanObjs[0].files:
|
|
|
|
|
# Удаляем файлы
|
|
|
|
|
os.remove(fileRm)
|
|
|
|
|
scanObjs[0].dirs.sort(lambda x, y: cmp(len(y), len(x)))
|
|
|
|
|
for dirRm in scanObjs[0].dirs:
|
|
|
|
|
# Удаляем директории
|
|
|
|
|
os.rmdir(dirRm)
|
|
|
|
|
if rmDir:
|
|
|
|
|
os.rmdir(rmDir)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def createDir(self, baseProfDir, profDir, baseDirMv, createDir):
|
|
|
|
|
"""Создает директорию
|
|
|
|
|
|
|
|
|
|
baseDirMv + результат вычитания из profDir baseProfDir
|
|
|
|
|
createDir - создаваемая директория
|
|
|
|
|
"""
|
|
|
|
|
if baseDirMv and not os.access(baseDirMv, os.F_OK):
|
|
|
|
|
os.makedirs(baseDirMv)
|
|
|
|
|
# Созданные директории
|
|
|
|
|
createDirs = []
|
|
|
|
|
baseDir = baseProfDir
|
|
|
|
|
if baseProfDir[-1] == "/":
|
|
|
|
|
baseDir = baseProfDir[:-1]
|
|
|
|
|
# Директория в системе относительно baseDirMv без условий
|
|
|
|
|
dirMvNoTerm = createDir.partition(baseDirMv)[2]
|
|
|
|
|
# директория в системе
|
|
|
|
|
dirMv = profDir.partition(baseDir)[2]
|
|
|
|
|
if len(dirMv)>1 and dirMv[-1] == "/":
|
|
|
|
|
dirMv = dirMv[:-1]
|
|
|
|
|
## директория в системе без условий
|
|
|
|
|
#dirMvNoTerm = "/".join(map(lambda x:x.split("?")[0],\
|
|
|
|
|
#dirMv.split("/")))
|
|
|
|
|
listDirMv = dirMv.split("/")
|
|
|
|
|
listDirMvNoTerm = dirMvNoTerm.split("/")
|
|
|
|
|
if len(listDirMv) != len(listDirMvNoTerm):
|
|
|
|
|
self.setError (_("Error in profile") + " :" + profDir)
|
|
|
|
|
return False
|
|
|
|
|
genIn = listDirMv.__iter__()
|
|
|
|
|
genOut = listDirMvNoTerm.__iter__()
|
|
|
|
|
inAndOutDirs = map(lambda x: [x,genOut.next()], genIn)
|
|
|
|
|
createDirs = []
|
|
|
|
|
createDir = []
|
|
|
|
|
while (len(inAndOutDirs)>1):
|
|
|
|
|
tmpDirIn = baseDir+"/".join(map(lambda x:x[0], inAndOutDirs))
|
|
|
|
|
tmpDirOut = baseDirMv + "/".join(map(lambda x:x[1],\
|
|
|
|
|
inAndOutDirs))
|
|
|
|
|
if os.access(tmpDirOut, os.F_OK):
|
|
|
|
|
break
|
|
|
|
|
else:
|
|
|
|
|
createDir.append((tmpDirIn, tmpDirOut))
|
|
|
|
|
inAndOutDirs.pop()
|
|
|
|
|
createDir.reverse()
|
|
|
|
|
for crDirIn,crDirOut in createDir:
|
|
|
|
|
try:
|
|
|
|
|
mode,uid,gid = self.getModeFile(crDirIn)
|
|
|
|
|
except OSError:
|
|
|
|
|
self.setError (_("not access dir:" ) + crDirIn)
|
|
|
|
|
return False
|
|
|
|
|
createDirs.append(crDirOut)
|
|
|
|
|
os.mkdir(crDirOut, mode)
|
|
|
|
|
os.chown(crDirOut, uid, gid)
|
|
|
|
|
return createDirs
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def applyVarsProfile(self, textProfile, nameProfile):
|
|
|
|
|
""" Заменяет переменные на их значения
|
|
|
|
|
"""
|
|
|
|
@ -2610,6 +2761,73 @@ class profile(_file, _terms, xmlShare):
|
|
|
|
|
"""
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def scanDirs(self, profilesDirs, objVar=False):
|
|
|
|
|
"""Измененный метод сканирования директорий"""
|
|
|
|
|
dirs = []
|
|
|
|
|
class dirProf:
|
|
|
|
|
def __init__(self):
|
|
|
|
|
self.baseDir = False
|
|
|
|
|
self.dirs = []
|
|
|
|
|
self.files = []
|
|
|
|
|
self.links = []
|
|
|
|
|
self.sockets = []
|
|
|
|
|
flagError = False
|
|
|
|
|
blockDirs = []
|
|
|
|
|
def getFilesDir(dirP, dirname, names):
|
|
|
|
|
for nameFile in names:
|
|
|
|
|
absNameFile = dirname + "/" + nameFile
|
|
|
|
|
findBlock = False
|
|
|
|
|
for blDir in blockDirs:
|
|
|
|
|
st,mid,end = absNameFile.partition(blDir)
|
|
|
|
|
if (not st) and mid and end:
|
|
|
|
|
findBlock = True
|
|
|
|
|
break
|
|
|
|
|
if not findBlock:
|
|
|
|
|
if os.path.islink(absNameFile):
|
|
|
|
|
dest = absNameFile
|
|
|
|
|
src = os.readlink(absNameFile)
|
|
|
|
|
dirP.links.append((src,dest))
|
|
|
|
|
elif os.path.isfile(absNameFile):
|
|
|
|
|
# Добавляем файлы кроме описаний директорий
|
|
|
|
|
if self.profDirNameFile != nameFile:
|
|
|
|
|
dirP.files.append(absNameFile)
|
|
|
|
|
elif os.path.isdir(absNameFile):
|
|
|
|
|
# Обработка условий в названии директории
|
|
|
|
|
if self.getNeedProfile(absNameFile):
|
|
|
|
|
if self.getError():
|
|
|
|
|
blockDirs.append(absNameFile)
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
dirP.dirs.append(absNameFile)
|
|
|
|
|
else:
|
|
|
|
|
if self.getError():
|
|
|
|
|
blockDirs.append(absNameFile)
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
blockDirs.append(absNameFile)
|
|
|
|
|
elif stat.S_ISSOCK(os.stat(absNameFile)[stat.ST_MODE]):
|
|
|
|
|
dirP.sockets.append(absNameFile)
|
|
|
|
|
for profileDir in profilesDirs:
|
|
|
|
|
if profileDir:
|
|
|
|
|
# Обработка условий в названии директории
|
|
|
|
|
if self.getNeedProfile(profileDir):
|
|
|
|
|
if self.getError():
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
dirP = dirProf()
|
|
|
|
|
dirP.baseDir = profileDir
|
|
|
|
|
dirs.append(dirP)
|
|
|
|
|
os.path.walk(profileDir, getFilesDir, dirP)
|
|
|
|
|
else:
|
|
|
|
|
if self.getError():
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
if flagError:
|
|
|
|
|
return []
|
|
|
|
|
return dirs
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def applyProfiles(self):
|
|
|
|
|
"""Применяет профили к конфигурационным файлам"""
|
|
|
|
|
if not self.objVar.defined("cl_profile_path"):
|
|
|
|
@ -2626,9 +2844,11 @@ class profile(_file, _terms, xmlShare):
|
|
|
|
|
else:
|
|
|
|
|
tmpDirsProfiles.append(False)
|
|
|
|
|
dirsProfiles = tmpDirsProfiles
|
|
|
|
|
dirObjs = self.scanDirs(dirsProfiles)
|
|
|
|
|
dirObjs = self.scanDirs(dirsProfiles,self.objVar)
|
|
|
|
|
#файлы к которым были применены профили
|
|
|
|
|
filesApply = []
|
|
|
|
|
# Словарь измененных директорий
|
|
|
|
|
changeDirs = {}
|
|
|
|
|
#созданные директории
|
|
|
|
|
createdDirs = []
|
|
|
|
|
# Получаем общее количество профилей (нужно для прогресбара)
|
|
|
|
@ -2649,25 +2869,85 @@ class profile(_file, _terms, xmlShare):
|
|
|
|
|
# сортируем файлы по названию
|
|
|
|
|
if dirObj.files:
|
|
|
|
|
dirObj.files.sort()
|
|
|
|
|
# сортируем директории по названию
|
|
|
|
|
if dirObj.dirs:
|
|
|
|
|
dirObj.dirs.sort()
|
|
|
|
|
blockDirs = []
|
|
|
|
|
for dirProfile in dirObj.dirs:
|
|
|
|
|
crDirs = self.createDir(dirObj.baseDir, dirProfile,
|
|
|
|
|
self._baseDir)
|
|
|
|
|
if crDirs == False:
|
|
|
|
|
return False
|
|
|
|
|
createdDirs += crDirs
|
|
|
|
|
newDir = self._baseDir + dirProfile.partition(dirObj.baseDir)[2]
|
|
|
|
|
newDir = "/".join(map(lambda x:x.split("?")[0],\
|
|
|
|
|
newDir.split("/")))
|
|
|
|
|
# Проверяем условие на директорию
|
|
|
|
|
dirInfoFile = os.path.join(dirProfile, self.profDirNameFile)
|
|
|
|
|
pathDir, objHeadDir = self.__getApplyHeadDir(newDir,
|
|
|
|
|
dirInfoFile,
|
|
|
|
|
changeDirs)
|
|
|
|
|
|
|
|
|
|
if objHeadDir:
|
|
|
|
|
if isinstance(objHeadDir, dirHeader):
|
|
|
|
|
if not objHeadDir.headerCorrect:
|
|
|
|
|
self.setError(_("Incorrect profile: " ) +\
|
|
|
|
|
dirInfoFile)
|
|
|
|
|
self.setError(objHeadDir.errorMessage)
|
|
|
|
|
return False
|
|
|
|
|
if not objHeadDir.headerTerm:
|
|
|
|
|
if objHeadDir.getError():
|
|
|
|
|
self.setError(_("Incorrect profile: " ) +\
|
|
|
|
|
dirInfoFile)
|
|
|
|
|
return False
|
|
|
|
|
if objHeadDir.params.has_key("name"):
|
|
|
|
|
changeDirs[dirProfile] = pathDir
|
|
|
|
|
crDirs = self.createDir(dirObj.baseDir, dirProfile,
|
|
|
|
|
self._baseDir, pathDir)
|
|
|
|
|
if crDirs == False:
|
|
|
|
|
return False
|
|
|
|
|
createdDirs += crDirs
|
|
|
|
|
else:
|
|
|
|
|
if self.getError():
|
|
|
|
|
self.setError(_("Incorrect profile: " ) +\
|
|
|
|
|
dirInfoFile)
|
|
|
|
|
return False
|
|
|
|
|
blockDirs.append(dirProfile)
|
|
|
|
|
for fileProfile in dirObj.files:
|
|
|
|
|
findBlock = False
|
|
|
|
|
for blDir in blockDirs:
|
|
|
|
|
st,mid,end = fileProfile.partition(blDir)
|
|
|
|
|
if (not st) and mid and end:
|
|
|
|
|
findBlock = True
|
|
|
|
|
break
|
|
|
|
|
if findBlock:
|
|
|
|
|
continue
|
|
|
|
|
numberProcessProfiles += 1
|
|
|
|
|
self.numberProcessProfiles(numberProcessProfiles)
|
|
|
|
|
if self.getNeedProfile(fileProfile):
|
|
|
|
|
if self.getError():
|
|
|
|
|
#print self.getError()
|
|
|
|
|
return False
|
|
|
|
|
oldFile = fileProfile.split(dirObj.baseDir)[1]
|
|
|
|
|
dirName,fileName = os.path.split(oldFile)
|
|
|
|
|
fileName = fileName.split("?")[0]
|
|
|
|
|
if dirName == "/":
|
|
|
|
|
dirName = ""
|
|
|
|
|
oldFile = self._baseDir + dirName + "/" + fileName
|
|
|
|
|
fileProfileChange = fileProfile
|
|
|
|
|
findChangeDir = False
|
|
|
|
|
listD = changeDirs.items()
|
|
|
|
|
listD.reverse()
|
|
|
|
|
for dirChangeIn, dirChangeOut in listD:
|
|
|
|
|
st,mid,end = fileProfile.partition(dirChangeIn)
|
|
|
|
|
if (not st) and mid and end:
|
|
|
|
|
findChangeDir = True
|
|
|
|
|
break
|
|
|
|
|
if findChangeDir:
|
|
|
|
|
#end = "/".join(map(lambda x:x.split("?")[0],\
|
|
|
|
|
#end.split("/")))
|
|
|
|
|
oldFile = dirChangeOut + end
|
|
|
|
|
else:
|
|
|
|
|
oldFile = fileProfile.partition(dirObj.baseDir)[2]
|
|
|
|
|
|
|
|
|
|
#dirName,fileName = os.path.split(oldFile)
|
|
|
|
|
#fileName = fileName.split("?")[0]
|
|
|
|
|
#if dirName == "/":
|
|
|
|
|
#dirName = ""
|
|
|
|
|
# файл в системе без условий
|
|
|
|
|
oldFile = "/".join(map(lambda x:x.split("?")[0],\
|
|
|
|
|
oldFile.split("/")))
|
|
|
|
|
if not findChangeDir:
|
|
|
|
|
oldFile = self._baseDir + oldFile
|
|
|
|
|
listProfTitle = dirObj.baseDir.split("/")[-2:]
|
|
|
|
|
profTitle = '"' + "/".join(listProfTitle) + '"'
|
|
|
|
|
# Записываем в переменную обрабатываемый файл
|
|
|
|
@ -2683,6 +2963,136 @@ class profile(_file, _terms, xmlShare):
|
|
|
|
|
self.closeFiles()
|
|
|
|
|
return (createdDirs, filesApply)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def __getApplyHeadDir(self, newDir, profileDirFile, changeDirs):
|
|
|
|
|
"""Применяет профиль к директории (права, владелец, и.т. д)"""
|
|
|
|
|
|
|
|
|
|
def function(text):
|
|
|
|
|
"""Функция обработки функций в заголовке"""
|
|
|
|
|
return self.applyFuncProfile(text, newDir, profileDirFile)
|
|
|
|
|
|
|
|
|
|
newDirMv = newDir
|
|
|
|
|
findChangeDir = False
|
|
|
|
|
#Меняем путь к директории
|
|
|
|
|
listD = changeDirs.items()
|
|
|
|
|
listD.reverse()
|
|
|
|
|
for dirChangeIn, dirChangeOut in listD:
|
|
|
|
|
st,mid,end = profileDirFile.partition(dirChangeIn)
|
|
|
|
|
if (not st) and mid:
|
|
|
|
|
findChangeDir = True
|
|
|
|
|
break
|
|
|
|
|
if findChangeDir:
|
|
|
|
|
pathRel = dirChangeOut
|
|
|
|
|
lenPathRel = len(pathRel.split("/"))
|
|
|
|
|
lenNewDir = len(newDir.split("/"))
|
|
|
|
|
lenEndDir = lenNewDir - lenPathRel
|
|
|
|
|
tmpDir = newDir
|
|
|
|
|
namesDirs = []
|
|
|
|
|
for i in range(lenEndDir):
|
|
|
|
|
namesDirs.append(os.path.split(tmpDir)[1])
|
|
|
|
|
tmpDir = os.path.split(tmpDir)[0]
|
|
|
|
|
namesDirs.reverse()
|
|
|
|
|
nameDir = "/".join(namesDirs)
|
|
|
|
|
newDirMv = os.path.join(pathRel, nameDir)
|
|
|
|
|
applyDir = newDirMv
|
|
|
|
|
if not os.path.exists(profileDirFile):
|
|
|
|
|
return (applyDir, True)
|
|
|
|
|
try:
|
|
|
|
|
FD = open(profileDirFile)
|
|
|
|
|
textProfile = FD.read()
|
|
|
|
|
FD.close()
|
|
|
|
|
except:
|
|
|
|
|
self.setError(_("Error open profile#: " ) +\
|
|
|
|
|
profileDirFile)
|
|
|
|
|
return (applyDir, False)
|
|
|
|
|
objHead = dirHeader(textProfile, self.objVar,function)
|
|
|
|
|
if not objHead.headerCorrect:
|
|
|
|
|
self.setError(_("Incorrect profile: " ) +\
|
|
|
|
|
profileDirFile)
|
|
|
|
|
self.setError(objHead.errorMessage)
|
|
|
|
|
return (applyDir, False)
|
|
|
|
|
if not objHead.headerTerm:
|
|
|
|
|
if objHead.getError():
|
|
|
|
|
self.setError(_("Incorrect profile: " ) +\
|
|
|
|
|
profileDirFile)
|
|
|
|
|
return (applyDir, False)
|
|
|
|
|
|
|
|
|
|
# Изменяем название директории
|
|
|
|
|
if objHead.params.has_key("name"):
|
|
|
|
|
nameDir = objHead.params['name']
|
|
|
|
|
if "/" in nameDir:
|
|
|
|
|
self.setError (_("False value 'name' in profile: " ) +\
|
|
|
|
|
profileDirFile)
|
|
|
|
|
return (applyDir, False)
|
|
|
|
|
if not findChangeDir:
|
|
|
|
|
pathRel = os.path.split(os.path.abspath(newDirMv))[0]
|
|
|
|
|
# Новый путь к оригинальному файлу
|
|
|
|
|
newDirMv = os.path.join(pathRel, nameDir)
|
|
|
|
|
applyDir = newDirMv
|
|
|
|
|
|
|
|
|
|
# Удаляем директорию
|
|
|
|
|
if objHead.typeAppend == "remove":
|
|
|
|
|
if os.path.isdir(newDirMv):
|
|
|
|
|
# удаляем директорию
|
|
|
|
|
try:
|
|
|
|
|
self.removeDir(newDirMv)
|
|
|
|
|
except:
|
|
|
|
|
self.setError(_("Can not delete dir: " ) +\
|
|
|
|
|
newDirMv)
|
|
|
|
|
return (applyDir, False)
|
|
|
|
|
|
|
|
|
|
# chmod - изменяем права
|
|
|
|
|
if objHead.params.has_key("chmod"):
|
|
|
|
|
mode = self.__octToInt(objHead.params['chmod'])
|
|
|
|
|
if mode:
|
|
|
|
|
if not os.path.exists(newDirMv):
|
|
|
|
|
os.mkdir(newDirMv, mode)
|
|
|
|
|
else:
|
|
|
|
|
self.setError (_("False value 'chmod' in profile: " ) +\
|
|
|
|
|
profileDirFile)
|
|
|
|
|
return (applyDir, False)
|
|
|
|
|
# chown - изменяем владельца и группу
|
|
|
|
|
if objHead.params.has_key("chown"):
|
|
|
|
|
owner = objHead.params['chown']
|
|
|
|
|
if owner:
|
|
|
|
|
if ":" in owner:
|
|
|
|
|
strUid, strGid = owner.split(":")
|
|
|
|
|
import pwd
|
|
|
|
|
try:
|
|
|
|
|
uid = pwd.getpwnam(strUid)[2]
|
|
|
|
|
except:
|
|
|
|
|
self.setError (_("Not user in this system: ") + strUid)
|
|
|
|
|
self.setError (_("False value 'chown' in profile: " )+\
|
|
|
|
|
profileDirFile)
|
|
|
|
|
return (applyDir, False)
|
|
|
|
|
try:
|
|
|
|
|
import grp
|
|
|
|
|
gid = grp.getgrnam(strGid)[2]
|
|
|
|
|
except:
|
|
|
|
|
self.setError (_("Not group in this system: ")+strGid)
|
|
|
|
|
self.setError (_("False value 'chown' in profile: " )+\
|
|
|
|
|
profileDirFile)
|
|
|
|
|
return (applyDir, False)
|
|
|
|
|
|
|
|
|
|
if not os.path.exists(newDirMv):
|
|
|
|
|
dirProfile = os.path.split(profileDirFile)[0]
|
|
|
|
|
try:
|
|
|
|
|
mode,uidTmp,gidTmp = self.getModeFile(dirProfile)
|
|
|
|
|
except OSError:
|
|
|
|
|
self.setError (_("not access dir:" ) + newDirMv)
|
|
|
|
|
return (applyDir, False)
|
|
|
|
|
os.mkdir(newDirMv, mode)
|
|
|
|
|
os.chown(newDirMv, uid, gid)
|
|
|
|
|
else:
|
|
|
|
|
self.setError (_("False value 'chown' in profile: " ) +\
|
|
|
|
|
profileDirFile)
|
|
|
|
|
return (applyDir, False)
|
|
|
|
|
else:
|
|
|
|
|
self.setError (_("False value 'chown' in profile: " ) +\
|
|
|
|
|
profileDirFile)
|
|
|
|
|
return (applyDir, False)
|
|
|
|
|
return (applyDir, objHead)
|
|
|
|
|
|
|
|
|
|
def __getApplyHeadProfile(self ,newFile, oldFile, copyFile):
|
|
|
|
|
"""Применяет заголовок к профилю (права, владелец, и.т. д)"""
|
|
|
|
|
|
|
|
|
@ -2698,7 +3108,7 @@ class profile(_file, _terms, xmlShare):
|
|
|
|
|
self.FN = self.openNewFile(self.nameFileNew)
|
|
|
|
|
self.newProfile = self.FN.read()
|
|
|
|
|
self.closeNewFile()
|
|
|
|
|
objHeadNew = calcHeader(self.newProfile, False,
|
|
|
|
|
objHeadNew = fileHeader(self.newProfile, False,
|
|
|
|
|
self.getFileType(),objVar=self.objVar,
|
|
|
|
|
function=function)
|
|
|
|
|
if not objHeadNew.headerCorrect:
|
|
|
|
@ -2712,22 +3122,35 @@ class profile(_file, _terms, xmlShare):
|
|
|
|
|
newFile)
|
|
|
|
|
return (applyFiles, False)
|
|
|
|
|
|
|
|
|
|
pathProg = ""
|
|
|
|
|
# Путь к оригинальному файлу
|
|
|
|
|
pathOldFile = oldFile
|
|
|
|
|
# Изменяем путь к оригинальному файлу
|
|
|
|
|
if objHeadNew.params.has_key("name"):
|
|
|
|
|
nameFile = objHeadNew.params['name']
|
|
|
|
|
if "/" in nameFile:
|
|
|
|
|
self.setError (_("False value 'name' in profile: " ) + newFile)
|
|
|
|
|
return False
|
|
|
|
|
pathRel = os.path.split(os.path.abspath(oldFile))[0]
|
|
|
|
|
# Новый путь к оригинальному файлу
|
|
|
|
|
pathOldFile = os.path.join(pathRel,nameFile)
|
|
|
|
|
|
|
|
|
|
# Удаляем оригинальный файл
|
|
|
|
|
if objHeadNew.typeAppend == "remove":
|
|
|
|
|
if os.path.islink(oldFile):
|
|
|
|
|
if os.path.islink(pathOldFile):
|
|
|
|
|
# удаляем ссылку
|
|
|
|
|
try:
|
|
|
|
|
os.unlink(oldFile)
|
|
|
|
|
os.unlink(pathOldFile)
|
|
|
|
|
except:
|
|
|
|
|
self.setError(_("Can not delete link: " ) +\
|
|
|
|
|
oldFile)
|
|
|
|
|
if os.path.isfile(oldFile):
|
|
|
|
|
pathOldFile)
|
|
|
|
|
if os.path.isfile(pathOldFile):
|
|
|
|
|
# удаляем файл
|
|
|
|
|
try:
|
|
|
|
|
os.remove(oldFile)
|
|
|
|
|
os.remove(pathOldFile)
|
|
|
|
|
except:
|
|
|
|
|
self.setError(_("Can not delete file: " ) +\
|
|
|
|
|
oldFile)
|
|
|
|
|
pathOldFile)
|
|
|
|
|
return (applyFiles, False)
|
|
|
|
|
|
|
|
|
|
flagSymlink = False
|
|
|
|
@ -2737,10 +3160,10 @@ class profile(_file, _terms, xmlShare):
|
|
|
|
|
if objHeadNew.params.has_key("link"):
|
|
|
|
|
profileFile = objHeadNew.params['link']
|
|
|
|
|
if not os.path.exists(profileFile):
|
|
|
|
|
if os.path.exists(oldFile):
|
|
|
|
|
os.remove(oldFile)
|
|
|
|
|
if os.path.exists(pathOldFile):
|
|
|
|
|
os.remove(pathOldFile)
|
|
|
|
|
return (applyFiles, False)
|
|
|
|
|
elif not os.path.exists(oldFile):
|
|
|
|
|
elif not os.path.exists(pathOldFile):
|
|
|
|
|
return (applyFiles, False)
|
|
|
|
|
# Если есть указатель на файл профиля (link)
|
|
|
|
|
if objHeadNew.params.has_key("link") and\
|
|
|
|
@ -2751,39 +3174,39 @@ class profile(_file, _terms, xmlShare):
|
|
|
|
|
FO = self.openNewFile(profileFile)
|
|
|
|
|
buff = FO.read()
|
|
|
|
|
FO.close()
|
|
|
|
|
if os.path.exists(oldFile):
|
|
|
|
|
os.remove(oldFile)
|
|
|
|
|
if os.path.exists(pathOldFile):
|
|
|
|
|
os.remove(pathOldFile)
|
|
|
|
|
if foundProfileFile:
|
|
|
|
|
fd = os.open(oldFile, os.O_CREAT)
|
|
|
|
|
fd = os.open(pathOldFile, os.O_CREAT)
|
|
|
|
|
os.close(fd)
|
|
|
|
|
os.chmod(oldFile, self._mode)
|
|
|
|
|
os.chown(oldFile, self._uid, self._gid)
|
|
|
|
|
FON = open (oldFile, "r+")
|
|
|
|
|
os.chmod(pathOldFile, self._mode)
|
|
|
|
|
os.chown(pathOldFile, self._uid, self._gid)
|
|
|
|
|
FON = open (pathOldFile, "r+")
|
|
|
|
|
FON.write(buff)
|
|
|
|
|
FON.close()
|
|
|
|
|
|
|
|
|
|
# Если символическая ссылка
|
|
|
|
|
if objHeadNew.params.has_key("symbolic"):
|
|
|
|
|
prevOldFile = oldFile
|
|
|
|
|
oldFile = objHeadNew.params['link']
|
|
|
|
|
prevOldFile = pathOldFile
|
|
|
|
|
pathOldFile = objHeadNew.params['link']
|
|
|
|
|
flagSymlink = True
|
|
|
|
|
if not "/" == oldFile[0]:
|
|
|
|
|
if not "/" == pathOldFile[0]:
|
|
|
|
|
pathLink = os.path.split(os.path.abspath(prevOldFile))[0]
|
|
|
|
|
pathProg = os.getcwd()
|
|
|
|
|
os.chdir(pathLink)
|
|
|
|
|
|
|
|
|
|
oldFileExists = os.path.exists(oldFile)
|
|
|
|
|
pathOldFileExists = os.path.exists(pathOldFile)
|
|
|
|
|
# В случае force
|
|
|
|
|
if objHeadNew.params.has_key("force") and oldFileExists:
|
|
|
|
|
FO = self.openNewFile(oldFile)
|
|
|
|
|
if objHeadNew.params.has_key("force") and pathOldFileExists:
|
|
|
|
|
FO = self.openNewFile(pathOldFile)
|
|
|
|
|
buff = FO.read()
|
|
|
|
|
FO.close()
|
|
|
|
|
os.remove(oldFile)
|
|
|
|
|
fd = os.open(oldFile, os.O_CREAT)
|
|
|
|
|
os.remove(pathOldFile)
|
|
|
|
|
fd = os.open(pathOldFile, os.O_CREAT)
|
|
|
|
|
os.close(fd)
|
|
|
|
|
os.chmod(oldFile, self._mode)
|
|
|
|
|
os.chown(oldFile, self._uid, self._gid)
|
|
|
|
|
FON = open (oldFile, "r+")
|
|
|
|
|
os.chmod(pathOldFile, self._mode)
|
|
|
|
|
os.chown(pathOldFile, self._uid, self._gid)
|
|
|
|
|
FON = open (pathOldFile, "r+")
|
|
|
|
|
FON.write(buff)
|
|
|
|
|
FON.close()
|
|
|
|
|
|
|
|
|
@ -2791,10 +3214,10 @@ class profile(_file, _terms, xmlShare):
|
|
|
|
|
if objHeadNew.params.has_key("chmod"):
|
|
|
|
|
mode = self.__octToInt(objHeadNew.params['chmod'])
|
|
|
|
|
if mode:
|
|
|
|
|
if not os.path.exists(oldFile):
|
|
|
|
|
fd = os.open(oldFile, os.O_CREAT)
|
|
|
|
|
if not os.path.exists(pathOldFile):
|
|
|
|
|
fd = os.open(pathOldFile, os.O_CREAT)
|
|
|
|
|
os.close(fd)
|
|
|
|
|
os.chmod(oldFile, mode)
|
|
|
|
|
os.chmod(pathOldFile, mode)
|
|
|
|
|
else:
|
|
|
|
|
self.setError (_("False value 'chmod' in profile: " ) +\
|
|
|
|
|
newFile)
|
|
|
|
@ -2823,13 +3246,13 @@ class profile(_file, _terms, xmlShare):
|
|
|
|
|
newFile)
|
|
|
|
|
return (applyFiles, False)
|
|
|
|
|
|
|
|
|
|
if not os.path.exists(oldFile):
|
|
|
|
|
if not os.path.exists(pathOldFile):
|
|
|
|
|
FO = self.openNewFile(newFile)
|
|
|
|
|
FO.close()
|
|
|
|
|
fd = os.open(oldFile, os.O_CREAT)
|
|
|
|
|
fd = os.open(pathOldFile, os.O_CREAT)
|
|
|
|
|
os.close(fd)
|
|
|
|
|
os.chmod(oldFile, self._mode)
|
|
|
|
|
os.chown(oldFile, uid, gid)
|
|
|
|
|
os.chmod(pathOldFile, self._mode)
|
|
|
|
|
os.chown(pathOldFile, uid, gid)
|
|
|
|
|
else:
|
|
|
|
|
self.setError (_("False value 'chown' in profile: " ) +\
|
|
|
|
|
newFile)
|
|
|
|
@ -2839,7 +3262,7 @@ class profile(_file, _terms, xmlShare):
|
|
|
|
|
newFile)
|
|
|
|
|
return (applyFiles, False)
|
|
|
|
|
|
|
|
|
|
self.openFiles(newFile, oldFile)
|
|
|
|
|
self.openFiles(newFile, pathOldFile)
|
|
|
|
|
if flagSymlink:
|
|
|
|
|
if os.path.exists(prevOldFile) or os.path.islink(prevOldFile):
|
|
|
|
|
if os.path.islink(prevOldFile):
|
|
|
|
@ -2848,17 +3271,18 @@ class profile(_file, _terms, xmlShare):
|
|
|
|
|
else:
|
|
|
|
|
# иначе удаляем файл
|
|
|
|
|
os.remove(prevOldFile)
|
|
|
|
|
if not "/" == oldFile[0]:
|
|
|
|
|
os.symlink(oldFile, prevOldFile)
|
|
|
|
|
applyFiles = [prevOldFile,os.path.join(pathLink,oldFile)]
|
|
|
|
|
os.chdir(pathProg)
|
|
|
|
|
if not "/" == pathOldFile[0]:
|
|
|
|
|
os.symlink(pathOldFile, prevOldFile)
|
|
|
|
|
applyFiles = [prevOldFile,os.path.join(pathLink,pathOldFile)]
|
|
|
|
|
else:
|
|
|
|
|
os.symlink(oldFile, prevOldFile)
|
|
|
|
|
applyFiles = [prevOldFile,oldFile]
|
|
|
|
|
os.symlink(pathOldFile, prevOldFile)
|
|
|
|
|
applyFiles = [prevOldFile,pathOldFile]
|
|
|
|
|
if not objHeadNew.body.strip():
|
|
|
|
|
return (applyFiles, False)
|
|
|
|
|
else:
|
|
|
|
|
applyFiles = [oldFile]
|
|
|
|
|
applyFiles = [pathOldFile]
|
|
|
|
|
if pathProg:
|
|
|
|
|
os.chdir(pathProg)
|
|
|
|
|
return (applyFiles, objHeadNew)
|
|
|
|
|
|
|
|
|
|
def createNewClass(self, name, bases, attrs={}):
|
|
|
|
@ -2924,6 +3348,7 @@ class profile(_file, _terms, xmlShare):
|
|
|
|
|
copyFile = False
|
|
|
|
|
filesApply, objHeadNew = self.__getApplyHeadProfile(newFile, oldFile,
|
|
|
|
|
copyFile)
|
|
|
|
|
#print filesApply
|
|
|
|
|
if not objHeadNew:
|
|
|
|
|
return filesApply
|
|
|
|
|
# Флаг - кодировка с бинарными примесями у файла профиля включаем при
|
|
|
|
@ -2955,7 +3380,7 @@ class profile(_file, _terms, xmlShare):
|
|
|
|
|
|
|
|
|
|
objHeadOld = False
|
|
|
|
|
if objHeadNew.comment:
|
|
|
|
|
objHeadOld = calcHeader(self.oldProfile, objHeadNew.comment)
|
|
|
|
|
objHeadOld = fileHeader(self.oldProfile, objHeadNew.comment)
|
|
|
|
|
# Тестирование
|
|
|
|
|
#print self.nameFileOld
|
|
|
|
|
#print objHeadNew.typeAppend
|
|
|
|
@ -3119,7 +3544,7 @@ class profile(_file, _terms, xmlShare):
|
|
|
|
|
#self.saveOldFile()
|
|
|
|
|
#return True
|
|
|
|
|
|
|
|
|
|
objHeadOld = calcHeader(self.oldProfile, objProfNew._comment)
|
|
|
|
|
objHeadOld = fileHeader(self.oldProfile, objProfNew._comment)
|
|
|
|
|
if objHeadOld.body:
|
|
|
|
|
self.oldProfile = objHeadOld.body
|
|
|
|
|
else:
|
|
|
|
|