#-*- coding: utf-8 -*- #Copyright 2008 Calculate Pack, http://www.calculate-linux.ru # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import os import re import sys import cl_base import cl_profile import cl_utils2 import cl_utils import ldap import types import getpass import _cl_keys Version = "calculate-client 0.0.1" tr = cl_base.lang() tr.setLanguage(sys.modules[__name__]) pcs = cl_utils.prettyColumnStr class printNoColor: def colorPrint(self,attr,fg,bg,string): sys.stdout.write(string) # Импортированные классы в cl_ldap # Запись ошибок imp_cl_err = cl_profile._error # Работа с XML imp_cl_xml = cl_profile.xmlShare # Обработка параметров командной строки imp_cl_help = cl_utils2.cl_help # Форматированный вывод imp_cl_smcon = cl_utils2.cl_smartcon class cl_client(imp_cl_err, imp_cl_xml, imp_cl_help, imp_cl_smcon): """Основной класс для работы клиентских приложений""" def __init__(self, cmdName): # объект для форматированного вывода imp_cl_help.__init__(self, cmdName) servName = "" if "user" in cmdName: servName = _("user") self.chapter = [\ # расположение разделов на странице # имя раздела, видимый или невидимый, кол. "\n" после # названия раздела, кол. "\n" после раздела # тип раздела ("Copyright",False,0,2,""), (_("Usage"),True,0,1,""), ("Function",False,0,2,""), (_("Examples"),True,1,1,""), (_("Common options"),True,1,0,"options"), ] # имена используемых программ и их номера для доступа к переменным # self.data self.progName = { 'cl-client':0, 'cl-createhome':1, 'cl-sync':2 } # Cвязь длинных опций помощи и выводимых разделов помощи с опциями self.relOptions = {"h":[_("Common options")],} # список разделов, которые на наличие в ней информации # используется для автоматического отображения/скрытия # опций help-имя # Пример: self.relOption = # { "help-all":[_("Common options"], _("Unix service options"), # _("Samba service options"), _("LDAP service options")}] # self.relChapterPass = (_("Common options"),) # это означается что опция будет активна, если только в разделах # кроме Common options есть хоть одна доступная опция. self.relChapterPass = (_("Common options"),) self.data = [\ { #Copyright #'progAccess':(3,), 'helpChapter':"Copyright", 'help':Version }, #Usage { 'progAccess':(0,), 'helpChapter':_("Usage"), 'help': cmdName + " [" + _("options") + "] " + _("domain") }, { 'progAccess':(1,), 'helpChapter':_("Usage"), 'help': cmdName + " " + _("user") }, { 'progAccess':(2,), 'helpChapter':_("Usage"), 'help': cmdName + " [" + _("options") + "] " + _("user") }, # Function { 'progAccess':(0,), 'helpChapter':"Function", 'help':_("Changes settings for connecting to domain \ (calculate-server)") }, { 'progAccess':(1,), 'helpChapter':"Function", 'help':_("Create home directory for the new user account") }, { 'progAccess':(2,), 'helpChapter':"Function", 'help':_("Mounting directories and synchronize the user preferences") }, # Examples { 'progAccess':(0,), 'helpChapter':_("Examples"), 'help':pcs( " cl-client 192.168.0.1", self.column_width, "# " + _("Adds settings for connecting to domain \ (ip 192.168.0.1)"), self.consolewidth-self.column_width ) }, # Options {'shortOption':"h", 'longOption':"help", 'helpChapter':_("Common options"), 'help':_("display this help and exit") }, {'progAccess':(0,), 'shortOption':"r", 'helpChapter':_("Common options"), 'help':_("Removes the settings for connecting to a domain") }, {'progAccess':(0,1,2), 'longOption':"vars", 'optVal':_("TYPE_VAR"), 'helpChapter':_("Common options"), 'help':_("print variables (TYPE_VAR - all:full var)") }, {'progAccess':(0,1,2), 'longOption':"color", 'optVal':_("WHEN"), 'helpChapter':_("Common options"), 'help':_("control whether color is used to distinguish file types. \ WHEN may be 'never', 'always', or 'auto'") }, {'progAccess':(0,), 'longOption':"mount", 'helpChapter':_("Common options"), 'help':_("mount [remote] resource for Samba (calculate-server)") }, {'progAccess':(2,), 'longOption':"login", 'helpChapter':_("Common options"), 'help':_("mount user resources")+ " " +\ _("and synchronize the user preferences") }, {'progAccess':(2,), 'longOption':"logout", 'helpChapter':_("Common options"), 'help':_("Synchronize the user preferences") + " " +\ _("and umount user resources") }, #{'progAccess':(0,), #'shortOption':"p", #'longOption':"prvar", #'optVal':_("TYPES_VAR"), #'helpChapter':_("Common options"), #'help':_("print variable (filter type - comma delimited)") #}, ] self._cl_help__setParamHelp() # Удаляем ненужный аттрибут класса cl_profile.xmlShare self._createElement = False delattr(self, "_createElement") # Переменная объект Vars self.clVars = False # Переменная объект ldapFunction self.ldapObj = False # Переменная соединение с LDAP сервером self.conLdap = False # Базовый DN LDAP сервера self.baseDN = False # DN сервисов относительно базового self.ServicesDN = "ou=Services" self.relUsDN = 'ou=Users' self.relServDN = 'ou=Unix' self.relDN = self.addDN(self.relServDN,self.ServicesDN) # DN пользователей, относительно базового DN self.relUsersDN = self.addDN(self.relUsDN, self.relDN) # Объект хранения переменных self.clVars = False def createClVars(self, clVars=False): """Создает объект Vars""" if not clVars: clVars = cl_base.DataVars() clVars.flClient() clVars.flIniFile() # Устанавливаем у объекта объект Vars self.clVars = clVars return True def addDN(self, *arg): """Складывает текстовые элементы DN""" DNs = [] for dn in arg: if dn: DNs.append(dn) return ','.join(DNs) def searchLdapDN(self, name, relDN, attr, retAttr=None): """Находит DN в LDAP""" baseDN = self.clVars.Get("ld_base_dn") DN = self.addDN(relDN,baseDN) #searchScope = ldap.SCOPE_SUBTREE searchScope = ldap.SCOPE_ONELEVEL searchFilter = "%s=%s" %(attr,name) retrieveAttributes = retAttr resSearch = self.ldapObj.ldapSearch(DN, searchScope, searchFilter, retrieveAttributes) return resSearch def searchUnixUser(self, userName): """Находит пользователя сервиса Unix""" resSearch = self.searchLdapDN(userName, self.relUsersDN, "uid") return resSearch def getLdapObjBind(self, host, printError=True): """Получаем объект ldapFunction Соединяемся пользователем bind В выходном объекте есть соединение с LDAP сервером: self.conLdap """ self.createClVars(self.clVars) bindDn = self.clVars.Get("ld_bind_dn") bindPw = self.clVars.Get("ld_bind_pw") if not (bindDn or bindPw): if printError: self.printERROR(_("Not found LDAP bind DN or password") +\ " ...") return False ldapObj = cl_utils2.ldapFun(bindDn, bindPw, host) if ldapObj.getError(): if printError: self.printERROR (_("LDAP connect error") + ": " +\ ldapObj.getError().strip()) return False # Устанавливаем у объекта соединение и объект LDAP функций self.ldapObj = ldapObj self.conLdap = ldapObj.conLdap return True def searchLineInFile(self, name, fileName, numEl=0): """Ищет строку в которой есть название разделенное ':' в файле похожем на /etc/passwd""" if os.path.exists(fileName): FD = open(fileName) lines = FD.readlines() FD.close() lineFound = "" for line in lines: if name == line.split(":")[numEl]: lineFound = line break if lineFound: return lineFound else: return False def searchPasswdUser(self, userName): """Ищет пользователей в /etc/passwd""" filePasswd = "/etc/passwd" return self.searchLineInFile(userName, filePasswd) def getUserLdapInfo(self, userName, printError=True): """Выдаем uid и gid пользователя""" searchUser = self.searchUnixUser(userName) if not searchUser: if printError: self.printERROR(_("User %s not found in Unix service")\ %str(userName)) return False uid = False gid = False fullName = "" mail = "" if searchUser[0][0][1].has_key('uidNumber'): uid = searchUser[0][0][1]['uidNumber'][0] if searchUser[0][0][1].has_key('gidNumber'): gid = searchUser[0][0][1]['gidNumber'][0] if searchUser[0][0][1].has_key('cn'): fullName = searchUser[0][0][1]['cn'][0] if searchUser[0][0][1].has_key('mail'): mail = searchUser[0][0][1]['mail'][0] if searchUser[0][0][1].has_key('homeDirectory'): home = searchUser[0][0][1]['homeDirectory'][0] if uid and gid: return (uid,gid,fullName,mail,home) else: return () def createUserDir(self, uid, gid, userDir, mode=0700): """Создание пользовательской директории""" if not os.path.exists(userDir): os.makedirs(userDir) if mode: os.chmod(userDir,mode) os.chown(userDir,uid,gid) return True else: self.printERROR(_("Path %s exists") %userDir) return False def applyProfilesFromUser(self): """Применяем профили для пользователя""" # Cоздаем объект профиль clProf = cl_profile.profile(self.clVars) # Объединяем профили dirsFiles = clProf.applyProfiles() if clProf.getError(): self.printERROR(clProf.getError()) return False else: return dirsFiles def getUserPassword(self, pwDialog=False): """Получить пароль у пользователя pwDialog - приглашение ввода пароля """ if not pwDialog: pwDialog = _("Password") userPwd = getpass.getpass(pwDialog+":") userPwd = re.sub("(\W)", r"\\\1",userPwd) return userPwd def chownR(self, directory, uid, gid, dirsAndFiles=False): """изменяет владельца и группу для всех файлов и директорий внутри directory """ if dirsAndFiles: dirs, files = dirsAndFiles # меняем владельца домашней директории os.chown(directory, uid,gid) # Меняем владельца директорий for dirCh in dirs: if os.path.exists(dirCh): os.chown(dirCh, uid,gid) # Меняем владельца файлов for fileCh in files: if os.path.exists(fileCh): os.chown(fileCh, uid,gid) return True else: fileObj = cl_profile._file() scanObjs = fileObj.scanDirs([directory]) # меняем владельца домашней директории os.chown(directory, uid,gid) # Меняем владельца директорий for dirCh in scanObjs[0].dirs: os.chown(dirCh, uid,gid) # Меняем владельца файлов for fileCh in scanObjs[0].files: os.chown(fileCh, uid,gid) # Меняем владельца ссылок for linkCh in scanObjs[0].links: os.lchown(linkCh[1], uid, gid) return True def execProg(self, cmdStrProg, inStr=False, retFull=True): """Выполняет внешнюю программу Параметры: cmdStrProg внешняя программа inStr данные передаваемые программе на страндартный вход. Возвращаемые параметры: строка которую выведет внешняя программа """ return cl_utils.runOsCommand(cmdStrProg, inStr, retFull) #def getUidAndGidUser(self, userName): #strRes = self.execProg("id %s" %userName) #reFind = re.compile("uid=(\d+)\(.+gid=(\d+)\(") #res = reFind.search(strRes) #if res: #return res.group(1), res.group(2) #else: #self.printERROR(_("User %s not found")\ #%str(userName)) #return False def getUserPasswdInfo(self, userName): """получаем uid и gid пользователя из /etc/passwd""" resPasswd = self.searchPasswdUser(userName) if resPasswd: uid = resPasswd.split(":")[2] gid = resPasswd.split(":")[3] full_name = resPasswd.split(":")[4] mail = "" return (uid, gid, full_name,mail) else: return False def getAlwaysProfilePath(self): """Получаем пути к профилям которые применяются постоянно""" profilePath = self.clVars.Get('cl_profile_path') alwProfilePath = [] for prPath in profilePath: if os.path.split(prPath)[1] == "always": alwProfilePath.append(prPath) return alwProfilePath def createHome(self, userName): """Создание пользовательской директории с настройками для kde4""" # Создаем объект переменных self.createClVars() uidGid = False # Подсоединяемся к серверу domain = self.clVars.Get("cl_remote_host") connectLdap = False if domain: if not self.getLdapObjBind(domain): return False connectLdap = True if connectLdap: # uid и gid и mail из Ldap uidGid = self.getUserLdapInfo(userName,False) if not domain: # uid и gid и mail из passwd uidGid = self.getUserPasswdInfo(userName) if not uidGid: self.printERROR(_("Not found user uid and gid")) return False uid = int(uidGid[0]) gid = int(uidGid[1]) fullName = uidGid[2] mail = uidGid[3] # Создаем пользовательскую директорию homeDir = os.path.join("/home",userName) self.clVars.Set('cl_root_path',homeDir,True) homeExists = os.path.exists(homeDir) if homeExists: self.printWARNING(_("Home dir %s exists")%homeDir) if set(os.listdir(homeDir))-set(["Home","Disks"]): # Получаем пути к профилям постоянного наложения alwProfilePath = self.getAlwaysProfilePath() if not alwProfilePath: return True # Записываем пути к профилям постоянного наложения #в переменную self.printSUCCESS(_("Apply always profiles") + " ...") self.clVars.Set('cl_profile_path',alwProfilePath, True) if not os.path.exists(homeDir): self.createUserDir(uid, gid, homeDir) # Записываем переменную логин self.clVars.Set('ur_login',userName) self.clVars.Set('ur_fullname',fullName) self.clVars.Set('ur_mail',mail) # Применяем профили для пользователя dirsAndFiles = self.applyProfilesFromUser() if not dirsAndFiles: self.printERROR(_("Not apply user profile")) return False self.chownR(homeDir, uid, gid, dirsAndFiles) if not homeExists: self.printSUCCESS(_("Created home dir %s")%homeDir + " ...") self.printSUCCESS(_("User account is configured") + " ...") return True def isDomain(self): """Находится ли компьютер в домене""" self.createClVars(self.clVars) foundMountRemote =self.isMount("/var/calculate/remote" ,"cifs") foundMountHome =self.isMount("/var/calculate/home" ,"none", False) if not self.clVars.Get("cl_remote_host") and not foundMountRemote and\ not foundMountHome: self.printERROR("The computer is not in domain") return False return (foundMountRemote,foundMountHome) def isMount(self,path ,typeMount, secondPath=True): """Примонтирована ли директория""" foundMount = False if secondPath: reFoundMount = re.compile("on\s+%s\s+type\s+%s"%(path,typeMount)) else: reFoundMount = re.compile("%s\s+.+type\s+%s"%(path,typeMount)) resMount = self.execProg("mount",False,False) if resMount and type(resMount) == types.ListType: for string in resMount: if reFoundMount.search(string): foundMount = True break return foundMount def mountRemote(self): self.createClVars(self.clVars) foundMount = self.isDomain() if not foundMount: return False foundMountRemote = foundMount[0] foundMountHome = foundMount[1] pathHome = "/var/calculate/home" if foundMountRemote: self.printWARNING(_("Samba resource [remote] is mount") + \ " ...") if foundMountHome: self.printWARNING(str(pathHome) + " " +_("is mount")+ " ...") if foundMountHome and foundMountRemote: return True if not foundMountRemote: pathRemote = "/var/calculate/remote" domain = self.clVars.Get("cl_remote_host") pwdRemote = self.clVars.Get("cl_remote_pw") if not (domain and pwdRemote): self.printERROR(_("Not found vaiables: cl_remote_host or \ cl_remote_pw") + " ...") return False if not os.path.exists(pathRemote): os.makedirs(pathRemote) mountStr = "mount -t cifs -o user=client,password=%s \ //%s/remote %s" %(pwdRemote,domain,pathRemote) textLine = self.execProg(mountStr) if not (textLine == None): self.printERROR(_("Can not mount Samba resource [remote]") +\ " ...") return False self.printSUCCESS(_("Mount Samba resource [remote]") +\ " ...") if not foundMountHome: if not os.path.exists(pathHome): os.makedirs(pathHome) mountStr = "mount -o bind %s /home" %pathHome textLine = self.execProg(mountStr) if not (textLine == None): self.printERROR(_("Can not mount") + " " + str(pathHome) +\ " ...") return False self.printSUCCESS(_("Mount") + " " + str(pathHome) + " " +\ " ...") return True def delDomain(self): """выводим из домена""" self.createClVars() pathRemote = "/var/calculate/remote" pathHome = "/var/calculate/home" foundMountRemote =self.isMount(pathRemote ,"cifs") foundMountHome =self.isMount(pathHome ,"none",False) domain = self.clVars.Get("cl_remote_host") if not domain: self.printWARNING("The computer is not in domain") return True if foundMountRemote: umountStr = "umount %s"%(pathRemote) textLine = self.execProg(umountStr) if not (textLine == None): self.printERROR(_("Can not umount Samba resource [remote]") + \ " ...") return False if foundMountHome: umountStr = "umount %s"%(pathHome) textLine = self.execProg(umountStr) if not (textLine == None): self.printERROR(_("Can not umount") + " " + pathHome +\ " ...") return False self.execProg("calculate -P install/6intranet") self.clVars.Delete("cl_remote_host","local") self.clVars.Delete("cl_remote_pw","local") self.printOK(_("Computer removed from domain %s")%domain + " ...") return True def addDomain(self, domain): """Вводим в домен""" # Создаем объект переменных self.createClVars() resPing = self.execProg("ping -c 2 -i 0.3 %s" %domain,False,False) foudHost = False foudHostSamba = False foundMountRemote = False reFoundHost = re.compile("(\d+)\% packet loss") if resPing and type(resPing) == types.ListType and len(resPing)>=2: pingStr = resPing[-2].strip() reSearch = reFoundHost.search(pingStr) if reSearch and reSearch.group(1) == "0": foudHost = True if not foudHost: self.printERROR(_("Not found domain %s")%domain) return False reFoundHostSamba = re.compile("Server=\[Samba.+\]") resSmbClient = self.execProg("smbclient -N -L %s" %domain, False,False) if resSmbClient and type(resSmbClient) == types.ListType: for string in resSmbClient: if reFoundHostSamba.search(string): foudHostSamba = True break if not foudHostSamba: self.printERROR(_("Not found Samba server in %s")%domain) return False foundMountRemote =self.isMount("/var/calculate/remote" ,"cifs") foundMountHome =self.isMount("/var/calculate/home" ,"none", False) if foundMountRemote: self.printWARNING(_("Samba resource [remote] mount") + \ " ...") else: userPwd = self.getUserPassword("Domain password for the desktop") pathRemote = "/var/calculate/remote" pwdRemote = userPwd if not os.path.exists(pathRemote): os.makedirs(pathRemote) mountStr = "mount -t cifs -o user=client,password=%s \ //%s/remote %s" %(pwdRemote,domain,pathRemote) textLine = self.execProg(mountStr) if not (textLine == None): self.printERROR(_("Can not mount Samba resource [remote]") + \ " ...") return False else: self.printSUCCESS(_("Mount Samba resource [remote]") + \ " ...") self.clVars.Write("cl_remote_host", domain, False, "local") self.clVars.Write("cl_remote_pw", userPwd, False, "local") pathHome = "/var/calculate/home" if foundMountHome: self.printWARNING(str(pathHome)+ " " +_("is mount")+ " ...") else: if not os.path.exists(pathHome): os.makedirs(pathHome) mountStr = "mount -o bind %s /home" %pathHome textLine = self.execProg(mountStr) if not (textLine == None): self.printERROR(_("Can not mount") + " " + str(pathHome) +\ " ...") return False self.printSUCCESS(_("Mount") + " " + str(pathHome) + " " +\ " ...") self.clVars.flIniFile() #считаем переменные для клиента servDn = self.clVars.Get("ld_services_dn") unixDN = self.clVars.Get("ld_unix_dn") bindDn = self.clVars.Get("ld_bind_dn") bindPw = self.clVars.Get("ld_bind_pw") # запишем их if not (servDn and unixDN and bindDn and bindPw): self.printERROR(_("Not found variables:")) self.printERROR("ld_services_dn or ld_unix_dn \ or ld_bind_dn or ld_bind_pw") return False execStr = "calculate --set-server_url=%s --set-ldap_base=%s \ --set-ldap_root=%s --set-ldap_bind=%s --set-ldap_bindpw=%s -P \ install/6intranet" %(domain,servDn,unixDN,bindDn,bindPw) self.execProg(execStr) self.printOK(_("Computer added to domain %s")%domain + " ...") return True def umountUserRes(self, userName): """Отмонтирование пользовательских ресурсов и синхронизация настроек""" connectDomain = self.isDomain() if not connectDomain: return False elif not connectDomain[0]: self.printERROR(_("Can not mount Samba resource [remote]") + \ " ...") return False # Подсоединяемся к серверу domain = self.clVars.Get("cl_remote_host") if not self.getLdapObjBind(domain): return False # homeDir из LDAP resLdap = self.getUserLdapInfo(userName) if not resLdap: return False homeDir = resLdap[4] home = os.path.split(homeDir)[0] pathRemote = [] # Удаленный ресурс профилей pathRemote.append((os.path.join(home,"." + userName), "unix")) # Удаленный ресурс home pathRemote.append((os.path.join(homeDir,"Home"), "homes")) # Удаленный ресурс share pathRemote.append((os.path.join(homeDir,"Disks"), "share")) if not self.syncUser(userName, homeDir, "logout"): return False flagError = False for path, res in pathRemote: if self.isMount(path ,"cifs"): textLine = self.execProg("umount %s"%path) if not (textLine == None): self.printERROR(_("Can not umount Samba resource \ [%s]")%res + " ...") flagError = True break if os.path.exists(path) and not os.listdir(path): try: os.rmdir(path) except: self.printERROR(_("Can not remove dir %s")% path) flagError = True break if flagError: self.printERROR(_("Keep a user profile in the domain")) return False self.printSUCCESS(_("Keep a user profile in the domain")) self.printOK(_("Umount user resources in domain") + " ...") return True def mountUserRes(self, userName): """Монтирование пользовательских ресурсов и синхронизация настроек""" self.createClVars() # В случае компьютера вне домена if not self.clVars.Get("cl_remote_host"): self.printSUCCESS(_("To be used by local profile.")) return True # Проверим что компьютер в домене и смонтирован [remote] connectDomain = self.isDomain() if not connectDomain: return False elif not connectDomain[0]: self.printERROR(_("Can not mount Samba resource [remote]") + \ " ...") return False # Подсоединяемся к серверу domain = self.clVars.Get("cl_remote_host") if not self.getLdapObjBind(domain): return False # homeDir из LDAP resLdap = self.getUserLdapInfo(userName) if not resLdap: return False uid = int(resLdap[0]) gid = int(resLdap[1]) homeDir = resLdap[4] # При отсуствии создаем домашнюю директорию if not os.path.exists(homeDir): os.makedirs(homeDir) os.chown(homeDir,uid,gid) os.chmod(homeDir,0700) # Получаем пароль пользователя из ключей ядра userPwd = _cl_keys.getKey(userName) if not userPwd: self.printERROR(_("Not found user password")) return False home = os.path.split(homeDir)[0] pathRemote = [] # Удаленный ресурс профилей pathRemote.append((os.path.join(home,"." + userName), "unix")) # Удаленный ресурс home pathRemote.append((os.path.join(homeDir,"Home"), "homes")) # Удаленный ресурс share pathRemote.append((os.path.join(homeDir,"Disks"), "share")) flagError = False for path, res in pathRemote: # Создаем директории для монтирования if not os.path.exists(path): try: os.mkdir(path) os.chown(path, uid, gid) os.chmod(path,0700) except OSError: self.printERROR(_("Error creating directory")) self.printERROR(_("Permission denied: '%s'")%path) flagError = True break # Проверяем на монтирование директории if self.isMount(path, 'cifs'): continue # Монтируем директории mountStr="mount -t cifs -o user=%s,password=%s"%(userName, userPwd) + " " +\ "//%s/%s %s" %(self.clVars.Get("cl_remote_host"), res, path) textLine = self.execProg(mountStr) if not (textLine == None): self.printERROR(_("Can not mount Samba resource [%s]")%res + \ " ...") flagError = True break if flagError: return False # Синхронизируем настройки if not self.syncUser(userName, homeDir, "login"): return False self.printSUCCESS(_("Mount user resources in domain")) self.printOK(_("Get a user profile in the domain") + " ...") return True def syncUser(self, userName, userHome, sync): """Синхронизация пользовательских настроек""" home = os.path.split(userHome)[0] homeProfile = os.path.join(home,"." + userName) flagError = False execStr = "" if sync == "login": if os.path.exists(userHome) and\ os.path.exists(homeProfile): execStr = '/usr/bin/rsync --exclude="/.googleearth" \ --exclude="*~" --exclude="/Home" --exclude="/Disks" \ -a --delete -x %s/ %s/' %(homeProfile,userHome) elif sync == "logout": if os.path.exists(userHome) and os.listdir(userHome) and\ os.path.exists(homeProfile): execStr = '/usr/bin/rsync --exclude="/.googleearth" \ --exclude="*~" --exclude="/Home" --exclude="/Disks" \ -a -b --delete -x %s/ %s/'%(userHome,homeProfile) else: self.printERROR(_("Method syncUser: option sync=%s incorrect")\ %str(sync)) return False if execStr: textLine = self.execProg(execStr) if not (textLine == None): self.printERROR(_("Can not rsync") + " " + str(sync) +\ " ...") flagError = True else: if sync == "login": if not (os.path.exists(userHome)): self.printERROR(_("Directory %s not exists")%userHome) else: self.printERROR(_("Directory %s not exists")%homeProfile) elif sync == "logout": if not (os.path.exists(userHome)): self.printERROR(_("Directory %s is empty or not exists")\ %userHome) else: self.printERROR(_("Directory %s not exists")%homeProfile) flagError = True if flagError: return False else: return True class tsOpt(cl_base.opt): """Класс для обработки параметров и вывода help Параметры: helpObj объект-справка содержащий необходимые опции notOptError выдавать ошибку при отсутствии опций командной строки """ def __init__(self, helpObj, notOptError=False): # от cl_help получаем короткие и длинные опции shortOpt,longOpt = helpObj.getAllOpt('all', helpObj.relOptions['h']) # вызвать конструктор объекта, распознающего опции cl_base.opt.__init__(self,shortOpt,longOpt) self.nameParams = ['user'] self.sysArgv = sys.argv[1:] self.helpObj = helpObj self.__iter = 0 self.opt = {} self.params = {} self.getopt() # Обработка help self.flagHelp = False # определяем есть ли среди опций опции, которые влияют на показ # опциональных разделов (метод пересечения множеств) helpopt = \ tuple(set(self.opt.keys()).intersection(helpObj.relOptions.keys())) #Если есть опции help if len(helpopt) > 0: print helpObj.getHelp(helpObj.relOptions[helpopt[0]]) self.flagHelp = True #Если нет хвостов #elif not self.params: #print helpObj.getHelp(helpObj.relOptions['h']) #self.flagHelp = True else: if self.params.has_key('user'): if len(self.nameParams) != self.__iter: self.handlerErrOpt() # В случае остсутствия опций командной строки и имени пользователя if notOptError: if not self.opt: self.printErrorNotOpt() self.flagHelp = True elif not self.opt and not self.params.has_key('user'): print helpObj.getHelp(helpObj.relOptions['h']) self.flagHelp = True def printErrorNotOpt(self): """Сообщение в случае отсутствия опций""" print _("Options are absent.") def handlerOpt(self,option,value): # Обработчик (опция значение) #print option, value shortOpt = self.helpObj.getShortOpt(option) if not shortOpt: shortOpt = option if not shortOpt in self.opt: self.opt[shortOpt] = value def handlerErrOpt(self): # Обработчик ошибок argv = " ".join(sys.argv[1:]) print _("Unrecognized option") + ' "' + argv + '"\n' + \ _("Try") + ' "' + sys.argv[0].split("/")[-1] + ' --help" ' +\ _("for more information.") def handlerParam(self,param): # Обработчик хвостов (значение) self.__iter += 1 if self.__iter<=len(self.nameParams): self.params[self.nameParams[self.__iter-1]] = param