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";
key_serial_t dest;
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 stat
import subprocess
import time
from encrypt import encrypt
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',
'/var/calculate/remote/profiles',
'/var/calculate/profiles']
def __init__(self, cmdName):
# объект для форматированного вывода
imp_cl_help.__init__(self, cmdName)
@ -584,6 +584,8 @@ conjunction with the 'login' or 'logout'")
# используемое для прогрессбара
self.configFileDesktop = "desktop.env"
self.configFileServer = "server.env"
# Файл - список файлов профиля пользователя
self.listProfFile = ".calculate/files.txt"
# Путь относительно домашней директории в котором находятся
# конфигурационные файлы
self.pathConfig = ".calculate"
@ -599,10 +601,9 @@ conjunction with the 'login' or 'logout'")
replBranch = self.replAttr + "=" + self.replBranchName
# DN хранения последнего посещенного пользователя
self.replHostsDN = self.addDN(replBranch,self.sysDN)
# Файл репликации
self.replLogoutFile = ".logout"
self.logOutFile = ".logout"
self.skipHomeFile = ["Home","Disks","FTP",
self.replLogoutFile,
self.logOutFile,
os.path.join(self.pathConfig,self.configFileDesktop)]
# Если атрибут установлен то значит (ошибка и отмонтируются
# пользовательские ресурсы)
@ -923,7 +924,7 @@ conjunction with the 'login' or 'logout'")
objConfig = cl_base.iniParser(fileConfig)
varsRun = {"run":"on"}
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")\
%fileConfig)
return False
@ -931,6 +932,16 @@ conjunction with the 'login' or 'logout'")
os.chown(fileConfig, uid, gid)
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):
"""Установка пароля пользователя на сервере"""
# Проверяем на root
@ -973,7 +984,8 @@ conjunction with the 'login' or 'logout'")
# ~/.calculate/server.env
fileConfig = os.path.join(os.environ["HOME"], self.pathConfig,
self.configFileServer)
if not self.setServerCommand("passwd_samba", varsConfig, fileConfig):
if not self.setServerCommand(["passwd_samba"], varsConfig,
fileConfig):
return False
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.clearKey(userName) == 0:
ret = _cl_keys.clearKey(userName)
if ret == 0:
return True
else:
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,
self.configFileDesktop)
home = os.path.split(homeDir)[0]
pathRemote = []
# Удаленный ресурс профилей
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"))
# Получаем монтируемые директории
names, dictRes = self.getUserMountResources(userName, homeDir, False)
if os.path.exists(homeDir):
self.moveHomeDir(homeDir)
else:
@ -1759,11 +1763,7 @@ or ld_bind_dn or ld_bind_pw")
self.printERROR(_("Directory %s not found") % homeDir)
return False
# Синхронизируем настройки
pathUnix = ""
for path, res in pathRemote:
if res == 'unix':
pathUnix = path
break
pathUnix = dictRes["profile"]["path"]
if pathUnix and self.isMount(pathUnix ,"cifs") and \
not(domain in self.isMount(pathUnix ,"cifs")):
# Убиваем rsync
@ -1795,7 +1795,6 @@ or ld_bind_dn or ld_bind_pw")
return False
# проверяем произведен ли корректный вход в систему -
# в этом случае закачиваем профиль с локальной машины на сервер
logOutFile = os.path.join(homeDir,self.replLogoutFile)
# необходима ли синхронизация с локальным сервером
needSync = False
try:
@ -1803,12 +1802,12 @@ or ld_bind_dn or ld_bind_pw")
# то на локальный сервер закачиваем профиль
# так как даже если он будет поврежден на другом сервере
# остаётся правильная копия
if not self.isCorrectProfileOnLocalServer(userName):
if self.getNameRemoteServer(userName):
needSync = True
else:
exitStr = cl_base.iniParser(\
configFileName).getVar('main','status')
# проверяем logOutFile: не содержит ли он "process"
configFileName).getVar('main','status_sync')
# проверяем атус синхронизации: не содержит ли он "process"
if exitStr != "process":
needSync = True
except:
@ -1821,8 +1820,10 @@ or ld_bind_dn or ld_bind_pw")
# Отмонтируем пользовательские ресурсы в случае ошибки
self.errorAndUnmountUserRes = True
return False
if needSync and not self.syncUser(userName,homeDir,"logout",uid,gid):
osLinuxShort = self.clVars.Get("os_linux_shortname")
homeProfile = os.path.join(pathUnix, osLinuxShort)
if needSync and not self.syncUser(userName, homeDir,"logout",uid,gid,
homeProfile):
# Удаляем файлы, мешающие работе dm
self.removeNoiseFiles(homeDir)
# Удаляем приватные файлы
@ -1839,7 +1840,9 @@ or ld_bind_dn or ld_bind_pw")
# Очищаем ключ в ядре
self.clearUserKey(userName)
flagError = False
for path, res in pathRemote:
# Отмонтируем директории
for name in names:
path = dictRes[name]["path"]
if self.isMount(path ,"cifs"):
textLine = self.umountSleepPath(path)
if not textLine:
@ -1900,20 +1903,14 @@ or ld_bind_dn or ld_bind_pw")
else:
homeDir = resLdap[5]
home = os.path.split(homeDir)[0]
pathRemote = []
# Удаленный ресурс профилей
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"))
# Получаем монтируемые директории
names, dictRes = self.getUserMountResources(userName, homeDir, True)
serverHomePath = dictRes["home"]["path"]
flagError = False
if self.isMount(pathRemote[1][0] ,"cifs"):
if self.isMount(serverHomePath, "cifs"):
self.moveHomeDir(homeDir)
for path, res in pathRemote:
for name in names:
path = dictRes[name]["path"]
if self.isMount(path ,"cifs"):
textLine = self.umountSleepPath(path)
if not textLine:
@ -2016,9 +2013,8 @@ or ld_bind_dn or ld_bind_pw")
os.rmdir(rmDir)
return True
def isCorrectProfileOnLocalServer(self,userName):
"""Узнать находится ли актуальный профиль пользователя на локальном
сервере
def getNameRemoteServer(self,userName):
"""Если профиль на удаленном сервере, то выдать DNS имя этого сервера
"""
searchPrevHost = self.searchPrevHost(userName)
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'):
return True
else:
return False
else:
return prevHost
def setCurrentVersionToConfig(self, configFileName, uid, gid):
def setDateAndVersionToConfig(self, configFileName, uid, gid, strTime):
"""Записывает текущую версию в файл конфигурации"""
# Текущая версия программы
currentVersion = self.clVars.Get("cl_ver")
if self.setVarToConfig("main", {"version":currentVersion},
if self.setVarToConfig("main", {"version":currentVersion,
"date":strTime},
configFileName, uid, gid):
return True
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)
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):
"""Монтирование пользовательских ресурсов и синхронизация настроек"""
# Имя пользователя
@ -2126,11 +2365,8 @@ or ld_bind_dn or ld_bind_pw")
os.chown(homeDir,uid,gid)
os.chmod(homeDir,0700)
# записываем в конфигурационный файл статус "в процессе"
self.setVarToConfig("main", {"status":"process"},
self.setVarToConfig("main", {"status_sync":"process"},
configFileName, uid, gid)
# записываем в .logout файл статус "в процессе"
logOutFile = os.path.join(homeDir,self.replLogoutFile)
self.createUserFile(logOutFile,"PROCESS", uid, gid)
# Получаем пароль пользователя из ключей ядра
userPwd = _cl_keys.getKey(userName)
if not userPwd:
@ -2138,26 +2374,49 @@ or ld_bind_dn or ld_bind_pw")
# Отмонтируем пользовательские ресурсы в случае ошибки
self.errorAndUnmountUserRes = True
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
# Имя удаленного сервера
remoteServer = ""
# В случае включения репликации на сервере True
replOn = self.searchReplBranch()
if replOn:
remoteServer = self.getNameRemoteServer(userName)
# Получаем монтируемые директории
names, dictRes = self.getUserMountResources(userName, homeDir,
remoteServer)
# Путь к профилю пользователя по умолчанию
defaultPath = ""
# Хост пользователя по умолчанию
defaultHost = self.clVars.Get("cl_remote_host")
for path, res in pathRemote:
# Создаем директории для монтирования
# Флаг - будет использован инкрементальный архив
flagIncrArch = True
# Ошибка при монтировании удаленного сервера
flagErrorMountRemote = False
# Ошибка при cинхронизации с удаленного сервера
flagErrorSyncRemote = False
# Статус синхронизации
syncStatus = True
osLinuxShort = self.clVars.Get("os_linux_shortname")
# Если профиль на удаленном сервере
if remoteServer and replOn:
# имя файла архива в процессе архивации
archPathProcess = ""
# имя файла архива - после архивации
archPathSuccess = ""
# Создаем инкрементальный архив в случае репликации
prevHost = ""
# Дата профиля на текущем сервере
dateDefaultProfile = ""
# Текущее время
currTime = str(float(time.time()))
# Создаваемые пути при монтировании
for name in names:
path = dictRes[name]["path"]
res = dictRes[name]["resource"]
# Создаем пользовательскую директории для профиля
if not os.path.exists(path):
try:
os.mkdir(path)
@ -2171,206 +2430,223 @@ or ld_bind_dn or ld_bind_pw")
#Проверяем на монтирование директории
if self.isMount(path, 'cifs'):
continue
# Создаем директории пользователя
# на текущем сервере
if replOn and res=="unix":
defaultPath = path
# Монтируем Samba ресурс
textLine = self.mountSambaRes(userName,userPwd,uid,gid,res,path)
if name == "remote_profile":
self.clVars.Set("cl_remote_host", remoteServer, True)
textLine = self.mountSleepRes(userName,userPwd,uid,gid,
res,path)
if name == "remote_profile":
self.clVars.Set("cl_remote_host", defaultHost, True)
if not (textLine is None):
if name == "remote_profile":
flagErrorMountRemote = True
break
else:
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 = ""
# Монтирование по умолчанию (default - cвой сервер, remote - чужой)
mountServer = ""
if replOn:
searchPrevHost = self.searchPrevHost(userName)
if searchPrevHost and searchPrevHost[0][0][1].has_key('host'):
prevHost = searchPrevHost[0][0][1]['host'][0]
# Монтируем ресурс unix текущего сервера
mountServer = "default"
# Переносим настройки пользователя в новую директорию
# CLD
if not self.upgradeProfileClient(userName, homeDir):
# Отмонтируем пользовательские ресурсы в случае ошибки
self.errorAndUnmountUserRes = True
return False
# Если на текущем сервере в ресурсе unix есть файлы
# то синхронируем настройки
# Получаем директорию хранения профиля на сервере
homeProfile = os.path.join(home, "." + userName, osLinuxShort)
if os.listdir(homeProfile):
# Конфигурационный файл клинта на сервере desktop.env
configFileNameServer = os.path.join(homeProfile,
if name == "profile" or name == "remote_profile":
# Находим директорию профиля
homeProfile = os.path.join(path, osLinuxShort)
if not os.path.exists(homeProfile):
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 not self.setCurrentVersionToConfig(configFileNameServer,
uid,gid):
# Отмонтируем пользовательские ресурсы в случае ошибки
self.errorAndUnmountUserRes = True
return False
if not self.syncUser(userName, homeDir, "login", uid, gid,\
progress=progress,
host=self.clVars.Get('cl_remote_host')):
# Отмонтируем пользовательские ресурсы в случае ошибки
self.errorAndUnmountUserRes = True
return False
else:
# Удаляем ненужные файлы (очищаем домашнюю директорию)
if not self.clearHomeDir(homeDir):
self.errorAndUnmountUserRes = True
return False
if prevHost and prevHost != self.clVars.Get("cl_remote_host"):
# Отмонтируем ресурс
textLine = self.umountSleepPath(defaultPath)
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:
# Отмонтируем пользовательские ресурсы в случае ошибки
self.errorAndUnmountUserRes = True
return False
# Монтируем настройки пользователя удаленного сервера
# если сервер найден
self.clVars.Set("cl_remote_host", prevHost, True)
mountServer = "remote"
flagError = True
break
pathProfileCurr = dictRes["profile"]["path"]
homeProfileCurr = os.path.join(pathProfileCurr,osLinuxShort)
# Синхронизация профиля с текущего сервера
if not self.syncLoginProfile(userName,homeDir,
homeProfileCurr,
uid, gid, progress):
flagError = True
break
# Монтируем директорию профиля с удаленного сервера
self.clVars.Set("cl_remote_host", remoteServer, True)
textLine = self.mountSleepRes(userName,userPwd,uid,gid,
"unix",defaultPath)
res,path)
self.clVars.Set("cl_remote_host", defaultHost, True)
if not (textLine is None):
if self.isMount(defaultPath, 'cifs'):
textLine = self.umountSleepPath(defaultPath)
if not textLine:
# Отмонтируем пользовательские ресурсы
# в случае ошибки
self.errorAndUnmountUserRes = True
return False
# Монтируем текущий сервер если ошибка подключения к
# к найденному серверу
mountServer = "default"
textLine = self.mountSleepRes(userName,userPwd,uid,gid,
"unix",defaultPath)
if not (textLine is None):
self.printERROR(_("Can not mount Samba resource \
[%s]")%"unix" + " ...")
# Отмонтируем пользовательские ресурсы
# в случае ошибки
self.errorAndUnmountUserRes = True
return False
replErrorMount = True
if mountServer == "remote":
# Переносим настройки пользователя в новую директорию
# CLD
if not self.upgradeProfileClient(userName, homeDir):
self.printERROR(_("Can not mount Samba resource [%s]")\
%res + " ...")
flagError = True
break
extSuccess = "gz"
extProcess = "process"
strCurrentTime = currTime.replace(".","_")
archPathTmp = os.path.join(path, "profile.%s.%s.tar"\
%(osLinuxShort, strCurrentTime))
# имя файла архива в процессе архивации
archPathSuccess = "%s.%s"%(archPathTmp,extSuccess)
# имя файла архива - после архивации
archPathProcess = "%s.%s"%(archPathTmp,extProcess)
# Ищем файл архива
if not self.foundArchFile(strCurrentTime, archPathProcess,
archPathSuccess, progress,
remoteServer):
flagIncrArch = False
break
# Если нет архива применяем rsync синхронизацию
if not os.path.exists(archPathSuccess):
flagIncrArch = False
break
else:
# Распаковываем архив в домашнюю директорию
if not self.unpackProfile(homeDir, archPathSuccess,
progress, remoteServer):
flagError = True
break
# Cканирование домашней директории и получение списка
# файлов
pathListFile = os.path.join(homeProfile,
self.listProfFile)
self.removeFilesInProfile(homeDir, pathListFile)
else:
if name == "remote_profile":
flagIncrArch = False
if archPathProcess or archPathSuccess:
# Удаление архивных файлов
rmFiles = [archPathProcess, archPathSuccess]
for rmFile in rmFiles:
if os.path.exists(rmFile):
# Удаляем файл архива
os.remove(archPathSuccess)
# Если не удалось замонтировать удаленный профиль
if flagErrorMountRemote:
syncStatus = False
# Если не удалось использовать инкрементальный архив
elif flagIncrArch is False:
# Синхронизируем удаленный профиль
homeProfile = os.path.join(dictRes["remote_profile"]["path"],
osLinuxShort)
if not self.upgradeProfileClient(userName, homeDir,
homeProfile):
# Отмонтируем пользовательские ресурсы в случае ошибки
self.errorAndUnmountUserRes = True
return False
# Получаем директорию хранения профиля на сервере
homeProfile = os.path.join(home, "." + userName,
# Синхронизация профиля с удаленного сервера
self.clVars.Set("cl_remote_host", remoteServer, True)
ret = self.syncLoginProfile(userName, homeDir, homeProfile,
uid, gid, progress, False)
self.clVars.Set("cl_remote_host", defaultHost, True)
if not ret:
flagErrorSyncRemote = True
syncStatus = False
# Если не удалось синхронизировать удаленный синхронизируем
# текущий
homeProfile = os.path.join(dictRes["profile"]["path"],
osLinuxShort)
if os.listdir(homeProfile):
# Конфигурационный файл клинта на сервере
# desktop.env
configFileNameServer = os.path.join(homeProfile,
self.pathConfig,
self.configFileDesktop)
# Пишем версию клиента на сервер
if not self.setCurrentVersionToConfig(\
configFileNameServer,
uid,gid):
if not self.syncLoginProfile(userName, homeDir, homeProfile,
uid, gid, progress):
# Отмонтируем пользовательские ресурсы в случае ошибки
self.errorAndUnmountUserRes = True
return False
if not self.syncUser(userName,homeDir,"login",
uid,gid, progress=progress,
host=prevHost):
replErrorSync = True
else:
# Удаляем ненужные файлы (очищаем домашнюю директорию)
if not self.clearHomeDir(homeDir):
self.errorAndUnmountUserRes = True
return False
# Перемонтируем ресурс профилей
# на текущий сервер
textLine = self.umountSleepPath(defaultPath)
# Отмонтируем директорию профиля пользователя на удаленном сервере
if "remote_profile" in dictRes:
umountPath = dictRes["remote_profile"]["path"]
textLine = self.umountSleepPath(umountPath)
if not textLine:
# Отмонтируем пользовательские ресурсы в случае ошибки
self.errorAndUnmountUserRes = True
return False
textLine = self.mountSambaRes(userName,userPwd,uid,gid,
"unix",defaultPath)
# Удаляем директорию удаленного профиля у клиента
if os.path.exists(umountPath):
os.rmdir(umountPath)
# Если профиль на текущем сервере
elif not remoteServer and replOn or not replOn:
# Создаваемые пути при монтировании
for name in names:
path = dictRes[name]["path"]
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]")\
%"unix" + " ...")
%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
return False
# если репликации нет
else:
curHost=self.clVars.Get('cl_remote_host')
# Синхронизируем настройки пользователя
# Переносим настройки пользователя в новую директорию
# CLD
if not self.upgradeProfileClient(userName, homeDir):
# Отмонтируем пользовательские ресурсы в случае ошибки
self.errorAndUnmountUserRes = True
return False
# Получаем директорию хранения профиля на сервере
homeProfile = os.path.join(home, "." + userName, osLinuxShort)
if os.listdir(homeProfile):
# Конфигурационный файл клинта на сервере desktop.env
configFileNameServer = os.path.join(homeProfile,
self.pathConfig,
self.configFileDesktop)
# Пишем версию клиента на сервер
if not self.setCurrentVersionToConfig(configFileNameServer,
uid,gid):
if flagError:
# Отмонтируем пользовательские ресурсы в случае ошибки
self.errorAndUnmountUserRes = True
return False
if not self.syncUser(userName, homeDir, "login", uid, gid,\
progress=progress,host=curHost):
# Отмонтируем пользовательские ресурсы
# в случае ошибки
self.errorAndUnmountUserRes = True
return False
else:
# Удаляем ненужные файлы (очищаем домашнюю директорию)
if not self.clearHomeDir(homeDir):
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"},
logOutFile = os.path.join(homeDir,self.logOutFile)
if syncStatus:
self.setVarToConfig("main", {"status_sync":"success"},
configFileName, uid, gid)
self.createUserFile(logOutFile,"SUCCESS", uid, gid)
else:
self.setVarToConfig("main", {"status":"success"},
self.createUserFile(logOutFile,"ERROR", uid, gid)
self.setVarToConfig("main", {"status_sync":"error"},
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.printOK(_("Get a user profile from the domain") + " ...")
return True
@ -2499,7 +2775,7 @@ or ld_bind_dn or ld_bind_pw")
return False
return True
def upgradeProfileClient(self, userName, userHome):
def upgradeProfileClient(self, userName, userHome, pathProfiles):
"""Переносит данные клиента в директорию без точки
например: было /home/.user/.CLD стало /home/.user/CLD
@ -2508,7 +2784,6 @@ or ld_bind_dn or ld_bind_pw")
"""
# Директория хранения старых профилей
home = os.path.split(userHome)[0]
pathProfiles = os.path.join(home, "." + userName)
if os.path.exists(pathProfiles):
osLinuxShort = self.clVars.Get("os_linux_shortname")
pathNewProfile = os.path.join(pathProfiles, osLinuxShort)
@ -2529,19 +2804,13 @@ or ld_bind_dn or ld_bind_pw")
os.rmdir(pathOldProfile)
return True
def syncUser(self, userName, userHome, sync, uid, gid, progress=False,\
host="default"):
def syncUser(self, userName, userHome, sync, uid, gid, homeProfile, \
progress=False, host="default"):
"""Синхронизация пользовательских настроек
Перед вызовом этого метода обязательно должен быть определен атрибут
объекта 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
execStr = ""
if sync == "login":

Loading…
Cancel
Save