You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
calculate-utils-3-desktop/pym/cl_desktop.py

303 lines
12 KiB

#-*- 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
14 years ago
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)
14 years ago
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"))
14 years ago
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<len(sleeps) and textLine is False):
# Задержка перед следующей попыткой
time.sleep(sleeps[i])
# Отмонтируем Samba ресурс
if os.path.ismount(path):
textLine = self.execProg("umount %s"%path)
else:
textLine = None
break
i += 1
if textLine != None:
self.printERROR(_("Can not unmount path %s")%path + " ...")
return False
return True
14 years ago
def umountUserRes(self, homeDir=False):
"""Отмонтируем пользовательские директории если они есть"""
umountPaths = self.getMountUserPaths(homeDir)
ret = True
for umountPath in umountPaths:
if not self.umountSleepPath(umountPath):
ret = False
break
return ret