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.

628 lines
22 KiB

#-*- coding: utf-8 -*-
# Copyright 2008-2010 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 cl_utils import getpathenv, runOsCommand, typeFile,process
import re
from os import path, R_OK
try:
from cl_ldap import ldapUser
except ImportError:
ldapUser = None
from operator import itemgetter
class clLocale:
lang = {
#Belarussian
'be_BY' : {
'locale':'be_BY.UTF-8',
'keymap':'by',
'dumpkeys_charset': 'koi8-u',
'consolefont':'Cyr_a8x16',
'xkblayout':'us,by',
'language':'be',
},
#Bulgarian
'bg_BG' : {
'locale':'bg_BG.UTF-8',
'keymap':'bg_bds-utf8',
'dumpkeys_charset': '',
'consolefont':'ter-m14n',
'xkblayout':'us,bg',
'language':'bg',
},
#Belgian
'fr_BE' : {
'locale':'fr_BE.UTF-8',
'keymap':'be-latin1',
'dumpkeys_charset':'',
'consolefont':'lat9w-16',
'xkblayout':'us,be',
'language':'fr',
},
#Brazilian Portuguese
'pt_BR' : {
'locale':'pt_BR.UTF-8',
'keymap':'br-abnt2',
'dumpkeys_charset':'',
'consolefont':'lat9w-16',
'xkblayout':'pt,us',
'language':'pt_BR',
},
#Canadian French
'fr_CA' : {
'locale':'fr_CA.UTF-8',
'keymap':'cf',
'dumpkeys_charset':'',
'consolefont':'default8x16',
'xkblayout':'us,ca_enhanced',
'language':'fr',
},
#Danish
'da_DK' : {
'locale':'da_DK.UTF-8',
'keymap':'dk-latin1',
'dumpkeys_charset':'',
'consolefont':'lat0-16',
'xkblayout':'us,dk',
'language':'da',
},
#French
'fr_FR' : {
'locale':'fr_FR.UTF-8',
'keymap':'fr-latin9',
'dumpkeys_charset':'',
'consolefont':'lat0-16',
'xkblayout':'fr,us',
'language':'fr',
},
#German
'de_DE' : {
'locale':'de_DE.UTF-8',
'keymap':'de-latin1',
'dumpkeys_charset':'',
'consolefont':'lat9w-16',
'xkblayout':'de,us',
'language':'de',
},
#Icelandic
'is_IS' : {
'locale':'is_IS.UTF-8',
'keymap':'is-latin1',
'dumpkeys_charset':'',
'consolefont':'cp850-8x16',
'xkblayout':'us,is',
'language':'is',
},
#Italian
'it_IT' : {
'locale':'it_IT.UTF-8',
'keymap':'it',
'dumpkeys_charset':'',
'consolefont':'default8x16',
'xkblayout':'us,it',
'language':'it',
},
#Norwegian
'nn_NO' : {
'locale':'nn_NO.UTF-8',
'keymap':'no-latin1',
'dumpkeys_charset':'',
'consolefont':'lat9w-16',
'xkblayout':'us,no',
'language':'nn',
},
#Polish
'pl_PL' : {
'locale':'pl_PL.UTF-8',
'keymap':'pl',
'dumpkeys_charset':'',
'consolefont':'lat2-16',
'xkblayout':'us,pl',
'language':'pl',
},
#Portuguese
'pt_PT' : {
'locale':'pl_PL.UTF-8@euro',
'keymap':'pt-latin9',
'dumpkeys_charset':'',
'consolefont':'lat0-16',
'xkblayout':'pt,us',
'language':'pt',
},
#Romanian
'ro_RO' : {
'locale':'ro_RO.UTF-8',
'keymap':'ro_win',
'dumpkeys_charset':'',
'consolefont':'lat2-16',
'xkblayout':'ro,us',
'language':'ro',
},
#Russian
'ru_RU' : {
'locale':'ru_RU.UTF-8',
'keymap':'-u ruwin_cplk-UTF-8',
'dumpkeys_charset':'',
'consolefont':'ter-k14n',
'xkblayout':'us,ru(winkeys)',
'language':'ru',
},
#Spanish
'es_ES' : {
'locale':'es_ES.UTF-8',
'keymap':'es euro2',
'dumpkeys_charset':'',
'consolefont':'lat0-16',
'xkblayout':'es,us',
'language':'es',
},
#Swedish
'sv_SE' : {
'locale':'sv_SE.UTF-8',
'keymap':'sv-latin1',
'dumpkeys_charset':'',
'consolefont':'lat0-16',
'xkblayout':'us,se',
'language':'sv',
},
#Ukrainian
'uk_UA' : {
'locale':'uk_UA.UTF-8',
'keymap':'ua-utf',
'dumpkeys_charset':'koi8-u',
'consolefont':'ter-v14n',
'xkblayout':'us,ua(winkeys)',
'language':'uk',
},
#United Kingdom/British
'en_GB' : {
'locale':'en_GB.UTF-8',
'keymap':'uk',
'dumpkeys_charset':'',
'consolefont':'LatArCyrHeb-16',
'xkblayout':'us,gb',
'language':'en',
},
#United State/English
'en_US' : {
'locale':'en_US.UTF-8',
'keymap':'us',
'dumpkeys_charset':'',
'consolefont':'LatArCyrHeb-16',
'xkblayout':'us',
'language':'en',
}
}
def getLangs(self):
return self.lang.keys()
def getLanguages(self):
return map(lambda x:self.lang[x]['language'],
self.lang.keys())
def isLangExists(self,lang):
return lang in self.lang.keys()
def isValueInFieldExists(self,field,value):
return value in map(lambda x:self.lang[x][field],self.lang.keys())
def getFields(self,field):
return [ l[1][field] for l in self.lang.items() ]
def getFieldByLang(self,field,lang):
return self.lang.get(lang, self.lang['en_US'])[field]
def getFieldByKeymap(self,field,keymap):
return self.lang.get(self.getLangByField('keymap',keymap),
self.lang['en_US'])[field]
def getLangByField(self,field,value):
langs = [lang[0] for lang in self.lang.items()
if lang[1][field] == value ]
if not langs:
return 'en_US'
else:
return langs[0]
class varsShare:
"""Share methods and attributs for fill vars methods"""
dictNetworkManagers = {"openrc":"sys-apps/openrc",
"networkmanager":"net-misc/networkmanager"}
dictLinuxName = {"CLD":"Calculate Linux Desktop",
"CLDX":"Calculate Linux Desktop",
"CLDG":"Calculate Linux Desktop",
"CDS":"Calculate Directory Server",
"CLS":"Calculate Linux Scratch",
"CSS":"Calculate Scratch Server",
"CMC":"Calculate Media Center",
"Gentoo":"Gentoo"}
dictLinuxSubName = {"CLD":"KDE", "CLDX":"XFCE", "CLDG":"GNOME"}
dictNameSystem = {'CDS':'server',
'CLD':'desktop',
'CLDG':'desktop',
'CLDX':'desktop',
'CLS':'desktop',
'CMC':'desktop',
'CSS':'server'}
# data object from LDAP
_ldapUserObject = False
# user data from LDAP
_ldapUserData = {}
reFindVer = re.compile(
"(?<=version )(\d+\.?\d*\.?\d*\.?\d*)([^\d* ])*(\d*)")
def getFilesByType(self,pathname,descr):
"""Get files from "pathname" has "descr" in descriptions"""
filelist = map(lambda x:path.join(pathname,x),os.listdir(pathname))
ftype = typeFile(magic=0x4).getMType
filesWithType = map(lambda x:(x,ftype(x)), filelist)
return filter(lambda x:descr in x[1],filesWithType)
def getInitrd(self,arch,shortname,chroot,kernel,suffix="",notsuffix=""):
"""Get initrd for kernel"""
reInitrdVer = re.compile("(initrd|initramfs)-(.+?)(-install)?$",re.S)
def initrd_version_by_name(filename):
resInitrdVer = reInitrdVer.search(filename)
if resInitrdVer:
return resInitrdVer.groups()[1]
return ""
ftype = typeFile(magic=0x4).getMType
kernelfile = path.join(chroot,'boot',kernel)
typeKernelFile = ftype(kernelfile)
if typeKernelFile == None:
return ""
resKernelVer = self.reFindVer.search(ftype(kernelfile))
if resKernelVer:
kernelVersion = "%s-%s-%s"% \
(resKernelVer.group().replace('-calculate',''),
arch, shortname)
origKernelVer = resKernelVer.group()
bootdir = path.join(chroot,'boot')
initramfsFiles = self.getFilesByType(bootdir,"ASCII cpio archive")
initramfsWithVer = \
filter(lambda x: (kernelVersion in x[1] or
origKernelVer in x[1]) and \
x[0].endswith(suffix) and \
(not notsuffix or not x[0].endswith(notsuffix)),
map(lambda x:(x[0],initrd_version_by_name(x[0])),
initramfsFiles))
if initramfsWithVer:
return path.split(min(initramfsWithVer,
key=itemgetter(0))[0])[-1]
return ""
def getDirList(self,pathname):
"""Get directory list by pathname"""
dirs = []
if path.exists(pathname):
dirs = filter(lambda x: path.isdir(path.join(pathname,x)),
os.listdir(pathname))
return dirs
def getUserInfo(self):
"""Get information about user from LDAP in dict format"""
userName = self.Get('ur_login')
if userName:
if userName in self._ldapUserData:
return self._ldapUserData[userName]
elif not ldapUser is None:
ldapObj = self.getLdapUserObject()
if ldapObj:
userInfo = ldapObj.getUserLdapInfo(userName)
if userInfo:
self._ldapUserData[userName] = userInfo
return userInfo
return {}
def getLdapUserObject(self):
"""Get data obejct from LDAP"""
if not self._ldapUserObject:
self._ldapUserObject = ldapUser()
return self._ldapUserObject
def _runos(self, cmd, env={}):
"""Return result of os command perform"""
if not env:
env.update(os.environ.items() + [("PATH",getpathenv())] +\
env.items())
retCode, programOut = runOsCommand(cmd, None, env_dict=env)
if not retCode:
return programOut
return False
def get_composite_from_xorgconf(self,chroot="/"):
"""Get composite value from xorg.conf"""
xorgConfig = path.join(chroot,
"etc/X11/xorg.conf")
try:
confLines = open(xorgConfig,"r").readlines()
except:
return None
flagStartExtensions = False
lineCompositeTmp = ""
lineComposite = ""
for line in confLines:
line = line.strip()
if flagStartExtensions:
if line.startswith('EndSection'):
lineComposite = lineCompositeTmp
break
elif line.startswith('Section'):
break
if line.startswith('Option') and '"Composite"' in line:
lineCompositeTmp = line
else:
if '"Extensions"' in line and line.startswith('Section'):
flagStartExtensions = True
if lineComposite:
listOpt = filter(lambda x: x.strip(), lineComposite.split('"'))
if len(listOpt) == 3:
ret = listOpt[2].lower()
if ret in ("on","true","yes","1"):
return "on"
elif ret in ("off","false","no","0"):
return "off"
return None
def getValueFromCmdLine(self,option,num):
"""Get value of parameter from boot params
Parameters:
option param name
num number part of value parameter (, split)
"""
cmdLine = "/proc/cmdline"
calculateParam = "calculate"
names = ("lang","keymap","timezone",
"resolution","video","composite","domain","domain_pw")
# try get timezone from kernel calculate param
try:
if type(num) == str and not num.isdigit():
name = num
num = names.index(name)
else:
name = names[int(num)]
for param in open(cmdLine,"r").read().split(" "):
parname,op,value = param.partition("=")
if parname == calculateParam and op == "=":
# new format
if ":" in value:
params = dict(
map(lambda x:x.partition(':')[0::2],
filter(lambda x:x,
value.split(','))))
return params.get(name,"").strip()
# old format
else:
values = value.split(",")
if len(values) > num and values[num].strip():
return values[num].strip()
except (IOError,ValueError,IndexError),e:
return ""
def getValueFromConfig(self,config,name):
"""Get value of parameter from bash type file
Parameters:
config config file name
name param name
"""
reMatch = re.compile("^%s\s*=\s*\"?(.*?)(\"\s*)?$"%name, re.I)
try:
if path.exists(config):
for line in open(config,"r").readlines():
match = reMatch.match(line)
if match:
return match.groups()[0].strip()
except:
pass
return False
def getX11Resolution(self):
"""Return current screen resolution (width, height), X must be ran"""
lines=self._runos("xdpyinfo")
if not lines:
return ""
reRes = re.compile("dimensions:\s+(\d+)x(\d+)\s+pixels")
searchRes=False
for line in lines:
searchRes = reRes.search(line)
if searchRes:
break
if searchRes:
return (searchRes.group(1), searchRes.group(2))
else:
return ""
def getShortnameByMakeprofile(self,systemroot):
"""Get shortname by symlink of make.profile"""
makeprofile = path.join(systemroot,'etc/make.profile')
if path.exists(makeprofile):
link = os.readlink(makeprofile)
reMakeProfileLink = re.compile('/calculate/(desktop|server)/(%s)/'%
"|".join(self.dictLinuxName.keys()),re.S)
shortnameSearch = reMakeProfileLink.search(link)
if shortnameSearch:
return shortnameSearch.groups()[1]
return None
def getShortnameByIni(self,systemroot):
"""Get shortname by calculate.ini file"""
inifile = path.join(systemroot,'etc/calculate/calculate.ini')
if path.exists(inifile):
FD = open(inifile)
data = FD.readlines()
FD.close()
shortNameList = filter(lambda y:y,
map(lambda x:\
len(x.split("="))==2 and\
x.split("=")[0]=="calculate" and\
x.split("=")[1].strip(), data))
if shortNameList:
return shortNameList[0]
def detectOtherShortname(self,systemroot):
"""Detect other system. Now only Gentoo."""
gentooFile = path.join(systemroot,"etc/gentoo-release")
if path.exists(gentooFile):
return "Gentoo"
return None
def getVersionFromMetapackage(self,systemroot,shortname):
"""Get version from meta package"""
pkgInfoDir = path.join(systemroot,'var/db/pkg/app-misc/')
if not os.access(pkgInfoDir,os.R_OK):
return None
metaPkgs = sorted(filter(lambda x:"calculate-meta" in x or \
"%s-meta"%shortname.lower() in x,
os.listdir(pkgInfoDir)))
if metaPkgs:
reFindVer = re.compile("(?<=\-)\d+\.?\d*\.?\d*")
findVer = reFindVer.search(metaPkgs[0])
if findVer:
return findVer.group()
return None
def getVersionFromCalculateIni(self,systemroot):
"""Get version from calculate ini"""
pathname = path.join(systemroot,
'etc/calculate/calculate.ini')
if path.exists(pathname):
FD = open(pathname)
data = FD.readlines()
FD.close()
verList = filter(lambda y:y,
map(lambda x:\
len(x.split("="))==2 and\
x.split("=")[0]=="linuxver" and\
x.split("=")[1].strip(), data))
if verList:
reVer=re.compile("^(\d+\.)*\d$",re.S)
reRes = filter(reVer.search,verList)
if reRes:
return reRes[0]
def selectVar(self,selField,where="",eq=""):
"""Select value from matrix variables
Example:
selectVar("os_disk_dev",where="os_disk_mount",eq="/")"""
res = filter(lambda x:x[1] == eq,
zip(self.Get(selField),
self.Get(where))) or [("","")]
return res[0][0]
def getVersionFromGentooFiles(self,systemroot):
"""Get version from gentoo files"""
gentooFile = path.join(systemroot,"etc/gentoo-release")
systemVersion = ""
flagGentoo = False
reVer=re.compile("^(\d+\.)*\d$",re.S)
if path.exists(gentooFile):
gentooLink = path.join(systemroot,"etc/make.profile")
if path.islink(gentooLink):
vers = filter(reVer.search,
os.readlink(gentooLink).split('/'))
if vers:
return vers[-1]
def getVersionFromUname(self):
"""Get version from uname"""
textLines = self._runos("uname -r")
reVer=re.compile("^(\d+\.)*\d",re.S)
kernelVersion = ""
if textLines:
kernelVersion = textLines[0]
if kernelVersion:
reRes = reVer.search(kernelVersion)
if reRes:
return reRes.group()
def isChroot(self,pid):
"""Detect chroot mode by different mountinfo"""
if not os.access('/proc/self/mountinfo',R_OK) or \
not os.access('/proc/1/mountinfo',R_OK):
return False
return open('/proc/1/mountinfo','r').read() != \
open('/proc/self/mountinfo','r').read()
def getProgPath(self,progname):
"""Get full path of program or False"""
baseprogname = os.path.basename(progname)
env = {"LANG":"C"}
env.update(os.environ.items() + [("PATH",getpathenv())] +\
env.items())
res = self._runos("which %s"%progname,env=env)
if res:
return res[0].strip()
elif os.path.isabs(progname) and os.path.exists(progname):
return progname
else:
return False
def getVideoByDefault(self,drivers_list):
"""Get video by default, or wrong specified"""
workedModules = map(lambda x:x[0],
filter(lambda x:x[1].isdigit() and int(x[1])>0,
map(lambda x:x.split()[:3:2],
open('/proc/modules','r'))))
if "nouveau" in workedModules:
defaultNvidia = "nouveau"
elif "nvidia" in drivers_list:
defaultNvidia = "nvidia"
else:
defaultNvidia = "nv"
if "radeon" in workedModules:
defaultAti = "radeon"
elif "fglrx" in drivers_list:
defaultAti = "fglrx"
else:
defaultAti = "radeon"
defaultDriver = {
'nvidia':defaultNvidia,
'ati':defaultAti,
'intel':'intel',
'via':'via',
'vmware':'vmware'}
hr_video = self.Get('hr_video')
if hr_video in defaultDriver and \
defaultDriver[hr_video] in drivers_list:
return defaultDriver[hr_video]
else:
return "other"
def getKernelUid(self,device):
"""Get Kernel UID by UUID of device"""
blkidProcess = process('/sbin/blkid','-c','/dev/null','-s','UUID',
'-o','value',device)
res = blkidProcess.read().strip()
if res:
return res[:8]
else:
return "no_uid"