Added creation of differential archives for a user profile

master
Самоукин Алексей 14 years ago
parent 13413a316b
commit 13b815425e

@ -52,5 +52,8 @@ int clearKey(char *login)
buffer = "XXXXXXXX"; buffer = "XXXXXXXX";
key_serial_t dest; key_serial_t dest;
dest = KEY_SPEC_USER_SESSION_KEYRING; dest = KEY_SPEC_USER_SESSION_KEYRING;
return add_key("user", login, buffer, strlen(buffer), dest); if (add_key("user", login, buffer, strlen(buffer), dest)!=-1)
return 0;
else
return 1;
}; };

@ -31,7 +31,6 @@ import _cl_keys
import time import time
import stat import stat
import subprocess import subprocess
import time
from encrypt import encrypt from encrypt import encrypt
from signal import SIGTERM from signal import SIGTERM
@ -365,6 +364,7 @@ class cl_client(imp_cl_err, imp_cl_xml, imp_cl_help, imp_cl_smcon, encrypt):
rootProfilePaths=['/usr/lib/calculate/calculate-client/profiles', rootProfilePaths=['/usr/lib/calculate/calculate-client/profiles',
'/var/calculate/remote/profiles', '/var/calculate/remote/profiles',
'/var/calculate/profiles'] '/var/calculate/profiles']
def __init__(self, cmdName): def __init__(self, cmdName):
# объект для форматированного вывода # объект для форматированного вывода
imp_cl_help.__init__(self, cmdName) imp_cl_help.__init__(self, cmdName)
@ -584,6 +584,8 @@ conjunction with the 'login' or 'logout'")
# используемое для прогрессбара # используемое для прогрессбара
self.configFileDesktop = "desktop.env" self.configFileDesktop = "desktop.env"
self.configFileServer = "server.env" self.configFileServer = "server.env"
# Файл - список файлов профиля пользователя
self.listProfFile = ".calculate/files.txt"
# Путь относительно домашней директории в котором находятся # Путь относительно домашней директории в котором находятся
# конфигурационные файлы # конфигурационные файлы
self.pathConfig = ".calculate" self.pathConfig = ".calculate"
@ -599,10 +601,9 @@ conjunction with the 'login' or 'logout'")
replBranch = self.replAttr + "=" + self.replBranchName replBranch = self.replAttr + "=" + self.replBranchName
# DN хранения последнего посещенного пользователя # DN хранения последнего посещенного пользователя
self.replHostsDN = self.addDN(replBranch,self.sysDN) self.replHostsDN = self.addDN(replBranch,self.sysDN)
# Файл репликации self.logOutFile = ".logout"
self.replLogoutFile = ".logout"
self.skipHomeFile = ["Home","Disks","FTP", self.skipHomeFile = ["Home","Disks","FTP",
self.replLogoutFile, self.logOutFile,
os.path.join(self.pathConfig,self.configFileDesktop)] os.path.join(self.pathConfig,self.configFileDesktop)]
# Если атрибут установлен то значит (ошибка и отмонтируются # Если атрибут установлен то значит (ошибка и отмонтируются
# пользовательские ресурсы) # пользовательские ресурсы)
@ -923,7 +924,7 @@ conjunction with the 'login' or 'logout'")
objConfig = cl_base.iniParser(fileConfig) objConfig = cl_base.iniParser(fileConfig)
varsRun = {"run":"on"} varsRun = {"run":"on"}
varsRun.update(varsCommand) varsRun.update(varsCommand)
if not objConfig.setVar(["command", command], varsRun): if not objConfig.setVar(["command"]+command, varsRun):
self.printERROR(_("Can not write variables in file %s")\ self.printERROR(_("Can not write variables in file %s")\
%fileConfig) %fileConfig)
return False return False
@ -931,6 +932,16 @@ conjunction with the 'login' or 'logout'")
os.chown(fileConfig, uid, gid) os.chown(fileConfig, uid, gid)
return True return True
def getDataInConfig(self, section, listVars, objConfig):
"""Читаем переменные listVars из секции section конф. файла"""
varsConfig = {}
for varName in listVars:
varsConfig[varName] = objConfig.getVar(section,varName)
if objConfig.getError():
return False
return varsConfig
def setUserPasswordToServer(self, options): def setUserPasswordToServer(self, options):
"""Установка пароля пользователя на сервере""" """Установка пароля пользователя на сервере"""
# Проверяем на root # Проверяем на root
@ -973,7 +984,8 @@ conjunction with the 'login' or 'logout'")
# ~/.calculate/server.env # ~/.calculate/server.env
fileConfig = os.path.join(os.environ["HOME"], self.pathConfig, fileConfig = os.path.join(os.environ["HOME"], self.pathConfig,
self.configFileServer) self.configFileServer)
if not self.setServerCommand("passwd_samba", varsConfig, fileConfig): if not self.setServerCommand(["passwd_samba"], varsConfig,
fileConfig):
return False return False
self.printOK(_("Changed password of user %s")%os.environ["USER"] + \ self.printOK(_("Changed password of user %s")%os.environ["USER"] + \
" ...") " ...")
@ -1686,7 +1698,8 @@ or ld_bind_dn or ld_bind_pw")
# Ищем ключ в ядре # Ищем ключ в ядре
if _cl_keys.getKey(userName): if _cl_keys.getKey(userName):
# Если нашли очищаем # Если нашли очищаем
if _cl_keys.clearKey(userName) == 0: ret = _cl_keys.clearKey(userName)
if ret == 0:
return True return True
else: else:
self.printERROR(_("Can not clear kernel key from user %s")\ self.printERROR(_("Can not clear kernel key from user %s")\
@ -1740,17 +1753,8 @@ or ld_bind_dn or ld_bind_pw")
# Файл хранения настроек пакета # Файл хранения настроек пакета
configFileName = os.path.join(homeDir, self.pathConfig, configFileName = os.path.join(homeDir, self.pathConfig,
self.configFileDesktop) self.configFileDesktop)
home = os.path.split(homeDir)[0] # Получаем монтируемые директории
pathRemote = [] names, dictRes = self.getUserMountResources(userName, homeDir, False)
# Удаленный ресурс профилей
pathRemote.append((os.path.join(home,"." + userName), "unix"))
# Удаленный ресурс home
pathRemote.append((os.path.join(homeDir,"Home"), "homes"))
# Удаленный ресурс ftp
if self.clVars.Get("cl_remote_ftp"):
pathRemote.append((os.path.join(homeDir,"FTP"), "ftp"))
# Удаленный ресурс share
pathRemote.append((os.path.join(homeDir,"Disks"), "share"))
if os.path.exists(homeDir): if os.path.exists(homeDir):
self.moveHomeDir(homeDir) self.moveHomeDir(homeDir)
else: else:
@ -1759,11 +1763,7 @@ or ld_bind_dn or ld_bind_pw")
self.printERROR(_("Directory %s not found") % homeDir) self.printERROR(_("Directory %s not found") % homeDir)
return False return False
# Синхронизируем настройки # Синхронизируем настройки
pathUnix = "" pathUnix = dictRes["profile"]["path"]
for path, res in pathRemote:
if res == 'unix':
pathUnix = path
break
if pathUnix and self.isMount(pathUnix ,"cifs") and \ if pathUnix and self.isMount(pathUnix ,"cifs") and \
not(domain in self.isMount(pathUnix ,"cifs")): not(domain in self.isMount(pathUnix ,"cifs")):
# Убиваем rsync # Убиваем rsync
@ -1795,7 +1795,6 @@ or ld_bind_dn or ld_bind_pw")
return False return False
# проверяем произведен ли корректный вход в систему - # проверяем произведен ли корректный вход в систему -
# в этом случае закачиваем профиль с локальной машины на сервер # в этом случае закачиваем профиль с локальной машины на сервер
logOutFile = os.path.join(homeDir,self.replLogoutFile)
# необходима ли синхронизация с локальным сервером # необходима ли синхронизация с локальным сервером
needSync = False needSync = False
try: try:
@ -1803,12 +1802,12 @@ or ld_bind_dn or ld_bind_pw")
# то на локальный сервер закачиваем профиль # то на локальный сервер закачиваем профиль
# так как даже если он будет поврежден на другом сервере # так как даже если он будет поврежден на другом сервере
# остаётся правильная копия # остаётся правильная копия
if not self.isCorrectProfileOnLocalServer(userName): if self.getNameRemoteServer(userName):
needSync = True needSync = True
else: else:
exitStr = cl_base.iniParser(\ exitStr = cl_base.iniParser(\
configFileName).getVar('main','status') configFileName).getVar('main','status_sync')
# проверяем logOutFile: не содержит ли он "process" # проверяем атус синхронизации: не содержит ли он "process"
if exitStr != "process": if exitStr != "process":
needSync = True needSync = True
except: except:
@ -1821,8 +1820,10 @@ or ld_bind_dn or ld_bind_pw")
# Отмонтируем пользовательские ресурсы в случае ошибки # Отмонтируем пользовательские ресурсы в случае ошибки
self.errorAndUnmountUserRes = True self.errorAndUnmountUserRes = True
return False return False
osLinuxShort = self.clVars.Get("os_linux_shortname")
if needSync and not self.syncUser(userName,homeDir,"logout",uid,gid): homeProfile = os.path.join(pathUnix, osLinuxShort)
if needSync and not self.syncUser(userName, homeDir,"logout",uid,gid,
homeProfile):
# Удаляем файлы, мешающие работе dm # Удаляем файлы, мешающие работе dm
self.removeNoiseFiles(homeDir) self.removeNoiseFiles(homeDir)
# Удаляем приватные файлы # Удаляем приватные файлы
@ -1839,7 +1840,9 @@ or ld_bind_dn or ld_bind_pw")
# Очищаем ключ в ядре # Очищаем ключ в ядре
self.clearUserKey(userName) self.clearUserKey(userName)
flagError = False flagError = False
for path, res in pathRemote: # Отмонтируем директории
for name in names:
path = dictRes[name]["path"]
if self.isMount(path ,"cifs"): if self.isMount(path ,"cifs"):
textLine = self.umountSleepPath(path) textLine = self.umountSleepPath(path)
if not textLine: if not textLine:
@ -1900,20 +1903,14 @@ or ld_bind_dn or ld_bind_pw")
else: else:
homeDir = resLdap[5] homeDir = resLdap[5]
home = os.path.split(homeDir)[0] home = os.path.split(homeDir)[0]
pathRemote = [] # Получаем монтируемые директории
# Удаленный ресурс профилей names, dictRes = self.getUserMountResources(userName, homeDir, True)
pathRemote.append((os.path.join(home,"." + userName), "unix")) serverHomePath = dictRes["home"]["path"]
# Удаленный ресурс home
pathRemote.append((os.path.join(homeDir,"Home"), "homes"))
# Удаленный ресурс ftp
if self.clVars.Get("cl_remote_ftp"):
pathRemote.append((os.path.join(homeDir,"FTP"), "ftp"))
# Удаленный ресурс share
pathRemote.append((os.path.join(homeDir,"Disks"), "share"))
flagError = False flagError = False
if self.isMount(pathRemote[1][0] ,"cifs"): if self.isMount(serverHomePath, "cifs"):
self.moveHomeDir(homeDir) self.moveHomeDir(homeDir)
for path, res in pathRemote: for name in names:
path = dictRes[name]["path"]
if self.isMount(path ,"cifs"): if self.isMount(path ,"cifs"):
textLine = self.umountSleepPath(path) textLine = self.umountSleepPath(path)
if not textLine: if not textLine:
@ -2016,9 +2013,8 @@ or ld_bind_dn or ld_bind_pw")
os.rmdir(rmDir) os.rmdir(rmDir)
return True return True
def isCorrectProfileOnLocalServer(self,userName): def getNameRemoteServer(self,userName):
"""Узнать находится ли актуальный профиль пользователя на локальном """Если профиль на удаленном сервере, то выдать DNS имя этого сервера
сервере
""" """
searchPrevHost = self.searchPrevHost(userName) searchPrevHost = self.searchPrevHost(userName)
if searchPrevHost and searchPrevHost[0][0][1].has_key('host'): if searchPrevHost and searchPrevHost[0][0][1].has_key('host'):
@ -2028,15 +2024,16 @@ or ld_bind_dn or ld_bind_pw")
# если местоположение актуального профиля найти не удалось # если местоположение актуального профиля найти не удалось
# или его местоположение не на локальном сервере # или его местоположение не на локальном сервере
if not prevHost or prevHost == self.clVars.Get('cl_remote_host'): if not prevHost or prevHost == self.clVars.Get('cl_remote_host'):
return True
else:
return False return False
else:
return prevHost
def setCurrentVersionToConfig(self, configFileName, uid, gid): def setDateAndVersionToConfig(self, configFileName, uid, gid, strTime):
"""Записывает текущую версию в файл конфигурации""" """Записывает текущую версию в файл конфигурации"""
# Текущая версия программы # Текущая версия программы
currentVersion = self.clVars.Get("cl_ver") currentVersion = self.clVars.Get("cl_ver")
if self.setVarToConfig("main", {"version":currentVersion}, if self.setVarToConfig("main", {"version":currentVersion,
"date":strTime},
configFileName, uid, gid): configFileName, uid, gid):
return True return True
self.printERROR(_("can not write the version number in the file %s")\ self.printERROR(_("can not write the version number in the file %s")\
@ -2075,6 +2072,248 @@ or ld_bind_dn or ld_bind_pw")
os.remove(delFile) os.remove(delFile)
return True return True
def getUserMountResources(self, userName, homeDir, flagRemoteServer):
"""Получение монтируемых ресурсов для пользователя"""
home = os.path.split(homeDir)[0]
dictResources = {}
names = []
# Pесурс share
name = "share"
dictResources[name] = {"resource":"share",
"path":os.path.join(homeDir,"Disks")}
names.append(name)
# Ресурс профилей
name = "profile"
dictResources[name] = {"resource":"unix",
"path":os.path.join(home,"."+userName)}
names.append(name)
# Ресурс - домашняя директория (файлы пользователя на сервере)
name = "home"
dictResources[name] = {"resource":"homes",
"path":os.path.join(homeDir,"Home")}
names.append(name)
if self.clVars.Get("cl_remote_ftp"):
# Ресурс ftp
name = "ftp"
dictResources[name] = {"resource":"ftp",
"path":os.path.join(homeDir,"FTP")}
names.append(name)
if flagRemoteServer:
# Ресурс профилей на удаленном сервере
name = "remote_profile"
dictResources[name] = {"resource":"unix",
"path":os.path.join(home,"."+userName+"."+"remote")}
names.append(name)
return names, dictResources
def syncLoginProfile(self, userName, homeDir, homeProfile, uid, gid,
progress, flagClearHomeDir=True):
"""Синхронизация профиля пользователя с сервера
в переменной 'cl_remote_host' хост для прогрессбара
"""
home = os.path.split(homeDir)[0]
# Если на текущем сервере в ресурсе unix есть файлы
# то синхронируем настройки
if os.listdir(homeProfile):
if not self.syncUser(userName, homeDir, "login", uid, gid,\
homeProfile, progress=progress,
host=self.clVars.Get('cl_remote_host')):
return False
else:
if flagClearHomeDir:
# Удаляем ненужные файлы (очищаем домашнюю директорию)
if not self.clearHomeDir(homeDir):
return False
return True
def fileReader(self, fileName, stdin, progressObj=False):
"""Читает файл блоками в поток"""
fd = os.open(fileName, os.O_RDONLY)
if progressObj:
currSize = 0
# Размер файлового буфера в байтах
buffSize=131072
dataBlock = os.read(fd, buffSize)
while dataBlock:
if progressObj:
currSize += len(dataBlock)
progressObj.setValue(currSize)
stdin.write(dataBlock)
dataBlock = os.read(fd, buffSize)
stdin.close()
os.close(fd)
def unpackProfile(self, homeDir, archFile, progress=False,\
remoteServer=False):
"""Распаковка архива в домашнюю директорию пользователя"""
# Создаем прогрессбар
if progress:
title = _("Unpacking the archive from server")
if remoteServer:
title += " " + remoteServer
title += " ..."
progressObj = ProgressBar(title)
archiveSize = os.stat(archFile).st_size
progressObj.setMaximum(archiveSize)
execStr = "tar -C '%s' -xzf -" %homeDir
# Выполняем разархивацию
pipe = subprocess.Popen(execStr,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
close_fds=True,
env=os.environ, shell=True)
# Чтение файла в поток
if progress:
self.fileReader(archFile, pipe.stdin, progressObj)
else:
self.fileReader(archFile, pipe.stdin)
ret = pipe.wait()
pipe.stdout.close()
pipe.stderr.close()
if progress:
progressObj.shutdownDialog()
#ret = os.system(execStr)
if ret:
self.printERROR(_("Can not execute %s") %execStr)
self.printERROR(_("Can not unpack %s") %archFile)
return False
return True
def scanDirectory(self, scanDir, listFiles, skipPath=[], prefix=False,
flagDir=False):
"""Генерация списка файлов и директорий"""
if not prefix:
prefix = os.path.join(scanDir,"")
if flagDir or stat.S_ISDIR(os.lstat(scanDir)[stat.ST_MODE]):
for fileOrDir in os.listdir(scanDir):
absPath = os.path.join(scanDir,fileOrDir)
relPath = absPath.split(prefix)[1]
if relPath in skipPath:
continue
listFiles.append(relPath)
stInfo = os.lstat(absPath)
statInfo = stInfo[stat.ST_MODE]
if stat.S_ISDIR(statInfo):
self.scanDirectory(absPath, listFiles,
skipPath, prefix, True)
def getListFilesProfile(self, homeDir):
"""Генерация списка файлов в домашней директориии
Исключая монтируемые директории
"""
home = os.path.join(homeDir, "")
execStr = "mount"
textLines = self.execProg(execStr,False,False)
# Пропускаемые директории для сканирования
skipPaths = []
if textLines:
for line in textLines:
if home in line:
skipPath =\
line.partition(home)[2].rpartition(" type")[0]
skipPaths.append(skipPath)
# Список файлов в профиле пользователя
listFiles = []
if not skipPaths:
self.printERROR(_("Not found the mount point of server resources"))
return False
self.scanDirectory(homeDir, listFiles, skipPaths)
return listFiles
def removeFilesInProfile(self, homeDir, pathListFile):
"""Удаляем файлы которых нет в профиле пользователя"""
# Получаем файлы профиля на сервере
try:
filesProfileTxt = open(pathListFile).read()
except:
self.printERROR(_("Can not open %s")%pathListFile)
return False
listFilesProfile = filter(lambda x: x.strip(),
filesProfileTxt.split("\n"))
filesProfile = set(listFilesProfile)
# Получаем файлы в домашней директории
listFilesHome = self.getListFilesProfile(homeDir)
if listFilesHome is False:
return False
filesHome = set(listFilesHome)
filesRemove = list(filesHome - filesProfile)
filesRemove.sort(lambda x, y: cmp(len(y), len(x)))
rmPath = ""
try:
for rmFile in filesRemove:
rmPath = os.path.join(homeDir, rmFile)
if os.path.isdir(rmPath):
os.rmdir(rmPath)
elif os.path.isfile(rmPath):
os.remove(rmPath)
elif os.path.islink(rmPath):
os.unlink(rmPath)
else:
os.remove(rmPath)
except:
self.printERROR(_("Can nor remove %s")%rmPath)
return False
return True
def foundArchFile(self,strCurrentTime,archPathProcess,
archPathSuccess, progress=False,
remoteServer=False):
"""Поиск архива профиля пользователя"""
# Ищем архив профиля
# Задержки при поиске файла архива .process
if progress:
title = _("Packing the archive at the server")
if remoteServer:
title += " " + remoteServer
title += " ..."
progressObj = ProgressBar(title, 0)
progressObj.openDialog(title, 0)
sleepsFindProcess = [0.1, 0.2, 0.5]
# Задержки при проверке размера архива
sleepsArch = [0.5, 1, 2]
lenFP = len(sleepsFindProcess)
lenA = len(sleepsArch)
i = 0
# Ждем появления файла архива
while(not (os.path.exists(archPathProcess) or\
os.path.exists(archPathSuccess)) and i<lenFP):
time.sleep(sleepsFindProcess[i])
i +=1
# Если нет архива применяем rsync синхронизацию
if not (os.path.exists(archPathProcess) or\
os.path.exists(archPathSuccess)):
# Архив не найден rsync схема синхронизации
if progress:
progressObj.shutdownDialog()
return False
# Ожидание создания архива
if os.path.exists(archPathProcess):
i = 0
while(os.path.exists(archPathProcess)):
if os.path.exists(archPathSuccess):
break
if i>=lenA:
# rsync схема синхронизации
if progress:
progressObj.shutdownDialog()
return False
startSize = os.stat(archPathProcess).st_size
time.sleep(sleepsArch[i])
if os.path.exists(archPathSuccess):
break
endSize = os.stat(archPathProcess).st_size
if startSize == endSize:
i += 1
if progress:
progressObj.shutdownDialog()
return True
def mountUserRes(self, userName, sync=True, progress=False): def mountUserRes(self, userName, sync=True, progress=False):
"""Монтирование пользовательских ресурсов и синхронизация настроек""" """Монтирование пользовательских ресурсов и синхронизация настроек"""
# Имя пользователя # Имя пользователя
@ -2126,11 +2365,8 @@ or ld_bind_dn or ld_bind_pw")
os.chown(homeDir,uid,gid) os.chown(homeDir,uid,gid)
os.chmod(homeDir,0700) os.chmod(homeDir,0700)
# записываем в конфигурационный файл статус "в процессе" # записываем в конфигурационный файл статус "в процессе"
self.setVarToConfig("main", {"status":"process"}, self.setVarToConfig("main", {"status_sync":"process"},
configFileName, uid, gid) configFileName, uid, gid)
# записываем в .logout файл статус "в процессе"
logOutFile = os.path.join(homeDir,self.replLogoutFile)
self.createUserFile(logOutFile,"PROCESS", uid, gid)
# Получаем пароль пользователя из ключей ядра # Получаем пароль пользователя из ключей ядра
userPwd = _cl_keys.getKey(userName) userPwd = _cl_keys.getKey(userName)
if not userPwd: if not userPwd:
@ -2138,239 +2374,279 @@ or ld_bind_dn or ld_bind_pw")
# Отмонтируем пользовательские ресурсы в случае ошибки # Отмонтируем пользовательские ресурсы в случае ошибки
self.errorAndUnmountUserRes = True self.errorAndUnmountUserRes = True
return False return False
home = os.path.split(homeDir)[0] # Флаг ошибки
pathRemote = []
# Удаленный ресурс share
pathRemote.append((os.path.join(homeDir,"Disks"), "share"))
# Удаленный ресурс профилей
pathRemote.append((os.path.join(home,"." + userName), "unix"))
# Удаленный ресурс home
pathRemote.append((os.path.join(homeDir,"Home"), "homes"))
if self.clVars.Get("cl_remote_ftp"):
# Удаленный ресурс ftp
pathRemote.append((os.path.join(homeDir,"FTP"), "ftp"))
flagError = False flagError = False
# Имя удаленного сервера
remoteServer = ""
# В случае включения репликации на сервере True # В случае включения репликации на сервере True
replOn = self.searchReplBranch() replOn = self.searchReplBranch()
if replOn:
remoteServer = self.getNameRemoteServer(userName)
# Получаем монтируемые директории
names, dictRes = self.getUserMountResources(userName, homeDir,
remoteServer)
# Путь к профилю пользователя по умолчанию # Путь к профилю пользователя по умолчанию
defaultPath = "" defaultPath = ""
# Хост пользователя по умолчанию # Хост пользователя по умолчанию
defaultHost = self.clVars.Get("cl_remote_host") defaultHost = self.clVars.Get("cl_remote_host")
for path, res in pathRemote: # Флаг - будет использован инкрементальный архив
# Создаем директории для монтирования flagIncrArch = True
if not os.path.exists(path):
try: # Ошибка при монтировании удаленного сервера
os.mkdir(path) flagErrorMountRemote = False
os.chown(path, uid, gid) # Ошибка при cинхронизации с удаленного сервера
os.chmod(path,0700) flagErrorSyncRemote = False
except OSError: # Статус синхронизации
self.printERROR(_("Error creating directory")) syncStatus = True
self.printERROR(_("Permission denied: '%s'")%path) osLinuxShort = self.clVars.Get("os_linux_shortname")
flagError = True
break # Если профиль на удаленном сервере
# Проверяем на монтирование директории if remoteServer and replOn:
if self.isMount(path, 'cifs'): # имя файла архива в процессе архивации
continue archPathProcess = ""
# Создаем директории пользователя # имя файла архива - после архивации
# на текущем сервере archPathSuccess = ""
if replOn and res=="unix": # Создаем инкрементальный архив в случае репликации
defaultPath = path
# Монтируем Samba ресурс
textLine = self.mountSambaRes(userName,userPwd,uid,gid,res,path)
if not (textLine is None):
self.printERROR(_("Can not mount Samba resource [%s]")\
%res + " ...")
flagError = True
break
if flagError:
# Отмонтируем пользовательские ресурсы в случае ошибки
self.errorAndUnmountUserRes = True
return False
flagFirstSync = False
if replOn or sync:
# Ошибка при монтировании unix ресурса удаленного сервера при
# включенной репликации
replErrorMount = False
# Ошибка при cинхронизации unix ресурса удаленного сервера при
# включенной репликации
replErrorSync = False
# Синхронизируем настройки
if sync:
# Короткое имя системы
osLinuxShort = self.clVars.Get("os_linux_shortname")
# В случае репликации
prevHost = "" prevHost = ""
# Монтирование по умолчанию (default - cвой сервер, remote - чужой) # Дата профиля на текущем сервере
mountServer = "" dateDefaultProfile = ""
if replOn: # Текущее время
searchPrevHost = self.searchPrevHost(userName) currTime = str(float(time.time()))
if searchPrevHost and searchPrevHost[0][0][1].has_key('host'): # Создаваемые пути при монтировании
prevHost = searchPrevHost[0][0][1]['host'][0] for name in names:
# Монтируем ресурс unix текущего сервера path = dictRes[name]["path"]
mountServer = "default" res = dictRes[name]["resource"]
# Переносим настройки пользователя в новую директорию # Создаем пользовательскую директории для профиля
# CLD if not os.path.exists(path):
if not self.upgradeProfileClient(userName, homeDir): try:
# Отмонтируем пользовательские ресурсы в случае ошибки os.mkdir(path)
self.errorAndUnmountUserRes = True os.chown(path, uid, gid)
return False os.chmod(path,0700)
# Если на текущем сервере в ресурсе unix есть файлы except OSError:
# то синхронируем настройки self.printERROR(_("Error creating directory"))
# Получаем директорию хранения профиля на сервере self.printERROR(_("Permission denied: '%s'")%path)
homeProfile = os.path.join(home, "." + userName, osLinuxShort) flagError = True
if os.listdir(homeProfile): break
# Конфигурационный файл клинта на сервере desktop.env #Проверяем на монтирование директории
configFileNameServer = os.path.join(homeProfile, if self.isMount(path, 'cifs'):
self.pathConfig, continue
self.configFileDesktop) # Монтируем Samba ресурс
# Пишем версию клиента на сервер if name == "remote_profile":
if not self.setCurrentVersionToConfig(configFileNameServer, self.clVars.Set("cl_remote_host", remoteServer, True)
uid,gid): textLine = self.mountSleepRes(userName,userPwd,uid,gid,
# Отмонтируем пользовательские ресурсы в случае ошибки res,path)
self.errorAndUnmountUserRes = True if name == "remote_profile":
return False self.clVars.Set("cl_remote_host", defaultHost, True)
if not self.syncUser(userName, homeDir, "login", uid, gid,\ if not (textLine is None):
progress=progress, if name == "remote_profile":
host=self.clVars.Get('cl_remote_host')): flagErrorMountRemote = True
# Отмонтируем пользовательские ресурсы в случае ошибки break
self.errorAndUnmountUserRes = True else:
return False self.printERROR(_("Can not mount Samba resource [%s]")\
else: %res + " ...")
# Удаляем ненужные файлы (очищаем домашнюю директорию) flagError = True
if not self.clearHomeDir(homeDir): break
self.errorAndUnmountUserRes = True if name == "profile" or name == "remote_profile":
return False # Находим директорию профиля
if prevHost and prevHost != self.clVars.Get("cl_remote_host"): homeProfile = os.path.join(path, osLinuxShort)
# Отмонтируем ресурс if not os.path.exists(homeProfile):
textLine = self.umountSleepPath(defaultPath) homeProfile = os.path.join(path, "." + osLinuxShort)
# Примонтирована директория профиля с текущего сервера
if name == "profile":
# Перенос профиля на сервере в директорию без точки
if not self.upgradeProfileClient(userName, homeDir,
path):
flagError = True
break
fileConfig = os.path.join(homeProfile,
self.pathConfig,
self.configFileDesktop)
if os.path.exists(fileConfig):
objConfig = cl_base.iniParser(fileConfig)
data = self.getDataInConfig("main", ["status_sync",
"date"],
objConfig)
if data:
status = data.get("status_sync")
date = data.get("date")
if date and status=="success":
dateDefaultProfile = date
# Примонтирована директория профиля с удаленного сервера
# и есть дата профиля текущего сервера
if name == "remote_profile" and dateDefaultProfile:
# Даем команду на создание инкрементального архива проф.
fileConfig = os.path.join(homeProfile,
self.pathConfig,
self.configFileServer)
varsConfig = {"arch_date":dateDefaultProfile,
"curr_time":currTime}
self.setServerCommand(["pack"], varsConfig, fileConfig)
# Отмонтируем директорию профиля с удаленного сервера
textLine = self.umountSleepPath(path)
if not textLine: if not textLine:
# Отмонтируем пользовательские ресурсы в случае ошибки flagError = True
self.errorAndUnmountUserRes = True break
return False pathProfileCurr = dictRes["profile"]["path"]
# Монтируем настройки пользователя удаленного сервера homeProfileCurr = os.path.join(pathProfileCurr,osLinuxShort)
# если сервер найден # Синхронизация профиля с текущего сервера
self.clVars.Set("cl_remote_host", prevHost, True) if not self.syncLoginProfile(userName,homeDir,
mountServer = "remote" homeProfileCurr,
uid, gid, progress):
flagError = True
break
# Монтируем директорию профиля с удаленного сервера
self.clVars.Set("cl_remote_host", remoteServer, True)
textLine = self.mountSleepRes(userName,userPwd,uid,gid, textLine = self.mountSleepRes(userName,userPwd,uid,gid,
"unix",defaultPath) res,path)
self.clVars.Set("cl_remote_host", defaultHost, True) self.clVars.Set("cl_remote_host", defaultHost, True)
if not (textLine is None): if not (textLine is None):
if self.isMount(defaultPath, 'cifs'): self.printERROR(_("Can not mount Samba resource [%s]")\
textLine = self.umountSleepPath(defaultPath) %res + " ...")
if not textLine: flagError = True
# Отмонтируем пользовательские ресурсы break
# в случае ошибки extSuccess = "gz"
self.errorAndUnmountUserRes = True extProcess = "process"
return False strCurrentTime = currTime.replace(".","_")
# Монтируем текущий сервер если ошибка подключения к archPathTmp = os.path.join(path, "profile.%s.%s.tar"\
# к найденному серверу %(osLinuxShort, strCurrentTime))
mountServer = "default" # имя файла архива в процессе архивации
textLine = self.mountSleepRes(userName,userPwd,uid,gid, archPathSuccess = "%s.%s"%(archPathTmp,extSuccess)
"unix",defaultPath) # имя файла архива - после архивации
if not (textLine is None): archPathProcess = "%s.%s"%(archPathTmp,extProcess)
self.printERROR(_("Can not mount Samba resource \ # Ищем файл архива
[%s]")%"unix" + " ...") if not self.foundArchFile(strCurrentTime, archPathProcess,
# Отмонтируем пользовательские ресурсы archPathSuccess, progress,
# в случае ошибки remoteServer):
self.errorAndUnmountUserRes = True flagIncrArch = False
return False break
replErrorMount = True # Если нет архива применяем rsync синхронизацию
if mountServer == "remote": if not os.path.exists(archPathSuccess):
# Переносим настройки пользователя в новую директорию flagIncrArch = False
# CLD break
if not self.upgradeProfileClient(userName, homeDir): else:
# Отмонтируем пользовательские ресурсы в случае ошибки # Распаковываем архив в домашнюю директорию
self.errorAndUnmountUserRes = True if not self.unpackProfile(homeDir, archPathSuccess,
return False progress, remoteServer):
# Получаем директорию хранения профиля на сервере flagError = True
homeProfile = os.path.join(home, "." + userName, break
osLinuxShort) # Cканирование домашней директории и получение списка
if os.listdir(homeProfile): # файлов
# Конфигурационный файл клинта на сервере pathListFile = os.path.join(homeProfile,
# desktop.env self.listProfFile)
configFileNameServer = os.path.join(homeProfile, self.removeFilesInProfile(homeDir, pathListFile)
self.pathConfig, else:
self.configFileDesktop) if name == "remote_profile":
# Пишем версию клиента на сервер flagIncrArch = False
if not self.setCurrentVersionToConfig(\ if archPathProcess or archPathSuccess:
configFileNameServer, # Удаление архивных файлов
uid,gid): rmFiles = [archPathProcess, archPathSuccess]
# Отмонтируем пользовательские ресурсы в случае ошибки for rmFile in rmFiles:
self.errorAndUnmountUserRes = True if os.path.exists(rmFile):
return False # Удаляем файл архива
if not self.syncUser(userName,homeDir,"login", os.remove(archPathSuccess)
uid,gid, progress=progress, # Если не удалось замонтировать удаленный профиль
host=prevHost): if flagErrorMountRemote:
replErrorSync = True syncStatus = False
else: # Если не удалось использовать инкрементальный архив
# Удаляем ненужные файлы (очищаем домашнюю директорию) elif flagIncrArch is False:
if not self.clearHomeDir(homeDir): # Синхронизируем удаленный профиль
self.errorAndUnmountUserRes = True homeProfile = os.path.join(dictRes["remote_profile"]["path"],
return False osLinuxShort)
# Перемонтируем ресурс профилей if not self.upgradeProfileClient(userName, homeDir,
# на текущий сервер homeProfile):
textLine = self.umountSleepPath(defaultPath)
if not textLine: # Отмонтируем пользовательские ресурсы в случае ошибки
# Отмонтируем пользовательские ресурсы в случае ошибки self.errorAndUnmountUserRes = True
self.errorAndUnmountUserRes = True return False
return False # Синхронизация профиля с удаленного сервера
textLine = self.mountSambaRes(userName,userPwd,uid,gid, self.clVars.Set("cl_remote_host", remoteServer, True)
"unix",defaultPath) ret = self.syncLoginProfile(userName, homeDir, homeProfile,
if not (textLine is None): uid, gid, progress, False)
self.printERROR(_("Can not mount Samba resource [%s]")\ self.clVars.Set("cl_remote_host", defaultHost, True)
%"unix" + " ...") if not ret:
# Отмонтируем пользовательские ресурсы в случае ошибки flagErrorSyncRemote = True
self.errorAndUnmountUserRes = True syncStatus = False
return False # Если не удалось синхронизировать удаленный синхронизируем
# если репликации нет # текущий
else: homeProfile = os.path.join(dictRes["profile"]["path"],
curHost=self.clVars.Get('cl_remote_host') osLinuxShort)
# Синхронизируем настройки пользователя if not self.syncLoginProfile(userName, homeDir, homeProfile,
uid, gid, progress):
# Отмонтируем пользовательские ресурсы в случае ошибки
self.errorAndUnmountUserRes = True
return False
# Переносим настройки пользователя в новую директорию # Отмонтируем директорию профиля пользователя на удаленном сервере
# CLD if "remote_profile" in dictRes:
if not self.upgradeProfileClient(userName, homeDir): umountPath = dictRes["remote_profile"]["path"]
textLine = self.umountSleepPath(umountPath)
if not textLine:
# Отмонтируем пользовательские ресурсы в случае ошибки # Отмонтируем пользовательские ресурсы в случае ошибки
self.errorAndUnmountUserRes = True self.errorAndUnmountUserRes = True
return False return False
# Получаем директорию хранения профиля на сервере # Удаляем директорию удаленного профиля у клиента
homeProfile = os.path.join(home, "." + userName, osLinuxShort) if os.path.exists(umountPath):
if os.listdir(homeProfile): os.rmdir(umountPath)
# Конфигурационный файл клинта на сервере desktop.env
configFileNameServer = os.path.join(homeProfile, # Если профиль на текущем сервере
self.pathConfig, elif not remoteServer and replOn or not replOn:
self.configFileDesktop) # Создаваемые пути при монтировании
# Пишем версию клиента на сервер for name in names:
if not self.setCurrentVersionToConfig(configFileNameServer, path = dictRes[name]["path"]
uid,gid): res = dictRes[name]["resource"]
# Создаем пользовательскую директории для профиля
if not os.path.exists(path):
try:
os.mkdir(path)
os.chown(path, uid, gid)
os.chmod(path,0700)
except OSError:
self.printERROR(_("Error creating directory"))
self.printERROR(_("Permission denied: '%s'")%path)
flagError = True
break
# Проверяем на монтирование директории
if self.isMount(path, 'cifs'):
continue
textLine = self.mountSleepRes(userName,userPwd,uid,gid,
res, path)
if not (textLine is None):
self.printERROR(_("Can not mount Samba resource [%s]")\
%res + " ...")
flagError = True
break
if name == "profile":
pathProfile = path
# Перенос профиля на сервере в директорию без точки
if not self.upgradeProfileClient(userName, homeDir,
pathProfile):
flagError = True
break
# Директория профиля
homeProfile = os.path.join(path, osLinuxShort)
# Синхронизируем
if not self.syncLoginProfile(userName, homeDir, homeProfile,
uid, gid, progress):
# Отмонтируем пользовательские ресурсы в случае ошибки # Отмонтируем пользовательские ресурсы в случае ошибки
self.errorAndUnmountUserRes = True self.errorAndUnmountUserRes = True
return False return False
if not self.syncUser(userName, homeDir, "login", uid, gid,\
progress=progress,host=curHost): if flagError:
# Отмонтируем пользовательские ресурсы # Отмонтируем пользовательские ресурсы в случае ошибки
# в случае ошибки self.errorAndUnmountUserRes = True
self.errorAndUnmountUserRes = True return False
return False
else: logOutFile = os.path.join(homeDir,self.logOutFile)
# Удаляем ненужные файлы (очищаем домашнюю директорию) if syncStatus:
if not self.clearHomeDir(homeDir): self.setVarToConfig("main", {"status_sync":"success"},
self.errorAndUnmountUserRes = True
return False
if replOn:
if replErrorMount or replErrorSync:
self.createUserFile(logOutFile,"ERROR", uid, gid)
self.setVarToConfig("main", {"status":"error"},
configFileName, uid, gid)
else:
self.setVarToConfig("main", {"status":"success"},
configFileName, uid, gid) configFileName, uid, gid)
self.createUserFile(logOutFile,"SUCCESS", uid, gid) self.createUserFile(logOutFile,"SUCCESS", uid, gid)
else: else:
self.setVarToConfig("main", {"status":"success"}, self.createUserFile(logOutFile,"ERROR", uid, gid)
self.setVarToConfig("main", {"status_sync":"error"},
configFileName, uid, gid) configFileName, uid, gid)
self.createUserFile(logOutFile,"SUCCESS", uid, gid) self.printWARNING(_("Error in sync with the remote server %s")\
%remoteServer)
self.printSUCCESS(_("Mounted user resource of the domain")) self.printSUCCESS(_("Mounted user resource of the domain"))
self.printOK(_("Get a user profile from the domain") + " ...") self.printOK(_("Get a user profile from the domain") + " ...")
return True return True
@ -2499,7 +2775,7 @@ or ld_bind_dn or ld_bind_pw")
return False return False
return True return True
def upgradeProfileClient(self, userName, userHome): def upgradeProfileClient(self, userName, userHome, pathProfiles):
"""Переносит данные клиента в директорию без точки """Переносит данные клиента в директорию без точки
например: было /home/.user/.CLD стало /home/.user/CLD например: было /home/.user/.CLD стало /home/.user/CLD
@ -2508,7 +2784,6 @@ or ld_bind_dn or ld_bind_pw")
""" """
# Директория хранения старых профилей # Директория хранения старых профилей
home = os.path.split(userHome)[0] home = os.path.split(userHome)[0]
pathProfiles = os.path.join(home, "." + userName)
if os.path.exists(pathProfiles): if os.path.exists(pathProfiles):
osLinuxShort = self.clVars.Get("os_linux_shortname") osLinuxShort = self.clVars.Get("os_linux_shortname")
pathNewProfile = os.path.join(pathProfiles, osLinuxShort) pathNewProfile = os.path.join(pathProfiles, osLinuxShort)
@ -2529,19 +2804,13 @@ or ld_bind_dn or ld_bind_pw")
os.rmdir(pathOldProfile) os.rmdir(pathOldProfile)
return True return True
def syncUser(self, userName, userHome, sync, uid, gid, progress=False,\ def syncUser(self, userName, userHome, sync, uid, gid, homeProfile, \
host="default"): progress=False, host="default"):
"""Синхронизация пользовательских настроек """Синхронизация пользовательских настроек
Перед вызовом этого метода обязательно должен быть определен атрибут Перед вызовом этого метода обязательно должен быть определен атрибут
объекта self.clVars - объект переменных объекта self.clVars - объект переменных
""" """
home = os.path.split(userHome)[0]
osLinuxShort = self.clVars.Get("os_linux_shortname")
homeProfile = os.path.join(home, "." + userName, osLinuxShort)
if not os.path.exists(homeProfile):
homeProfile = os.path.join(home, "." + userName,
"." + osLinuxShort)
flagError = False flagError = False
execStr = "" execStr = ""
if sync == "login": if sync == "login":

Loading…
Cancel
Save