#-*- coding: utf-8 -*- # Copyright 2010 Mir 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. # 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. __version__ = "2.2.0" __version_info__ = tuple([int(num) for num in __version__.split('.')]) __app__ = "calculate-desktop" import os import re import sys import pwd from cl_lang import lang from cl_template import template from cl_datavars import DataVars from cl_print import color_print from cl_ldap import ldapUser from client.progressbar import ProgressBar from cl_utils import runOsCommand, getpathenv lang().setLanguage(sys.modules[__name__]) class DataVarsDesktop(DataVars): """Хранение переменных""" def flDesktop(self, **args): '''Заполнить конфигурацию переменных, для десктопа''' # Имя секции в calculate.env envSection = "desktop" # заполнить переменные окружения алгоритмом по умолнанию self.importData(envSection, ('cl_vars_desktop','cl_fill_desktop')) class ProgressTemplate(template): def __init__(self, vars): template.__init__(self, vars) self.progress = ProgressBar(_("Setting up user profile") + " ...") def numberAllTemplates(self, number): self.progress.setMaximum(number) return True def numberProcessTemplates(self,number): self.progress.setValue(number) return True def close(self): self.progress.shutdownDialog() class share(color_print): """Общие методы""" # Объект хранения переменных clVars = False def isRoot(self, printError=True): """Определяет является ли пользователь root""" if os.getuid() == 0 and os.getgid() == 0: return True else: if printError: self.printERROR(_("The user is not root")) return False def createClVars(self, clVars=False): """Создает объект Vars""" if not clVars: clVars = DataVarsDesktop() clVars.flDesktop() clVars.flIniFile() # Устанавливаем у объекта объект Vars self.clVars = clVars return True def applyTemplatesFromSystem(self): """Применяем шаблоны для cистемы""" # Cоздаем объект обработки шаблонов clTempl = template(self.clVars) # Объединяем шаблоны dirsFiles = clTempl.applyTemplates() if clTempl.getError(): self.printERROR(clTempl.getError().strip()) return False else: return dirsFiles def printVars(self, opts): """Печать существующих переменных""" if opts == ["all"]: self.clVars.printVars() else: self.clVars.printVars(opts) class install(share): """Методы для наложения шаблонов на систему при инсталяции программы""" def installProg(self): """Наложение шаблонов на систему при инсталяции""" # Проверяем на root if not self.isRoot(): return False # Действие инсталяция self.clVars.Set("cl_pass_action", "install", True) if not self.applyTemplatesFromSystem(): self.printERROR(_("Can not apply install templates")) return False self.printOK(_("Apply install templates")) return True class uninstall(share): """Методы для наложения шаблонов на систему при деинсталяции программы""" def uninstallProg(self): """Наложение шаблонов на систему при деинсталяции""" # Проверяем на root if not self.isRoot(): return False # Действие деинсталяция self.clVars.Set("cl_pass_action", "uninstall", True) if not self.applyTemplatesFromSystem(): self.printERROR(_("Can not apply uninstall templates")) return False self.printOK(_("Apply uninstall templates")) return True class desktop(share): """Методы работы с профилем пользователя""" # Имя пользователя userName = "" # Объект для поиска пользовательских данных в LDAP ldapUserObj = ldapUser() def existsUser(self, userName): """Существует ли пользователь""" try: pwd.getpwnam(userName).pw_gid except: self.printERROR(_("User %s not exists")%userName) return False return True 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 applyTemplatesFromUser(self,progress=False): """Применяем шаблоны для пользователя""" # Cоздаем объект обработки шаблонов if progress: clTempl = ProgressTemplate(self.clVars) else: clTempl = template(self.clVars) # Объединяем шаблоны dirsFiles = clTempl.applyTemplates() if progress: clTempl.close() if clTempl.getError(): self.printERROR(clTempl.getError().strip()) return False else: return dirsFiles def createHome(self, progress=False): """Создание профиля пользователя (пользовательской директории)""" # Имя пользователя userName = self.clVars.Get("ur_login") # Проверяем на root if not self.isRoot(): return False uidGid = False # Домен для подключения Samba domain = self.clVars.Get("cl_remote_host") if domain: # Информация о пользователе из LDAP userLdapInfo = self.ldapUserObj.getUserLdapInfo(userName) if userLdapInfo: uid = int(userLdapInfo['uid']) gid = int(userLdapInfo['uid']) homeDir = userLdapInfo['home'] else: self.printERROR(_("Can not found user %s in LDAP")%userName) self.umountUserRes() return False else: pwdInfo = pwd.getpwnam(userName) uid = pwdInfo.pw_uid gid = pwdInfo.pw_gid homeDir = pwdInfo.pw_dir # Создаем пользовательскую директорию rootPath = self.clVars.Get('cl_root_path') # Реальный путь к домашней директории homeDir = os.path.join(rootPath, homeDir[1:]) # Домашняя директория существует flagHomeExists = True # Создаем домашнюю директорию если ее нет if not os.path.exists(homeDir): flagHomeExists = False self.createUserDir(uid, gid, homeDir) # Действие шаблоны пользователя self.clVars.Set("cl_pass_action", "user", True) # Применяем профили для пользователя dirsAndFiles = self.applyTemplatesFromUser(progress) if not dirsAndFiles: # Отмонтируем пользовательские ресурсы в случае ошибки self.printERROR(_("Can not apply user profile")) self.umountUserRes(homeDir) return False if not flagHomeExists: self.printSUCCESS(_("Created home dir %s")%homeDir + " ...") self.printSUCCESS(_("User account is configured") + " ...") return True def getMountUserPaths(self, homeDir=False): """Находит пользовательские примонтированные пути""" # Имя пользователя if not homeDir: userName = self.clVars.Get("ur_login") try: homeDir = pwd.getpwnam(userName).pw_dir except: homeDir = os.path.join("/home",userName) dirStart, dirEnd = os.path.split(homeDir) mountProfileDir = os.path.join(dirStart, ".%s" %dirEnd) mountRemoteProfileDir = os.path.join(dirStart, ".%s.remote" %dirEnd) return filter(lambda x: x.startswith(homeDir) or\ x.startswith(mountProfileDir) or\ x.startswith(mountRemoteProfileDir), map(lambda x: x.split(" ")[1],\ open("/proc/mounts").readlines())) def execProg(self, cmdStrProg, inStr=False, retFull=True, envProg={}): """Выполняет внешнюю программу Параметры: cmdStrProg внешняя программа inStr данные передаваемые программе на страндартный вход. Возвращаемые параметры: строка которую выведет внешняя программа или False в случае ошибки """ env_path = {"PATH":getpathenv()} env = {} env.update(os.environ.items() + env_path.items() + envProg.items()) retCode,programOut = runOsCommand(cmdStrProg,inStr,retFull,env) if not retCode: return programOut return False def umountSleepPath(self, path): """Отмонтирует путь при неудаче задержка потом повтор""" # Задержки при отмонтированиии директории sleeps = [0.5, 2, 5] # Проверяем на монтирование директорию if os.path.ismount(path): textLine = self.execProg("umount %s"%path) if textLine is False: i = 0 flagError = False while (i