|
|
|
@ -30,6 +30,8 @@ import _cl_keys
|
|
|
|
|
|
|
|
|
|
import time
|
|
|
|
|
import stat
|
|
|
|
|
import popen2
|
|
|
|
|
import time
|
|
|
|
|
|
|
|
|
|
Version = "calculate-client 2.0.15"
|
|
|
|
|
|
|
|
|
@ -42,6 +44,133 @@ class printNoColor:
|
|
|
|
|
def colorPrint(self,attr,fg,bg,string):
|
|
|
|
|
sys.stdout.write(string)
|
|
|
|
|
|
|
|
|
|
class ProgressBar:
|
|
|
|
|
suffixSet = 'org.freedesktop.DBus.Properties.Set \
|
|
|
|
|
org.kde.kdialog.ProgressDialog'
|
|
|
|
|
execenv = 'HOME="/root" '
|
|
|
|
|
max = 100
|
|
|
|
|
kdialog = None
|
|
|
|
|
def __init__(self,title,kdialog=None):
|
|
|
|
|
self.title = title
|
|
|
|
|
if kdialog == None:
|
|
|
|
|
self.openDialog(self.title)
|
|
|
|
|
|
|
|
|
|
def openDialog(self,title):
|
|
|
|
|
pipe = popen2.Popen4(self.execenv+
|
|
|
|
|
'/usr/bin/kdialog --progressbar "%s" %d' % (\
|
|
|
|
|
self.title,self.max))
|
|
|
|
|
if pipe.poll() != 0:
|
|
|
|
|
time.sleep(0.5)
|
|
|
|
|
if pipe.poll() == 0:
|
|
|
|
|
self.kdialog = pipe.fromchild.readline().strip()
|
|
|
|
|
while not "org.kde.kdialog" in self.kdialog:
|
|
|
|
|
s = fout.fromchild.readline()
|
|
|
|
|
if s == "":
|
|
|
|
|
self.kdialog = None
|
|
|
|
|
self.kdialog = s.strip()
|
|
|
|
|
|
|
|
|
|
def setValue(self,value):
|
|
|
|
|
'''Установить текущее значения для прогресса'''
|
|
|
|
|
if self.kdialog and value <= self.max:
|
|
|
|
|
os.system(self.execenv+
|
|
|
|
|
'/usr/bin/qdbus %s %s value %d >/dev/null' % (\
|
|
|
|
|
self.kdialog,self.suffixSet, value));
|
|
|
|
|
|
|
|
|
|
def setMaximum(self,max):
|
|
|
|
|
'''Установить максимальное значения для прогресса'''
|
|
|
|
|
self.max = max
|
|
|
|
|
if self.kdialog:
|
|
|
|
|
os.system(self.execenv+
|
|
|
|
|
'/usr/bin/qdbus %s %s maximum %d >/dev/null' % (\
|
|
|
|
|
self.kdialog,self.suffixSet, self.max));
|
|
|
|
|
|
|
|
|
|
def setTitle(self,title):
|
|
|
|
|
'''Установить описания прогресса'''
|
|
|
|
|
if self.kdialog:
|
|
|
|
|
os.system(self.execenv+
|
|
|
|
|
'/usr/bin/qdbus %s setLabelText %s >/dev/null' % \
|
|
|
|
|
(self.kdialog,self.title))
|
|
|
|
|
|
|
|
|
|
def close(self):
|
|
|
|
|
'''Закрыть прогресс'''
|
|
|
|
|
if self.kdialog:
|
|
|
|
|
self.setValue(self.max)
|
|
|
|
|
os.system(self.execenv+
|
|
|
|
|
'/usr/bin/qdbus %s close >/dev/null' % self.kdialog)
|
|
|
|
|
|
|
|
|
|
class ProgressProfile(cl_profile.profile):
|
|
|
|
|
def __init__(self, vars):
|
|
|
|
|
cl_profile.profile.__init__(self,vars)
|
|
|
|
|
self.progress = ProgressBar("Merging profiles...")
|
|
|
|
|
|
|
|
|
|
def numberAllProfiles(self, number):
|
|
|
|
|
self.progress.setMaximum(number)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def numberProcessProfiles(self,number):
|
|
|
|
|
self.progress.setValue(number)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
class RsyncProgressBar(ProgressBar):
|
|
|
|
|
'''Объект запуска rsync для получения количества созданных файлов и
|
|
|
|
|
при необходимости вывода progressbar
|
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
# получение номера передаваемого файла из инф потока rsync
|
|
|
|
|
senderre = re.compile("\[sender\] i=(\d+) ", re.S)
|
|
|
|
|
# получение номера получаемого файла из потока rsync
|
|
|
|
|
receiverre = re.compile("recv_generator\(.+,([0-9]+)\)", re.S)
|
|
|
|
|
pipe = None
|
|
|
|
|
maximum = 1
|
|
|
|
|
|
|
|
|
|
def __init__(self, title, rsyncstr, maximum=1):
|
|
|
|
|
self.title = title
|
|
|
|
|
self.maximum = maximum
|
|
|
|
|
self.rsyncstr = rsyncstr
|
|
|
|
|
|
|
|
|
|
def getFilesNum(self):
|
|
|
|
|
'''Получить количество файлов созданных генератором'''
|
|
|
|
|
if self.pipe:
|
|
|
|
|
return self.value
|
|
|
|
|
|
|
|
|
|
def getExitCode(self):
|
|
|
|
|
'''Получить код выхода rsync'''
|
|
|
|
|
if self.pipe:
|
|
|
|
|
return os.WEXITSTATUS(self.pipe.wait())
|
|
|
|
|
|
|
|
|
|
def runsilent(self):
|
|
|
|
|
'''Запустить rsync без progressbar'''
|
|
|
|
|
self.pipe = popen2.Popen4(self.rsyncstr)
|
|
|
|
|
while True:
|
|
|
|
|
s = self.pipe.fromchild.readline()
|
|
|
|
|
if len(s) == 0:
|
|
|
|
|
break
|
|
|
|
|
q = self.receiverre.search(s)
|
|
|
|
|
if q:
|
|
|
|
|
self.value = int(q.groups()[0])
|
|
|
|
|
|
|
|
|
|
def run(self):
|
|
|
|
|
'''Запустить rsync с progressbar'''
|
|
|
|
|
self.openDialog(self.title)
|
|
|
|
|
self.pipe = popen2.Popen4(self.rsyncstr)
|
|
|
|
|
oldpercent = 0
|
|
|
|
|
while True:
|
|
|
|
|
s = self.pipe.fromchild.readline()
|
|
|
|
|
if len(s) == 0:
|
|
|
|
|
break
|
|
|
|
|
q = self.senderre.search(s)
|
|
|
|
|
if q:
|
|
|
|
|
maximum = int(q.groups()[0])
|
|
|
|
|
if self.maximum < maximum:
|
|
|
|
|
self.maximum = maximum
|
|
|
|
|
continue
|
|
|
|
|
q = self.receiverre.search(s)
|
|
|
|
|
if q:
|
|
|
|
|
self.value = int(q.groups()[0])
|
|
|
|
|
newpercent = self.value * 100 / self.maximum
|
|
|
|
|
if oldpercent < newpercent:
|
|
|
|
|
oldpercent = newpercent
|
|
|
|
|
self.setValue(oldpercent)
|
|
|
|
|
# Импортированные классы в cl_ldap
|
|
|
|
|
# Запись ошибок
|
|
|
|
|
imp_cl_err = cl_profile._error
|
|
|
|
@ -236,6 +365,10 @@ conjunction with the 'login' or 'logout'")
|
|
|
|
|
self.clVars = False
|
|
|
|
|
# Файл в ресурсе share для обработки подключения клиента
|
|
|
|
|
self.replRunFileShare = ".reprun"
|
|
|
|
|
# файл с дополнительной информацией о профиле
|
|
|
|
|
# на данный момент только количество файлов для rsync
|
|
|
|
|
# используемое для прогрессбара
|
|
|
|
|
self.configFile = ".calculate.ini"
|
|
|
|
|
# При включениии репликации
|
|
|
|
|
# Временные задержки для монтирования в секундах
|
|
|
|
|
self.sleeps = [0.5, 2, 5]
|
|
|
|
@ -422,9 +555,11 @@ conjunction with the 'login' or 'logout'")
|
|
|
|
|
def applyProfilesFromUser(self):
|
|
|
|
|
"""Применяем профили для пользователя"""
|
|
|
|
|
# Cоздаем объект профиль
|
|
|
|
|
clProf = cl_profile.profile(self.clVars)
|
|
|
|
|
#clProf = cl_profile.profile(self.clVars)
|
|
|
|
|
clProf = ProgressProfile(self.clVars)
|
|
|
|
|
# Объединяем профили
|
|
|
|
|
dirsFiles = clProf.applyProfiles()
|
|
|
|
|
clProf.progress.close()
|
|
|
|
|
if clProf.getError():
|
|
|
|
|
self.printERROR(clProf.getError())
|
|
|
|
|
return False
|
|
|
|
@ -934,7 +1069,8 @@ install/6intranet" %(domain,servDn,unixDN,bindDn,bindPw)
|
|
|
|
|
if res == 'unix':
|
|
|
|
|
pathUnix = path
|
|
|
|
|
break
|
|
|
|
|
if pathUnix and not(domain in self.isMount(pathUnix ,"cifs")):
|
|
|
|
|
if pathUnix and self.isMount(pathUnix ,"cifs") and \
|
|
|
|
|
not(domain in self.isMount(pathUnix ,"cifs")):
|
|
|
|
|
# Убиваем rsync
|
|
|
|
|
if not self.killRsync():
|
|
|
|
|
# Отмонтируем пользовательские ресурсы в случае ошибки
|
|
|
|
@ -962,7 +1098,7 @@ install/6intranet" %(domain,servDn,unixDN,bindDn,bindPw)
|
|
|
|
|
# Отмонтируем пользовательские ресурсы в случае ошибки
|
|
|
|
|
self.errorAndUnmountUserRes = True
|
|
|
|
|
return False
|
|
|
|
|
if not self.syncUser(userName, homeDir, "logout"):
|
|
|
|
|
if not self.syncUser(userName, homeDir, "logout", uid, gid):
|
|
|
|
|
# Отмонтируем пользовательские ресурсы в случае ошибки
|
|
|
|
|
self.errorAndUnmountUserRes = True
|
|
|
|
|
return False
|
|
|
|
@ -1289,7 +1425,7 @@ install/6intranet" %(domain,servDn,unixDN,bindDn,bindPw)
|
|
|
|
|
# Если на текущем сервере в ресурсе unix есть файлы
|
|
|
|
|
# то синхронируем настройки
|
|
|
|
|
if os.listdir(defaultPath):
|
|
|
|
|
if not self.syncUser(userName, homeDir, "login"):
|
|
|
|
|
if not self.syncUser(userName, homeDir, "login", uid, gid):
|
|
|
|
|
# Отмонтируем пользовательские ресурсы в случае ошибки
|
|
|
|
|
self.errorAndUnmountUserRes = True
|
|
|
|
|
return False
|
|
|
|
@ -1360,7 +1496,7 @@ install/6intranet" %(domain,servDn,unixDN,bindDn,bindPw)
|
|
|
|
|
return False
|
|
|
|
|
# Синхронизируем настройки пользователя
|
|
|
|
|
if not (pathReplRun and mountServer == "default"):
|
|
|
|
|
if not self.syncUser(userName, homeDir, "login"):
|
|
|
|
|
if not self.syncUser(userName, homeDir, "login", uid, gid):
|
|
|
|
|
if pathReplRun and mountServer == "remote":
|
|
|
|
|
replErrorSync = True
|
|
|
|
|
else:
|
|
|
|
@ -1495,7 +1631,7 @@ install/6intranet" %(domain,servDn,unixDN,bindDn,bindPw)
|
|
|
|
|
FD.close()
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def syncUser(self, userName, userHome, sync):
|
|
|
|
|
def syncUser(self, userName, userHome, sync, uid, gid):
|
|
|
|
|
"""Синхронизация пользовательских настроек"""
|
|
|
|
|
home = os.path.split(userHome)[0]
|
|
|
|
|
homeProfile = os.path.join(home,"." + userName)
|
|
|
|
@ -1515,7 +1651,7 @@ install/6intranet" %(domain,servDn,unixDN,bindDn,bindPw)
|
|
|
|
|
# содержит данные о виртуальных машинах
|
|
|
|
|
if os.path.exists(userHome) and\
|
|
|
|
|
os.path.exists(homeProfile):
|
|
|
|
|
execStr = '/usr/bin/rsync -q --delete-excluded --delete \
|
|
|
|
|
execStr = '/usr/bin/rsync --delete-excluded --delete \
|
|
|
|
|
--exclude="/.googleearth" --exclude="/.kde4/share/config/phonondevicesrc" \
|
|
|
|
|
--exclude="*~" --exclude="/Home" --exclude="/Disks" --exclude="/FTP" \
|
|
|
|
|
--exclude="/.local/share/akonadi/db_data" --exclude="/.VirtualBox" \
|
|
|
|
@ -1527,11 +1663,11 @@ install/6intranet" %(domain,servDn,unixDN,bindDn,bindPw)
|
|
|
|
|
--filter="P /.mozilla/firefox/calculate.default/urlclassifier3.sqlite" \
|
|
|
|
|
--filter="P /.local/share/mime/mime.cache" \
|
|
|
|
|
--filter="P /.kde4/share/apps/nepomuk/repository/main/data" \
|
|
|
|
|
--filter="P /FTP" -a -x %s/ %s/' %(homeProfile,userHome)
|
|
|
|
|
--filter="P /FTP" -a -x -v -v -v -v %s/ %s/' %(homeProfile,userHome)
|
|
|
|
|
elif sync == "logout":
|
|
|
|
|
if os.path.exists(userHome) and os.listdir(userHome) and\
|
|
|
|
|
os.path.exists(homeProfile):
|
|
|
|
|
execStr = '/usr/bin/rsync -q --delete-excluded --delete \
|
|
|
|
|
execStr = '/usr/bin/rsync --delete-excluded --delete \
|
|
|
|
|
--exclude="/.googleearth" --exclude="/Home" --exclude="/Disks" --exclude="/FTP"\
|
|
|
|
|
--exclude="*~" --exclude="/.kde4/cache-*" --exclude="/.kde4/tmp-*" \
|
|
|
|
|
--exclude="/.local/share/akonadi/db_data" --exclude="/.VirtualBox" \
|
|
|
|
@ -1539,16 +1675,44 @@ install/6intranet" %(domain,servDn,unixDN,bindDn,bindPw)
|
|
|
|
|
--exclude="/.local/share/mime/mime.cache" \
|
|
|
|
|
--exclude="/.kde4/share/apps/nepomuk/repository/main/data" \
|
|
|
|
|
--exclude="/.kde4/socket-*" --exclude="/.kde4/share/config/phonondevicesrc"\
|
|
|
|
|
-a -x %s/ %s/'%(userHome,homeProfile)
|
|
|
|
|
-a -x -v -v -v -v %s/ %s/'%(userHome,homeProfile)
|
|
|
|
|
else:
|
|
|
|
|
self.printERROR(_("Method syncUser: option sync=%s incorrect")\
|
|
|
|
|
%str(sync))
|
|
|
|
|
return False
|
|
|
|
|
if execStr:
|
|
|
|
|
textLine = self.execProg(execStr)
|
|
|
|
|
if not (textLine == None):
|
|
|
|
|
rsync = RsyncProgressBar("Syncronizing user settings...",execStr)
|
|
|
|
|
configFileName = os.path.join(homeProfile,self.configFile)
|
|
|
|
|
if sync == "login":
|
|
|
|
|
# получить переменную files из секции Rsync файла
|
|
|
|
|
# .calculate.ini
|
|
|
|
|
try:
|
|
|
|
|
numfiles = cl_base.iniParser( \
|
|
|
|
|
configFileName).getVar('rsync','files')
|
|
|
|
|
if numfiles == False:
|
|
|
|
|
if os.path.exists(configFileName):
|
|
|
|
|
os.remove(configFileName)
|
|
|
|
|
numfiles = 1
|
|
|
|
|
else:
|
|
|
|
|
numfiles = int(numfiles)
|
|
|
|
|
except:
|
|
|
|
|
numfiles = 1
|
|
|
|
|
rsync.maximum = numfiles
|
|
|
|
|
rsync.run()
|
|
|
|
|
if sync == "logout":
|
|
|
|
|
rsync.runsilent()
|
|
|
|
|
# получаем uid и gid пользователя
|
|
|
|
|
try:
|
|
|
|
|
if cl_base.iniParser(configFileName).setVar('rsync',{'files':\
|
|
|
|
|
rsync.getFilesNum()}):
|
|
|
|
|
os.chmod(configFileName, 0600)
|
|
|
|
|
os.chown(configFileName,uid,gid)
|
|
|
|
|
except:
|
|
|
|
|
pass
|
|
|
|
|
rsync.close()
|
|
|
|
|
if rsync.getExitCode() != 0:
|
|
|
|
|
self.printERROR(_("Can not rsync") + " " + str(sync) +\
|
|
|
|
|
" ...")
|
|
|
|
|
" ...")
|
|
|
|
|
flagError = True
|
|
|
|
|
else:
|
|
|
|
|
if sync == "login":
|
|
|
|
|