Refactoring

master3.4 3.4.1.1
Mike Khiretskiy 9 years ago
parent b0ce98e865
commit 76171566a9

@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2013-2014 Calculate Ltd. http://www.calculate-linux.org # Copyright 2013-2015 Calculate Ltd. http://www.calculate-linux.org
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -25,11 +25,11 @@ import os
from os import path from os import path
import dbus.mainloop.glib import dbus.mainloop.glib
from calculate.lib.datavars import DataVars, VariableError from calculate.lib.datavars import DataVars, VariableError
from calculate.lib.utils.files import isMount, getRunCommands
from calculate.client.client import Client from calculate.client.client import Client
from argparse import ArgumentParser from argparse import ArgumentParser
from time import sleep from time import sleep
class ResourceRemounter: class ResourceRemounter:
""" """
Object contains one method for handle 'Resuming' dbus signal. Object contains one method for handle 'Resuming' dbus signal.
@ -37,6 +37,8 @@ class ResourceRemounter:
'handle_resuming' method checks and remounts user remote resources. 'handle_resuming' method checks and remounts user remote resources.
Also the object refreshes NSS-cache. Also the object refreshes NSS-cache.
""" """
nscd_refresh = "/usr/sbin/nscd-refresh"
def __init__(self, dv): def __init__(self, dv):
self.dv = dv self.dv = dv
self.dv.defaultModule = 'client' self.dv.defaultModule = 'client'
@ -51,16 +53,11 @@ class ResourceRemounter:
if self.client.checkDomainServer( if self.client.checkDomainServer(
self.dv.Get('cl_remote_host'), self.dv.Get('cl_remote_host'),
self.dv.Get('os_net_domain')): self.dv.Get('os_net_domain')):
try:
if refresh_nscd and path.exists(self.nscd_refresh): if refresh_nscd and path.exists(self.nscd_refresh):
os.system(self.nscd_refresh) os.system(self.nscd_refresh)
except:
pass
return True return True
return False return False
nscd_refresh = "/usr/sbin/nscd-refresh"
def remount_remote(self): def remount_remote(self):
""" """
Remount remote resource of the domain Remount remote resource of the domain
@ -69,7 +66,7 @@ class ResourceRemounter:
self.client.mountRemoteRes(self.dv.Get('cl_remote_pw'), self.client.mountRemoteRes(self.dv.Get('cl_remote_pw'),
self.dv.Get('cl_client_remote_path'), self.dv.Get('cl_client_remote_path'),
self.dv.Get('cl_remote_host')) self.dv.Get('cl_remote_host'))
except: except Exception:
pass pass
def remount_user_resources(self): def remount_user_resources(self):
@ -82,7 +79,7 @@ class ResourceRemounter:
int(self.dv.Get('ur_uid')), int(self.dv.Get('ur_uid')),
int(self.dv.Get('ur_gid')), int(self.dv.Get('ur_gid')),
"unix", "share", "homes", "ftp") "unix", "share", "homes", "ftp")
except: except Exception:
pass pass
def handle_resuming(self, statename): def handle_resuming(self, statename):
@ -92,7 +89,7 @@ class ResourceRemounter:
try: try:
if self.check_server(True): if self.check_server(True):
break break
except: except Exception:
pass pass
sleep(wait) sleep(wait)
# check and remount remote resources # check and remount remote resources
@ -123,7 +120,8 @@ def main(argv):
sys.exit(1) sys.exit(1)
rm = ResourceRemounter(dv) rm = ResourceRemounter(dv)
bus.add_signal_receiver(rm.handle_resuming,dbus_interface="org.freedesktop.UPower", bus.add_signal_receiver(rm.handle_resuming,
dbus_interface="org.freedesktop.UPower",
signal_name="NotifyResume") signal_name="NotifyResume")
loop = gobject.MainLoop() loop = gobject.MainLoop()
context = loop.get_context() context = loop.get_context()
@ -132,5 +130,6 @@ def main(argv):
context.iteration(1) context.iteration(1)
sleep(1) sleep(1)
if __name__ == '__main__': if __name__ == '__main__':
main(sys.argv) main(sys.argv)

@ -18,29 +18,22 @@ import os
import stat import stat
import re import re
import sys import sys
import pwd
import subprocess import subprocess
import ldap import ldap
import time import time
import types
import getpass import getpass
from os import path from os import path
from datavars import DataVarsClient, DataVars, __version__,__app__ from calculate.lib.cl_ini_parser import iniParser
from calculate.lib.cl_template import (Template, iniParser, TemplatesError,
ProgressTemplate)
from calculate.lib.cl_print import color_print from calculate.lib.cl_print import color_print
from calculate.lib.cl_ldap import ldapUser from calculate.lib.utils.ip import Pinger, IPError
from calculate.lib.utils.ip import Pinger, isOpenPort, IPError
from calculate.lib.utils.files import (getModeFile, removeDir, from calculate.lib.utils.files import (getModeFile, removeDir,
isMount, readFile, pathJoin, tarLinks, isMount, pathJoin, tarLinks,
listDirectory, process, find, STDOUT, listDirectory, process, find, STDOUT,
sambaPasswordCheck, checkUtils) sambaPasswordCheck, checkUtils)
from calculate.lib.utils.common import (getpathenv, appendProgramToEnvFile, from calculate.lib.utils.common import cmpVersion
removeProgramToEnvFile, cmpVersion)
from calculate.desktop._cl_keys import getKey, clearKey from calculate.desktop._cl_keys import getKey, clearKey
from calculate.lib.convertenv import convertEnv from calculate.lib.convertenv import convertEnv
from calculate.lib.encrypt import encrypt from calculate.lib.encrypt import encrypt
@ -48,16 +41,19 @@ from client_cache import userCache
from shutil import copy2 from shutil import copy2
from socket import gethostbyname from socket import gethostbyname
import tarfile import tarfile
from collections import OrderedDict
from calculate.desktop.desktop import Desktop from calculate.desktop.desktop import Desktop
from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate
_ = lambda x: x
setLocalTranslate('cl_client3', sys.modules[__name__]) setLocalTranslate('cl_client3', sys.modules[__name__])
__ = getLazyLocalTranslate(_) __ = getLazyLocalTranslate(_)
class ClientError(Exception): class ClientError(Exception):
pass pass
class RsyncProgressBar: class RsyncProgressBar:
""" """
Rsync with using setProgress Rsync with using setProgress
@ -171,6 +167,7 @@ class RsyncProgressBar:
def close(self): def close(self):
self.parent.endTask() self.parent.endTask()
class commandServer(color_print): class commandServer(color_print):
"""Server command object""" """Server command object"""
@ -217,7 +214,6 @@ class commandServer(color_print):
стандартного ввода (stdin) стандартного ввода (stdin)
pwDialog - структура для вывода приглашения в режиме диалога pwDialog - структура для вывода приглашения в режиме диалога
""" """
userPwd = ""
if optStdIn and options.has_key(optStdIn): if optStdIn and options.has_key(optStdIn):
pwdA = sys.stdin.readline().rstrip() pwdA = sys.stdin.readline().rstrip()
pwdB = sys.stdin.readline().rstrip() pwdB = sys.stdin.readline().rstrip()
@ -227,8 +223,8 @@ class commandServer(color_print):
_("Retype the new password")] _("Retype the new password")]
pwdA = getpass.getpass(pwDialog[0] + _(":")) pwdA = getpass.getpass(pwDialog[0] + _(":"))
pwdB = getpass.getpass(pwDialog[1] + _(":")) pwdB = getpass.getpass(pwDialog[1] + _(":"))
if (optStdIn and options.has_key(optStdIn)) or\ else:
(optDialog and options.has_key(optDialog)): return ""
if not pwdA or not (pwdA == pwdB): if not pwdA or not (pwdA == pwdB):
self.printERROR(_("ERROR") + _(": ") + \ self.printERROR(_("ERROR") + _(": ") + \
_("passwords do not match")) _("passwords do not match"))
@ -236,6 +232,7 @@ class commandServer(color_print):
userPwd = pwdA userPwd = pwdA
return userPwd return userPwd
class Client(commandServer, encrypt, Desktop): class Client(commandServer, encrypt, Desktop):
""" """
Клиентский модуль работы с доменом Клиентский модуль работы с доменом
@ -278,7 +275,8 @@ class Client(commandServer, encrypt, Desktop):
self.clVars.Set("os_remote_auth", "", True) self.clVars.Set("os_remote_auth", "", True)
return True return True
def mountSambaRes(self,host,userName,userPwd,res,rpath,uid=None,gid=None): def mountSambaRes(self, host, userName, userPwd, res, rpath, uid=None,
gid=None):
""" """
Подключить samba ресурс Подключить samba ресурс
""" """
@ -290,7 +288,8 @@ class Client(commandServer, encrypt, Desktop):
if not uid is None: if not uid is None:
# mount by uid # mount by uid
p = process(mountCmd, "-t", "cifs", "-o", p = process(mountCmd, "-t", "cifs", "-o",
"cache=loose,user=%s,uid=%d,gid=%d,noperm%s"%(userName,uid,gid,nomapposix), "cache=loose,user=%s,uid=%d,gid=%d,noperm%s" % (
userName, uid, gid, nomapposix),
"//%s/%s" % (host, res), rpath, "//%s/%s" % (host, res), rpath,
envdict={"PASSWD": userPwd}, stderr=STDOUT) envdict={"PASSWD": userPwd}, stderr=STDOUT)
return p.success() return p.success()
@ -301,7 +300,8 @@ class Client(commandServer, encrypt, Desktop):
envdict={"PASSWD": userPwd}, stderr=STDOUT) envdict={"PASSWD": userPwd}, stderr=STDOUT)
return p.success() return p.success()
def mountSleepRes(self,host,userName,userPwd,res,rpath,uid=None,gid=None): def mountSleepRes(self, host, userName, userPwd, res, rpath, uid=None,
gid=None):
""" """
Подключить пользовательский ресурс Подключить пользовательский ресурс
""" """
@ -319,11 +319,10 @@ class Client(commandServer, encrypt, Desktop):
return False return False
def syncUser(self, uid, gid, userHome, sync, remoteProfile, def syncUser(self, uid, gid, userHome, sync, remoteProfile,
host="default",skipList=[]): host="default", skipList=()):
""" """
Синхронизация профиля пользователя Синхронизация профиля пользователя
""" """
flagError = False
execStr = "" execStr = ""
skipPaths = self.clVars.Get("cl_sync_skip_path") skipPaths = self.clVars.Get("cl_sync_skip_path")
if not skipPaths: if not skipPaths:
@ -333,35 +332,39 @@ class Client(commandServer, encrypt, Desktop):
deletePaths = self.clVars.Get("cl_sync_del_path") deletePaths = self.clVars.Get("cl_sync_del_path")
if not deletePaths: if not deletePaths:
deletePaths = [] deletePaths = []
excludePaths = " ".join(map(lambda x: '--exclude="/%s"'\ excludePaths = " ".join(map(
%x.replace('"',"").replace("'",""), lambda x: '--exclude="/%s"' % x.replace('"', "").replace(
"'", ""),
skipPaths + deletePaths + skipList)) skipPaths + deletePaths + skipList))
if sync == "login": if sync == "login":
if os.path.exists(userHome) and \ if os.path.exists(userHome) and \
os.path.exists(remoteProfile): os.path.exists(remoteProfile):
filterPath = " ".join(map(lambda x: '--filter="P /%s"'\ filterPath = " ".join(map(
%x.replace('"',"").replace("'",""), lambda x: '--filter="P /%s"' % x.replace(
'"', "").replace("'", ""),
skipPaths)) skipPaths))
execStr = '/usr/bin/rsync --delete-excluded --delete %s %s '\ execStr = ('/usr/bin/rsync --delete-excluded --delete %s %s '
'-rlptgo -x -v -v -v %s/ %s/' \ '-rlptgo -x -v -v -v %s/ %s/'
%(excludePaths, filterPath, remoteProfile, userHome) % (excludePaths, filterPath,
remoteProfile, userHome))
elif sync == "logout": elif sync == "logout":
if os.path.exists(userHome) and os.listdir(userHome) and \ if os.path.exists(userHome) and os.listdir(userHome) and \
os.path.exists(remoteProfile): os.path.exists(remoteProfile):
execStr = '/usr/bin/rsync --delete-excluded --delete %s \ execStr = ('/usr/bin/rsync --delete-excluded --delete %s '
-rlpt -x -v -v -v %s/ %s/'%(excludePaths, userHome, remoteProfile) '-rlpt -x -v -v -v %s/ %s/' % (
excludePaths, userHome, remoteProfile))
else: else:
raise ClientError( raise ClientError(
_("Method syncUser: wrong option sync=%s") % str(sync)) _("Method syncUser: wrong option sync=%s") % str(sync))
if execStr: if execStr:
host = "<i>" + host + "</i>" host = "<i>" + host + "</i>"
if sync == "login": if sync == "login":
rsync = RsyncProgressBar(\ rsync = RsyncProgressBar(
_("Fetching the file list from %s") % host, _("Fetching the file list from %s") % host,
_("Fetching the user profile from %s") % host, _("Fetching the user profile from %s") % host,
execStr, self, rsyncver=self.clVars.Get('cl_rsync_ver')) execStr, self, rsyncver=self.clVars.Get('cl_rsync_ver'))
else: else:
rsync = RsyncProgressBar(\ rsync = RsyncProgressBar(
_("Sending the file list to %s") % host, _("Sending the file list to %s") % host,
_("Uploading the user profile to %s") % host, _("Uploading the user profile to %s") % host,
execStr, self, rsyncver=self.clVars.Get('cl_rsync_ver')) execStr, self, rsyncver=self.clVars.Get('cl_rsync_ver'))
@ -379,15 +382,15 @@ class Client(commandServer, encrypt, Desktop):
if sync == "login": if sync == "login":
# get rsync files # get rsync files
try: try:
numfiles = \ numfiles = iniParser(
iniParser(configFileName).getVar('rsync','files') configFileName).getVar('rsync', 'files')
if numfiles is False: if numfiles is False:
if os.path.exists(configFileName): if os.path.exists(configFileName):
os.remove(configFileName) os.remove(configFileName)
numfiles = 0 numfiles = 0
else: else:
numfiles = int(numfiles) numfiles = int(numfiles)
except: except Exception:
numfiles = 0 numfiles = 0
rsync.maximum = numfiles rsync.maximum = numfiles
if sync == "login": if sync == "login":
@ -395,19 +398,19 @@ class Client(commandServer, encrypt, Desktop):
if sync == "logout": if sync == "logout":
rsync.run() rsync.run()
try: try:
if iniParser(configFileName).setVar('rsync', if iniParser(configFileName).setVar(
{'files':rsync.getFilesNum()}): 'rsync', {'files': rsync.getFilesNum()}):
os.chmod(configFileName, 0600) os.chmod(configFileName, 0600)
os.chown(configFileName, uid, gid) os.chown(configFileName, uid, gid)
except: except Exception:
pass pass
rsync.close() rsync.close()
try: try:
if iniParser(configFileName).setVar(\ if iniParser(configFileName).setVar(
'rsync', {'exitcode': rsync.getExitCode()}): 'rsync', {'exitcode': rsync.getExitCode()}):
os.chmod(configFileName, 0600) os.chmod(configFileName, 0600)
os.chown(configFileName, uid, gid) os.chown(configFileName, uid, gid)
except: except Exception:
pass pass
if rsync.getExitCode() != 0: if rsync.getExitCode() != 0:
self.printERROR(rsync.getErrMessage()) self.printERROR(rsync.getErrMessage())
@ -455,7 +458,7 @@ class Client(commandServer, encrypt, Desktop):
eq=resourceName, limit=1), eq=resourceName, limit=1),
profileName) profileName)
# if currect server has any files then sync it # if currect server has any files then sync it
if any(not x in ('.calculate') for x in listDirectory(homeProfile)): if any(x not in ('.calculate',) for x in listDirectory(homeProfile)):
if not self.syncUser(uid, gid, homeDir, "login", if not self.syncUser(uid, gid, homeDir, "login",
homeProfile, host=host): homeProfile, host=host):
return False return False
@ -496,7 +499,8 @@ class Client(commandServer, encrypt, Desktop):
""" """
remoteProfilePath = path.join( remoteProfilePath = path.join(
self.clVars.Select('cl_client_user_mount_path', self.clVars.Select('cl_client_user_mount_path',
where='cl_client_user_mount_name', eq=resourceName, where='cl_client_user_mount_name',
eq=resourceName,
limit=1), profileName) limit=1), profileName)
fileServer = path.join(remoteProfilePath, fileServer = path.join(remoteProfilePath,
Client.configFileServer) Client.configFileServer)
@ -516,32 +520,34 @@ class Client(commandServer, encrypt, Desktop):
""" """
Ожидание архива профиля от домена Ожидание архива профиля от домена
""" """
archPathSuccess,archPathProcess = \ arch_fn_success, arch_fn_process = self._getArchNames(
self._getArchNames(packTime,profileName,resourceName) packTime, profileName, resourceName)
def arch_exists():
return any(os.path.exists(x) for x in (arch_fn_process,
arch_fn_success))
for sleeptime in [0.1, 0.2, 0.5]: for sleeptime in [0.1, 0.2, 0.5]:
# archive in packing process found # archive in packing process found
if os.path.exists(archPathProcess) or \ if arch_exists():
os.path.exists(archPathSuccess):
break break
time.sleep(sleeptime) time.sleep(sleeptime)
else: else:
return False return False
# wait finish packing # wait finish packing
if path.exists(archPathProcess) or \ if arch_exists():
path.exists(archPathSuccess): while arch_exists():
while path.exists(archPathProcess) or \
path.exists(archPathSuccess):
for waittime in [0.5, 1, 2]: for waittime in [0.5, 1, 2]:
if path.exists(archPathSuccess): if path.exists(arch_fn_success):
return True return True
try: try:
startSize = os.stat(archPathProcess).st_size startSize = os.stat(arch_fn_process).st_size
time.sleep(waittime) time.sleep(waittime)
if startSize != os.stat(archPathProcess).st_size: if startSize != os.stat(arch_fn_process).st_size:
break break
except OSError as e: except OSError:
if path.exists(archPathSuccess): if path.exists(arch_fn_success):
return True return True
else: else:
return False return False
@ -551,6 +557,7 @@ class Client(commandServer, encrypt, Desktop):
""" """
Распаковать архив с профилем Распаковать архив с профилем
""" """
def fileReader(fileName, stdin, maxSize): def fileReader(fileName, stdin, maxSize):
""" """
Прочитать файл по блокам Прочитать файл по блокам
@ -580,9 +587,11 @@ class Client(commandServer, encrypt, Desktop):
stderr=subprocess.PIPE, stderr=subprocess.PIPE,
close_fds=True, close_fds=True,
env=os.environ, shell=True) env=os.environ, shell=True)
try:
# прочитать в конвеер # прочитать в конвеер
fileReader(archFile, pipe.stdin, archiveSize) fileReader(archFile, pipe.stdin, archiveSize)
self.endTask() self.endTask()
finally:
ret = pipe.wait() ret = pipe.wait()
pipe.stdout.close() pipe.stdout.close()
pipe.stderr.close() pipe.stderr.close()
@ -601,7 +610,8 @@ class Client(commandServer, encrypt, Desktop):
профиля профиля
""" """
for rmFile in filter(lambda x: x and path.exists(x), for rmFile in filter(lambda x: x and path.exists(x),
self._getArchNames(packTime,profileName,resourceName)): self._getArchNames(packTime, profileName,
resourceName)):
os.remove(rmFile) os.remove(rmFile)
return True return True
@ -633,7 +643,7 @@ class Client(commandServer, encrypt, Desktop):
if iniParser(configFileName).setVar(nameSection, varsDict): if iniParser(configFileName).setVar(nameSection, varsDict):
os.chmod(configFileName, 0600) os.chmod(configFileName, 0600)
os.chown(configFileName, uid, gid) os.chown(configFileName, uid, gid)
except: except Exception:
return False return False
return True return True
@ -655,7 +665,6 @@ class Client(commandServer, encrypt, Desktop):
""" """
Mount all local samba resource Mount all local samba resource
""" """
res = True
for rpath, res, host in \ for rpath, res, host in \
self.clVars.Select(['cl_client_user_mount_path', self.clVars.Select(['cl_client_user_mount_path',
'cl_client_user_mount_resource', 'cl_client_user_mount_resource',
@ -690,12 +699,11 @@ class Client(commandServer, encrypt, Desktop):
Создать tar архив с симлинками Создать tar архив с симлинками
""" """
linkArch = pathJoin(userHome, ".calculate/links.tar.bz2") linkArch = pathJoin(userHome, ".calculate/links.tar.bz2")
symList = []
try: try:
tarLinks(userHome, linkArch, skip=delPath + skipPath) tarLinks(userHome, linkArch, skip=delPath + skipPath)
if path.exists(linkArch): if path.exists(linkArch):
os.chown(linkArch, uid, gid) os.chown(linkArch, uid, gid)
except Exception as e: except Exception:
return False return False
return True return True
@ -709,7 +717,7 @@ class Client(commandServer, encrypt, Desktop):
tf = tarfile.open(linksArch) tf = tarfile.open(linksArch)
tf.extractall(userHome) tf.extractall(userHome)
tf.close() tf.close()
except Exception as e: except Exception:
return False return False
return True return True
@ -720,14 +728,13 @@ class Client(commandServer, encrypt, Desktop):
""" """
desktopDir = "Desktop" desktopDir = "Desktop"
resourcePath = self.clVars.Select('cl_client_user_mount_path', resourcePath = self.clVars.Select('cl_client_user_mount_path',
where='cl_client_user_mount_name', eq=resourceName, where='cl_client_user_mount_name',
eq=resourceName,
limit=1) limit=1)
if not isMount(resourcePath): if not isMount(resourcePath):
raise ClientError(_("Unable to mount %s") % resourcePath) raise ClientError(_("Unable to mount %s") % resourcePath)
movedPath = path.join(resourcePath, movedDir) movedPath = path.join(resourcePath, movedDir)
movedLink = path.join(userHome, movedDir) movedLink = path.join(userHome, movedDir)
dirs = []
files = []
if not skipPaths: if not skipPaths:
skipPaths = ['Disks', 'Share', 'Home', 'Moved', 'FTP', 'Desktop'] skipPaths = ['Disks', 'Share', 'Home', 'Moved', 'FTP', 'Desktop']
filesAndDir = filter(lambda x: not ( filesAndDir = filter(lambda x: not (
@ -744,12 +751,12 @@ class Client(commandServer, encrypt, Desktop):
# find files in Desktop # find files in Desktop
pathDesktop = path.join(userHome, desktopDir) pathDesktop = path.join(userHome, desktopDir)
filesDirDesk = filter(lambda x: (not path.islink(x) and filesDirDesk = filter(lambda x: (not path.islink(x) and
not path.split(x)[1].startswith('.') and not path.split(x)[1].startswith(
'.') and
not x.rpartition('.')[2] == 'desktop'), not x.rpartition('.')[2] == 'desktop'),
listDirectory(pathDesktop, fullPath=True)) listDirectory(pathDesktop, fullPath=True))
movedPathDesk = os.path.join(movedPath, desktopDir)
filesDir += filesDirDesk filesDir += filesDirDesk
if not filesDir or not path.exists(movedPath): if not filesDir or not path.exists(resourcePath):
# remove empty Moved folder # remove empty Moved folder
if path.exists(movedPath) and not listDirectory(movedPath): if path.exists(movedPath) and not listDirectory(movedPath):
os.rmdir(movedPath) os.rmdir(movedPath)
@ -798,7 +805,8 @@ class Client(commandServer, encrypt, Desktop):
# .ssh files relative user home directory # .ssh files relative user home directory
privateFiles += map(lambda x: os.path.join(privateHomeDir, x), privateFiles += map(lambda x: os.path.join(privateHomeDir, x),
filter(lambda x: \ filter(lambda x: \
os.path.isfile(os.path.join(privateDir,x)), os.path.isfile(
os.path.join(privateDir, x)),
os.listdir(privateDir))) os.listdir(privateDir)))
return self.privateFiles + privateFiles return self.privateFiles + privateFiles
@ -826,7 +834,8 @@ class Client(commandServer, encrypt, Desktop):
if not os.path.exists(dstPath): if not os.path.exists(dstPath):
listElPath = [] listElPath = []
for el in filter(lambda x: x, for el in filter(lambda x: x,
dstPath.partition(userHomeDir)[2].split("/")): dstPath.partition(userHomeDir)[2].split(
"/")):
listElPath.append(el) listElPath.append(el)
joinPath = "/".join(listElPath) joinPath = "/".join(listElPath)
dPath = os.path.join(userHomeDir, joinPath) dPath = os.path.join(userHomeDir, joinPath)
@ -855,7 +864,7 @@ class Client(commandServer, encrypt, Desktop):
# read file list from config # read file list from config
try: try:
filesProfileTxt = open(pathListFile).read() filesProfileTxt = open(pathListFile).read()
except: except IOError:
return False return False
listFilesProfile = filter(lambda x: x.strip(), listFilesProfile = filter(lambda x: x.strip(),
filesProfileTxt.split("\n")) filesProfileTxt.split("\n"))
@ -866,7 +875,6 @@ class Client(commandServer, encrypt, Desktop):
return False return False
filesHome = set(listFilesHome) filesHome = set(listFilesHome)
filesRemove = list(filesHome - filesProfile) filesRemove = list(filesHome - filesProfile)
rmPath = ""
try: try:
for rmFile in sorted(filesRemove, reverse=True): for rmFile in sorted(filesRemove, reverse=True):
rmPath = os.path.join(homeDir, rmFile) rmPath = os.path.join(homeDir, rmFile)
@ -880,12 +888,13 @@ class Client(commandServer, encrypt, Desktop):
os.rmdir(rmPath) os.rmdir(rmPath)
else: else:
os.remove(rmPath) os.remove(rmPath)
except Exception as e: except Exception:
return False return False
return True return True
def getRunCommandsWithEnv(self): def getRunCommandsWithEnv(self):
"""List run program""" """List run program"""
def getCmd(procNum): def getCmd(procNum):
cmdLineFile = '/proc/%s/cmdline' % procNum cmdLineFile = '/proc/%s/cmdline' % procNum
environFile = '/proc/%s/environ' % procNum environFile = '/proc/%s/environ' % procNum
@ -894,24 +903,25 @@ class Client(commandServer, encrypt, Desktop):
os.path.exists(environFile): os.path.exists(environFile):
return (open(cmdLineFile, 'r').read().strip(), return (open(cmdLineFile, 'r').read().strip(),
open(environFile, 'r').read().strip()) open(environFile, 'r').read().strip())
except: except (OSError, IOError):
pass pass
return ("","") return "", ""
if not os.access('/proc', os.R_OK): if not os.access('/proc', os.R_OK):
return [] return []
return map(getCmd, return map(getCmd,
filter(lambda x: x.isdigit(), filter(lambda x: x.isdigit(),
os.listdir('/proc'))) os.listdir('/proc')))
def clearUserKey(self, userName): def clearUserKey(self, userName):
""" """
Clear user key from kernel Clear user key from kernel
""" """
# find user key in kernel and check on relogout # find user key in kernel and check on relogout
if getKey(userName) and not \ if getKey(userName) and not \
filter(lambda x:"xdm/xdm\x00--login" in x[0] and \ filter(lambda x: "xdm/xdm\x00--login" in x[0] and
("USER=%s"%userName) in x[1],self.getRunCommandsWithEnv()): ("USER=%s" % userName) in x[1],
self.getRunCommandsWithEnv()):
# clean # clean
ret = clearKey(userName) ret = clearKey(userName)
if ret == 0: if ret == 0:
@ -939,7 +949,8 @@ class Client(commandServer, encrypt, Desktop):
retRes = True retRes = True
for resourceName in resourceNames: for resourceName in resourceNames:
resourcePath = self.clVars.Select('cl_client_user_mount_path', resourcePath = self.clVars.Select('cl_client_user_mount_path',
where='cl_client_user_mount_name', eq=resourceName, where='cl_client_user_mount_name',
eq=resourceName,
limit=1) limit=1)
if resourcePath: if resourcePath:
result = self.umountSleepPath(resourcePath) result = self.umountSleepPath(resourcePath)
@ -973,7 +984,8 @@ class Client(commandServer, encrypt, Desktop):
filter(lambda x: len(x) > 1 and "default" in x[1], filter(lambda x: len(x) > 1 and "default" in x[1],
# [\s*<название_службы>\s*,\s*уровень запуска\s*] # [\s*<название_службы>\s*,\s*уровень запуска\s*]
map(lambda x: x.split('|'), map(lambda x: x.split('|'),
# \s*<название_службы>\s*|\s*<уроверь запуска>?\s* # \s*<название_службы>\s*|
# \s*<уроверь запуска>?\s*
p.readlines()))) p.readlines())))
else: else:
raise ClientError(_("ERROR") + _(": ") + p.read()) raise ClientError(_("ERROR") + _(": ") + p.read())
@ -1014,7 +1026,7 @@ class Client(commandServer, encrypt, Desktop):
Получить параметр севирса из удаленного env Получить параметр севирса из удаленного env
""" """
if not envFile: if not envFile:
if self.convObj == None: if self.convObj is None:
# file /var/calculate/remote/server.env # file /var/calculate/remote/server.env
envFile = self.clVars.Get("cl_env_server_path") envFile = self.clVars.Get("cl_env_server_path")
if os.access(envFile, os.R_OK): if os.access(envFile, os.R_OK):
@ -1046,6 +1058,7 @@ class Client(commandServer, encrypt, Desktop):
domain = domainName domain = domainName
else: else:
import socket import socket
domain = "%s.%s" % (domainName, netDomain) domain = "%s.%s" % (domainName, netDomain)
try: try:
gethostbyname(domain) gethostbyname(domain)
@ -1074,17 +1087,17 @@ class Client(commandServer, encrypt, Desktop):
""" """
Получить пароль для ввода в домен Получить пароль для ввода в домен
""" """
def passwdQueue(): def passwdQueue():
remotePw = self.clVars.Get('cl_remote_pw') remotePw = self.clVars.Get('cl_remote_pw')
if remotePw: if remotePw:
yield remotePw yield remotePw
if remotePw: if remotePw:
self.printERROR(_("Wrong password")) self.printERROR(_("Wrong password"))
yield self.askPassword(\ yield self.askPassword(
_("Domain password for the desktop"), False) _("Domain password for the desktop"), False)
self.printERROR(_("Wrong password")) self.printERROR(_("Wrong password"))
pathRemote = "/var/calculate/remote"
for pwdRemote in passwdQueue(): for pwdRemote in passwdQueue():
pwdRemote = pwdRemote or "" pwdRemote = pwdRemote or ""
if sambaPasswordCheck("client", pwdRemote, domain, "remote"): if sambaPasswordCheck("client", pwdRemote, domain, "remote"):
@ -1114,7 +1127,8 @@ class Client(commandServer, encrypt, Desktop):
# check info from server # check info from server
if not (servDn and unixDn and bindDn and bindPw): if not (servDn and unixDn and bindDn and bindPw):
raise ClientError(_("Info not found on the server") + _(": ") + raise ClientError(_("Info not found on the server") + _(": ") +
_("services DN or unix DN or bind DN or bind password")) _(
"services DN or unix DN or bind DN or bind password"))
self.clVars.Set("os_remote_auth", domain) self.clVars.Set("os_remote_auth", domain)
return True return True
@ -1140,7 +1154,6 @@ class Client(commandServer, encrypt, Desktop):
if hostAuth: if hostAuth:
self.printSUCCESS(_("The workstation was configured for work " self.printSUCCESS(_("The workstation was configured for work "
"in the domain")) "in the domain"))
currentVersion = self.clVars.Get("cl_ver")
self.clVars.Write("os_remote_auth", hostAuth, True) self.clVars.Write("os_remote_auth", hostAuth, True)
else: else:
self.printSUCCESS(_("The workstation was configured for work " self.printSUCCESS(_("The workstation was configured for work "
@ -1153,7 +1166,7 @@ class Client(commandServer, encrypt, Desktop):
Удалить LDAP пользователей из системы (/etc/passwd и т.д.) и Удалить LDAP пользователей из системы (/etc/passwd и т.д.) и
синхронизировать кэш синхронизировать кэш
""" """
cacheObj = userCache() cacheObj = userCache(self)
if not cacheObj.deleteCacheUsersFromSystem(): if not cacheObj.deleteCacheUsersFromSystem():
return False return False
if not cacheObj.syncCacheToLdap(): if not cacheObj.syncCacheToLdap():
@ -1164,7 +1177,7 @@ class Client(commandServer, encrypt, Desktop):
""" """
Добавить кэш пользователей из системы Добавить кэш пользователей из системы
""" """
cacheObj = userCache() cacheObj = userCache(self)
if not cacheObj.addCacheUsersFromSystem(): if not cacheObj.addCacheUsersFromSystem():
return False return False
return True return True
@ -1173,7 +1186,7 @@ class Client(commandServer, encrypt, Desktop):
""" """
Добавить пользователя в кэш Добавить пользователя в кэш
""" """
cacheObj = userCache() cacheObj = userCache(self)
pwdHash = self.getHashPasswd(userPwd, "shadow_ssha256") pwdHash = self.getHashPasswd(userPwd, "shadow_ssha256")
if not cacheObj.addUserToCache(userName, pwdHash): if not cacheObj.addUserToCache(userName, pwdHash):
return False return False
@ -1183,7 +1196,7 @@ class Client(commandServer, encrypt, Desktop):
""" """
Удалить LDAP пользователей из системы и очистить кэш Удалить LDAP пользователей из системы и очистить кэш
""" """
cacheObj = userCache() cacheObj = userCache(self)
if not cacheObj.deleteCacheUsersFromSystem(): if not cacheObj.deleteCacheUsersFromSystem():
return False return False
if not cacheObj.clearCache(): if not cacheObj.clearCache():
@ -1223,16 +1236,19 @@ class Client(commandServer, encrypt, Desktop):
varsConfig = {"unix_hash": self.getHashPasswd(password, "ssha"), varsConfig = {"unix_hash": self.getHashPasswd(password, "ssha"),
"samba_lm_hash": self.getHashPasswd(password, "lm"), "samba_lm_hash": self.getHashPasswd(password, "lm"),
"samba_nt_hash": self.getHashPasswd(password, "nt"), "samba_nt_hash": self.getHashPasswd(password, "nt"),
"samba_nt_hash_old":self.getHashPasswd(curPassword,"nt")} "samba_nt_hash_old": self.getHashPasswd(curPassword,
"nt")}
if filter(lambda x: not x, varsConfig.values()): if filter(lambda x: not x, varsConfig.values()):
return False return False
# ~/.calculate/server.env # ~/.calculate/server.env
fileConfig = os.path.join(homeDir, self.configFileServer) fileConfig = os.path.join(homeDir, self.configFileServer)
try: try:
res = self.setServerCommand(["passwd_samba"], varsConfig, fileConfig, res = self.setServerCommand(["passwd_samba"], varsConfig,
fileConfig,
uid, gid) uid, gid)
except OSError as e: except OSError as e:
if e.errno == 13: if e.errno == 13:
self.printERROR(_("Permission denied")) self.printERROR(_("Permission denied"))
return False return False
return False
return res return res

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2012-2013 Calculate Ltd. http://www.calculate-linux.org # Copyright 2012-2015 Calculate Ltd. http://www.calculate-linux.org
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -14,16 +14,33 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import os, sys, time import os
import sys
import time
from calculate.lib.utils.files import getModeFile from calculate.lib.utils.files import getModeFile
from calculate.lib.cl_print import color_print
from calculate.lib.cl_ldap import ldapUser from calculate.lib.cl_ldap import ldapUser
from calculate.lib.cl_lang import setLocalTranslate from calculate.lib.cl_lang import setLocalTranslate
_ = lambda x: x
setLocalTranslate('cl_client3', sys.modules[__name__]) setLocalTranslate('cl_client3', sys.modules[__name__])
class _shareData(color_print):
class Printable(object):
def __init__(self, parent):
if isinstance(parent, Printable):
self.parent = parent.parent
self.parent = parent
def printERROR(self, s):
self.parent.printERROR(s)
class _shareData(Printable):
"""Share class""" """Share class"""
fileName = ""
template = ""
lenData = 0
data = [] data = []
def getDataInFile(self, fileName='', lenData=0): def getDataInFile(self, fileName='', lenData=0):
@ -107,6 +124,7 @@ class _shareData(color_print):
else: else:
return [] return []
class passwd(_shareData): class passwd(_shareData):
'''Class for working with the file /etc/passwd''' '''Class for working with the file /etc/passwd'''
fileName = "/etc/passwd" fileName = "/etc/passwd"
@ -130,13 +148,14 @@ class passwd(_shareData):
self.data.append(userList) self.data.append(userList)
return True return True
class group(_shareData): class group(_shareData):
'''Class for working with the file /etc/group''' '''Class for working with the file /etc/group'''
fileName = "/etc/group" fileName = "/etc/group"
template = "%(group_name)s:x:%(gid)s:%(user_list)s" template = "%(group_name)s:x:%(gid)s:%(user_list)s"
lenData = 4 lenData = 4
def add(self, name, gid, userList=[]): def add(self, name, gid, userList=()):
groupData = self.template % {'group_name': name, 'gid': gid, groupData = self.template % {'group_name': name, 'gid': gid,
'user_list': ','.join(userList)} 'user_list': ','.join(userList)}
groupList = groupData.split(":") groupList = groupData.split(":")
@ -165,7 +184,7 @@ class group(_shareData):
# Constant gid # Constant gid
listDataWork[2] = self.data[index][2] listDataWork[2] = self.data[index][2]
# Join user list # Join user list
userList = delEmpty(self.data[index][3].split(',') +\ userList = delEmpty(self.data[index][3].split(',') +
listDataWork[3].split(',')) listDataWork[3].split(','))
# unique list # unique list
userList = reduce(lambda x, y: \ userList = reduce(lambda x, y: \
@ -221,11 +240,12 @@ class group(_shareData):
self.data = data self.data = data
return self.data return self.data
class shadow(_shareData): class shadow(_shareData):
'''Class for working with the file /etc/shadow''' '''Class for working with the file /etc/shadow'''
fileName = "/etc/shadow" fileName = "/etc/shadow"
template = "%(login)s:%(hash)s:%(shadowLastChange)s:\ template = ("%(login)s:%(hash)s:%(shadowLastChange)s:"
%(shadowMin)s:%(shadowMax)s:%(shadowWarning)s:::" "%(shadowMin)s:%(shadowMax)s:%(shadowWarning)s:::")
lenData = 9 lenData = 9
def add(self, name, pwdHash, def add(self, name, pwdHash,
@ -252,20 +272,20 @@ class shadow(_shareData):
return _shareData.equally(self, getData(listDataA), return _shareData.equally(self, getData(listDataA),
getData(listDataB)) getData(listDataB))
class _shareCache():
class _shareCache(_shareData):
def save(self): def save(self):
path = os.path.dirname(self.fileName) path = os.path.dirname(self.fileName)
if not os.path.exists(path): if not os.path.exists(path):
try: try:
os.makedirs(path) os.makedirs(path)
except: except OSError:
self.printERROR(_("Failed to create directory %s") % path) self.printERROR(_("Failed to create directory %s") % path)
return False return False
if not os.path.exists(self.fileName): if not os.path.exists(self.fileName):
try: try:
open(self.fileName, "w") open(self.fileName, "w")
except: except IOError:
self.printERROR(_("Failed to create file %s") % self.fileName) self.printERROR(_("Failed to create file %s") % self.fileName)
return False return False
if self.getFileAccess(perm="WRITE"): if self.getFileAccess(perm="WRITE"):
@ -294,9 +314,11 @@ class _shareCache():
else: else:
return False return False
class cachePasswd(_shareCache, passwd): class cachePasswd(_shareCache, passwd):
fileName = "/var/lib/calculate/calculate-client/cache/passwd" fileName = "/var/lib/calculate/calculate-client/cache/passwd"
class cacheGroup(_shareCache, group): class cacheGroup(_shareCache, group):
fileName = "/var/lib/calculate/calculate-client/cache/group" fileName = "/var/lib/calculate/calculate-client/cache/group"
@ -306,16 +328,20 @@ class cacheGroup(_shareCache, group):
def equally(self, listDataA, listDataB): def equally(self, listDataA, listDataB):
return _shareData.equally(self, listDataA, listDataB) return _shareData.equally(self, listDataA, listDataB)
class cacheShadow(_shareCache, shadow): class cacheShadow(_shareCache, shadow):
fileName = "/var/lib/calculate/calculate-client/cache/shadow" fileName = "/var/lib/calculate/calculate-client/cache/shadow"
class cacheCreateGroup(cacheGroup): class cacheCreateGroup(cacheGroup):
fileName = "/var/lib/calculate/calculate-client/cache/create_group" fileName = "/var/lib/calculate/calculate-client/cache/create_group"
class cacheCreatePasswd(cachePasswd): class cacheCreatePasswd(cachePasswd):
fileName = "/var/lib/calculate/calculate-client/cache/create_passwd" fileName = "/var/lib/calculate/calculate-client/cache/create_passwd"
class userCache(color_print):
class userCache(Printable):
ldapObj = ldapUser() ldapObj = ldapUser()
def addUserToCache(self, userName, pwdHash): def addUserToCache(self, userName, pwdHash):
@ -326,7 +352,7 @@ class userCache(color_print):
return False return False
groupName = ldapData['group'] groupName = ldapData['group']
# Add user # Add user
cachePasswdObj = cachePasswd() cachePasswdObj = cachePasswd(self)
if not cachePasswdObj.add(userName, ldapData['uid'], ldapData['gid'], if not cachePasswdObj.add(userName, ldapData['uid'], ldapData['gid'],
gecos=ldapData['fullName'], gecos=ldapData['fullName'],
directory=ldapData['home'], directory=ldapData['home'],
@ -334,7 +360,7 @@ class userCache(color_print):
return False return False
if not cachePasswdObj.save(): if not cachePasswdObj.save():
return False return False
cacheGroupObj = cacheGroup() cacheGroupObj = cacheGroup(self)
# Add primary group # Add primary group
if not cacheGroupObj.add(groupName, ldapData['gid']): if not cacheGroupObj.add(groupName, ldapData['gid']):
return False return False
@ -360,7 +386,7 @@ class userCache(color_print):
if not cacheGroupObj.save(): if not cacheGroupObj.save():
return False return False
# Add shadow user # Add shadow user
cacheShadowObj = cacheShadow() cacheShadowObj = cacheShadow(self)
if not cacheShadowObj.add(userName, pwdHash, if not cacheShadowObj.add(userName, pwdHash,
shadowLastChange=ldapData['shadowLastChange'], shadowLastChange=ldapData['shadowLastChange'],
shadowMin=ldapData['shadowMin'], shadowMin=ldapData['shadowMin'],
@ -373,14 +399,14 @@ class userCache(color_print):
def delUserFromCacheCreate(self, userName): def delUserFromCacheCreate(self, userName):
'''Delete LDAP user from createCache''' '''Delete LDAP user from createCache'''
cacheCreatePasswdObj = cacheCreatePasswd() cacheCreatePasswdObj = cacheCreatePasswd(self)
cacheUserData = cacheCreatePasswdObj.get(userName) cacheUserData = cacheCreatePasswdObj.get(userName)
if cacheUserData is False: if cacheUserData is False:
return False return False
if not cacheUserData: if not cacheUserData:
return True return True
gid = cacheUserData[3] gid = cacheUserData[3]
cacheCreateGroupObj = cacheCreateGroup() cacheCreateGroupObj = cacheCreateGroup(self)
cacheSecondGroups = cacheCreateGroupObj.getSecondUserGroups(userName) cacheSecondGroups = cacheCreateGroupObj.getSecondUserGroups(userName)
if cacheSecondGroups is False: if cacheSecondGroups is False:
return False return False
@ -407,14 +433,14 @@ class userCache(color_print):
def delUserFromCache(self, userName): def delUserFromCache(self, userName):
'''Delete LDAP user from cache''' '''Delete LDAP user from cache'''
cachePasswdObj = cachePasswd() cachePasswdObj = cachePasswd(self)
cacheUserData = cachePasswdObj.get(userName) cacheUserData = cachePasswdObj.get(userName)
if cacheUserData is False: if cacheUserData is False:
return False return False
if not cacheUserData: if not cacheUserData:
return True return True
gid = cacheUserData[3] gid = cacheUserData[3]
cacheGroupObj = cacheGroup() cacheGroupObj = cacheGroup(self)
cacheSecondGroups = cacheGroupObj.getSecondUserGroups(userName) cacheSecondGroups = cacheGroupObj.getSecondUserGroups(userName)
if cacheSecondGroups is False: if cacheSecondGroups is False:
return False return False
@ -437,7 +463,7 @@ class userCache(color_print):
if not cacheGroupObj.save(): if not cacheGroupObj.save():
return False return False
# delete shadow user # delete shadow user
cacheShadowObj = cacheShadow() cacheShadowObj = cacheShadow(self)
if not cacheShadowObj.delete(userName): if not cacheShadowObj.delete(userName):
return False return False
if not cacheShadowObj.save(): if not cacheShadowObj.save():
@ -446,13 +472,13 @@ class userCache(color_print):
def delUserFromSystem(self, userName): def delUserFromSystem(self, userName):
'''Delete LDAP user from system files ( passwd, group, shadow )''' '''Delete LDAP user from system files ( passwd, group, shadow )'''
cacheCreatePasswdObj = cacheCreatePasswd() cacheCreatePasswdObj = cacheCreatePasswd(self)
cacheCreatePasswdData = cacheCreatePasswdObj.get(userName) cacheCreatePasswdData = cacheCreatePasswdObj.get(userName)
if cacheCreatePasswdData is False: if cacheCreatePasswdData is False:
return False return False
if not cacheCreatePasswdData: if not cacheCreatePasswdData:
return True return True
passwdObj = passwd() passwdObj = passwd(self)
userData = passwdObj.get(userName) userData = passwdObj.get(userName)
if userData is False: if userData is False:
return False return False
@ -464,11 +490,11 @@ class userCache(color_print):
if not passwdObj.save(): if not passwdObj.save():
return False return False
# delete user group # delete user group
groupObj = group() groupObj = group(self)
listGroupData = groupObj.getData() listGroupData = groupObj.getData()
if listGroupData is False: if listGroupData is False:
return False return False
cacheCreateGroupObj = cacheCreateGroup() cacheCreateGroupObj = cacheCreateGroup(self)
secondUsersGroups = groupObj.getSecondUserGroups(userName) secondUsersGroups = groupObj.getSecondUserGroups(userName)
usersGids = map(lambda x: x[3], passwdObj.data) usersGids = map(lambda x: x[3], passwdObj.data)
listGroupDataWork = [] listGroupDataWork = []
@ -487,7 +513,7 @@ class userCache(color_print):
if not groupObj.save(): if not groupObj.save():
return False return False
# delete user shadow # delete user shadow
shadowObj = shadow() shadowObj = shadow(self)
shadowData = shadowObj.get(userName) shadowData = shadowObj.get(userName)
if shadowData is False: if shadowData is False:
return False return False
@ -515,7 +541,7 @@ class userCache(color_print):
def deleteCacheUsersFromSystem(self): def deleteCacheUsersFromSystem(self):
'''Delete cache users from system''' '''Delete cache users from system'''
cacheCreatePasswdObj = cacheCreatePasswd() cacheCreatePasswdObj = cacheCreatePasswd(self)
cacheCreateListPasswdData = cacheCreatePasswdObj.getData() cacheCreateListPasswdData = cacheCreatePasswdObj.getData()
if cacheCreateListPasswdData is False: if cacheCreateListPasswdData is False:
return False return False
@ -527,7 +553,7 @@ class userCache(color_print):
def getLoginDomainUsers(self): def getLoginDomainUsers(self):
'''Get all domain login users''' '''Get all domain login users'''
cacheCreatePasswdObj = cacheCreatePasswd() cacheCreatePasswdObj = cacheCreatePasswd(self)
cacheListCreatePasswdData = cacheCreatePasswdObj.getData() cacheListCreatePasswdData = cacheCreatePasswdObj.getData()
if cacheListCreatePasswdData is False: if cacheListCreatePasswdData is False:
return False return False
@ -535,13 +561,13 @@ class userCache(color_print):
def addCacheUsersFromSystem(self): def addCacheUsersFromSystem(self):
'''Add cache users from system''' '''Add cache users from system'''
cachePasswdObj = cachePasswd() cachePasswdObj = cachePasswd(self)
cacheListPasswdData = cachePasswdObj.getData() cacheListPasswdData = cachePasswdObj.getData()
if cacheListPasswdData is False: if not isinstance(cacheListPasswdData, (list, tuple)):
return False return False
# Add cache passwd users to system # Add cache passwd users to system
passwdObj = passwd() passwdObj = passwd(self)
cacheCreatePasswdObj = cacheCreatePasswd() cacheCreatePasswdObj = cacheCreatePasswd(self)
cacheListCreatePasswdData = cacheCreatePasswdObj.getData() cacheListCreatePasswdData = cacheCreatePasswdObj.getData()
if cacheListCreatePasswdData is False: if cacheListCreatePasswdData is False:
return False return False
@ -586,12 +612,12 @@ class userCache(color_print):
return False return False
if not cacheCreatePasswdObj.save(): if not cacheCreatePasswdObj.save():
return False return False
cacheShadowObj = cacheShadow() cacheShadowObj = cacheShadow(self)
cacheListShadowData = cacheShadowObj.getData() cacheListShadowData = cacheShadowObj.getData()
if cacheListShadowData is False: if not isinstance(cacheListShadowData, (list, tuple)):
return False return False
# Add cache shadow users to system # Add cache shadow users to system
shadowObj = shadow() shadowObj = shadow(self)
for cacheShadowData in cacheListShadowData: for cacheShadowData in cacheListShadowData:
userName, pwdHash, shadowLastChange, shadowMin, shadowMax, \ userName, pwdHash, shadowLastChange, shadowMin, shadowMax, \
shadowWarning, x, x, x = cacheShadowData shadowWarning, x, x, x = cacheShadowData
@ -605,13 +631,13 @@ class userCache(color_print):
if shadowObj.data: if shadowObj.data:
if not shadowObj.save(): if not shadowObj.save():
return False return False
cacheGroupObj = cacheGroup() cacheGroupObj = cacheGroup(self)
cacheListGroupData = cacheGroupObj.getData() cacheListGroupData = cacheGroupObj.getData()
if cacheListGroupData is False: if not isinstance(cacheListGroupData, (list, tuple)):
return False return False
cacheCreateGroupObj = cacheCreateGroup() cacheCreateGroupObj = cacheCreateGroup(self)
# Add cache group users to system # Add cache group users to system
groupObj = group() groupObj = group(self)
setAddUsers = set(addUsers) setAddUsers = set(addUsers)
for cacheGroupData in cacheListGroupData: for cacheGroupData in cacheListGroupData:
groupName, x, gid, listUsers = cacheGroupData groupName, x, gid, listUsers = cacheGroupData
@ -641,17 +667,18 @@ class userCache(color_print):
if not self.isConnectToLdap(): if not self.isConnectToLdap():
self.printERROR(_("Failed to connect to the LDAP server")) self.printERROR(_("Failed to connect to the LDAP server"))
return False return False
cachePasswdObj = cachePasswd() cachePasswdObj = cachePasswd(self)
cacheListPasswdData = cachePasswdObj.getData() cacheListPasswdData = cachePasswdObj.getData()
if cacheListPasswdData is False: if cacheListPasswdData is False:
return False return False
if not cacheListPasswdData: if (not isinstance(cacheListPasswdData, (tuple, list)) or
not cacheListPasswdData):
return True return True
cacheGroupObj = cacheGroup() cacheGroupObj = cacheGroup(self)
cacheListGroupData = cacheGroupObj.getData() cacheListGroupData = cacheGroupObj.getData()
if cacheListGroupData is False: if cacheListGroupData is False:
return False return False
cacheShadowObj = cacheShadow() cacheShadowObj = cacheShadow(self)
deletedCacheUsers = [] deletedCacheUsers = []
for cachePasswdData in cacheListPasswdData: for cachePasswdData in cacheListPasswdData:
userName, x, uid, gid, gecos, directory, shell = cachePasswdData userName, x, uid, gid, gecos, directory, shell = cachePasswdData
@ -711,8 +738,8 @@ class userCache(color_print):
def clearCache(self): def clearCache(self):
'''Clear cache files''' '''Clear cache files'''
cacheObjs = (cachePasswd(), cacheShadow(), cacheGroup(), cacheObjs = (cachePasswd(self), cacheShadow(self), cacheGroup(self),
cacheCreateGroup(), cacheCreatePasswd()) cacheCreateGroup(self), cacheCreatePasswd(self))
for cacheObj in cacheObjs: for cacheObj in cacheObjs:
if not cacheObj.save(): if not cacheObj.save():
return False return False

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2012-2013 Calculate Ltd. http://www.calculate-linux.org # Copyright 2012-2015 Calculate Ltd. http://www.calculate-linux.org
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -15,15 +15,16 @@
# limitations under the License. # limitations under the License.
__app__ = 'calculate-client' __app__ = 'calculate-client'
__version__ = '3.1.8' __version__ = '3.4.2'
import os
import sys import sys
from calculate.lib.datavars import DataVars from calculate.lib.datavars import DataVars
from calculate.lib.cl_lang import setLocalTranslate from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_client3', sys.modules[__name__]) setLocalTranslate('cl_client3', sys.modules[__name__])
class DataVarsClient(DataVars): class DataVarsClient(DataVars):
"""Variable class for client package""" """Variable class for client package"""

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2013 Calculate Ltd. http://www.calculate-linux.org # Copyright 2013-2015 Calculate Ltd. http://www.calculate-linux.org
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -15,18 +15,18 @@
# limitations under the License. # limitations under the License.
import sys import sys
from os import path
from calculate.core.server.func import Action, Tasks from calculate.core.server.func import Action, Tasks
from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate
from calculate.lib.utils.files import FilesError from calculate.lib.utils.files import FilesError
from calculate.desktop.desktop import DesktopError from calculate.desktop.desktop import DesktopError
from calculate.client.client import ClientError from calculate.client.client import ClientError
from calculate.lib.cl_template import TemplatesError from calculate.lib.cl_template import TemplatesError
from calculate.lib.utils.files import isMount
_ = lambda x: x
setLocalTranslate('cl_client3', sys.modules[__name__]) setLocalTranslate('cl_client3', sys.modules[__name__])
__ = getLazyLocalTranslate(_) __ = getLazyLocalTranslate(_)
class ClClientAction(Action): class ClClientAction(Action):
""" """
Ввести машину в домен или вывести Ввести машину в домен или вывести
@ -140,7 +140,8 @@ class ClClientAction(Action):
'message': __("Workstation added to domain {cl_remote_host}") 'message': __("Workstation added to domain {cl_remote_host}")
}, },
{'name': 'domain:failed', {'name': 'domain:failed',
'error':__("Failed to add the workstation to domain {cl_remote_host}"), 'error': __(
"Failed to add the workstation to domain {cl_remote_host}"),
'depend': Tasks.failed() & Tasks.hasnot("interrupt"), 'depend': Tasks.failed() & Tasks.hasnot("interrupt"),
}, },
{'name': 'undomain:success', {'name': 'undomain:success',

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2013 Calculate Ltd. http://www.calculate-linux.org # Copyright 2013-2015 Calculate Ltd. http://www.calculate-linux.org
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -24,9 +24,11 @@ from calculate.client.client import ClientError
from calculate.lib.cl_template import TemplatesError from calculate.lib.cl_template import TemplatesError
from calculate.lib.utils.files import isMount from calculate.lib.utils.files import isMount
_ = lambda x: x
setLocalTranslate('cl_client3', sys.modules[__name__]) setLocalTranslate('cl_client3', sys.modules[__name__])
__ = getLazyLocalTranslate(_) __ = getLazyLocalTranslate(_)
class ClClientSyncLoginAction(Action): class ClClientSyncLoginAction(Action):
""" """
Синхронизировать локальный профиль с удаленным, подключить удаленные Синхронизировать локальный профиль с удаленным, подключить удаленные
@ -70,7 +72,8 @@ class ClClientSyncLoginAction(Action):
'method': 'Desktop.createCryptDir(ur_login,ur_uid,ur_gid,' 'method': 'Desktop.createCryptDir(ur_login,ur_uid,ur_gid,'
'ur_home_path,True)', 'ur_home_path,True)',
'condition': lambda Get: (Get('desktop.ur_home_crypt_set') == 'on' and 'condition': lambda Get: (Get('desktop.ur_home_crypt_set') == 'on' and
Get('install.cl_autologin') != Get('ur_login')) Get('install.cl_autologin') != Get(
'ur_login'))
}, },
{'name': 'domain_user:add_to_cache', {'name': 'domain_user:add_to_cache',
'essential': False, 'essential': False,
@ -90,7 +93,8 @@ class ClClientSyncLoginAction(Action):
__("A second X session cannot be opened for user {ur_login}."), __("A second X session cannot be opened for user {ur_login}."),
'condition': lambda dv: (dv.Get('ur_login') in 'condition': lambda dv: (dv.Get('ur_login') in
dv.Get('desktop.cl_desktop_online_user') and dv.Get('desktop.cl_desktop_online_user') and
int(dv.Select('desktop.cl_desktop_online_count', int(dv.Select(
'desktop.cl_desktop_online_count',
where='desktop.cl_desktop_online_user', where='desktop.cl_desktop_online_user',
eq=dv.Get('ur_login'), limit=1) > 1) and eq=dv.Get('ur_login'), limit=1) > 1) and
dv.Get('cl_client_sync') == 'on') dv.Get('cl_client_sync') == 'on')
@ -137,7 +141,8 @@ class ClClientSyncLoginAction(Action):
}, },
# ошибка синхронизации с локальным доменом # ошибка синхронизации с локальным доменом
{'name': 'local_sync_error', {'name': 'local_sync_error',
'warning':__("Error synchronizing with the local server {cl_remote_host}"), 'warning': __(
"Error synchronizing with the local server {cl_remote_host}"),
'depend': Tasks.failed_one_of("mount_local", "sync_local") 'depend': Tasks.failed_one_of("mount_local", "sync_local")
}, },
# подключить удаленный профиль пользователя с "репликации" # подключить удаленный профиль пользователя с "репликации"
@ -174,7 +179,8 @@ class ClClientSyncLoginAction(Action):
'method': 'Client.syncLoginProfile(cl_replication_host,ur_uid,' 'method': 'Client.syncLoginProfile(cl_replication_host,ur_uid,'
'ur_gid,ur_home_path,"remote_profile",' 'ur_gid,ur_home_path,"remote_profile",'
'cl_client_profile_name)', 'cl_client_profile_name)',
'depend':Tasks.failed_one_of('pack_remote','mount_local','sync_local', 'depend': Tasks.failed_one_of('pack_remote', 'mount_local',
'sync_local',
'wait_archive', 'unpack_profile'), 'wait_archive', 'unpack_profile'),
'condition': lambda Select: isMount( 'condition': lambda Select: isMount(
Select('cl_client_user_mount_path', Select('cl_client_user_mount_path',
@ -208,7 +214,8 @@ class ClClientSyncLoginAction(Action):
{'name': 'failed', {'name': 'failed',
'error': __("Failed to get the user profile from the domain"), 'error': __("Failed to get the user profile from the domain"),
'method': 'Client.setSyncStatus(ur_home_path,ur_uid,ur_gid,"error")', 'method': 'Client.setSyncStatus(ur_home_path,ur_uid,ur_gid,"error")',
'depend':Tasks.failed_all('sync_remote','sync_local','fallback_sync') | 'depend': Tasks.failed_all('sync_remote', 'sync_local',
'fallback_sync') |
(Tasks.hasnot('domain_sync') & Tasks.failed()) | (Tasks.hasnot('domain_sync') & Tasks.failed()) |
Tasks.failed_one_of('mount_resources', 'two_session') Tasks.failed_one_of('mount_resources', 'two_session')
}, },
@ -264,7 +271,7 @@ class ClClientSyncLogoutAction(Action):
# проверка на попытку отключить ресурсы пользователя в X сессии # проверка на попытку отключить ресурсы пользователя в X сессии
{'name': 'domain_user:in_xsession', {'name': 'domain_user:in_xsession',
'error': __("User {ur_login} is already on the X session"), 'error': __("User {ur_login} is already on the X session"),
'condition':lambda Get:Get('ur_login') in \ 'condition': lambda Get: Get('ur_login') in
Get('desktop.cl_desktop_online_user'), Get('desktop.cl_desktop_online_user'),
}, },
# проверить наличие домашней директории # проверить наличие домашней директории
@ -275,7 +282,8 @@ class ClClientSyncLogoutAction(Action):
# проверить наличие подключенных ресурсов # проверить наличие подключенных ресурсов
{'name': 'domain_user:check_mount', {'name': 'domain_user:check_mount',
'condition': lambda Get: any(x and isMount(x) 'condition': lambda Get: any(x and isMount(x)
for x in Get('cl_client_user_mount_path')), for x in
Get('cl_client_user_mount_path')),
'else_error': __("Remote user resources not found") 'else_error': __("Remote user resources not found")
}, },
# установить время выхода из сеанса # установить время выхода из сеанса

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2013 Calculate Ltd. http://www.calculate-linux.org # Copyright 2013-2015 Calculate Ltd. http://www.calculate-linux.org
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -15,17 +15,18 @@
# limitations under the License. # limitations under the License.
import sys import sys
from os import path from calculate.core.server.func import Action
from calculate.core.server.func import Action,Tasks
from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate
from calculate.lib.utils.files import FilesError from calculate.lib.utils.files import FilesError
from calculate.desktop.desktop import DesktopError from calculate.desktop.desktop import DesktopError
from calculate.client.client import ClientError from calculate.client.client import ClientError
from calculate.lib.cl_template import TemplatesError from calculate.lib.cl_template import TemplatesError
_ = lambda x: x
setLocalTranslate('cl_client3', sys.modules[__name__]) setLocalTranslate('cl_client3', sys.modules[__name__])
__ = getLazyLocalTranslate(_) __ = getLazyLocalTranslate(_)
class ClPasswdAction(Action): class ClPasswdAction(Action):
""" """
Изменить пароль доменного пользователя Изменить пароль доменного пользователя

@ -14,15 +14,14 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import os
import sys import sys
from os import path from calculate.lib.datavars import ActionVariable
from calculate.lib.datavars import (Variable,VariableError,ReadonlyVariable,
ActionVariable)
from calculate.lib.cl_lang import setLocalTranslate from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_client3', sys.modules[__name__]) setLocalTranslate('cl_client3', sys.modules[__name__])
class VariableAcClientMerge(ActionVariable): class VariableAcClientMerge(ActionVariable):
""" """
Action variable which has value "up" for package install and Action variable which has value "up" for package install and
@ -32,9 +31,10 @@ class VariableAcClientMerge(ActionVariable):
def action(self, cl_action): def action(self, cl_action):
if cl_action in ("merge", "domain", "undomain"): if cl_action in ("merge", "domain", "undomain"):
ret = "on" return "on"
return "off" return "off"
class VariableAcClientDomain(ActionVariable): class VariableAcClientDomain(ActionVariable):
""" """
Action variable which has value "on" for domain action Action variable which has value "on" for domain action
@ -51,6 +51,7 @@ class VariableAcClientDomain(ActionVariable):
return "on" return "on"
return "off" return "off"
class VariableAcClientUndomain(ActionVariable): class VariableAcClientUndomain(ActionVariable):
""" """
Action variable which has value "on" for undomain action Action variable which has value "on" for undomain action

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2008-2013 Calculate Ltd. http://www.calculate-linux.org # Copyright 2008-2015 Calculate Ltd. http://www.calculate-linux.org
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -19,11 +19,12 @@ import sys
from os import path from os import path
import re import re
from calculate.lib.datavars import (Variable, VariableError, ReadonlyVariable, from calculate.lib.datavars import (Variable, VariableError, ReadonlyVariable,
ReadonlyTableVariable,FieldValue) ReadonlyTableVariable, FieldValue,
from calculate.lib.cl_template import iniParser HumanReadable)
from calculate.lib.utils.files import (readLinesFile,isMount,readFile, find, from calculate.lib.cl_ini_parser import iniParser
from calculate.lib.utils.files import (isMount, readFile, find,
FindFileType) FindFileType)
from calculate.lib.utils.common import getValueFromCmdLine,cmpVersion from calculate.lib.utils.common import getValueFromCmdLine
from calculate.lib.utils.portage import isPkgInstalled from calculate.lib.utils.portage import isPkgInstalled
from calculate.lib.variables.user import VariableUrLogin from calculate.lib.variables.user import VariableUrLogin
from calculate.lib.convertenv import convertEnv from calculate.lib.convertenv import convertEnv
@ -37,14 +38,18 @@ import pwd
from calculate.client.client import Client from calculate.client.client import Client
from calculate.lib.cl_lang import setLocalTranslate from calculate.lib.cl_lang import setLocalTranslate
_ = lambda x: x
setLocalTranslate('cl_client3', sys.modules[__name__]) setLocalTranslate('cl_client3', sys.modules[__name__])
class VariableClRemoteHost(Variable): class VariableClRemoteHost(Variable):
""" """
IP or domain name of CDS IP or domain name of CDS
""" """
value = "" value = ""
class VariableClRemoteHostNew(Variable): class VariableClRemoteHostNew(Variable):
""" """
IP or domain name of CDS IP or domain name of CDS
@ -69,10 +74,12 @@ class VariableClRemoteHostNew(Variable):
raise VariableError( raise VariableError(
_("The specified address is not available")) _("The specified address is not available"))
class VariableClRemoteHostLive(ReadonlyVariable): class VariableClRemoteHostLive(ReadonlyVariable):
""" """
Remote host from /proc/cmdline param domain Remote host from /proc/cmdline param domain
""" """
def get(self): def get(self):
return getValueFromCmdLine("calculate", "domain") or "" return getValueFromCmdLine("calculate", "domain") or ""
@ -104,6 +111,7 @@ class VariableClRemotePw(Variable):
def get(self): def get(self):
return getValueFromCmdLine("calculate", "domain_pw") or "" return getValueFromCmdLine("calculate", "domain_pw") or ""
class VariableClMovedSkipPath(Variable): class VariableClMovedSkipPath(Variable):
""" """
Skip "Moved" path Skip "Moved" path
@ -111,6 +119,7 @@ class VariableClMovedSkipPath(Variable):
type = "list" type = "list"
value = ['Disks', 'Home', 'Moved', 'FTP', 'Desktop', 'Share'] value = ['Disks', 'Home', 'Moved', 'FTP', 'Desktop', 'Share']
class VariableClSyncSkipPath(Variable): class VariableClSyncSkipPath(Variable):
""" """
Skip sync path Skip sync path
@ -124,6 +133,7 @@ class VariableClSyncSkipPath(Variable):
".Xauthority", ".thumbnails", ".mozilla/firefox/*/Cache", ".Xauthority", ".thumbnails", ".mozilla/firefox/*/Cache",
".kde4/socket-*", ".cache/", ".local/share/Trash"] ".kde4/socket-*", ".cache/", ".local/share/Trash"]
class VariableClSyncDelPath(Variable): class VariableClSyncDelPath(Variable):
""" """
Removed path on sync Removed path on sync
@ -132,10 +142,12 @@ class VariableClSyncDelPath(Variable):
value = [".kde4/share/config/phonondevicesrc", value = [".kde4/share/config/phonondevicesrc",
".kde4/cache-*", ".kde4/tmp-*"] ".kde4/cache-*", ".kde4/tmp-*"]
class VariableClProfileAllSet(Variable): class VariableClProfileAllSet(Variable):
type = "bool" type = "bool"
value = "off" value = "off"
class VariableClClientSync(Variable): class VariableClClientSync(Variable):
type = "bool" type = "bool"
value = "on" value = "on"
@ -147,6 +159,7 @@ class VariableClClientSync(Variable):
self.label = _("Synchronize the user profile") self.label = _("Synchronize the user profile")
self.help = _("synchronize user preferences") self.help = _("synchronize user preferences")
class VariableClLocalhostSet(Variable): class VariableClLocalhostSet(Variable):
""" """
Using autopartition Using autopartition
@ -171,7 +184,8 @@ class VariableClLocalhostSet(Variable):
if self.Get('cl_remote_host') == '' and value == "on": if self.Get('cl_remote_host') == '' and value == "on":
raise VariableError(_("The workstation is not in the domain")) raise VariableError(_("The workstation is not in the domain"))
if self.Get('cl_remote_host') != '' and value == "off": if self.Get('cl_remote_host') != '' and value == "off":
raise VariableError(_("The workstation is already in the domain %s") raise VariableError(
_("The workstation is already in the domain %s")
% self.Get('cl_remote_host') + "\n" + % self.Get('cl_remote_host') + "\n" +
_("Before joining the domain, " _("Before joining the domain, "
"you need to remove it from the previous domain")) "you need to remove it from the previous domain"))
@ -182,6 +196,7 @@ class VariableClLocalhostSet(Variable):
# else: # else:
# return "off" # return "off"
class VariableClClientMountSet(Variable): class VariableClClientMountSet(Variable):
""" """
Mount remote by configured domain information Mount remote by configured domain information
@ -195,6 +210,7 @@ class VariableClClientMountSet(Variable):
self.label = _("Only mount the domain resource") self.label = _("Only mount the domain resource")
self.help = _("only mount the [remote] domain resource") self.help = _("only mount the [remote] domain resource")
class VariableUrUserPw(Variable, LdapHelper): class VariableUrUserPw(Variable, LdapHelper):
""" """
Current user password Current user password
@ -212,7 +228,6 @@ class VariableUrUserPw(Variable,LdapHelper):
def checkUserPwdLDAP(self, server, userDN, password): def checkUserPwdLDAP(self, server, userDN, password):
"""Check unix user password on server""" """Check unix user password on server"""
ldapInit = ldap.initialize("ldap://%s" % server) ldapInit = ldap.initialize("ldap://%s" % server)
errMessage = ""
try: try:
ldapInit.bind_s(userDN, password) ldapInit.bind_s(userDN, password)
except ldap.INVALID_CREDENTIALS: except ldap.INVALID_CREDENTIALS:
@ -236,6 +251,7 @@ class VariableUrUserPw(Variable,LdapHelper):
usersDN) usersDN)
self.checkUserPwdLDAP(server, userDN, value) self.checkUserPwdLDAP(server, userDN, value)
class VariableUrUserNewPw(Variable): class VariableUrUserNewPw(Variable):
""" """
New user password New user password
@ -254,6 +270,7 @@ class VariableUrUserNewPw(Variable):
if not value: if not value:
raise VariableError(_("Empty password")) raise VariableError(_("Empty password"))
class VariableClClientLogin(VariableUrLogin): class VariableClClientLogin(VariableUrLogin):
""" """
User Login User Login
@ -275,11 +292,11 @@ class VariableClClientLogin(VariableUrLogin):
if value == "": if value == "":
raise VariableError(_("Please specify the user")) raise VariableError(_("Please specify the user"))
if value == "root" and self.Get('cl_action') == 'passwd': if value == "root" and self.Get('cl_action') == 'passwd':
raise VariableError(\ raise VariableError(
_("This action can be executed by a non-root user only")) _("This action can be executed by a non-root user only"))
try: try:
pwd.getpwnam(value).pw_gid pwd.getpwnam(value).pw_gid
except: except (TypeError, KeyError):
raise VariableError(_("User %s does not exist") % value) raise VariableError(_("User %s does not exist") % value)
def get(self): def get(self):
@ -288,6 +305,7 @@ class VariableClClientLogin(VariableUrLogin):
return self.Get('ur_login') return self.Get('ur_login')
return "" return ""
class VariableClClientRelevanceSet(ReadonlyVariable): class VariableClClientRelevanceSet(ReadonlyVariable):
""" """
Актуальны ли сейчас выполненные шаблоны Актуальны ли сейчас выполненные шаблоны
@ -307,20 +325,24 @@ class VariableClClientRelevanceSet(ReadonlyVariable):
return "off" return "off"
return "on" return "on"
class VariableClClientRemotePath(Variable): class VariableClClientRemotePath(Variable):
""" """
Путь для монитрования //domain/remote Путь для монитрования //domain/remote
""" """
value = "/var/calculate/remote" value = "/var/calculate/remote"
class VariableClClientProfileName(Variable): class VariableClClientProfileName(Variable):
""" """
Название удаленного профиля (CLD,CLDX,all) Название удаленного профиля (CLD,CLDX,all)
""" """
def get(self): def get(self):
return ("all" if self.Get('cl_profile_all_set') == 'on' return ("all" if self.Get('cl_profile_all_set') == 'on'
else self.Get('os_linux_shortname')) else self.Get('os_linux_shortname'))
class VariableClLdapData(ldapUser, ReadonlyVariable): class VariableClLdapData(ldapUser, ReadonlyVariable):
""" """
Внутренняя переменная, содержащая объект для доступа к данным LDAP Внутренняя переменная, содержащая объект для доступа к данным LDAP
@ -366,8 +388,7 @@ class VariableClLdapData(ldapUser,ReadonlyVariable):
def _gethostbyname(self, hostname): def _gethostbyname(self, hostname):
try: try:
return gethostbyname(hostname) return gethostbyname(hostname)
except: except Exception:
pass
return None return None
def getNameRemoteServer(self, userName, osLinuxShort, curHost): def getNameRemoteServer(self, userName, osLinuxShort, curHost):
@ -417,11 +438,13 @@ class VariableClReplicationHost(ReadonlyVariable):
""" """
Удаленный сервер при репликации, который содержит актуальный профиль Удаленный сервер при репликации, который содержит актуальный профиль
""" """
def get(self): def get(self):
return self.Get('cl_ldap_data').getNameRemoteServer( return self.Get('cl_ldap_data').getNameRemoteServer(
self.Get('ur_login'), self.Get('cl_client_profile_name'), self.Get('ur_login'), self.Get('cl_client_profile_name'),
self.Get('cl_remote_host')) self.Get('cl_remote_host'))
class VariableClClientUserMountData(ReadonlyTableVariable): class VariableClClientUserMountData(ReadonlyTableVariable):
""" """
Таблица монтирования ресурсов Таблица монтирования ресурсов
@ -431,15 +454,19 @@ class VariableClClientUserMountData(ReadonlyTableVariable):
'cl_client_user_mount_path', 'cl_client_user_mount_path',
'cl_client_user_mount_host'] 'cl_client_user_mount_host']
def get(self): def get(self, hr=HumanReadable.No):
home = path.split(self.Get('ur_home_path'))[0] home = path.split(self.Get('ur_home_path'))[0]
envFile = self.Get('cl_env_server_path') envFile = self.Get('cl_env_server_path')
def generate(): def generate():
yield ("share","share",path.join(self.Get('ur_home_path'),"Share"), yield (
"share", "share", path.join(self.Get('ur_home_path'), "Share"),
self.Get('cl_remote_host')) self.Get('cl_remote_host'))
yield ("unix","unix",path.join(home,".%s"%self.Get('ur_login')), yield (
"unix", "unix", path.join(home, ".%s" % self.Get('ur_login')),
self.Get('cl_remote_host')) self.Get('cl_remote_host'))
yield ("homes","homes",path.join(self.Get('ur_home_path'),"Home"), yield (
"homes", "homes", path.join(self.Get('ur_home_path'), "Home"),
self.Get('cl_remote_host')) self.Get('cl_remote_host'))
if convertEnv().getVar("ftp", "host"): if convertEnv().getVar("ftp", "host"):
yield ("ftp", "ftp", path.join(self.Get('ur_home_path'), "FTP"), yield ("ftp", "ftp", path.join(self.Get('ur_home_path'), "FTP"),
@ -452,8 +479,10 @@ class VariableClClientUserMountData(ReadonlyTableVariable):
self.Get('cl_replication_host')) self.Get('cl_replication_host'))
else: else:
yield ("remote_profile", 'unix', '', '') yield ("remote_profile", 'unix', '', '')
return list(generate()) return list(generate())
class VariableClClientUserMountName(FieldValue, ReadonlyVariable): class VariableClClientUserMountName(FieldValue, ReadonlyVariable):
""" """
Название удаленного ресурса Название удаленного ресурса
@ -471,6 +500,7 @@ class VariableClClientUserMountResource(FieldValue,ReadonlyVariable):
source_variable = "cl_client_user_mount_data" source_variable = "cl_client_user_mount_data"
column = 1 column = 1
class VariableClClientUserMountPath(FieldValue, ReadonlyVariable): class VariableClClientUserMountPath(FieldValue, ReadonlyVariable):
""" """
Путь подключения удаленного ресурса Путь подключения удаленного ресурса
@ -479,6 +509,7 @@ class VariableClClientUserMountPath(FieldValue,ReadonlyVariable):
source_variable = "cl_client_user_mount_data" source_variable = "cl_client_user_mount_data"
column = 2 column = 2
class VariableClClientUserMountHost(FieldValue, ReadonlyVariable): class VariableClClientUserMountHost(FieldValue, ReadonlyVariable):
""" """
Удаленный сервер Удаленный сервер
@ -487,11 +518,13 @@ class VariableClClientUserMountHost(FieldValue,ReadonlyVariable):
source_variable = "cl_client_user_mount_data" source_variable = "cl_client_user_mount_data"
column = 3 column = 3
class SyncHelper:
class SyncHelper(object):
""" """
Вспомогательный объект для определения статуса синхронизации и времени Вспомогательный объект для определения статуса синхронизации и времени
по конфигурационным файлам по конфигурационным файлам
""" """
def getSyncStatus(self, rpath): def getSyncStatus(self, rpath):
""" """
Получить status_sync из desktop файла Получить status_sync из desktop файла
@ -517,7 +550,6 @@ class SyncHelper:
return False return False
return varsConfig return varsConfig
def convertDate(self, strdate, dateformat="%Y-%m-%d %H:%M:%S"): def convertDate(self, strdate, dateformat="%Y-%m-%d %H:%M:%S"):
""" """
Convert date from string format (dateformat) to stuct or None Convert date from string format (dateformat) to stuct or None
@ -547,7 +579,8 @@ class SyncHelper:
return dates[0] return dates[0]
return "" return ""
def checkNeedSync(self,homeDir,rpath,curTimeObj,curStatusSync,osLinuxShort): def checkNeedSync(self, homeDir, rpath, curTimeObj, curStatusSync,
osLinuxShort):
""" """
Проверить необходимость синхронизации текущего профиля с удаленным Проверить необходимость синхронизации текущего профиля с удаленным
""" """
@ -575,31 +608,39 @@ class SyncHelper:
return False return False
return True return True
class VariableClClientSyncTime(SyncHelper, ReadonlyVariable): class VariableClClientSyncTime(SyncHelper, ReadonlyVariable):
""" """
Текущее время синхронизации профиля Текущее время синхронизации профиля
""" """
def get(self): def get(self):
return self.getDateObjClientConf(self.Get('ur_home_path')) return self.getDateObjClientConf(self.Get('ur_home_path'))
class VariableClClientPackTime(SyncHelper, ReadonlyVariable): class VariableClClientPackTime(SyncHelper, ReadonlyVariable):
""" """
Время комады упаковки профиля Время комады упаковки профиля
""" """
def get(self): def get(self):
return str(float(time.time())) return str(float(time.time()))
class VariableClClientSyncStatus(SyncHelper, ReadonlyVariable): class VariableClClientSyncStatus(SyncHelper, ReadonlyVariable):
""" """
Текущий статус синхронизации профиля Текущий статус синхронизации профиля
""" """
def get(self): def get(self):
return self.getSyncStatus(self.Get('ur_home_path')) return self.getSyncStatus(self.Get('ur_home_path'))
class VariableClClientLocalSyncTime(SyncHelper, ReadonlyVariable): class VariableClClientLocalSyncTime(SyncHelper, ReadonlyVariable):
""" """
Текущий статус синхронизации профиля Текущий статус синхронизации профиля
""" """
def get(self): def get(self):
return self.getDateObjClientConf( return self.getDateObjClientConf(
path.join( path.join(
@ -607,6 +648,7 @@ class VariableClClientLocalSyncTime(SyncHelper,ReadonlyVariable):
where='cl_client_user_mount_name', eq='unix', where='cl_client_user_mount_name', eq='unix',
limit=1), self.Get('cl_client_profile_name'))) limit=1), self.Get('cl_client_profile_name')))
class VariableClClientSyncReplicationSet(SyncHelper, ReadonlyVariable): class VariableClClientSyncReplicationSet(SyncHelper, ReadonlyVariable):
""" """
Нужно ли синхронизировать текущий профиль с удаленным доменом Нужно ли синхронизировать текущий профиль с удаленным доменом
@ -624,7 +666,9 @@ class VariableClClientSyncReplicationSet(SyncHelper,ReadonlyVariable):
return "on" if self.checkNeedSync(self.Get('ur_home_path'), profilePath, return "on" if self.checkNeedSync(self.Get('ur_home_path'), profilePath,
self.Get('cl_client_sync_time'), self.Get('cl_client_sync_time'),
self.Get('cl_client_sync_status'), self.Get('cl_client_sync_status'),
self.Get('cl_client_profile_name')) else "off" self.Get(
'cl_client_profile_name')) else "off"
class VariableClClientSyncLocalSet(SyncHelper, ReadonlyVariable): class VariableClClientSyncLocalSet(SyncHelper, ReadonlyVariable):
""" """
@ -643,12 +687,15 @@ class VariableClClientSyncLocalSet(SyncHelper,ReadonlyVariable):
return "on" if self.checkNeedSync(self.Get('ur_home_path'), profilePath, return "on" if self.checkNeedSync(self.Get('ur_home_path'), profilePath,
self.Get('cl_client_sync_time'), self.Get('cl_client_sync_time'),
self.Get('cl_client_sync_status'), self.Get('cl_client_sync_status'),
self.Get('cl_client_profile_name')) else "off" self.Get(
'cl_client_profile_name')) else "off"
class VariableClClientSymlinks(ReadonlyVariable): class VariableClClientSymlinks(ReadonlyVariable):
""" """
Список симлинков в пользовательском профиле Список симлинков в пользовательском профиле
""" """
def get(self): def get(self):
skipFiles = (self.Get('cl_sync_del_path') + skipFiles = (self.Get('cl_sync_del_path') +
self.Get('cl_sync_skip_path')) self.Get('cl_sync_skip_path'))
@ -658,22 +705,27 @@ class VariableClClientSymlinks(ReadonlyVariable):
find(self.Get('ur_home_path'), onefilesystem=True, find(self.Get('ur_home_path'), onefilesystem=True,
filetype=FindFileType.SymbolicLink)) filetype=FindFileType.SymbolicLink))
class VariableClClientNscdCache(Variable): class VariableClClientNscdCache(Variable):
""" """
Частота обновления кэша nscd при работе в домене в часах Частота обновления кэша nscd при работе в домене в часах
""" """
class VariableClCifsVer(ReadonlyVariable): class VariableClCifsVer(ReadonlyVariable):
""" """
Версия модуля CIFS Версия модуля CIFS
""" """
def get(self): def get(self):
return readFile("/sys/module/cifs/version") return readFile("/sys/module/cifs/version")
class VariableClRsyncVer(ReadonlyVariable): class VariableClRsyncVer(ReadonlyVariable):
""" """
Версия rsync Версия rsync
""" """
def get(self): def get(self):
data = isPkgInstalled('net-misc/rsync') data = isPkgInstalled('net-misc/rsync')
if data: if data:

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2012-2013 Calculate Ltd. http://www.calculate-linux.org # Copyright 2012-2015 Calculate Ltd. http://www.calculate-linux.org
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -28,6 +28,7 @@ import calculate.client.client as client
from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate
_ = lambda x: x
setLocalTranslate('cl_client3', sys.modules[__name__]) setLocalTranslate('cl_client3', sys.modules[__name__])
__ = getLazyLocalTranslate(_) __ = getLazyLocalTranslate(_)
@ -71,7 +72,8 @@ class Wsdl(WsdlBase):
'groups': [ 'groups': [
lambda group: group(_("Domain"), lambda group: group(_("Domain"),
normal=( normal=(
'cl_localhost_set', 'cl_remote_host_new', 'cl_localhost_set',
'cl_remote_host_new',
'cl_remote_pw'), 'cl_remote_pw'),
expert=('cl_client_mount_set', expert=('cl_client_mount_set',
'cl_templates_locate', 'cl_templates_locate',

Loading…
Cancel
Save