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.
492 lines
17 KiB
492 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.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_dev = self.Select('os_install_disk_parent',
|
|
where='os_install_disk_mount',
|
|
eq='/', limit=1)
|
|
if root_dev:
|
|
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:
|
|
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 __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("^VERSION = (\S+)\n"
|
|
"PATCHLEVEL = (\S+)\n"
|
|
"SUBLEVEL = (\S+)\n"
|
|
"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 = 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 VariableOsInstallKernelAttr(Variable):
|
|
"""
|
|
Install kernel attributes
|
|
"""
|
|
|
|
def get(self):
|
|
# on usb-hdd install must be "delay=5"
|
|
attr = ""
|
|
rdauto = ""
|
|
if self.Get('os_install_root_type') == 'usb-hdd':
|
|
attr = " scandelay=5"
|
|
if self.Get('os_install_mdadm_set') == 'on':
|
|
attr += " domdadm"
|
|
rdauto = " rd.auto"
|
|
if self.Get('os_install_lvm_set') == 'on':
|
|
attr += " dolvm"
|
|
if not rdauto:
|
|
rdauto = " rd.auto"
|
|
return attr + rdauto
|
|
|
|
|
|
class VariableOsInstallKernelResume(ReadonlyVariable):
|
|
"""
|
|
Install kernel resume
|
|
"""
|
|
|
|
def get(self):
|
|
"""install kernel resume parameter"""
|
|
for dev, install in zip(self.Get('os_install_disk_use'),
|
|
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:
|
|
return "real_resume=%s" % dev
|
|
return ""
|
|
|
|
|
|
class KernelHelper(VariableInterface):
|
|
"""
|
|
Helper for kernel variables
|
|
"""
|
|
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=MAGIC_COMPRESS | MAGIC_SYMLINK).getMType
|
|
filesWithType = map(lambda x: (x, ftype(x)),
|
|
filter(path.exists,
|
|
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=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.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 ""
|
|
|
|
|
|
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 = \
|
|
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
|
|
ifilter(lambda x: x[1] and x[1].group() in validKernel and
|
|
installMarch in x[0].rpartition('/')[2],
|
|
# (filename,version)
|
|
imap(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 = 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 ""
|