|
|
|
@ -1015,14 +1015,14 @@ class shareLdap(imp_cl_err, imp_cl_xml, imp_cl_help, imp_cl_smcon):
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
@adminConnectLdap
|
|
|
|
|
def fullElementDNtoText(self, relDN):
|
|
|
|
|
def fullElementDNtoText(self, relDN="", ldapFilter='(objectclass=*)'):
|
|
|
|
|
"""Выводит все внутренние элементы DN виде текста"""
|
|
|
|
|
DN = self.addDN(relDN, self.baseDN)
|
|
|
|
|
listDN=[]
|
|
|
|
|
try:
|
|
|
|
|
dnList = self.conLdap.search_s(DN,
|
|
|
|
|
ldap.SCOPE_SUBTREE,
|
|
|
|
|
'(objectclass=*)',None)
|
|
|
|
|
ldapFilter,None)
|
|
|
|
|
except ldap.LDAPError, e:
|
|
|
|
|
self.printERROR("fullElementDN: "+e[0]['desc'])
|
|
|
|
|
return False
|
|
|
|
@ -1033,6 +1033,22 @@ class shareLdap(imp_cl_err, imp_cl_xml, imp_cl_help, imp_cl_smcon):
|
|
|
|
|
FDOUT.seek(0)
|
|
|
|
|
return FDOUT.read()
|
|
|
|
|
|
|
|
|
|
@adminConnectLdap
|
|
|
|
|
def fullElementSambaDNtoText(self, relDN=""):
|
|
|
|
|
"""Выводит все внутренние элементы ветки Samba в виде текста"""
|
|
|
|
|
return self.fullElementDNtoText(relDN,'(|(|(|(|(ou:dn:=Samba)\
|
|
|
|
|
(ou:dn:=Unix))(ou:dn:=LDAP))\
|
|
|
|
|
(!(ou:dn:=Services)))\
|
|
|
|
|
(ou=Services))')
|
|
|
|
|
|
|
|
|
|
@adminConnectLdap
|
|
|
|
|
def fullElementUnixDNtoText(self, relDN=""):
|
|
|
|
|
"""Выводит все внутренние элементы ветки Unix в виде текста"""
|
|
|
|
|
return self.fullElementDNtoText(relDN,'(|(|(|(ou:dn:=Unix)\
|
|
|
|
|
(ou:dn:=LDAP))\
|
|
|
|
|
(!(ou:dn:=Services)))\
|
|
|
|
|
(ou=Services))')
|
|
|
|
|
|
|
|
|
|
@adminConnectLdap
|
|
|
|
|
def deleteDN(self, relDelDN):
|
|
|
|
|
"""Удаляет DN и все внутренние элементы"""
|
|
|
|
@ -4944,6 +4960,14 @@ class servLdap(shareLdap):
|
|
|
|
|
self.backupDirectory = "/var/calculate/server-backup/ldap"
|
|
|
|
|
# ldif файл базы LDAP
|
|
|
|
|
self.archLdifFile = "/tmp/LDAP_DATABASE.ldif"
|
|
|
|
|
# ldif файл базы LDAP для сервиса Unix
|
|
|
|
|
self.replArchLdifFileUnix = "/tmp/REPL_LDAP_DATABASE_UNIX.ldif"
|
|
|
|
|
# список файлов в архиве для сервиса Unix
|
|
|
|
|
self.replListFileUnix = "/tmp/REPL_LIST_FILES_UNIX.txt"
|
|
|
|
|
# ldif файл базы LDAP для сервиса Samba
|
|
|
|
|
self.replArchLdifFileSamba = "/tmp/REPL_LDAP_DATABASE_SAMBA.ldif"
|
|
|
|
|
# список файлов в архиве для сервиса Samba
|
|
|
|
|
self.replListFileSamba = "/tmp/REPL_LIST_FILES_SAMBA.txt"
|
|
|
|
|
# приватная директория Samba
|
|
|
|
|
self.sambaPrivate = "/var/lib/samba/private"
|
|
|
|
|
# директория c алиасами сервиса Mail
|
|
|
|
@ -4956,6 +4980,8 @@ class servLdap(shareLdap):
|
|
|
|
|
self.sslDirsMail = ["/etc/ssl/dovecot","/etc/ssl/postfix"]
|
|
|
|
|
# Файл сертификата сервиса jabber
|
|
|
|
|
self.sslJabberFile = "/etc/jabber/ssl.pem"
|
|
|
|
|
# директория для хранения временных файлов
|
|
|
|
|
self.tmpEnvDir = "/tmp/tmp_calculate"
|
|
|
|
|
|
|
|
|
|
def savePrivateFile(self, fileName, data):
|
|
|
|
|
"""Записать файл с правами 0600"""
|
|
|
|
@ -5035,9 +5061,21 @@ outdated. If the backup is obsolete, use cl-backup."))
|
|
|
|
|
_("input 'yes'") +", "+ _("if not 'no'")
|
|
|
|
|
if not self.dialogYesNo(messDialog):
|
|
|
|
|
return True
|
|
|
|
|
# Восстанавливаем сервисы не запуская их и не прописывая в автозагрузку
|
|
|
|
|
if not self.restoreServer(False):
|
|
|
|
|
return False
|
|
|
|
|
# В случае создания сервера репликации из файла backup c
|
|
|
|
|
# другого компьютера
|
|
|
|
|
if options.has_key("repl"):
|
|
|
|
|
# Находим имена сервисов репликации для этого сервера
|
|
|
|
|
replServices = self.getArchReplServices()
|
|
|
|
|
if not self.restoreServer(False,replServices):
|
|
|
|
|
return False
|
|
|
|
|
objRepl = servRepl()
|
|
|
|
|
# Изменяем и сохраняем переменные
|
|
|
|
|
if not objRepl.prepAndSaveEnv():
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
# Восстанавливаем сервисы не запуская их и не прописывая в автозагрузку
|
|
|
|
|
if not self.restoreServer(False):
|
|
|
|
|
return False
|
|
|
|
|
verbose = False
|
|
|
|
|
if options.has_key("v"):
|
|
|
|
|
opt = {'v':''}
|
|
|
|
@ -5099,9 +5137,6 @@ outdated. If the backup is obsolete, use cl-backup."))
|
|
|
|
|
'history=%s' - error, to use 'history on' or 'history off'")\
|
|
|
|
|
%str(history) + " ...")
|
|
|
|
|
return False
|
|
|
|
|
## Включение репликации и установка серверов репликации
|
|
|
|
|
#if options.has_key('r') and options['r']:
|
|
|
|
|
#replServers = options['r'].split(',')
|
|
|
|
|
|
|
|
|
|
# находим установленные сервисы
|
|
|
|
|
servInstalled = self.getServiceSetup()
|
|
|
|
@ -5168,12 +5203,12 @@ outdated. If the backup is obsolete, use cl-backup."))
|
|
|
|
|
# запишем переменные для сервера
|
|
|
|
|
if not flagError:
|
|
|
|
|
# Переменные для jabber
|
|
|
|
|
if serviceUpdate in ["all","jabber"]:
|
|
|
|
|
if "jabber" in servInstalled and serviceUpdate in ["all","jabber"]:
|
|
|
|
|
self.clVars.Write("sr_jabber_history",
|
|
|
|
|
self.clVars.Get("sr_jabber_history"),
|
|
|
|
|
True,"local")
|
|
|
|
|
# Переменные для почты
|
|
|
|
|
if serviceUpdate in ["all","mail"]:
|
|
|
|
|
if "mail" in servInstalled and serviceUpdate in ["all","mail"]:
|
|
|
|
|
self.clVars.Write("sr_mail_type",
|
|
|
|
|
self.clVars.Get("sr_mail_type"),
|
|
|
|
|
True,"local")
|
|
|
|
@ -5194,7 +5229,20 @@ outdated. If the backup is obsolete, use cl-backup."))
|
|
|
|
|
def updateLdapServer(self, options, serviceUpdate):
|
|
|
|
|
"""Обновление сервисов"""
|
|
|
|
|
return self.updateServer(options ,serviceUpdate)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def scanServiceDirs(self, servicePaths):
|
|
|
|
|
"""Сканирует пути сервисов и выдает список файлов от корня"""
|
|
|
|
|
allArchFiles = []
|
|
|
|
|
fileObj = cl_profile._file()
|
|
|
|
|
dirObjs = fileObj.scanDirs(servicePaths)
|
|
|
|
|
i = 0
|
|
|
|
|
for dirObj in dirObjs:
|
|
|
|
|
for fileProfile in dirObj.files:
|
|
|
|
|
archFile = fileProfile.split(servicePaths[i])[1]
|
|
|
|
|
allArchFiles.append(archFile)
|
|
|
|
|
i += 1
|
|
|
|
|
return allArchFiles
|
|
|
|
|
|
|
|
|
|
def backupServer(self):
|
|
|
|
|
"""Сохраняет настройки установленных сервисов и базу LDAP"""
|
|
|
|
|
# создаем директорию backup-а
|
|
|
|
@ -5208,20 +5256,35 @@ outdated. If the backup is obsolete, use cl-backup."))
|
|
|
|
|
# Соединяемся с LDAP
|
|
|
|
|
if not shareLdap.getLdapObjInFile(self):
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
# получаем ldif текст всей базы LDAP
|
|
|
|
|
ldifText = self.fullElementDNtoText("")
|
|
|
|
|
ldifText = self.fullElementDNtoText()
|
|
|
|
|
if not ldifText:
|
|
|
|
|
self.printERROR( "Unix service DN is not found or empty")
|
|
|
|
|
return False
|
|
|
|
|
self.printERROR(_("LDAP database empty"))
|
|
|
|
|
return False
|
|
|
|
|
replServices = []
|
|
|
|
|
# В случае включения репликации создаем ldif файлы для сервисов
|
|
|
|
|
if self.clVars.Get("ld_repl_set") == "on":
|
|
|
|
|
if self.clVars.Get("sr_unix_set") == "on":
|
|
|
|
|
# получаем ldif текст для сервиса Unix
|
|
|
|
|
ldifTextUnix = self.fullElementUnixDNtoText()
|
|
|
|
|
if not ldifText:
|
|
|
|
|
self.printERROR(_("LDAP database empty"))
|
|
|
|
|
return False
|
|
|
|
|
replServices.append('unix')
|
|
|
|
|
if self.clVars.Get("sr_samba_set") == "on":
|
|
|
|
|
# получаем ldif текст для сервиса Samba
|
|
|
|
|
ldifTextSamba = self.fullElementSambaDNtoText()
|
|
|
|
|
if not ldifText:
|
|
|
|
|
self.printERROR(_("LDAP database empty"))
|
|
|
|
|
return False
|
|
|
|
|
replServices.append('samba')
|
|
|
|
|
|
|
|
|
|
# генерируем название файла архива
|
|
|
|
|
strData = time.strftime("%Y%m%d%H%M%S",time.localtime(time.time()))
|
|
|
|
|
backupFile = "%s.tar.bz2" %strData
|
|
|
|
|
# удаляем если существуют ldif файл базы LDAP и файл список
|
|
|
|
|
if os.path.exists(self.archLdifFile):
|
|
|
|
|
os.remove(self.archLdifFile)
|
|
|
|
|
if os.path.exists(self.tmpListFile):
|
|
|
|
|
os.remove(self.tmpListFile)
|
|
|
|
|
# если существуют удаляем файлы в /tmp
|
|
|
|
|
self.removeTmpFiles()
|
|
|
|
|
# находим пути к профилям установленных сервисов
|
|
|
|
|
servicePaths, servInstalled = self.getServiceSetupPathProfiles()
|
|
|
|
|
if not servicePaths:
|
|
|
|
@ -5229,16 +5292,34 @@ outdated. If the backup is obsolete, use cl-backup."))
|
|
|
|
|
self.printERROR("Services are not installed")
|
|
|
|
|
return False
|
|
|
|
|
# Все файлы которые нужно заархивировать
|
|
|
|
|
allArchFiles = []
|
|
|
|
|
fileObj = cl_profile._file()
|
|
|
|
|
dirObjs = fileObj.scanDirs(servicePaths)
|
|
|
|
|
i = 0
|
|
|
|
|
for dirObj in dirObjs:
|
|
|
|
|
for fileProfile in dirObj.files:
|
|
|
|
|
archFile = fileProfile.split(servicePaths[i])[1]
|
|
|
|
|
allArchFiles.append(archFile)
|
|
|
|
|
i += 1
|
|
|
|
|
allArchFiles = self.scanServiceDirs(servicePaths)
|
|
|
|
|
scanPrivDirs = []
|
|
|
|
|
|
|
|
|
|
# файлы в архиве для Unix
|
|
|
|
|
replArchFilesUnix = []
|
|
|
|
|
# сканируемые директории для Unix
|
|
|
|
|
replScanPrivDirsUnix = []
|
|
|
|
|
# файлы в aрхиве для Samba
|
|
|
|
|
replArchFilesSamba = []
|
|
|
|
|
# сканируемые директории для Samba
|
|
|
|
|
replScanPrivDirsSamba = []
|
|
|
|
|
# В случае включения репликации
|
|
|
|
|
if replServices:
|
|
|
|
|
i = 0
|
|
|
|
|
serviceUnixPaths = []
|
|
|
|
|
serviceSambaPaths = []
|
|
|
|
|
for service in servInstalled:
|
|
|
|
|
if service == "unix":
|
|
|
|
|
serviceUnixPaths.append(servicePaths[i])
|
|
|
|
|
elif service == "samba":
|
|
|
|
|
serviceSambaPaths.append(servicePaths[i])
|
|
|
|
|
i += 1
|
|
|
|
|
# файлы в архиве для Unix
|
|
|
|
|
replArchFilesUnix = self.scanServiceDirs(serviceUnixPaths)
|
|
|
|
|
# файлы в aрхиве для Samba
|
|
|
|
|
replArchFilesSamba = self.scanServiceDirs(serviceSambaPaths)
|
|
|
|
|
# Cоздаем файловый объект
|
|
|
|
|
fileObj = cl_profile._file()
|
|
|
|
|
if "ldap" in servInstalled:
|
|
|
|
|
# Получаем путь к ini директории
|
|
|
|
|
ldapParser = iniLdapParser()
|
|
|
|
@ -5249,12 +5330,22 @@ outdated. If the backup is obsolete, use cl-backup."))
|
|
|
|
|
scanPrivDirs.append(dirDelUsers)
|
|
|
|
|
# Добавляем calulate.ldap
|
|
|
|
|
allArchFiles.append(ldapParser.nameIniFile)
|
|
|
|
|
if replServices:
|
|
|
|
|
if "unix" in replServices:
|
|
|
|
|
replArchFilesUnix.append(ldapParser.nameIniFile)
|
|
|
|
|
if "samba" in replServices:
|
|
|
|
|
replArchFilesSamba.append(ldapParser.nameIniFile)
|
|
|
|
|
# Добавляем calculate.env
|
|
|
|
|
iniFiles = self.clVars.Get("cl_env_path")
|
|
|
|
|
if iniFiles and len(iniFiles)>1:
|
|
|
|
|
for iniFile in iniFiles:
|
|
|
|
|
if os.path.exists(iniFile):
|
|
|
|
|
allArchFiles.append(iniFile)
|
|
|
|
|
if replServices:
|
|
|
|
|
if "unix" in replServices:
|
|
|
|
|
replArchFilesUnix.append(iniFile)
|
|
|
|
|
if "samba" in replServices:
|
|
|
|
|
replArchFilesSamba.append(iniFile)
|
|
|
|
|
profileDirs = self.clVars.Get("cl_profile_path")
|
|
|
|
|
if len(profileDirs)>1:
|
|
|
|
|
profileDirs = profileDirs[1:]
|
|
|
|
@ -5263,12 +5354,32 @@ outdated. If the backup is obsolete, use cl-backup."))
|
|
|
|
|
for pDir in profileDirs:
|
|
|
|
|
if os.path.exists(pDir):
|
|
|
|
|
scanPrivDirs.append(pDir)
|
|
|
|
|
if replServices:
|
|
|
|
|
if "unix" in replServices:
|
|
|
|
|
replScanPrivDirsUnix.append(pDir)
|
|
|
|
|
if "samba" in replServices:
|
|
|
|
|
replScanPrivDirsSamba.append(pDir)
|
|
|
|
|
if "samba" in servInstalled:
|
|
|
|
|
scanPrivDirs.append(self.sambaPrivate)
|
|
|
|
|
if replServices and "samba" in replServices:
|
|
|
|
|
replScanPrivDirsSamba.append(self.sambaPrivate)
|
|
|
|
|
if "mail" in servInstalled:
|
|
|
|
|
scanPrivDirs.append(self.mailPrivate)
|
|
|
|
|
# Добавляем в директории сканирования директории сертификатов mail
|
|
|
|
|
scanPrivDirs += self.sslDirsMail
|
|
|
|
|
# При включении репликации сканируем директории
|
|
|
|
|
if replServices:
|
|
|
|
|
if "samba" in replServices and replScanPrivDirsSamba:
|
|
|
|
|
dirObjs = fileObj.scanDirs(replScanPrivDirsSamba)
|
|
|
|
|
for dirObj in dirObjs:
|
|
|
|
|
for archFile in dirObj.files:
|
|
|
|
|
replArchFilesSamba.append(archFile)
|
|
|
|
|
if "unix" in replServices and replScanPrivDirsUnix:
|
|
|
|
|
dirObjs = fileObj.scanDirs(replScanPrivDirsUnix)
|
|
|
|
|
for dirObj in dirObjs:
|
|
|
|
|
for archFile in dirObj.files:
|
|
|
|
|
replArchFilesUnix.append(archFile)
|
|
|
|
|
# Сканируем директории
|
|
|
|
|
if scanPrivDirs:
|
|
|
|
|
dirObjs = fileObj.scanDirs(scanPrivDirs)
|
|
|
|
|
for dirObj in dirObjs:
|
|
|
|
@ -5277,9 +5388,62 @@ outdated. If the backup is obsolete, use cl-backup."))
|
|
|
|
|
# Добавляем сертификат jabber
|
|
|
|
|
if "jabber" in servInstalled:
|
|
|
|
|
allArchFiles.append(self.sslJabberFile)
|
|
|
|
|
allArchFiles.append(self.archLdifFile)
|
|
|
|
|
if replServices:
|
|
|
|
|
if "unix" in replServices:
|
|
|
|
|
# Дополнительные файлы добавляемые в архив
|
|
|
|
|
additFiles = [self.archLdifFile,
|
|
|
|
|
self.replArchLdifFileUnix,self.replListFileUnix]
|
|
|
|
|
for additFile in additFiles:
|
|
|
|
|
replArchFilesUnix.append(additFile)
|
|
|
|
|
replArchFilesUnix = self.unicList(replArchFilesUnix)
|
|
|
|
|
# Удаляем начальный "/"
|
|
|
|
|
replArchFilesUnix = map(lambda x:\
|
|
|
|
|
"/".join(filter(lambda y:y ,x.split("/"))),replArchFilesUnix)
|
|
|
|
|
replArchFilesUnix.sort()
|
|
|
|
|
if "samba" in replServices:
|
|
|
|
|
# Дополнительные файлы добавляемые в архив
|
|
|
|
|
additFiles = [self.archLdifFile,
|
|
|
|
|
self.replArchLdifFileUnix,self.replListFileUnix,
|
|
|
|
|
self.replArchLdifFileSamba,self.replListFileSamba]
|
|
|
|
|
for additFile in additFiles:
|
|
|
|
|
replArchFilesSamba.append(additFile)
|
|
|
|
|
replArchFilesSamba += replArchFilesUnix
|
|
|
|
|
# Удаляем начальный "/"
|
|
|
|
|
replArchFilesSamba = map(lambda x:\
|
|
|
|
|
"/".join(filter(lambda y:y ,x.split("/"))),replArchFilesSamba)
|
|
|
|
|
replArchFilesSamba = self.unicList(replArchFilesSamba)
|
|
|
|
|
replArchFilesSamba.sort()
|
|
|
|
|
|
|
|
|
|
for additFile in additFiles:
|
|
|
|
|
allArchFiles.append(additFile)
|
|
|
|
|
else:
|
|
|
|
|
allArchFiles.append(self.archLdifFile)
|
|
|
|
|
allArchFiles = self.unicList(allArchFiles)
|
|
|
|
|
# Сохраняем файл список архивируемых файлов
|
|
|
|
|
# В случае репликации сохраняем файлы (список файлов, ldif - файл)
|
|
|
|
|
if replServices:
|
|
|
|
|
if "samba" in replServices:
|
|
|
|
|
if not self.savePrivateFile (self.replListFileSamba,
|
|
|
|
|
"\n".join(replArchFilesSamba)):
|
|
|
|
|
self.printERROR(_("Can not create list archive files")+\
|
|
|
|
|
": " + str(self.replListFileSamba))
|
|
|
|
|
return False
|
|
|
|
|
if not self.savePrivateFile(self.replArchLdifFileSamba,
|
|
|
|
|
ldifTextSamba):
|
|
|
|
|
self.printERROR(_("Can not create ldif file") + ": " +\
|
|
|
|
|
str(self.archLdifFile))
|
|
|
|
|
return False
|
|
|
|
|
if "unix" in replServices:
|
|
|
|
|
if not self.savePrivateFile (self.replListFileUnix,
|
|
|
|
|
"\n".join(replArchFilesUnix)):
|
|
|
|
|
self.printERROR(_("Can not create list archive files")+\
|
|
|
|
|
": " + str(self.replListFileUnix))
|
|
|
|
|
return False
|
|
|
|
|
if not self.savePrivateFile(self.replArchLdifFileUnix,
|
|
|
|
|
ldifTextUnix):
|
|
|
|
|
self.printERROR(_("Can not create ldif file") + ": " +\
|
|
|
|
|
str(self.archLdifFile))
|
|
|
|
|
return False
|
|
|
|
|
# Сохраняем файл список архивируемых файлов
|
|
|
|
|
if not self.savePrivateFile (self.tmpListFile,
|
|
|
|
|
"\n".join(allArchFiles)):
|
|
|
|
|
self.printERROR(_("Can not create list archive files") + ": " +\
|
|
|
|
@ -5293,10 +5457,8 @@ outdated. If the backup is obsolete, use cl-backup."))
|
|
|
|
|
bFile = os.path.join(self.backupDirectory, backupFile)
|
|
|
|
|
self.execProg("tar --files-from=%s -cjf %s"\
|
|
|
|
|
%(self.tmpListFile, bFile))
|
|
|
|
|
if os.path.exists(self.archLdifFile):
|
|
|
|
|
os.remove(self.archLdifFile)
|
|
|
|
|
if os.path.exists(self.tmpListFile):
|
|
|
|
|
os.remove(self.tmpListFile)
|
|
|
|
|
# если существуют удаляем файлы в /tmp
|
|
|
|
|
self.removeTmpFiles()
|
|
|
|
|
if os.path.exists(bFile):
|
|
|
|
|
os.chmod(bFile,0600)
|
|
|
|
|
self.printSUCCESS(_("Created archive file") + ": " +\
|
|
|
|
@ -5352,7 +5514,87 @@ outdated. If the backup is obsolete, use cl-backup."))
|
|
|
|
|
return False
|
|
|
|
|
return bFile
|
|
|
|
|
|
|
|
|
|
def restoreServer(self, startServices=True):
|
|
|
|
|
def getArchReplServices(self):
|
|
|
|
|
"""Получаем сервис который нужно реплицировать из архивного файла"""
|
|
|
|
|
bFile = self.getArchFile()
|
|
|
|
|
if not bFile:
|
|
|
|
|
return False
|
|
|
|
|
# Получаем список файлов в архиве
|
|
|
|
|
textListFiles = self.execProg("tar -tjf %s" %bFile,False,False)
|
|
|
|
|
# Удаляем из элементов переводы строк
|
|
|
|
|
archFiles = map(lambda x: "".join(x.split('\n')),textListFiles)
|
|
|
|
|
flagError = False
|
|
|
|
|
# Находим в списке файлов env файлы и проверяем результат
|
|
|
|
|
envFiles = []
|
|
|
|
|
for archFile in archFiles:
|
|
|
|
|
if not "/" in archFile:
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
if len(archFile)>3 and archFile[-4:] == ".env":
|
|
|
|
|
envFiles.append(archFile)
|
|
|
|
|
if not envFiles:
|
|
|
|
|
self.printERROR(_("Inside the archive %s no files with\
|
|
|
|
|
the extension '.env'")%bFile)
|
|
|
|
|
return False
|
|
|
|
|
if flagError:
|
|
|
|
|
self.printERROR(_("Can not list the contents of an archive") +\
|
|
|
|
|
": " + str(bFile))
|
|
|
|
|
return False
|
|
|
|
|
# Удаляем временные файлы
|
|
|
|
|
self.removeTmpFiles()
|
|
|
|
|
# Сохраняем файл - список извлекаемых файлов
|
|
|
|
|
if not self.savePrivateFile (self.tmpListFile,
|
|
|
|
|
"\n".join(envFiles)):
|
|
|
|
|
self.printERROR(_("Can not create list extract files") + ": " +\
|
|
|
|
|
str(self.tmpListFile))
|
|
|
|
|
return False
|
|
|
|
|
# Cоздаем временную директорию
|
|
|
|
|
try:
|
|
|
|
|
os.makedirs(self.tmpEnvDir)
|
|
|
|
|
except os.IOError:
|
|
|
|
|
self.printERROR(_("Can not create directory") + ": " +\
|
|
|
|
|
str(self.tmpEnvDir))
|
|
|
|
|
return False
|
|
|
|
|
# Разархивируем env файлы во временную директорию
|
|
|
|
|
if not (self.execProg("tar -C %s --files-from=%s -xjf %s"\
|
|
|
|
|
%(self.tmpEnvDir,self.tmpListFile, bFile)) == None):
|
|
|
|
|
self.printERROR(_("Can not extract archive") + ": " + str(bFile))
|
|
|
|
|
return False
|
|
|
|
|
# Создаем объект переменных clVars
|
|
|
|
|
self.clVars = cl_base.DataVars()
|
|
|
|
|
self.clVars.flServer()
|
|
|
|
|
#Записываем новые пути к env в переменную
|
|
|
|
|
envPaths = []
|
|
|
|
|
for path in envFiles:
|
|
|
|
|
envPaths.append(os.path.join(self.tmpEnvDir,path))
|
|
|
|
|
self.clVars.Set("cl_env_path", envPaths, True)
|
|
|
|
|
# считаем переменные из ini файлов
|
|
|
|
|
self.clVars.flIniFile()
|
|
|
|
|
servicePaths, servInstalled = self.getServiceSetupPathProfiles()
|
|
|
|
|
if not servicePaths:
|
|
|
|
|
self.printERROR("Services are not installed in archive %s" %bFile)
|
|
|
|
|
return False
|
|
|
|
|
# Найдем сервисы которые нужно установить
|
|
|
|
|
replSambaServers = self.clVars.Get("ld_repl_samba_servers")
|
|
|
|
|
if replSambaServers:
|
|
|
|
|
replSambaServers = replSambaServers.split(",")
|
|
|
|
|
replUnixServers = self.clVars.Get("ld_repl_unix_servers")
|
|
|
|
|
if replUnixServers:
|
|
|
|
|
replUnixServers = replUnixServers.split(",")
|
|
|
|
|
hostName = self.clVars.Get('os_net_hostname')
|
|
|
|
|
domain = self.clVars.Get('os_net_domain')
|
|
|
|
|
services = []
|
|
|
|
|
fullHostName = "%s.%s"%(hostName,domain)
|
|
|
|
|
if not fullHostName in replSambaServers:
|
|
|
|
|
if fullHostName in replUnixServers:
|
|
|
|
|
services = ["unix"]
|
|
|
|
|
else:
|
|
|
|
|
services = ["unix","samba"]
|
|
|
|
|
# Удаляем временные файлы
|
|
|
|
|
self.removeTmpFiles()
|
|
|
|
|
return services
|
|
|
|
|
|
|
|
|
|
def restoreServer(self, startServices=True,replServices=False):
|
|
|
|
|
"""Восстанавливает из архива все установленные сервисы
|
|
|
|
|
|
|
|
|
|
Восстановленные сервисы будут запущены
|
|
|
|
@ -5379,8 +5621,18 @@ outdated. If the backup is obsolete, use cl-backup."))
|
|
|
|
|
return False
|
|
|
|
|
# Cписок разахивированных файлов (файл ldif)
|
|
|
|
|
allArchFiles = [self.archLdifFile[1:]]
|
|
|
|
|
if os.path.exists(self.tmpListFile):
|
|
|
|
|
os.remove(self.tmpListFile)
|
|
|
|
|
if replServices:
|
|
|
|
|
if "samba" in replServices:
|
|
|
|
|
allArchFiles = [self.replArchLdifFileSamba,
|
|
|
|
|
self.replListFileSamba]
|
|
|
|
|
elif "unix" in replServices:
|
|
|
|
|
allArchFiles = [self.replArchLdifFileUnix,
|
|
|
|
|
self.replListFileUnix]
|
|
|
|
|
# Удаляем начальный '/'
|
|
|
|
|
allArchFiles = map(lambda x:\
|
|
|
|
|
"/".join(filter(lambda y:y ,x.split("/"))),allArchFiles)
|
|
|
|
|
# Удаляем временные файлы
|
|
|
|
|
self.removeTmpFiles()
|
|
|
|
|
# Сохраняем файл - список извлекаемых файлов (файл ldif)
|
|
|
|
|
if not self.savePrivateFile (self.tmpListFile,
|
|
|
|
|
"\n".join(allArchFiles)):
|
|
|
|
@ -5388,16 +5640,22 @@ outdated. If the backup is obsolete, use cl-backup."))
|
|
|
|
|
str(self.tmpListFile))
|
|
|
|
|
return False
|
|
|
|
|
# Распаковываем ldif файл
|
|
|
|
|
ldifFile = self.archLdifFile
|
|
|
|
|
if replServices:
|
|
|
|
|
if "samba" in replServices:
|
|
|
|
|
ldifFile = self.replArchLdifFileSamba
|
|
|
|
|
elif "unix" in replServices:
|
|
|
|
|
ldifFile = self.replArchLdifFileUnix
|
|
|
|
|
if not (self.execProg("tar -C / --files-from=%s -xjf %s"\
|
|
|
|
|
%(self.tmpListFile, bFile)) == None):
|
|
|
|
|
self.printERROR(_("Can not extract archive") + ": " + str(bFile))
|
|
|
|
|
return False
|
|
|
|
|
if not os.path.exists(self.archLdifFile):
|
|
|
|
|
if not os.path.exists(ldifFile):
|
|
|
|
|
self.printERROR(_("Ldif file is not found") + " :" +\
|
|
|
|
|
str(self.archLdifFile))
|
|
|
|
|
str(ldifFile))
|
|
|
|
|
return False
|
|
|
|
|
# Читаем ldif файл
|
|
|
|
|
FD = open (self.archLdifFile, "r")
|
|
|
|
|
FD = open (ldifFile, "r")
|
|
|
|
|
ldif = FD.read()
|
|
|
|
|
FD.close()
|
|
|
|
|
# Добавляем в базу из ldif
|
|
|
|
@ -5410,16 +5668,29 @@ outdated. If the backup is obsolete, use cl-backup."))
|
|
|
|
|
return False
|
|
|
|
|
# Удаляем временные файлы нужные для установки сервисов
|
|
|
|
|
self.removeTmpRestoreFile()
|
|
|
|
|
# Распаковываем целиком архив
|
|
|
|
|
if not (self.execProg("tar -C / -xjf %s"\
|
|
|
|
|
%(bFile)) == None):
|
|
|
|
|
self.printERROR(_("Can not extract archive") + ": " + str(bFile))
|
|
|
|
|
return False
|
|
|
|
|
if replServices:
|
|
|
|
|
# Файл - список разархивируемых файлов
|
|
|
|
|
listReplFile = ""
|
|
|
|
|
if "samba" in replServices:
|
|
|
|
|
listReplFile = self.replListFileSamba
|
|
|
|
|
elif "unix" in replServices:
|
|
|
|
|
listReplFile = self.replListFileUnix
|
|
|
|
|
else:
|
|
|
|
|
self.printError(_("Not supported replication service %s")\
|
|
|
|
|
%replServices[0])
|
|
|
|
|
return False
|
|
|
|
|
if not (self.execProg("tar -C / --files-from=%s -xjf %s"\
|
|
|
|
|
%(listReplFile, bFile)) == None):
|
|
|
|
|
self.printERROR(_("Can not extract archive") + ": " + str(bFile))
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
# Распаковываем целиком архив
|
|
|
|
|
if not (self.execProg("tar -C / -xjf %s"\
|
|
|
|
|
%(bFile)) == None):
|
|
|
|
|
self.printERROR(_("Can not extract archive") + ": " + str(bFile))
|
|
|
|
|
return False
|
|
|
|
|
# Удаляем временные файлы
|
|
|
|
|
if os.path.exists(self.tmpListFile):
|
|
|
|
|
os.remove(self.tmpListFile)
|
|
|
|
|
if os.path.exists(self.archLdifFile):
|
|
|
|
|
os.remove(self.archLdifFile)
|
|
|
|
|
self.removeTmpFiles()
|
|
|
|
|
# считаем переменные из ini файлов
|
|
|
|
|
self.clVars.flIniFile()
|
|
|
|
|
if startServices:
|
|
|
|
@ -5427,17 +5698,28 @@ outdated. If the backup is obsolete, use cl-backup."))
|
|
|
|
|
if not self.startAllSetupServices():
|
|
|
|
|
return False
|
|
|
|
|
self.printOK(_("Restored all installed services") + " ...")
|
|
|
|
|
if replServices:
|
|
|
|
|
self.printOK(_("Replication on from services (%s)")\
|
|
|
|
|
%", ".join(replServices) + " ...")
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def removeTmpFiles(self):
|
|
|
|
|
"""Удаляем временные файлы"""
|
|
|
|
|
removeFiles = [self.tmpListFile,self.archLdifFile,
|
|
|
|
|
self.replArchLdifFileUnix,self.replListFileUnix,
|
|
|
|
|
self.replArchLdifFileSamba,self.replListFileSamba]
|
|
|
|
|
for rmFile in removeFiles:
|
|
|
|
|
if os.path.exists(rmFile):
|
|
|
|
|
os.remove(rmFile)
|
|
|
|
|
if os.path.exists(self.tmpEnvDir):
|
|
|
|
|
self.removeDir(self.tmpEnvDir)
|
|
|
|
|
|
|
|
|
|
def __del__(self):
|
|
|
|
|
# Удаляем временные файлы
|
|
|
|
|
if os.path.exists(self.tmpListFile):
|
|
|
|
|
os.remove(self.tmpListFile)
|
|
|
|
|
if os.path.exists(self.archLdifFile):
|
|
|
|
|
os.remove(self.archLdifFile)
|
|
|
|
|
"""Удаляем временные файлы"""
|
|
|
|
|
self.removeTmpFiles()
|
|
|
|
|
|
|
|
|
|
def removeTmpRestoreFile(self):
|
|
|
|
|
"""Удаляем временные файлы нужные для восстановлеиня сервисов"""
|
|
|
|
|
"""Удаляем временные файлы нужные для восстановления сервисов"""
|
|
|
|
|
profilePath = self.clVars.Get("cl_profile_path")[0]
|
|
|
|
|
backupDir = os.path.join(profilePath, self.backupDir)
|
|
|
|
|
fileObj = cl_profile._file()
|
|
|
|
@ -6447,6 +6729,12 @@ the password will be changed only for Samba account")
|
|
|
|
|
'longOption':"verbose",
|
|
|
|
|
'helpChapter':_("Common options"),
|
|
|
|
|
'help':_("displays additional information")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(10,),
|
|
|
|
|
'longOption':"repl",
|
|
|
|
|
'helpChapter':_("Common options"),
|
|
|
|
|
'help':_("using the backup of another server,\
|
|
|
|
|
replicate runs on the server")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(11,),
|
|
|
|
|
'shortOption':"l",
|
|
|
|
@ -7270,27 +7558,103 @@ class servRepl(shareLdap):
|
|
|
|
|
self.relWorkedDN = False
|
|
|
|
|
# Файл для определения выхода пользователя.
|
|
|
|
|
self.logOutFile = ".logout"
|
|
|
|
|
#repl_text = """
|
|
|
|
|
#rootdn "cn=ldaproot,dc=calculate"
|
|
|
|
|
|
|
|
|
|
#syncrepl rid=001
|
|
|
|
|
#provider=ldap://newserver
|
|
|
|
|
#type=refreshAndPersist
|
|
|
|
|
#retry="5 5 300 +"
|
|
|
|
|
#searchbase="ou=Unix,ou=Services,dc=calculate"
|
|
|
|
|
#attrs="*,+"
|
|
|
|
|
#bindmethod=simple
|
|
|
|
|
#binddn="ou=Unix,ou=Services,dc=calculate"
|
|
|
|
|
#credentials=UCwZO73Y1
|
|
|
|
|
|
|
|
|
|
#updateref ldap://newserver:389
|
|
|
|
|
|
|
|
|
|
#overlay syncprov
|
|
|
|
|
#syncprov-checkpoint 100 10
|
|
|
|
|
#syncprov-sessionlog 100
|
|
|
|
|
|
|
|
|
|
#mirrormode on
|
|
|
|
|
#serverID 2"""
|
|
|
|
|
# Переменные (/etc/calculate/calculate.env)
|
|
|
|
|
# которые будут сохранены при rebuild
|
|
|
|
|
self.restoreDefaultVar =["sr_ldap_set", "ld_repl_pw", "ld_repl_set",
|
|
|
|
|
"sr_unix_set", "sr_samba_set"]
|
|
|
|
|
# Переменные (/var/calculate/calculate.env)
|
|
|
|
|
# которые будут сохранены при rebuild
|
|
|
|
|
self.restoreLocalVar = ["sr_samba_domain","sr_samba_netbios",
|
|
|
|
|
"ld_repl_servers","ld_repl_unix_servers",
|
|
|
|
|
"ld_repl_samba_servers","ld_repl_ids"]
|
|
|
|
|
# Переменные клиента (/var/calculate/remote/calculate.env)
|
|
|
|
|
# которые будут сохранены при rebuild
|
|
|
|
|
self.restoreRemoteClientVar = ["ld_unix_dn","sr_samba_host",
|
|
|
|
|
"ld_services_dn","ld_bind_dn",
|
|
|
|
|
"ld_bind_pw","ld_base_dn",
|
|
|
|
|
"ur_organization","ur_signature"]
|
|
|
|
|
|
|
|
|
|
def prepAndSaveEnv(self):
|
|
|
|
|
"""Подготовка переменных и их запись в файлы в случае rebuild"""
|
|
|
|
|
# Cоздаем объект переменные
|
|
|
|
|
def removeNameFoundText(findText, listName):
|
|
|
|
|
"""Удаляет элементы списка.
|
|
|
|
|
|
|
|
|
|
Будут удалены элементы названии которых присутствует текст
|
|
|
|
|
(findText)
|
|
|
|
|
"""
|
|
|
|
|
outListName = []
|
|
|
|
|
for name in listName:
|
|
|
|
|
if not findText in name:
|
|
|
|
|
outListName.append(name)
|
|
|
|
|
return outListName
|
|
|
|
|
# Cоздаем объект переменные
|
|
|
|
|
self.createClVars()
|
|
|
|
|
if self.clVars.Get("ld_repl_set") != "on":
|
|
|
|
|
self.printERROR(_("Replication off in backup file") + " ...")
|
|
|
|
|
return False
|
|
|
|
|
#Модификация переменных
|
|
|
|
|
replSambaServers = self.clVars.Get("ld_repl_samba_servers")
|
|
|
|
|
if replSambaServers:
|
|
|
|
|
replSambaServers = replSambaServers.split(",")
|
|
|
|
|
replUnixServers = self.clVars.Get("ld_repl_unix_servers")
|
|
|
|
|
if replUnixServers:
|
|
|
|
|
replUnixServers = replUnixServers.split(",")
|
|
|
|
|
hostName = self.clVars.Get('os_net_hostname')
|
|
|
|
|
domain = self.clVars.Get('os_net_domain')
|
|
|
|
|
serviceRepl = ""
|
|
|
|
|
fullHostName = "%s.%s"%(hostName,domain)
|
|
|
|
|
if not fullHostName in replSambaServers:
|
|
|
|
|
if fullHostName in replUnixServers:
|
|
|
|
|
serviceRepl = "unix"
|
|
|
|
|
else:
|
|
|
|
|
serviceRepl = "samba"
|
|
|
|
|
if not serviceRepl:
|
|
|
|
|
self.printERROR(\
|
|
|
|
|
_("Not found this replication server %s in backup file")%fullHostName+\
|
|
|
|
|
" ...")
|
|
|
|
|
return False
|
|
|
|
|
if serviceRepl == "unix":
|
|
|
|
|
self.restoreDefaultVar = removeNameFoundText("samba",
|
|
|
|
|
self.restoreDefaultVar)
|
|
|
|
|
self.restoreLocalVar = removeNameFoundText("samba",
|
|
|
|
|
self.restoreLocalVar)
|
|
|
|
|
self.restoreRemoteClientVar = []
|
|
|
|
|
elif serviceRepl == "samba":
|
|
|
|
|
self.clVars.Set('sr_samba_netbios', "%s-cds"%hostName, True)
|
|
|
|
|
self.clVars.Set('sr_samba_host',fullHostName, True)
|
|
|
|
|
# Находим пути к env файлам
|
|
|
|
|
envPaths = self.clVars.Get("cl_env_path")
|
|
|
|
|
# Удаляем env файлы
|
|
|
|
|
for path in envPaths:
|
|
|
|
|
if os.path.exists(path):
|
|
|
|
|
os.remove(path)
|
|
|
|
|
flagError = False
|
|
|
|
|
# Записываем переменные сервера
|
|
|
|
|
for varName in self.restoreDefaultVar:
|
|
|
|
|
if not self.clVars.Write(varName,self.clVars.Get(varName),True):
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
if flagError:
|
|
|
|
|
self.printERROR(_("Variable '%s'")%varName + " " +\
|
|
|
|
|
_("can not be recorded in the file %s") %envPaths[2]+\
|
|
|
|
|
" ...")
|
|
|
|
|
return False
|
|
|
|
|
for varName in self.restoreLocalVar:
|
|
|
|
|
if not self.clVars.Write(varName,
|
|
|
|
|
self.clVars.Get(varName),True,'local'):
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
if flagError:
|
|
|
|
|
self.printERROR(_("Variable '%s'")%varName + " " +\
|
|
|
|
|
_("can not be recorded in the file %s") %envPaths[2]+\
|
|
|
|
|
" ...")
|
|
|
|
|
return False
|
|
|
|
|
# Записываем переменные клиента
|
|
|
|
|
if self.restoreRemoteClientVar:
|
|
|
|
|
if not self.saveVarsClient(self.restoreRemoteClientVar):
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
@adminConnectLdap
|
|
|
|
|
def isSysDNExists(self):
|
|
|
|
|