#-*- coding: utf-8 -*- # Copyright 2008-2013 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. import os import sys from os import path from itertools import * from calculate.lib.datavars import (TableVariable,Variable,ReadonlyVariable, VariableError) import calculate.lib.cl_template as cl_template from calculate.lib.utils.files import listDirectory,process,PIPE,pathJoin from calculate.lib.cl_lang import setLocalTranslate setLocalTranslate('cl_lib3',sys.modules[__name__]) _envData = [('system', '/etc/calculate/calculate.env'), ('local', '/var/calculate/calculate.env'), ('remote', '/var/calculate/remote/calculate.env')] class VariableClEnvData(TableVariable): """ Aliases and path to ini files """ source = ["cl_env_location","cl_env_path"] class VariableClEnvLocation(ReadonlyVariable): """ Aliases to ini files (from cl_env_data) """ type = 'list' value = list(zip(*_envData)[0]) class VariableClEnvPath(Variable): """ Path to ini files (from cl_env_data) """ type = 'list' value = list(zip(*_envData)[1]) class VariableClTemplateData(TableVariable): """ Aliases to templates path """ source = ["cl_template_location","cl_template_path"] class VariableClTemplateLocation(Variable): """ Name to templates """ type = 'list' value = ["overlay","local","remote"] class VariableClTemplatePath(Variable): """ Path to information file on server """ type = 'list' value = ["/var/lib/layman/calculate/profiles/templates", "/var/calculate/templates", "/var/calculate/remote/templates"] class VariableClEnvServerPath(ReadonlyVariable): """ Path to server environment """ value = '/var/calculate/remote/server.env' class VariableClTemplateCltPath(ReadonlyVariable): """ Paths to clt-template files """ type = 'list' def get(self): """ Clt templates path is /etc and CONFIG_PROTECT """ chroot = self.Get('cl_chroot_path') if "CONFIG_PROTECT" in os.environ: protectPaths = ["/etc"] + filter(lambda x: x.strip(), os.environ["CONFIG_PROTECT"].split(" ")) else: protectPaths = ["/etc", "/usr/share/X11/xkb", "var/lib/hsqldb", "/usr/share/config"] return filter(path.exists, map(lambda x:pathJoin(chroot,x), protectPaths)) class VariableClRootPath(Variable): """ Path to directory relative which perform joining templates to system files (sandbox) """ value = '/' class VariableClRootPathNext(Variable): """ Path to directory relative which perform joining templates to system files (sandbox). This set for configure packages specified throug merge= """ def get(self): return self.Get('cl_root_path') class VariableClChrootPath(ReadonlyVariable): """ Path to directory which contain other system """ value = '/' class VariableClPassStep(Variable): """ Pass for templates join 1,2,3,4,5 and etc """ class VariableClPassFile(Variable): """ Template file performed at now """ class VariableClMergeSet(ReadonlyVariable): """ Force by package template appling """ type = "bool" value = "off" class VariableClMergePkg(ReadonlyVariable): """ This variable work with template function belong(package_name) if the variable is defined then will use only template, which has package_name in belong equal value of this variable or hasn't belong function (package_name == value of cl_belong_pkg) """ type = "list" def get(self): return self.Get('cl_belong_pkg') class VariableClMergePkgNew(ReadonlyVariable): """ New variable value for cl_merge_pkg """ type = "list" class VariableClMergePkgPass(ReadonlyVariable): """ Performed packages """ type = "list" class VariableClBelongPkg(ReadonlyVariable): """ Depricated by cl_merge_pkg """ type = "list" class VariableClAction(ReadonlyVariable): """ Program action Example: install, uninstall, merge, domain, undomain, system, desktop """ class VariableClPassState(ReadonlyVariable): """ Program state specifies addition to cl_pass_action for needing """ class VariableClMerges(Variable): """ Programs have templates setup """ type = 'list' def get(self): return [] def set(self,value): return [] class VariableClAutoupdateSet(Variable): """ (on or off) autoupdate config from install program """ type = 'bool' def get(self): if self.Get('cl_dispatch_conf') == 'usenew': return "on" else: return "off" class VariableClHumanEditSet(Variable): """ Параметр для отметки "ручной правки" """ type = "bool" opt = ["--human-edit"] value = "off" def init(self): self.help = _("mark as human modification") self.label = _("Mark as human modification") class VariableClProtectUseSet(ReadonlyVariable): """ Использовать portage интеграцию с конфигурационными файлами """ type = "bool" def get(self): return "on" if self.Get('cl_human_edit_set') == 'off' else "off" class VariableClDispatchConf(Variable): """ """ type = "choice" opt = ["--conf"] value = "dispatch" syntax = "--{choice}-conf" metavalue = "METHOD" def init(self): self.help = "'usenew' - " +_("use the new config files") +\ ",\n'skip' - " + _("skip the update of config files") +\ ",\n'dispatch' - " + _("manually update config files") self.label = _("Method for updating config files") def choice(self): return [("usenew",_("Use the new config files")), ("skip",_("Skip the update of config files")), ("dispatch",_("Manually update config files"))] class VariableClWsdl(Variable): """ Packages with wsdl """ type = "list-choice" def choice(self): return self.Get('cl_wsdl_available') class VariableClWsdlAvailable(ReadonlyVariable): """ Packages which has wsdl interfaces """ type = "list" def get(self): sitePackages = map(lambda x:path.join(x,"calculate"), filter(lambda x:x.endswith('site-packages') and \ x.startswith('/usr/lib'),sys.path)) retList = [] for module,modDir in chain(*map(lambda x:map(lambda y:(path.basename(y),y), listDirectory(x,True,True)),sitePackages)): if path.exists(path.join(modDir,"wsdl_%s.py"%module)): if not "calculate-%s"%module in retList: retList.append("calculate-%s"%module) return retList class VariableClConfigProtectMask(ReadonlyVariable): """ Value of CONFIG_PROTECT after source /etc/profile, and /etc append """ type = "list" def get(self): displayEnv = process('/bin/bash',"-c","source /etc/profile;env", stdout=PIPE) for line in displayEnv: if line.startswith("CONFIG_PROTECT_MASK="): configProtectMask=line.rstrip().partition('=')[2].split() break else: configProtectMask = [] return configProtectMask class VariableClConfigProtect(ReadonlyVariable): """ Value of CONFIG_PROTECT after source /etc/profile, and /etc append """ type = "list" def get(self): displayEnv = process('/bin/bash',"-c","source /etc/profile;env", stdout=PIPE) for line in displayEnv: if line.startswith("CONFIG_PROTECT="): configProtect=line.rstrip().partition('=')[2].split() break else: configProtect = [] configProtect.append('/etc') return configProtect class VariableClVerboseSet(Variable): """ Verbose output variable """ type = "bool" opt = ["-v", "--verbose"] value = "off" def init(self): self.help = _("verbose output") self.label = _("Verbose output") class VariableClEbuildPhase(ReadonlyVariable): """ Current ebuild phase """ def get(self): return os.environ.get("EBUILD_PHASE","") class VariableClEmergeInfo(ReadonlyVariable): """ Emerge --info cache """ type = "list" def get(self): return filter(lambda x:x.startswith('PORTDIR_OVERLAY=') or \ x.startswith('EMERGE') or \ x.startswith('PORTDIR='), process("/usr/bin/emerge","--ask=n","--info", envdict=os.environ).read().split('\n')) class VariableClPortdirOverlay(ReadonlyVariable): """ Overlays path """ type = "list" def get(self): emergeInfo = self.Get('cl_emerge_info') for line in filter(lambda x:x.startswith("PORTDIR_OVERLAY="), emergeInfo): return filter(None, line.partition("=")[2].strip('\n"\'').split(' ')) return [] class VariableClEmergeDefaultOpts(ReadonlyVariable): """ EMERGE_DEFAULT_OPTS """ type = "list" def get(self): emergeInfo = self.Get('cl_emerge_info') for line in filter(lambda x:x.startswith("EMERGE_DEFAULT_OPTS="), emergeInfo): return filter(None, line.partition("=")[2].strip('\n"\'').split(' ')) return [] class VariableClTemplatesLocate(Variable): """ Выбранные типы хранилищ шаблонов """ type = "choice-list" #value = ['overlay','local','remote','clt'] element = "selecttable" opt = ["-T","--templates"] metavalue = "TEMPLATES" untrusted = True descriptionMap = {'overlay': _('Overlay templates'), 'local': _('Local templates'), 'distro': _('Distribution templates'), 'remote': _('Remote templates'), 'clt': _('clt templates')} def init(self): self.label = _("Templates location") self.help = _("select location for templates %s") \ %",".join(self.get()) def get(self): vals = \ self.Get('cl_template_location')[:len(self.Get('cl_template_path'))] if self.Get('cl_action') == 'desktop': return vals else: return vals + ['clt'] def choice(self): return map(lambda x:(x,self.descriptionMap.get(x,x)), self.get()) class VariableClTemplatePathUse(ReadonlyVariable): """ Пути до шаблонов, используемых в настройке системы или профиля пользователя """ type = 'list' def get(self): return self.Select('cl_template_path',where='cl_template_location', _in=self.Get('cl_templates_locate')) class VariableClTemplateCltSet(ReadonlyVariable): """ Использовать clt шаблоны для настройки системы """ def get(self): return "on" if "clt" in self.Get('cl_templates_locate') else "off" class VariableClEnvDebugSet(Variable): """ Переменная для включения отладки """ type = "bool" value = "on" class VariableClMakeProfile(Variable): """ Путь до актуального make.profile """ systemRoot = "/" def get_work_link(self, *links): for link in links: if path.exists(link): return link def get(self): files = ["etc/portage/make.profile", "etc/make.profile"] val = self.get_work_link( *[path.join(self.systemRoot, x) for x in files]) if not val: raise VariableError( _("Failed to detect the system profile.") + " " + _("Select the profile with command {cmd}").format( cmd="cl-update-profile")) return val