parent
94526a86d9
commit
288a826ce3
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,346 @@
|
||||
#-*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2008-2012 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 sys
|
||||
import re
|
||||
from os import path
|
||||
from files import (process,getProgPath,pathJoin,listDirectory,
|
||||
checkUtils)
|
||||
from common import getpathenv
|
||||
|
||||
from calculate.lib.cl_lang import setLocalTranslate
|
||||
setLocalTranslate('cl_lib',sys.modules[__name__])
|
||||
|
||||
def getUUIDDict(revers=False):
|
||||
"""Get dict UUID -> dev"""
|
||||
blkidProcess = process("/sbin/blkid","-s","UUID","-c","/dev/null")
|
||||
if revers:
|
||||
datafunc = lambda x,y: (y,x)
|
||||
else:
|
||||
datafunc = lambda x,y: (x,y)
|
||||
DEV,UUID = 0,1
|
||||
reSplit = re.compile('^([^:]+):.*UUID="([^"]+)"',re.S)
|
||||
return dict(
|
||||
map(lambda x:datafunc("UUID=%s"%x[UUID],
|
||||
getUdevDeviceInfo(name=x[DEV]).get('DEVNAME',x[DEV])),
|
||||
map(lambda x:x.groups(),
|
||||
filter(lambda x:x,
|
||||
map(reSplit.search,
|
||||
blkidProcess)))))
|
||||
|
||||
def detectDeviceForPartition(dev):
|
||||
"""Detect parent device for partition by udev and return property"""
|
||||
prop = getUdevDeviceInfo(name=dev)
|
||||
if prop.get('DEVTYPE','') != 'partition':
|
||||
return ''
|
||||
parentpath = path.dirname(prop.get('DEVPATH',''))
|
||||
if parentpath:
|
||||
devProp = getUdevDeviceInfo(path=parentpath)
|
||||
return devProp.get('DEVNAME','')
|
||||
return None
|
||||
|
||||
def countPartitions(devname):
|
||||
"""Count partition for specified device"""
|
||||
syspath = getUdevDeviceInfo(name=devname).get('DEVPATH','')
|
||||
if not syspath:
|
||||
return 0
|
||||
deviceName = path.basename(syspath)
|
||||
if not syspath.startswith("/sys"):
|
||||
syspath = pathJoin("/sys",syspath)
|
||||
return len(filter(lambda x:x.startswith(deviceName),
|
||||
listDirectory(syspath)))
|
||||
|
||||
def getLvmGroups():
|
||||
"""Get LVM groups"""
|
||||
pvdisplayCmd = getProgPath('/sbin/pvdisplay')
|
||||
pvdata = process(pvdisplayCmd,"-C","-o", "vg_name","--noh")
|
||||
return filter(lambda x:x,pvdata.read().split())
|
||||
|
||||
def getLvmPartitions(vg_name,lv_name,cache=[]):
|
||||
"""Get lvm partitions"""
|
||||
if not cache:
|
||||
pvdisplayCmd = getProgPath('/sbin/pvdisplay')
|
||||
pvdata = process(pvdisplayCmd,"-C","-o",
|
||||
"vg_name,lv_name,pv_name","--noh")
|
||||
if pvdata.success():
|
||||
cache.extend(
|
||||
filter(lambda x:x and len(x)==3,
|
||||
map(lambda x:x.split(),
|
||||
pvdata.read().split('\n'))))
|
||||
if cache:
|
||||
res = map(lambda x:x[2],
|
||||
filter(lambda x:x[0]==vg_name and x[1]==lv_name,cache))
|
||||
if res:
|
||||
return res
|
||||
return []
|
||||
|
||||
def getPartitionDevice(syspath):
|
||||
"""Get real parent device by partition,lvm,mdraid"""
|
||||
prop = getUdevDeviceInfo(path=syspath)
|
||||
# real device
|
||||
if prop.get('ID_TYPE',"") == "disk" and \
|
||||
prop.get('DEVTYPE',"") == "disk":
|
||||
return prop.get('DEVNAME',"")
|
||||
# partition
|
||||
if prop.get('DEVTYPE') == "partition":
|
||||
return getPartitionDevice(path.dirname(syspath))
|
||||
# md raid
|
||||
if prop.get('MD_LEVEL',"").startswith("raid"):
|
||||
if not syspath.startswith('/sys'):
|
||||
syspath = pathJoin('/sys',syspath)
|
||||
syspath = pathJoin(syspath,"md")
|
||||
for rd in filter(lambda x:path.basename(x).startswith('rd'),
|
||||
listDirectory(syspath,fullPath=True)):
|
||||
rdBlockPath = path.join(rd,"block")
|
||||
if path.exists(rdBlockPath):
|
||||
return getPartitionDevice(path.realpath(rdBlockPath))
|
||||
else:
|
||||
return ""
|
||||
# lvm
|
||||
if prop.get('DM_LV_NAME',"") != "":
|
||||
parts = getLvmPartitions(prop.get('DM_VG_NAME',''),
|
||||
prop.get('DM_LV_NAME',''))
|
||||
if parts:
|
||||
propPartLvm = getUdevDeviceInfo(name=parts[0])
|
||||
if 'DEVPATH' in propPartLvm:
|
||||
return getPartitionDevice(propPartLvm['DEVPATH'])
|
||||
return ""
|
||||
|
||||
def lspci(filtername=None,shortInfo=False):
|
||||
"""Get hash of lspci, filtred by filtername. If shortInfo, then
|
||||
type,vendor and name get only first word
|
||||
|
||||
pcidata(domain,bus,slot,func)
|
||||
'type'
|
||||
'vendor'
|
||||
'name'"""
|
||||
reData = re.compile(r'(\S+)\s"([^"]+)"\s+"([^"]+)"\s+"([^"]+)"',re.S)
|
||||
if filtername:
|
||||
filterfunc = lambda x: filtername in x
|
||||
else:
|
||||
filterfunc = lambda x:x
|
||||
if shortInfo:
|
||||
sfunc = lambda x:x.partition(" ")[0]
|
||||
else:
|
||||
sfunc = lambda x:x
|
||||
lspciProg = checkUtils('/usr/sbin/lspci')
|
||||
processLsPci = process(lspciProg,"-m")
|
||||
retData = {}
|
||||
for device in map(lambda x:x.groups(),
|
||||
filter(lambda x:x,
|
||||
map(reData.search,
|
||||
filter(filterfunc,
|
||||
processLsPci)))):
|
||||
retData[device[0]] = {'type':sfunc(device[1]),\
|
||||
'vendor':sfunc(device[2]),\
|
||||
'name':sfunc(device[3])}
|
||||
return retData
|
||||
|
||||
def getUdevDeviceInfo(path="",name=""):
|
||||
"""Get device info by syspath of name"""
|
||||
udevadmCmd = getProgPath('/sbin/udevadm')
|
||||
typeQuery = "--path" if path else "--name"
|
||||
value = path if path else name
|
||||
return dict(
|
||||
filter(lambda x:x[0],
|
||||
map(lambda x:x.partition("=")[0::2],
|
||||
process(udevadmCmd,"info","--query","property",
|
||||
typeQuery,value).read().split("\n"))))
|
||||
|
||||
def convertNameToSyspath(name):
|
||||
dev = getUdevDeviceInfo(name=name).get('DEVPATH',"")
|
||||
if dev and not dev.startswith('/sys'):
|
||||
dev = pathJoin('/sys',dev)
|
||||
return dev
|
||||
|
||||
def getPartitionSize(syspath=None,name=None):
|
||||
"""Get partition size"""
|
||||
if name:
|
||||
dev = convertNameToSyspath(name)
|
||||
else:
|
||||
dev = syspath
|
||||
SECTORSIZE=512
|
||||
sizeFile = pathJoin(dev,"size")
|
||||
if path.exists(sizeFile):
|
||||
size = int(open(sizeFile,'r').read().strip())*SECTORSIZE
|
||||
suffix = (((1024**0),"",False),
|
||||
((1024**1),"K",False),
|
||||
((1024**2),"M",False),
|
||||
((1024**3),"G",True),
|
||||
((1024**4),"T",True),
|
||||
((1024**5),"P",True))
|
||||
suffix = filter(lambda x:size >x[0],suffix)
|
||||
if suffix:
|
||||
suffix = suffix[-1]
|
||||
printSize = int(size / (float(suffix[0])/10))
|
||||
printSizeTail = printSize % 10
|
||||
printSize = printSize / 10
|
||||
if suffix[2] and printSizeTail:
|
||||
return "%d.%d%s"%(printSize,printSizeTail,suffix[1])
|
||||
else:
|
||||
return "%d%s"%(printSize,suffix[1])
|
||||
return ""
|
||||
|
||||
def getDeviceType(syspath=None,name=None):
|
||||
"""Get device type (disk,partition,lvm,raid)"""
|
||||
if name:
|
||||
prop = getUdevDeviceInfo(name=name)
|
||||
syspath = prop.get('DEVPATH','')
|
||||
else:
|
||||
prop = getUdevDeviceInfo(path=syspath)
|
||||
# real device
|
||||
if prop.get('ID_CDROM',""):
|
||||
return "cdrom"
|
||||
if prop.get('ID_TYPE',"") == "disk" and \
|
||||
prop.get('DEVTYPE',"") == "disk":
|
||||
return "disk"
|
||||
# partition
|
||||
if prop.get('DEVTYPE') == "partition":
|
||||
return getDeviceType(path.dirname(syspath))+"-partition"
|
||||
# md raid
|
||||
if prop.get('MD_LEVEL',"").startswith("raid"):
|
||||
if not syspath.startswith('/sys'):
|
||||
syspath = pathJoin('/sys',syspath)
|
||||
syspath = pathJoin(syspath,"md")
|
||||
for rd in filter(lambda x:path.basename(x).startswith('rd'),
|
||||
listDirectory(syspath,fullPath=True)):
|
||||
rdBlockPath = path.join(rd,"block")
|
||||
if path.exists(rdBlockPath):
|
||||
return getDeviceType(path.realpath(rdBlockPath))+"-raid"
|
||||
else:
|
||||
return "loop"
|
||||
# lvm
|
||||
if prop.get('DM_LV_NAME',"") != "":
|
||||
parts = getLvmPartitions(prop.get('DM_VG_NAME',''),
|
||||
prop.get('DM_LV_NAME',''))
|
||||
if parts:
|
||||
propPartLvm = getUdevDeviceInfo(name=parts[0])
|
||||
if 'DEVPATH' in propPartLvm:
|
||||
return getDeviceType(propPartLvm['DEVPATH'])+"-lvm"
|
||||
return "loop"
|
||||
|
||||
def getRaidPartitions(raidpath):
|
||||
"""Get raid partitions"""
|
||||
prop = getUdevDeviceInfo(path=raidpath)
|
||||
raidParts = []
|
||||
if prop.get('MD_LEVEL',"").startswith("raid"):
|
||||
if not raidpath.startswith('/sys'):
|
||||
raidpath = pathJoin('/sys',raidpath)
|
||||
raidpath = pathJoin(raidpath,"md")
|
||||
for rd in filter(lambda x:path.basename(x).startswith('rd'),
|
||||
listDirectory(raidpath,fullPath=True)):
|
||||
rdpath = path.join(raidpath,rd,"block")
|
||||
if path.exists(rdpath):
|
||||
raidParts.append(
|
||||
getUdevDeviceInfo(path=path.realpath(rdpath)).get(
|
||||
"DEVNAME",''))
|
||||
return filter(lambda x:x,raidParts)
|
||||
|
||||
|
||||
def getPartitionType(prop):
|
||||
"""Get type of dos part table (primary,extended or logical)"""
|
||||
if prop.get('ID_PART_ENTRY_SCHEME') == 'dos':
|
||||
partId = prop.get('ID_PART_ENTRY_TYPE','')
|
||||
partNumber = prop.get('ID_PART_ENTRY_NUMBER','')
|
||||
if partId and partNumber:
|
||||
if partId == "0x5":
|
||||
return "extended"
|
||||
elif int(partNumber)>4:
|
||||
return "logical"
|
||||
else:
|
||||
return "primary"
|
||||
return prop.get('ID_PART_TABLE_TYPE','')
|
||||
|
||||
def detectBuild(pathname,dictInfo):
|
||||
"""Detect build by root passwd 'root'"""
|
||||
shadowPath = pathJoin(pathname,'/etc/shadow')
|
||||
if r"root:$1$JMvNh5xg$VnV1DyJdTcwuZ0hp5YiJG0:14349:0:::::" in \
|
||||
readFile(shadowPath):
|
||||
dictInfo['type'] = ' assemble'
|
||||
elif path.exists(pathJoin(pathname,"delta")) and \
|
||||
path.exists(pathJoin(pathname,"workspace")):
|
||||
dictInfo['type'] = " builder"
|
||||
issue = readFile(pathJoin(pathname,'etc/gentoo-release'))
|
||||
if "Server" in issue:
|
||||
if "Scratch" in issue:
|
||||
dictInfo['name'] = "CSS"
|
||||
else:
|
||||
dictInfo['name'] = "CDS"
|
||||
elif "Desktop" in issue:
|
||||
if "XFCE" in issue:
|
||||
dictInfo['name'] = "CLDX"
|
||||
elif "KDE" in issue:
|
||||
dictInfo['name'] = "CLD"
|
||||
elif "GNOME" in issue:
|
||||
dictInfo['name'] = "CLDG"
|
||||
elif "Scratch" in issue:
|
||||
dictInfo['name'] = "CLS"
|
||||
else:
|
||||
dictInfo['type'] = ''
|
||||
return dictInfo
|
||||
|
||||
def getOsProberHash(getContentFunc=None):
|
||||
"""Get partition content by os-prober"""
|
||||
os_prober = getProgPath('/usr/bin/os-prober')
|
||||
if os_prober:
|
||||
DEV,LONG,SHORT,TYPE = 0,1,2,3
|
||||
osProberList = \
|
||||
map(lambda x:[getUdevDeviceInfo(name=x[DEV]).get('DEVNAME',''),
|
||||
x[LONG],x[SHORT],x[TYPE]],
|
||||
filter(lambda x:len(x)>=4,
|
||||
map(lambda x:x.split(":"),
|
||||
process(os_prober))))
|
||||
for osRecord in osProberList:
|
||||
if "Gentoo" in osRecord[SHORT] and getContentFunc:
|
||||
osDescr = getContentFunc(osRecord[DEV],addFunc=detectBuild)
|
||||
if "name" in osDescr and "march" in osDescr and \
|
||||
"build" in osDescr and "ver" in osDescr and \
|
||||
(osDescr["ver"] != "0" or osDescr["build"]):
|
||||
if osDescr['build']:
|
||||
osDescr['build'] = "-%s"%osDescr['build']
|
||||
else:
|
||||
osDescr['build'] = "-%s"%osDescr['ver']
|
||||
osRecord[SHORT] = \
|
||||
"{name}-{march}{build}{type}".format(**osDescr)
|
||||
else:
|
||||
osRecord[SHORT] = "Gentoo"
|
||||
elif "Gentoo" in osRecord[SHORT] and "Calculate" in osRecord[LONG]:
|
||||
osRecord[SHORT] = "Calculate"
|
||||
osProberHash = \
|
||||
dict(
|
||||
map(lambda x:(x[DEV],x[SHORT]),
|
||||
osProberList))
|
||||
else:
|
||||
osProberHash = {}
|
||||
return osProberHash
|
||||
|
||||
def refreshLVM():
|
||||
"""Run command which refresh information about LVM"""
|
||||
vgscan = getProgPath('/sbin/vgscan')
|
||||
vgchange = getProgPath('/sbin/vgchange')
|
||||
lvchange = getProgPath('/sbin/lvchange')
|
||||
|
||||
if vgscan and vgchange and lvchange:
|
||||
process(vgscan).success()
|
||||
process(vgchange,'-ay','--refresh').success()
|
||||
for group in getLvmGroups():
|
||||
process(lvchange,'-ay','--refresh',group).success()
|
||||
|
||||
def refreshUdev():
|
||||
"""Run command which refresh information about device in udev"""
|
||||
udevadm = getProgPath('/sbin/udevadm')
|
||||
if udevadm:
|
||||
process(udevadm,"trigger","--subsystem-match","block").success()
|
@ -0,0 +1,101 @@
|
||||
#-*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2008-2012 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 re
|
||||
import sys
|
||||
|
||||
import sys
|
||||
import re
|
||||
from os import path
|
||||
from files import listDirectory, readFile
|
||||
|
||||
from calculate.lib.cl_lang import setLocalTranslate
|
||||
setLocalTranslate('cl_lib',sys.modules[__name__])
|
||||
|
||||
reVerSplit = re.compile(r"^(.*?)-(([^-]+?)(?:-(r\d+))?)(?:.(tbz2))?$",re.S)
|
||||
def reVerSplitToPV(x):
|
||||
"""Convert match from reVerSplit to PV hash"""
|
||||
if type(x) == str:
|
||||
x = reVerSplit.search(x)
|
||||
if x:
|
||||
match = x.groups()
|
||||
return {'PN':match[0],
|
||||
'PF':"%s-%s"%(match[0],match[1]),
|
||||
'P':"%s-%s"%(match[0],match[2]),
|
||||
'PV':match[2],
|
||||
'PR':match[3] or "r0",
|
||||
'PVR':match[1]}
|
||||
return {'PN':"",
|
||||
'PF':"",
|
||||
'P':"",
|
||||
'PV':"",
|
||||
'PR':"",
|
||||
'PVR':""}.copy()
|
||||
|
||||
def getPkgUses(fullpkg):
|
||||
"""Get USE and IUSE from package"""
|
||||
category,slash,pkg = fullpkg.partition('/')
|
||||
pkgCategory = '/var/db/pkg/{0}'.format(category)
|
||||
packages = filter(lambda x:x['PN'] == pkg,
|
||||
map(reVerSplitToPV,
|
||||
filter(lambda x:x,
|
||||
map(lambda x:reVerSplit.search(x),
|
||||
listDirectory(pkgCategory)))))
|
||||
if not packages:
|
||||
return None
|
||||
usePath = path.join(pkgCategory,packages[-1]['PF'],"USE")
|
||||
iusePath = path.join(pkgCategory,packages[-1]['PF'],"IUSE")
|
||||
iuse = readFile(iusePath).strip().split()
|
||||
use = readFile(usePath).strip().split()
|
||||
return (map(lambda x:x[1:] if x.startswith("+") else x,
|
||||
filter(lambda x:x,
|
||||
use)),
|
||||
map(lambda x:x[1:] if x.startswith("+") else x,
|
||||
filter(lambda x:x,
|
||||
iuse)))
|
||||
|
||||
def isPkgInstalled(pkg,prefix='/'):
|
||||
"""Check is package installed"""
|
||||
pkgDir = path.join(prefix,'var/db/pkg')
|
||||
if "/" in pkg:
|
||||
category,op,pkg = pkg.partition('/')
|
||||
return bool(
|
||||
filter(lambda x:x['PN'] == pkg,
|
||||
map(reVerSplitToPV,
|
||||
listDirectory(path.join(pkgDir,category)))))
|
||||
else:
|
||||
return bool(
|
||||
filter(lambda x: filter(lambda y:y['PN'] == pkg,
|
||||
map(reVerSplitToPV,
|
||||
listDirectory(x))),
|
||||
listDirectory(pkgDir,fullPath=True)))
|
||||
|
||||
def getPkgActiveUses(fullpkg):
|
||||
"""Get active uses from package"""
|
||||
res = getPkgUses(fullpkg)
|
||||
if not res:
|
||||
return None
|
||||
return list(set(res[0]) & set(res[1]))
|
||||
|
||||
def getSquashList():
|
||||
"""Get supprted squashfs compressions method"""
|
||||
wantMethod = set(["lzo","lzma","xz","gzip"])
|
||||
usesSquashFs = getPkgActiveUses("sys-fs/squashfs-tools")
|
||||
if not usesSquashFs:
|
||||
return ["gzip"]
|
||||
else:
|
||||
return map(lambda x:{"lzma":"xz"}.get(x,x),
|
||||
list(set(usesSquashFs) & wantMethod))
|
Loading…
Reference in new issue