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-2.2-assemble/pym/cl_fill_assemble.py

539 lines
21 KiB

#-*- coding: utf-8 -*-
# Copyright 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
import re
import cl_overriding
import operator
from cl_vars_share import varsShare
from os import path
from cl_distr import DistributiveRepository
from cl_template import iniParser
from cl_vars import Data as libData
from cl_utils import (_toUNICODE,isMount,pathJoin,listDirectory,readFile,
readLinesFile,getProgPath,getUdevDeviceInfo)
from datetime import datetime
from os import readlink,access,R_OK
from cl_datavars import glob_attr
from cl_assemble import cl_assemble
from cl_lang import lang
tr = lang()
tr.setLocalDomain('cl_builder')
tr.setLanguage(sys.modules[__name__])
class fillVars(object, glob_attr):
def get_ac_assemble_prepare(self):
"""Need perform templates for assemble:prepare"""
if not self.Get('cl_action') in ('setup','make','break'):
return "up"
else:
return ""
def get_ac_assemble_setup(self):
"""Need perform templates for assemble:prepare"""
if not self.Get('cl_action') in ('configure','break','make'):
return "up"
else:
return ""
def get_os_assemble_linux_shortname(self):
"""Get short system name"""
if not self.Get('cl_action') in ('configure','setup'):
fromEnv = self._getFromEnv('os_assemble_linux_shortname')
if fromEnv:
return fromEnv
reShortname = re.compile("/(%s)/"%
"|".join(varsShare.dictNameSystem.keys()))
res = reShortname.search(self.Get('os_assemble_system_profile'))
if res:
return res.groups()[0]
return "Gentoo"
def get_os_assemble_linux_name(self):
"""Get full system name"""
linuxShortName = self.Get("os_assemble_linux_shortname")
return self.dictLinuxName.get(linuxShortName,"Linux")
def get_os_assemble_linux_subname(self):
"""Get posfix name of system"""
linuxShortName = self.Get("os_assemble_linux_shortname")
return self.dictLinuxSubName.get(linuxShortName,"")
def _getFromEnv(self,var):
"""Get variable from env"""
section = self.Get('os_assemble_system_profile').rpartition(
'/profiles/')[2]
envFile = '/etc/calculate/assemble.env'
envData = iniParser(envFile)
res = envData.getVar(section,var)
if res != False:
res = _toUNICODE(res).encode('utf-8')
return res
def get_os_assemble_linux_ver(self):
"""Get system version"""
fromEnv = self._getFromEnv('os_assemble_linux_ver')
if fromEnv:
return fromEnv
return ""
def get_os_assemble_arch_machine(self):
"""Marching architecture for assembling"""
if not self.Get('cl_action') in ('configure','setup'):
fromEnv = self._getFromEnv('os_assemble_arch_machine')
if fromEnv:
return fromEnv
return self.Get('os_arch_machine')
def get_cl_assemble_image_path(self):
if self.Get('cl_action') in ('configure','setup'):
paths = ['/var/calculate/remote/linux',
'/var/calculate/linux',
'/usr/calculate/share/linux',
'/var/calculate/remote/stages/',
'/usr/calculate/share/stages/']
if self.Get('os_assemble_system_profile'):
paths.insert(0,path.join("/var/calculate/remote/assemble",
self.Get('os_assemble_system_profile').rpartition(
'/profiles/')[2].replace('/','-'),
"linux"))
return paths
return []
def get_os_assemble_linux_system(self):
"""Get assemble linux system (server or desktop)"""
profile = self.Get('os_assemble_system_profile')
if '/server/' in profile:
return "server"
else:
return "desktop"
def getImage(self,imagePath,archMachine,
shortName,linuxVer=None):
"""Get image by parameters"""
distRep = DistributiveRepository(self.Get('cl_assemble_image_path'))
shortname = self.Get('cl_assemble_source').lower()
if shortname == "stage":
hardened = None \
if "hardened" in self.Get('os_assemble_profile') \
else False
return distRep.getBestStage(march=archMachine,hardened=hardened)
else:
return distRep.getBestDistributive(march=archMachine,
shortname=shortname,
discardType=[],
version=linuxVer)
def get_cl_assemble_image(self):
"""Get image file from distributive repository"""
fromEnv = self._getFromEnv('cl_assemble_image')
if fromEnv:
return fromEnv
linuxver=self.Get('os_assemble_linux_ver')
if self.Get('cl_action') in ('configure','setup'):
return self.getImage(self.Get('cl_assemble_image_path'),
self.Get('os_assemble_arch_machine'),
self.Get('os_assemble_linux_shortname')) or \
""
else:
return ""
def get_cl_assemble_image_type(self):
"""Get type of image"""
image = self.Get('cl_assemble_image')
if image:
if image.endswith('.iso'):
return "iso"
elif re.match(
r'^.*/stage\d-[^-]+(-hardened)?-\d+.tar.(bz2|gz|lzma|7z)$',
image):
return "stage"
return ""
def get_cl_assemble_meta(self):
"""Meta package for world building"""
return "world"
def get_cl_assemble_snapshot_portage(self):
"""Find latest snapshot"""
snapshotPaths = self.Get('cl_assemble_snapshot_path')
return DistributiveRepository()._findLatestFile(snapshotPaths,
re.compile(r'^.*/portage-(\d+)\.tar\.(bz2|gz|lzma|7z)$',
re.S),
lambda x:x.groups()[0])
def get_os_assemble_root_dev(self):
"""Get device for assembling"""
fromEnv = self._getFromEnv('os_assemble_root_dev')
if fromEnv:
return fromEnv
return ""
def get_cl_assemble_path(self):
fromEnv = self._getFromEnv('cl_assemble_path')
if fromEnv:
return fromEnv
rootDev = self.Get('os_assemble_root_dev')
if rootDev:
mp = isMount(rootDev)
if mp:
return mp
pathBuilder = path.join("/mnt",
self.Get('os_assemble_system_profile').rpartition(
'/profiles/')[2].replace("/","-"))
if path.exists(pathBuilder):
try:
os.rmdir(pathBuilder)
except:
pass
return pathBuilder
def get_os_disk_dev(self):
reSdaPart = re.compile("^/dev/sd([a-z])(\d+)$")
devices = map(lambda x:path.basename(x),
self.Get('os_device_hash').keys())
disks = reduce( lambda x,y: x +
map( lambda x: "/dev/%s"%x,
filter(lambda x: y in x,
listDirectory('/sys/block/%s'%y))),
devices, [] )
return disks
def get_os_assemble_makeopts(self):
"""Get makeopts for make.conf file"""
cpunum = self.Get('hr_cpu_num')
if cpunum == 1:
return "-j1"
else:
return "-j%d"%(cpunum+1)
def get_os_assemble_gentoo_arch(self):
"""Get gentoo arch by arch machine"""
convert = {'x86_64':'amd64',
'ia64':'amd64',
'mips64':'mips'}
arch = self.Get('os_assemble_arch_machine')
if re.match(r'^i.86$',arch):
return "x86"
if re.match(r'^arm.*$',arch):
return "arm"
return convert.get(arch,arch)
def get_os_assemble_system_profile(self):
"""Detect update or stable profile"""
makeProfileFile = '/etc/make.profile'
if self.Get('cl_action') in ('configure','setup') \
and path.exists(makeProfileFile):
return os.readlink(makeProfileFile)
distros = self.Get('cl_assemble_distro')
if len(distros) == 1:
newprofile = distros[0]
if newprofile.startswith("calculate"):
return path.join("../var/lib/layman/calculate/profiles",
newprofile)
else:
return path.join("../usr/portage/profiles",
newprofile)
return ""
def get_cl_assemble_step_system(self):
"""action: emerge -e system"""
fromEnv = self._getFromEnv('cl_assemble_step_system')
if fromEnv:
return fromEnv
return ""
def get_cl_assemble_make(self):
"""action: current action"""
fromEnv = self._getFromEnv('cl_assemble_make')
if fromEnv:
return fromEnv
return ""
def get_cl_assemble_step_world(self):
"""action full update"""
fromEnv = self._getFromEnv('cl_assemble_step_world')
if fromEnv:
return fromEnv
return ""
def get_cl_assemble_distro(self):
"""Current assembling systems"""
envFile = '/etc/calculate/assemble.env'
envData = iniParser(envFile)
return filter(lambda x:envData.getVar(x,
'os_assemble_root_dev'),
map(lambda x:_toUNICODE(x).encode('utf-8').rpartition(
'/profiles/')[2],
envData.getAllSectionNames()))
def get_cl_assemble_dev(self):
"""Used devices for system assembling"""
envFile = '/etc/calculate/assemble.env'
envData = iniParser(envFile)
return map(lambda x:_toUNICODE(envData.getVar(x,
'os_assemble_root_dev')).encode('utf-8'),
self.Get('cl_assemble_distro'))
def get_cl_assemble_pid(self):
fromEnv = self._getFromEnv('cl_assemble_pid')
commPath = path.join('/proc',fromEnv)
if fromEnv and "cl-make" in readFile(commPath):
return fromEnv
return str(os.getpid())
def get_cl_assemble_profile(self):
"""Get available profiles"""
lines = []
for profileDesc in ['/usr/portage/profiles/profiles.desc',
'/var/lib/layman/calculate/profiles/profiles.desc']:
lines += map(lambda x:x, readLinesFile(profileDesc))
profiles = map(lambda x:filter(lambda x:x,x.split()),
filter(lambda x:x.strip() and not x.startswith("#"),
lines))
gentooarch = self.Get('os_assemble_gentoo_arch')
if gentooarch == "amd64":
addonArch = map(lambda x:x[1],filter(lambda x:x[0] == "ia64",
profiles))
else:
addonArch = []
return sorted(map(lambda x:x[1],
filter(lambda x:x[0] == gentooarch,profiles))) \
+ addonArch
def get_cl_assemble_buildpkg_set(self):
"""Get buildpkg from env or 'no'"""
fromEnv = self._getFromEnv('cl_assemble_buildpkg_set')
if fromEnv:
return fromEnv
return "on"
def get_cl_assemble_pkgdir(self):
"""Get PKGDIR for binary packages"""
fromEnv = self._getFromEnv('cl_assemble_pkgdir')
if fromEnv:
return fromEnv
return path.join("/var/calculate/remote/assemble",
self.Get('os_assemble_system_profile').rpartition(
'/profiles/')[2].replace("/","-"),
"packages")
def get_cl_assemble_linuxdir(self):
"""Get directory, which contains distro"""
return path.join("/var/calculate/remote/assemble",
self.Get('os_assemble_system_profile').rpartition(
'/profiles/')[2].replace("/","-"),
"linux")
def get_cl_assemble_sync(self):
"""Preferred rsync mirror for portages"""
fromEnv = self._getFromEnv('cl_assemble_sync')
if fromEnv:
return fromEnv
makepath = path.join(self.Get('cl_assemble_path'),
'etc/make.conf')
if path.exists(makepath):
val = self.getValueFromConfig(makepath,"SYNC")
if val != False:
return val[6:]
return "git://git.calculate.ru/calculate/portage.git"
def get_cl_assemble_branch(self):
"""Preferred branch of git portage mirror"""
fromEnv = self._getFromEnv('cl_assemble_branch')
if fromEnv:
return fromEnv
if self.Get('cl_assemble_sync').startswith('git:'):
return "master"
return ""
def get_cl_assemble_source(self):
"""Assemble source"""
imagePath = self.Get('cl_assemble_image_path')
if imagePath:
imagePath=imagePath[0]
distRep = DistributiveRepository([imagePath])
shortname = self.Get('os_assemble_linux_shortname').lower()
archMachine = self.Get('os_assemble_arch_machine')
distr = distRep.getBestDistributive(march=archMachine,
shortname=shortname,
discardType=[],
version=None)
if distr:
return shortname
return "stage"
def get_os_assemble_profile(self):
"""Real make.profile link"""
discardName = "/binary"
profile = self.Get('os_assemble_system_profile')
if profile and profile.endswith(discardName):
return profile[:-len(discardName)]
return profile
def get_os_assemble_root_format(self):
"""Get default file system format"""
for fs in ['ext4','reiserfs','ext3']:
mkfsUtil = "/sbin/mkfs.%s"%fs
if getProgPath(mkfsUtil):
return fs
return "ext2"
#########################################################
# Import from depricated install
#########################################################
def get_os_device_hash(self):
"""Generate hash information about device"""
def onlyDisk(devpath):
"""Check by udevadm that devpath is device (disk)"""
prop = getUdevDeviceInfo(devpath)
return prop.get("ID_TYPE","")=="disk" and \
prop.get("DEVTYPE","")=="disk"
# get usb device by '/dev/disk/by-id'(usb devices contain 'usb' in name)
diskIdPath = '/dev/disk/by-id'
if path.exists(diskIdPath):
usbdevices = \
map(lambda x: readlink(path.join(diskIdPath,x)).rpartition('/')[2],
filter(lambda x: x.startswith('usb-'),listDirectory(diskIdPath)))
else:
usbdevices = []
# get devices from /sys/block directories(discard mem,sr,loop and other)
sysBlockPath = '/sys/block'
devices = map(lambda x:path.join(sysBlockPath,x),
filter(lambda x: onlyDisk(path.join(sysBlockPath,x)),
filter(lambda x: not self.reWrongDevice.search(x),
listDirectory(sysBlockPath))))
device_hash = {}
# filling hash
for mapnum,device in enumerate(sorted(devices,key=self.separateDevice)):
# get information by udev
props = getUdevDeviceInfo(device)
if not "DEVNAME" in props:
continue
# DEVNAME - /dev/(device_name)
device = props['DEVNAME']
device_hash[device] = {}
# get partition table
# (if PART_TABLE_TYPE absent then get by child partition)
device_hash[device]['table'] = props.get('ID_PART_TABLE_TYPE',
self.getTableByChild(device))
# enumerate disk for legecy grub
device_hash[device]['map'] = mapnum
# if device is usb device
if path.basename(device) in usbdevices:
# check for usb flash (removeable fiel in sysfs contains "1")
removablePath = '/sys/block/%s/removable'%path.basename(device)
if os.access(removablePath,R_OK) and \
open(removablePath,'r').read().strip() == "1":
devtype = "flash"
else:
devtype = "usb-hdd"
else:
devtype = "hdd"
# set detect device type (hdd,flash or usb-hdd)
device_hash[device]['type'] = devtype
return device_hash
def separateDevice(self,device):
return map(lambda x: int(x) if x.isdigit() else x,
re.findall('\d+|\D+',device))
def getAttributeFromHash(self,var,attr):
hash = self.Get(var)
return map(lambda x: hash[x][attr] if attr in hash[x] else "",
sorted(hash.keys(),
key=self.separateDevice))
reWrongDevice = re.compile("|".join(['^fd','^ram','^loop']))
def getTableByChild(self,device):
"""Get table by child partitions"""
syspath = getUdevDeviceInfo(name=device).get('DEVPATH','')
if not syspath.startswith('/sys'):
syspath = pathJoin('/sys',syspath)
shortnameDevice = path.basename(device)
childs = filter(lambda x:x.startswith(shortnameDevice),
listDirectory(syspath))
if childs:
child = pathJoin(syspath,childs[0])
return getUdevDeviceInfo(path=child).get('ID_PART_ENTRY_SCHEME','')
return ""
def get_os_device_dev(self):
"""Devices"""
return sorted(self.Get('os_device_hash').keys(),
key=self.separateDevice)
def get_os_device_type(self):
"""Device type (hdd,cdrom,usb-flash)"""
return self.getAttributeFromHash('os_device_hash','type')
def get_cl_assemble_drivers_info(self):
"""matrix for prepare driver script"""
return []
def prepareScript(self,info):
"""
Script lines from info
"""
reVerSplit = cl_assemble.reVerSplit
yield "#!/bin/bash"
yield "PKG=$1"
yield "MASK=`cl-core --method core_variables_show --only-value install.os_nvidia_mask 2>/dev/null`"
yield "PORTAGE=/usr/portage"
yield "OVERLAY=/var/lib/layman/calculate"
yield "WORLD=/var/lib/portage/world"
yield '[[ -z "$(tail -c1 $WORLD)" ]] || echo >> $WORLD'
for verName,maskName,drvVer,ebuilds in info:
yield "if [[ $PKG == 'x11-drivers/{verName}' ]] " \
"&& [[ $MASK == '{maskName}' ]]"\
.format(verName=verName,maskName=maskName)
yield "then"
for ebuild in ebuilds.split(" "):
packageName = reVerSplit.search(ebuild)
if packageName:
packageName = packageName.group(1)
else:
continue
if "::calculate" in ebuild:
portage="$OVERLAY"
ebuild = ebuild.replace('::calculate','')
else:
portage="$PORTAGE"
ebuild = ebuild.partition('/')[2]
yield "\tcd {portage}".format(portage=portage)
yield "\t[[ -f {pkgName}/{ebuild}.ebuild ]] " \
"|| git checkout {pkgName}".format(pkgName=packageName,
ebuild=ebuild)
yield "\tebuild {pkgName}/{ebuild}.ebuild merge " \
"--skip-manifest"\
.format(pkgName=packageName,
ebuild=ebuild)
yield "\tres=$?"
yield "\techo 'x11-drivers/{verName}' >>$WORLD".format(verName=verName)
yield "\texit $res"
yield "fi"
yield "exit 1"
def get_cl_assemble_drivers_script(self):
"""part of script for driver installing"""
return "\n".join(self.prepareScript(
self.Get('cl_assemble_drivers_info')))