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

511 lines
17 KiB

# -*- coding: utf-8 -*-
# Copyright 2008-2016 Mir Calculate. 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
from os import path
from calculate.lib.datavars import (Variable, ReadonlyVariable,
ReadonlyTableVariable, FieldValue,
HumanReadable, VariableInterface)
from calculate.lib.utils.files import (readFile,
typeFile, process, listDirectory,
MAGIC_SYMLINK, MAGIC_COMPRESS)
from calculate.lib.utils.kernel import InitrdFile
from calculate.lib.cl_lang import setLocalTranslate
_ = lambda x: x
setLocalTranslate('cl_install3', sys.modules[__name__])
from operator import itemgetter
from calculate.lib.utils.files import readLinesFile
from calculate.lib.utils.common import (getKernelUid, getTupleVersion,
getValueFromCmdLine, CmdlineParams)
from itertools import *
from calculate.install.distr import DistributiveError
class VariableOsInstallKernelScheduler(Variable):
"""
Install scheduler opts (cfq,bfq,none,deadline)
"""
type = "choice"
opt = ["--scheduler"]
metavalue = "SCHEDULER"
def init(self):
self.help = _("toggle the I/O scheduler")
self.label = _("I/O scheduler")
def check_scheduler(self, scheduler):
return scheduler in self.Select('os_install_kernel_schedule_name',
where='os_install_kernel_schedule_set',
eq='on')
def get_default(self):
root_devs = self.Select('os_install_disk_parent',
where='os_install_disk_mount',
eq='/', limit=1).split(',')
for root_dev in root_devs:
dev_ssd, dev_virtual = self.Select(['os_device_ssd_set',
'os_device_virtual_set'],
where='os_device_dev',
eq=root_dev, limit=1)
if ((dev_ssd == 'on' or dev_virtual == 'on') and
self.check_scheduler("noop")):
return "noop"
return self.Get('os_install_kernel_schedule_default')
def get(self):
"""Get scheduler for install root device"""
if self.Get('os_root_type') == 'livecd':
return self.get_default()
else:
currentScheduler = getValueFromCmdLine(
CmdlineParams.IOScheduler)
if currentScheduler in map(lambda x: x[0], self.choice()):
return currentScheduler
return self.Get('os_install_kernel_schedule_default')
def choice(self):
schedulers = {"deadline": "Deadline",
"cfq": "CFQ",
"noop": "No-op",
"bfq": "BFQ"}
return [(x, schedulers.get(x, x))
for x in self.Select('os_install_kernel_schedule_name',
where='os_install_kernel_schedule_set',
eq='on')] + [("auto", _("Default"))]
def set(self, value):
if value == "auto":
return self.get_default()
return value
def uncompatible(self):
"""
Unavailable for flash installation
"""
if self.Get('os_install_root_type') == 'flash':
return _("I/O scheduler unavailable for Flash install")
class KernelConfig(object):
def __init__(self, kernel_config):
self.data = readFile(kernel_config).split('\n')
self.config = kernel_config
def __iter__(self):
return iter(self.data)
def __str__(self):
return "kernel config (%s)" % self.config
def __len__(self):
return len(self.data)
def __contains__(self, item):
if "=" in item:
if item.endswith("=n"):
key = "# %s is not set" % item[:-2]
else:
key = item
else:
key = "%s=" % item
return any(key in x for x in self)
class VariableOsInstallKernelConfig(ReadonlyVariable):
"""
Install config kernel filename
"""
def get_kernel_src(self, distr_path):
"""
Get version of kernel from .config
"""
kernel_src = 'usr/src/linux'
makefile_path = path.join(distr_path, kernel_src, "Makefile")
# get version from Makefile
re_makefile = re.compile(r"^VERSION = (\S+)\n"
r"PATCHLEVEL = (\S+)\n"
r"SUBLEVEL = (\S+)\n"
r"EXTRAVERSION = (\S*)\n", re.M)
if path.exists(makefile_path):
with open(makefile_path) as f:
match = re_makefile.search(f.read(200))
if match:
return "{0}.{1}.{2}{3}".format(*match.groups())
return ""
def configs(self, distr_path):
src_kernel_ver = self.get_kernel_src(distr_path)
if src_kernel_ver:
yield path.join("boot", "config-%s" % src_kernel_ver)
if self.Get('cl_chroot_path') == '/':
ver = process('/bin/uname', '-r').read().strip()
yield path.join("boot", "config-%s" % ver)
yield 'usr/src/linux/.config'
def get(self):
image = self.Get('cl_image')
if image:
with image:
try:
distrPath = image.getDirectory()
for config in self.configs(distrPath):
config_name = path.join(distrPath, config)
if path.exists(config_name):
return KernelConfig(config_name)
except DistributiveError:
return ""
return ""
class VariableOsKernelConfig(VariableOsInstallKernelConfig):
"""
Current config kernel
"""
def configs(self, distr_path):
ver = process('/bin/uname', '-r').read().strip()
yield path.join("boot", "config-%s" % ver)
yield 'usr/src/linux/.config'
def get(self):
for config in self.configs("/"):
config_name = path.join("/", config)
if path.exists(config_name):
return KernelConfig(config_name)
return ""
class VariableOsInstallKernelScheduleDefault(Variable):
"""
IO планировщик по умолчанию
"""
type = "choice"
def get(self):
for line in self.Get('os_install_kernel_config'):
if "CONFIG_DEFAULT_IOSCHED=" in line:
key, op, value = line.partition("=")
return value.strip('"')
return "cfq"
def choice(self):
return self.Select('os_install_kernel_schedule_name',
where='os_install_kernel_schedule_set',
eq='on')
class VariableOsInstallKernelScheduleData(ReadonlyTableVariable):
"""
Information about kernel schedule
"""
source = ['os_install_kernel_schedule_name',
'os_install_kernel_schedule_set']
def get(self, hr=HumanReadable.No):
schedulers = {'CONFIG_IOSCHED_BFQ=y': 'bfq',
'CONFIG_IOSCHED_NOOP=y': 'noop',
'CONFIG_IOSCHED_CFQ=y': 'cfq',
'CONFIG_IOSCHED_DEADLINE=y': 'deadline'}
installed = list(map(schedulers.get,
filter(lambda x: x in schedulers,
self.Get('os_install_kernel_config')))) or ['cfq']
return [[x, "on" if x in installed else "off"]
for x in sorted(schedulers.values())]
setValue = Variable.setValue
class VariableOsInstallKernelScheduleName(FieldValue, ReadonlyVariable):
"""
Schedule name
"""
type = "list"
source_variable = "os_install_kernel_schedule_data"
column = 0
class VariableOsInstallKernelScheduleSet(FieldValue, ReadonlyVariable):
"""
Kernel has schedule
"""
type = "list-bool"
source_variable = "os_install_kernel_schedule_data"
column = 1
class VariableOsInstallKernelTuxoniceSet(ReadonlyVariable):
"""
Available BFQ in kernel
"""
type = "bool"
def get(self):
if any("CONFIG_TOI_CORE=y" in x
for x in self.Get('os_install_kernel_config')):
return "on"
return "off"
class VariableOsInstallKernelBfqSet(ReadonlyVariable):
"""
Available BFQ in kernel
"""
type = "bool"
def get(self):
if any("CONFIG_IOSCHED_BFQ=y" in x
for x in self.Get('os_install_kernel_config')):
return "on"
return "off"
class VariableOsInstallNomodeset(Variable):
type = "bool"
def get(self):
cmdLine = '/proc/cmdline'
if 'nomodeset' in readFile(cmdLine):
return "on"
return "off"
class VariableOsInstallKernelAttr(Variable):
"""
Install kernel attributes
"""
def get(self):
def generate():
# 5 sec for usb hdd boot
if self.GetBool('os_install_nomodeset'):
yield "nomodeset"
if self.Get('os_install_root_type') == 'usb-hdd':
yield "scandelay=5"
if (self.GetBool('os_install_mdadm_set') or
self.GetBool('os_install_lvm_set')):
yield "rd.auto"
yield "rd.retry=40"
return " ".join(generate())
class VariableOsInstallKernelResume(ReadonlyVariable):
"""
Install kernel resume
"""
def get(self):
"""install kernel resume parameter"""
for dev, partuuid, install in zip(self.Get('os_install_disk_use'),
self.Get('os_install_disk_partuuid'),
self.Get('os_install_disk_mount')):
if install == "swap":
if self.Get('os_install_kernel_tuxonice_set') == 'on':
return "tuxonice tuxonice_resume=%s real_resume=%s" % (
dev, dev)
else:
if partuuid:
return "resume=PARTUUID=%s" % partuuid
else:
return "resume=%s" % dev
return ""
class KernelHelper(VariableInterface):
"""
Helper for kernel variables
"""
reFindVer = re.compile(
r"(?<=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=MAGIC_COMPRESS | MAGIC_SYMLINK).getMType
filesWithType = map(lambda x: (x, ftype(x)),
filter(path.exists,
filelist))
return list(filter(lambda x: x[1] and descr in x[1], filesWithType))
def getInitrdFiles(self, pathname):
filelist = list(map(lambda x: path.join(pathname, x), os.listdir(pathname)))
return [x for x in filelist if path.exists(x) and InitrdFile.is_cpio(x)]
def getInitrd(self, arch, shortname, chroot, kernel, suffix="",
notsuffix=""):
"""Get initrd for kernel"""
reInitrdVer = re.compile(r"(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=MAGIC_COMPRESS | MAGIC_SYMLINK).getMType
kernelfile = path.join(chroot, 'boot', kernel)
typeKernelFile = ftype(kernelfile)
if typeKernelFile is 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.getInitrdFiles(bootdir)
initramfsWithVer = \
list(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, initrd_version_by_name(x)),
initramfsFiles)))
if initramfsWithVer:
return path.split(min(initramfsWithVer,
key=itemgetter(0))[0])[-1]
return ""
class VariableOsInstallKernel(ReadonlyVariable, KernelHelper):
"""
Kernel filename
"""
def get(self):
bootdir = path.join(self.Get('cl_chroot_path'), 'boot')
modulesdir = path.join(self.Get('cl_chroot_path'), 'lib/modules')
validKernel = listDirectory(modulesdir)
kernelFiles = self.getFilesByType(bootdir, "Linux kernel")
installMarch = self.Get('os_install_arch_machine')
kernelsWithVer = \
list(map(lambda x: (
x[0], (getTupleVersion("".join(x[1].groups()[0:3:2])),
path.getmtime(x[0]))),
# convert version to tuple( versionTuple, mtime)
# version detect, for this version lib contains moudules
# kernel arch equal install arch
filter(lambda x: x[1] and x[1].group() in validKernel and
installMarch in x[0].rpartition('/')[2],
# (filename,version)
map(lambda x: (x[0], self.reFindVer.search(x[1])),
kernelFiles))))
if kernelsWithVer:
return path.split(max(kernelsWithVer, key=itemgetter(1))[0])[-1]
else:
return "vmlinuz"
class VariableOsInstallInitrd(ReadonlyVariable, KernelHelper):
"""
Optimized initramfs filename
"""
def get(self):
return self.getInitrd(self.Get('os_install_arch_machine'),
self.Get('os_install_linux_shortname'),
self.Get('cl_chroot_path'),
self.Get('os_install_kernel'),
suffix="", notsuffix="-install") or \
self.getInitrd(self.Get('os_install_arch_machine'),
self.Get('os_install_linux_shortname'),
self.Get('cl_chroot_path'),
self.Get('os_install_kernel'),
suffix="-install")[:-8] \
or "initrd"
class VariableOsInstallInitrdInstall(ReadonlyVariable, KernelHelper):
"""
Install initramfs filename
"""
def get(self):
return self.getInitrd(self.Get('os_install_arch_machine'),
self.Get('os_install_linux_shortname'),
self.Get('cl_chroot_path'),
self.Get('os_install_kernel'),
suffix="-install") or "initrd-install"
class VariableOsInstallSystemMap(ReadonlyVariable):
"""
Install system map filename
"""
def get(self):
systemmapfile = self.Get('os_install_kernel').replace('vmlinuz',
'System.map')
if systemmapfile.startswith('System.map') and path.exists(
path.join(self.Get('cl_chroot_path'), 'boot', systemmapfile)):
return systemmapfile
else:
return ""
class VariableOsInstallKernelCpufreq(ReadonlyVariable):
"""
Cpufreq modules
"""
def get(self):
"""Get cpufreq (and other from modules_3= param) from conf.d/modules"""
cpufreqmods = list(map(lambda x: x.partition('=')[2].strip("\n '\""),
filter(lambda x: x.startswith('modules_3'),
readLinesFile('/etc/conf.d/modules'))))
if cpufreqmods:
return cpufreqmods[0]
else:
return ""
class VariableClInstallKernelUid(ReadonlyVariable):
"""
Variable install kernel UID
"""
def get(self):
return getKernelUid(self.Get('os_install_root_dev'))
class VariableClInstallKernelBuild(Variable):
"""
Переменная используемся для GRP дистрибутивов и сборки нескольких ядер
"""
value = ""
class VariableClInstallKernelVersion(VariableOsInstallKernelConfig):
"""
Версия ядра в /usr/src/linux
"""
def get(self):
image = self.Get('cl_image')
if image:
with image:
try:
distrPath = image.getDirectory()
return self.get_kernel_src(distrPath)
except DistributiveError as e:
return ""
return ""