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-client/pym/client/variables/client.py

877 lines
29 KiB

9 years ago
# -*- coding: utf-8 -*-
12 years ago
# Copyright 2008-2016 Mir Calculate. http://www.calculate-linux.org
12 years ago
#
# 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.
12 years ago
import os
import sys
from os import path
import re
9 years ago
from calculate.lib.datavars import (Variable, VariableError, ReadonlyVariable,
ReadonlyTableVariable, FieldValue,
HumanReadable)
from calculate.lib.cl_ini_parser import iniParser
from calculate.lib.configparser import ConfigParser
import calculate.lib.utils.device as device
from calculate.lib.utils.files import (readFile, find,
9 years ago
FindFileType)
from calculate.lib.utils.mount import isMount
from calculate.lib.utils.common import getValueFromCmdLine, CmdlineParams
from calculate.lib.utils.portage import isPkgInstalled
from calculate.lib.variables import user
from calculate.lib.convertenv import convertEnv
12 years ago
from calculate.lib.utils.ip import isOpenPort
import time
import ldap
from socket import gethostbyname
from calculate.lib.cl_ldap import ldapUser
from calculate.lib.variables.user import LdapHelper
import pwd
from ..client import Client
from ..rsync import ProfileSyncer, ProfileSyncerError
12 years ago
from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate
9 years ago
_ = lambda x: x
setLocalTranslate('cl_client3', sys.modules[__name__])
__ = getLazyLocalTranslate(_)
9 years ago
12 years ago
class VariableClRemoteHost(Variable):
"""
IP or domain name of CDS
"""
value = ""
class VariableClRemoteDomain(Variable):
"""
Имя домена
"""
value = ""
9 years ago
12 years ago
class VariableClRemoteHostNew(Variable):
"""
IP or domain name of CDS
"""
opt = ["cl_remote_host_new"]
metavalue = "DOMAIN"
type = "choiceedit"
value = ""
untrusted = True
def init(self):
self.label = _("Domain IP")
self.help = _("domain")
9 years ago
def check(self, value):
12 years ago
if self.Get('cl_client_mount_set') == 'off':
if self.Get('cl_localhost_set') == 'off':
if self.Get('cl_remote_host') == '':
if not value:
raise VariableError(_("Please specify the domain"))
9 years ago
elif not isOpenPort(value, 445):
12 years ago
raise VariableError(
12 years ago
_("The specified address is not available"))
12 years ago
9 years ago
12 years ago
class VariableClRemoteHostLive(ReadonlyVariable):
"""
Remote host from /proc/cmdline param domain
"""
9 years ago
12 years ago
def get(self):
return getValueFromCmdLine(CmdlineParams.Calculate,
CmdlineParams.Domain) or ""
12 years ago
class VariableOsRemoteAuth(Variable):
"""
Client work mode (local or hostname)
"""
class VariableOsRemoteClient(Variable):
"""
Version which apply templates
"""
pass
class VariableClRemotePw(Variable):
"""
Client password
"""
12 years ago
type = "onepassword"
12 years ago
opt = ["--domain-password"]
def init(self):
self.label = __("Domain password")
12 years ago
self.help = _("specify the domain password")
12 years ago
def get(self):
return getValueFromCmdLine(CmdlineParams.Calculate,
CmdlineParams.DomainPassword) or ""
9 years ago
12 years ago
class VariableClMovedSkipPath(Variable):
"""
Skip "Moved" path
"""
type = "list"
9 years ago
value = ['Disks', 'Home', 'Moved', 'FTP', 'Desktop', 'Share']
12 years ago
class VariableClSyncSkipPath(Variable):
"""
Skip sync path
"""
type = "list"
value = [".googleearth", "Home", "Disks", "FTP",
9 years ago
'Share', ".local/share/akonadi/db_data", ".VirtualBox",
".mozilla/firefox/calculate.default/urlclassifier3.sqlite",
".local/share/mime/mime.cache", ".gvfs",
".kde4/share/apps/nepomuk/repository/main/data", ".logout",
".Xauthority", ".thumbnails", ".mozilla/firefox/*/Cache",
".kde4/socket-*", ".cache/", ".local/share/Trash"]
12 years ago
class VariableClSyncDelPath(Variable):
"""
Removed path on sync
"""
type = "list"
value = [".kde4/share/config/phonondevicesrc",
".kde4/cache-*", ".kde4/tmp-*"]
9 years ago
12 years ago
class VariableClProfileAllSet(Variable):
type = "bool"
value = "off"
9 years ago
12 years ago
class VariableClClientSync(Variable):
type = "bool"
value = "on"
metavalue = "ON/OFF"
opt = ["--sync"]
def init(self):
12 years ago
self.label = _("Synchronize the user profile")
12 years ago
self.help = _("synchronize user preferences")
12 years ago
9 years ago
12 years ago
class VariableClLocalhostSet(Variable):
"""
Using autopartition
"""
type = "bool"
element = "radio"
value = "off"
opt = ["-r"]
metavalue = "ON/OFF"
untrusted = True
12 years ago
def init(self):
self.label = _("Workstation role")
12 years ago
self.help = _("remove the domain connection settings")
12 years ago
def choice(self):
9 years ago
return [("off", _("Domain workstation")),
("on", _("Local workstation"))]
12 years ago
9 years ago
def check(self, value):
if self.Get('cl_client_mount_set') == 'off':
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":
9 years ago
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"))
# def get(self):
# if self.Get('cl_remote_host') == '':
# return "on"
# else:
# return "off"
12 years ago
class VariableClClientMountSet(Variable):
"""
Mount remote by configured domain information
"""
type = "bool"
value = "off"
metavalue = "ON/OFF"
opt = ["--mount"]
def init(self):
self.label = _("Only mount the domain resource")
self.help = _("only mount the [remote] domain resource")
9 years ago
class VariableUrUserPw(Variable, LdapHelper):
"""
Current user password
"""
type = "need-onepassword"
opt = ["--old-password"]
metavalue = "OLDPASSWORD"
value = ""
untrusted = True
def init(self):
self.label = _("Current password")
self.help = _("current user password")
def checkUserPwdLDAP(self, server, userDN, password):
12 years ago
"""Check unix user password on server"""
9 years ago
ldapInit = ldap.initialize("ldap://%s" % server)
try:
ldapInit.bind_s(userDN, password)
except ldap.INVALID_CREDENTIALS:
raise VariableError(_("Wrong password"))
3 years ago
except ldap.LDAPError as e:
raise VariableError(f"{e.args[0]['desc']}; {e.args[0]['info']}")
return True
9 years ago
def check(self, value):
if not value:
raise VariableError(_("Empty password"))
# читаем os_remote_auth, так как при смене пароля
# чтение должно выполняться от пользователя,
# cl_remote_host не может быть прочитан пользователем
server = self.Get('os_remote_auth')
ldapObj = self.getLdapUserObject()
if ldapObj:
usersDN = ldapObj.getUsersDN()
9 years ago
userDN = ldapObj.addDN("uid=%s" % self.Get('ur_login'),
usersDN)
self.checkUserPwdLDAP(server, userDN, value)
class VariableUrUserNewPw(Variable):
"""
New user password
"""
type = "need-password"
opt = ["--new-password"]
metavalue = "NEWPASSWORD"
value = ""
untrusted = True
def init(self):
self.label = _("New password")
self.help = _("new user password")
9 years ago
def check(self, value):
if not value:
raise VariableError(_("Empty password"))
9 years ago
class VariableClClientLogin(user.VariableUrLogin):
"""
User Login
"""
opt = ["cl_client_login"]
alias = "ur_login"
def choice(self):
loginChoice = user.VariableUrLogin.choice(self)
if self.Get('cl_action') == 'passwd':
3 years ago
return [x for x in loginChoice if x != "root"]
else:
return loginChoice
9 years ago
def check(self, value):
"""Does user exist"""
if not value in self.choice() and self.Get('cl_action') == 'logout':
raise VariableError(_("X session users not found"))
if value == "":
raise VariableError(_("Please specify the user"))
if value == "root" and self.Get('cl_action') == 'passwd':
9 years ago
raise VariableError(
_("This action can be executed by a non-root user only"))
try:
pwd.getpwnam(value).pw_gid
9 years ago
except (TypeError, KeyError):
raise VariableError(_("User %s does not exist") % value)
def get(self):
9 years ago
if (self.Get('cl_action') == 'passwd' and
self.Get('ur_login') != 'root'):
return self.Get('ur_login')
return ""
9 years ago
class VariableClClientRelevanceSet(ReadonlyVariable):
"""
Актуальны ли сейчас выполненные шаблоны
"""
type = "bool"
def get(self):
# если происходят действия ввода или вывода из домена
9 years ago
if (self.Get('cl_action') in ("domain", "undomain") and
self.Get('cl_client_mount_set') == 'off'):
return "off"
# если изменился домен
if self.Get('cl_remote_host') != self.Get("os_remote_auth"):
return "off"
if (self.Get('cl_remote_host') and
9 years ago
not isMount(self.Get('cl_client_remote_path'))):
return "off"
return "on"
9 years ago
class VariableClClientRemotePath(Variable):
"""
Путь для монитрования //domain/remote
"""
value = "/var/calculate/remote"
9 years ago
class VariableClClientProfileName(Variable):
"""
Название удаленного профиля (CLD,CLDX,all)
"""
9 years ago
def get(self):
return ("all" if self.Get('cl_profile_all_set') == 'on'
else self.Get('os_linux_shortname'))
9 years ago
class VariableClLdapData(ldapUser, ReadonlyVariable):
"""
Внутренняя переменная, содержащая объект для доступа к данным LDAP
"""
type = "object"
def get(self):
return self
def getReplDN(self):
"""
Получить из LDAP домен на котором находится актуальный профиль
Get from LDAP last domain server
Branch has ((username,systemname,host))
"""
usersDN = self.getUsersDN()
if usersDN:
partDN = "ou=Worked,ou=Replication,ou=LDAP"
servicesDN = "ou=Services"
9 years ago
baseDN = usersDN.rpartition(servicesDN + ",")[2]
replDN = self.addDN(partDN, servicesDN, baseDN)
return replDN
return False
def searchPrevHost(self, userName, osLinuxShort):
"""Find server which user use"""
connectData = self.getBindConnectData()
if connectData:
bindDn, bindPw, host = connectData
replDN = self.getReplDN()
# find string for service replication branch
9 years ago
userAndOsName = "%s@%s" % (userName, osLinuxShort)
findAttr = "uid=%s" % userAndOsName
# connect to LDAP
if not self.ldapConnect(bindDn, bindPw, host):
return False
resSearch = self.ldapObj.ldapSearch(replDN, ldap.SCOPE_ONELEVEL,
findAttr, ["host"])
return resSearch
return False
9 years ago
def _gethostbyname(self, hostname):
try:
return gethostbyname(hostname)
9 years ago
except Exception:
return None
9 years ago
def getNameRemoteServer(self, userName, osLinuxShort, curHost):
"""
Get remote domain hostname or empty if profile is keeped on
current server
"""
searchPrevHost = self.searchPrevHost(userName, osLinuxShort)
3 years ago
if searchPrevHost and 'host' in searchPrevHost[0][0][1]:
prevHost = searchPrevHost[0][0][1]['host'][0]
else:
prevHost = None
# get ip address of previous server and current server
prevIp = self._gethostbyname(prevHost)
curIp = self._gethostbyname(curHost)
# if actual profile not found or on local
if not prevHost or curIp and prevIp == curIp:
return ""
else:
return prevHost
def isRepl(self):
"""
Is on or off replication on server
"""
connectData = self.getBindConnectData()
if connectData:
bindDn, bindPw, host = connectData
usersDN = self.getUsersDN()
partDN = "ou=Replication,ou=LDAP"
servicesDN = "ou=Services"
9 years ago
baseDN = usersDN.rpartition(servicesDN + ",")[2]
replDN = self.addDN(partDN, servicesDN, baseDN)
findAttr = "ou=Worked"
# connect to LDAP
if not self.ldapConnect(bindDn, bindPw, host):
return False
resSearch = self.ldapObj.ldapSearch(replDN, ldap.SCOPE_ONELEVEL,
findAttr,
[findAttr.partition("=")[0]])
if resSearch:
return True
return False
class VariableClReplicationHost(ReadonlyVariable):
"""
Удаленный сервер при репликации, который содержит актуальный профиль
"""
9 years ago
def get(self):
return self.Get('cl_ldap_data').getNameRemoteServer(
9 years ago
self.Get('ur_login'), self.Get('cl_client_profile_name'),
self.Get('cl_remote_host'))
9 years ago
class VariableClClientUserMountData(ReadonlyTableVariable):
"""
Таблица монтирования ресурсов
"""
source = ['cl_client_user_mount_name',
'cl_client_user_mount_resource',
'cl_client_user_mount_path',
'cl_client_user_mount_host']
9 years ago
def get(self, hr=HumanReadable.No):
home = path.split(self.Get('ur_home_path'))[0]
envFile = self.Get('cl_env_server_path')
samba_host = self.Get('sr_samba_host')
ftp_host = convertEnv().getVar("ftp", "host")
9 years ago
def generate():
9 years ago
yield (
"share", "share", path.join(self.Get('ur_home_path'), "Share"),
samba_host)
9 years ago
yield (
"unix", "unix", path.join(home, ".%s" % self.Get('ur_login'),
"profile"),
samba_host)
9 years ago
yield (
"homes", "homes", path.join(self.Get('ur_home_path'), "Home"),
samba_host)
if ftp_host:
9 years ago
yield ("ftp", "ftp", path.join(self.Get('ur_home_path'), "FTP"),
ftp_host)
else:
9 years ago
yield ("ftp", '', '', '')
if self.Get('cl_replication_host'):
9 years ago
yield ("remote_profile", "unix",
path.join(home, ".%s" % self.Get('ur_login'),
"remote_profile"),
self.Get('cl_replication_host'))
else:
9 years ago
yield ("remote_profile", 'unix', '', '')
return list(generate())
9 years ago
class VariableClClientUserMountUnixPath(ReadonlyVariable):
"""
Путь до подключенного unix ресурса данного пользователя
"""
def get(self):
return self.select('cl_client_user_mount_path',
cl_client_user_mount_name='unix', limit=1) or ""
9 years ago
class VariableClClientUserMountName(FieldValue, ReadonlyVariable):
"""
Название удаленного ресурса
"""
type = "list"
source_variable = "cl_client_user_mount_data"
column = 0
9 years ago
class VariableClClientUserMountResource(FieldValue, ReadonlyVariable):
"""
Название удаленного ресурса
"""
type = "list"
source_variable = "cl_client_user_mount_data"
column = 1
9 years ago
class VariableClClientUserMountPath(FieldValue, ReadonlyVariable):
"""
Путь подключения удаленного ресурса
"""
type = "list"
source_variable = "cl_client_user_mount_data"
column = 2
9 years ago
class VariableClClientUserMountHost(FieldValue, ReadonlyVariable):
"""
Удаленный сервер
"""
type = "list"
source_variable = "cl_client_user_mount_data"
column = 3
9 years ago
3 years ago
class SyncHelper():
"""
Вспомогательный объект для определения статуса синхронизации и времени
по конфигурационным файлам
"""
9 years ago
def getSyncStatus(self, rpath):
"""
Получить status_sync из desktop файла
"""
fileConfig = path.join(rpath, Client.configFileDesktop)
# get data from desktop config on success run get by archive
if os.path.exists(fileConfig):
objConfig = iniParser(fileConfig)
data = self.getDataInConfig("main", ["status_sync"],
9 years ago
objConfig)
if data:
9 years ago
return data.get("status_sync", "")
return ""
def getDataInConfig(self, section, listVars, objConfig):
"""
Прочитать список переменных из области конфигурационного файла
"""
varsConfig = {}
for varName in listVars:
9 years ago
varsConfig[varName] = objConfig.getVar(section, varName)
if objConfig.getError():
return False
return varsConfig
9 years ago
def convertDate(self, strdate, dateformat="%Y-%m-%d %H:%M:%S"):
"""
Convert date from string format (dateformat) to stuct or None
"""
if strdate:
try:
9 years ago
return time.strptime(strdate, dateformat)
except ValueError:
pass
return ""
def getDateObjClientConf(self, rpath):
"""
Получить время синхронизации из .calculate/desktop.env
"""
fileConfig = path.join(rpath, Client.configFileDesktop)
if os.path.exists(fileConfig):
objConfig = iniParser(fileConfig)
data = self.getDataInConfig("main", ["date", "date_logout"],
objConfig)
timeLogout = data["date_logout"]
timeConfig = data["date"]
3 years ago
dates = [x for x in [self.convertDate(timeLogout),
self.convertDate(timeConfig)] if x]
if dates:
return dates[0]
return ""
9 years ago
def checkNeedSync(self, homeDir, rpath, curTimeObj, curStatusSync,
osLinuxShort):
"""
Проверить необходимость синхронизации текущего профиля с удаленным
"""
# profile directory
9 years ago
# fileConfig = os.path.join(homeDir, Client.configFileServer)
pathProfile = os.path.join(rpath, osLinuxShort)
9 years ago
# if readFile(fileConfig).strip():
# return True
fileSoftConfigThis = os.path.join(pathProfile,
9 years ago
Client.configFileSoft)
fileSoftConfigCur = os.path.join(homeDir,
9 years ago
Client.configFileSoft)
xSessionCur = iniParser(fileSoftConfigCur).getVar('main', 'xsession')
xSessionThis = iniParser(fileSoftConfigThis).getVar('main', 'xsession')
# check profile date on current server
9 years ago
# fileConfigThis = os.path.join(pathProfile, Client.configFileDesktop)
# if iniParser(fileConfigThis).getVar('main','status_sync') == "success":
# self.setVarToConfig("main", {"status_sync":"success_mount"},
# fileConfigThis)
thisTimeObj = self.getDateObjClientConf(pathProfile)
if curStatusSync == "success_logout" and \
9 years ago
xSessionCur == xSessionThis and \
thisTimeObj and curTimeObj and \
curTimeObj >= thisTimeObj:
return False
return True
def getSyncDate(self, osLinuxShort, ps):
"""
Получить время синхронизации из ::profile/.calculate/desktop.env
"""
desktopEnvRemoteData = ps.readfile("::profile/{}/{}".format(
osLinuxShort, Client.configFileDesktop))
if desktopEnvRemoteData:
cpRemote = ConfigParser(strict=False)
cpRemote.read_string(desktopEnvRemoteData)
timeLogout = cpRemote.get("main", "date_logout", fallback=None)
timeConfig = cpRemote.get("main", "date", fallback=None)
3 years ago
dates = [x for x in [self.convertDate(timeLogout),
self.convertDate(timeConfig)] if x]
if dates:
return dates[0]
return ""
def checkNeedSyncNew(self, homeDir, rpath, curTimeObj, curStatusSync,
osLinuxShort, ps):
"""
Проверить необходимость синхронизации текущего профиля с удаленным
"""
iniEnvRemoteData = ps.readfile("::profile/{}/{}".format(
osLinuxShort, Client.configFileSoft))
fileConfigCur = os.path.join(homeDir, Client.configFileSoft)
iniEnvCurrentData = readFile(fileConfigCur)
cpCur = ConfigParser(strict=False)
cpCur.read_string(iniEnvCurrentData)
cpRemote = ConfigParser(strict=False)
cpRemote.read_string(iniEnvRemoteData)
xSessionCur = cpCur.get('main', 'xsession', fallback=None)
xSessionThis = cpRemote.get('main', 'xsession', fallback=None)
if curStatusSync == "success_logout" and \
xSessionCur == xSessionThis:
thisTimeObj = self.getSyncDate(osLinuxShort, ps)
if thisTimeObj and curTimeObj and \
curTimeObj >= thisTimeObj:
return False
return True
9 years ago
class VariableClClientSyncTime(SyncHelper, ReadonlyVariable):
"""
Текущее время синхронизации профиля
"""
9 years ago
def get(self):
return self.getDateObjClientConf(self.Get('ur_home_path'))
9 years ago
class VariableClClientPackTime(SyncHelper, ReadonlyVariable):
"""
Время комады упаковки профиля
"""
9 years ago
def get(self):
return str(float(time.time()))
9 years ago
class VariableClClientSyncStatus(SyncHelper, ReadonlyVariable):
"""
Текущий статус синхронизации профиля
"""
9 years ago
def get(self):
return self.getSyncStatus(self.Get('ur_home_path'))
9 years ago
class VariableClClientLocalSyncTime(SyncHelper, ReadonlyVariable):
"""
Текущий статус синхронизации профиля
"""
9 years ago
def get(self):
return self.getDateObjClientConf(
9 years ago
path.join(
self.Select('cl_client_user_mount_path',
9 years ago
where='cl_client_user_mount_name', eq='unix',
limit=1), self.Get('cl_client_profile_name')))
9 years ago
class VariableClClientRsyncProfileSet(ReadonlyVariable):
"""
Используется rsync через ssh для синхронизации пользовательского профиля
"""
type = "bool"
value = "off"
9 years ago
class VariableClClientSyncReplicationSet(SyncHelper, ReadonlyVariable):
"""
Нужно ли синхронизировать текущий профиль с удаленным доменом
"""
type = "bool"
host_varname = "cl_replication_host"
profile_type = "remote_profile"
def old_synchronize(self):
profilePath = self.Select('cl_client_user_mount_path',
9 years ago
where='cl_client_user_mount_name',
eq=self.profile_type, limit=1)
if self.Get('cl_action') == 'login' and not isMount(profilePath):
raise VariableError(_("Remote profile not mounted"))
9 years ago
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"
def new_synchronize(self):
user = self.Get('ur_login')
pwd = self.Get('desktop.ur_password')
remotehost = self.Get(self.host_varname)
ps = ProfileSyncer(remotehost, 2009, user, pwd)
#there was a typo before - profilePath was missing
profilePath = self.Select('cl_client_user_mount_path',
where='cl_client_user_mount_name',
eq=self.profile_type, limit=1)
if ps.check():
return "on" if self.checkNeedSyncNew(
self.Get('ur_home_path'), profilePath,
self.Get('cl_client_sync_time'),
self.Get('cl_client_sync_status'),
self.Get('cl_client_profile_name'),
ps) else "off"
return "off"
def get(self):
if not self.Get(self.host_varname):
return "off"
if self.GetBool('cl_client_rsync_profile_set'):
return self.new_synchronize()
else:
return self.old_synchronize()
class VariableClClientSyncLocalSet(VariableClClientSyncReplicationSet):
"""
Нужно ли синхронизировать текущий профиль с локальным доменом
"""
type = "bool"
host_varname = "cl_remote_host"
profile_type = "unix"
9 years ago
class VariableClClientSymlinks(ReadonlyVariable):
"""
Список симлинков в пользовательском профиле
"""
9 years ago
def get(self):
skipFiles = (self.Get('cl_sync_del_path') +
9 years ago
self.Get('cl_sync_skip_path'))
3 years ago
reSkip = re.compile("|".join((x.replace("*", ".*") for x in skipFiles))).search
return [x for x in find(self.Get('ur_home_path'), onefilesystem=True,
filetype=FindFileType.SymbolicLink)
if not reSkip(x)]
9 years ago
class VariableClClientNscdCache(Variable):
"""
Частота обновления кэша nscd при работе в домене в часах
"""
9 years ago
class VariableClCifsVer(ReadonlyVariable):
"""
Версия модуля CIFS
"""
9 years ago
def get(self):
return device.sysfs.read(device.sysfs.Path.Module, "cifs/version")
9 years ago
class VariableClCifsCache(Variable):
"""
Параметр cache= при монтировании cifs
"""
value = "loose"
class VariableClCifsMountVers(Variable):
"""
Параметр vers= для cifs
"""
value = "1.0"
class VariableClRsyncVer(ReadonlyVariable):
"""
Версия rsync
"""
9 years ago
def get(self):
data = isPkgInstalled('net-misc/rsync')
if data:
return data[0]['PVR']
return ""
class VariableClCifsutilsVer(ReadonlyVariable):
"""
Версия cifs-utils
"""
def get(self):
data = isPkgInstalled('net-fs/cifs-utils')
if data:
return data[0]['PV']
return ""
class VariableClClientIgnoreErrorsSet(Variable):
"""
Параметр, для отключения отмонтирования пользовательских ресурсов,
при ошбиках, возникших во вермя cl-client-sync-login
"""
type = "bool"
value = "on"
metavalue = "ON/OFF"
opt = ["--unmount-on-error"]
def init(self):
self.label = _("Unmount user resources on error")
self.help = _("unmount user resources on error")
class VariableClSyncMovedSet(Variable):
"""
Использовать или нет перенос файлов из домашней директории в Home/Moved при
синхронизации
"""
type = "bool"
value = "on"
class VariableSrSambaHost(Variable):
"""
Хост на котором находятся samba ресурсы
"""
def get(self):
return self.Get('cl_remote_host') or ''