Refactoring

develop 3.4.1.1
Mike Khiretskiy 9 years ago
parent b0ce98e865
commit 76171566a9

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

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

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

@ -1,6 +1,6 @@
# -*- 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");
# you may not use this file except in compliance with the License.
@ -15,15 +15,16 @@
# limitations under the License.
__app__ = 'calculate-client'
__version__ = '3.1.8'
__version__ = '3.4.2'
import os
import sys
from calculate.lib.datavars import DataVars
from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_client3', sys.modules[__name__])
class DataVarsClient(DataVars):
"""Variable class for client package"""

@ -1,6 +1,6 @@
# -*- 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");
# you may not use this file except in compliance with the License.
@ -15,18 +15,18 @@
# limitations under the License.
import sys
from os import path
from calculate.core.server.func import Action, Tasks
from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate
from calculate.lib.utils.files import FilesError
from calculate.desktop.desktop import DesktopError
from calculate.client.client import ClientError
from calculate.lib.cl_template import TemplatesError
from calculate.lib.utils.files import isMount
_ = lambda x: x
setLocalTranslate('cl_client3', sys.modules[__name__])
__ = getLazyLocalTranslate(_)
class ClClientAction(Action):
"""
Ввести машину в домен или вывести
@ -140,7 +140,8 @@ class ClClientAction(Action):
'message': __("Workstation added to domain {cl_remote_host}")
},
{'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"),
},
{'name': 'undomain:success',

@ -1,6 +1,6 @@
# -*- 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");
# 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.utils.files import isMount
_ = lambda x: x
setLocalTranslate('cl_client3', sys.modules[__name__])
__ = getLazyLocalTranslate(_)
class ClClientSyncLoginAction(Action):
"""
Синхронизировать локальный профиль с удаленным, подключить удаленные
@ -70,7 +72,8 @@ class ClClientSyncLoginAction(Action):
'method': 'Desktop.createCryptDir(ur_login,ur_uid,ur_gid,'
'ur_home_path,True)',
'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',
'essential': False,
@ -90,7 +93,8 @@ class ClClientSyncLoginAction(Action):
__("A second X session cannot be opened for user {ur_login}."),
'condition': lambda dv: (dv.Get('ur_login') in
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',
eq=dv.Get('ur_login'), limit=1) > 1) and
dv.Get('cl_client_sync') == 'on')
@ -137,7 +141,8 @@ class ClClientSyncLoginAction(Action):
},
# ошибка синхронизации с локальным доменом
{'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")
},
# подключить удаленный профиль пользователя с "репликации"
@ -174,7 +179,8 @@ class ClClientSyncLoginAction(Action):
'method': 'Client.syncLoginProfile(cl_replication_host,ur_uid,'
'ur_gid,ur_home_path,"remote_profile",'
'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'),
'condition': lambda Select: isMount(
Select('cl_client_user_mount_path',
@ -208,7 +214,8 @@ class ClClientSyncLoginAction(Action):
{'name': 'failed',
'error': __("Failed to get the user profile from the domain"),
'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.failed_one_of('mount_resources', 'two_session')
},
@ -264,7 +271,7 @@ class ClClientSyncLogoutAction(Action):
# проверка на попытку отключить ресурсы пользователя в X сессии
{'name': 'domain_user:in_xsession',
'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'),
},
# проверить наличие домашней директории
@ -275,7 +282,8 @@ class ClClientSyncLogoutAction(Action):
# проверить наличие подключенных ресурсов
{'name': 'domain_user:check_mount',
'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")
},
# установить время выхода из сеанса

@ -1,6 +1,6 @@
# -*- 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");
# you may not use this file except in compliance with the License.
@ -15,17 +15,18 @@
# limitations under the License.
import sys
from os import path
from calculate.core.server.func import Action,Tasks
from calculate.core.server.func import Action
from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate
from calculate.lib.utils.files import FilesError
from calculate.desktop.desktop import DesktopError
from calculate.client.client import ClientError
from calculate.lib.cl_template import TemplatesError
_ = lambda x: x
setLocalTranslate('cl_client3', sys.modules[__name__])
__ = getLazyLocalTranslate(_)
class ClPasswdAction(Action):
"""
Изменить пароль доменного пользователя

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

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

@ -1,6 +1,6 @@
# -*- 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");
# 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
_ = lambda x: x
setLocalTranslate('cl_client3', sys.modules[__name__])
__ = getLazyLocalTranslate(_)
@ -71,7 +72,8 @@ class Wsdl(WsdlBase):
'groups': [
lambda group: group(_("Domain"),
normal=(
'cl_localhost_set', 'cl_remote_host_new',
'cl_localhost_set',
'cl_remote_host_new',
'cl_remote_pw'),
expert=('cl_client_mount_set',
'cl_templates_locate',

Loading…
Cancel
Save