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-update/pym/builder/variables/builder.py

1196 lines
37 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# -*- coding: utf-8 -*-
# Copyright 2015 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
from os import path
import os
import re
from calculate.install.variables.kernel import KernelConfig
from calculate.lib.utils.portage import getSquashList
from .action import Actions
from calculate.install import distr
from calculate.lib.utils.device import getUdevDeviceInfo, humanreadableSize
from calculate.lib.utils.files import isMount, process, typeFile, listDirectory, \
pathJoin
from calculate.lib.utils.kernel import InitrdFile
from calculate.lib.utils.tools import max_default
from calculate.lib.utils.git import Git
from ..build_storage import BuildStorage, Build
from ..drive_spool import DriveSpool
from calculate.lib.datavars import Variable, VariableError, ReadonlyVariable, \
TableVariable
from functools import wraps
_ = lambda x:x
from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_builder3',sys.modules[__name__])
def debug(func):
@wraps(func)
def _wrapped_func(*args, **kw):
ret = func(*args, **kw)
print "MYDEBUG",ret
return ret
return _wrapped_func
def is_action(*available_action, **action_kwargs):
def decorator(func):
@wraps(func)
def _wrapped_func(self, *args, **kw):
if self.Get('cl_action') in available_action:
return func(self, *args, **kw)
else:
return action_kwargs.get('default_value', '')
return _wrapped_func
return decorator
def as_list(func):
@wraps(func)
def _wrapped_func(self, *args, **kw):
return list(func(self, *args, **kw))
return _wrapped_func
class VariableClBuilderStorage(ReadonlyVariable):
type = "object"
def get(self):
return BuildStorage()
class VariableClBuilderAvailableDev(Variable):
"""
Список дисков, которые можно использовать для сборки
"""
type = "list"
def get(self):
if self.Get('os_root_type') == "livecd":
return ["/run/initramfs/workspace/var/calculate/assemble"]
return []
class VariableClBuilderDeviceSpool(ReadonlyVariable):
"""
Стэк дисков, которые можно использовать для сборки
"""
type = "object"
def get(self):
ds = DriveSpool(self.Get('cl_builder_available_dev'))
return ds
class BaseBuildId(Variable):
"""
Базовый класс для переменной id
"""
opt = ["--id"]
metavalue = "ID"
def init(self):
self.label = _("Build ID")
self.help = _("build ID")
class VariableClBuilderVideoDriverPath(Variable):
"""
Имя файла, содержащего данные об установки драйверов во время загрузки
"""
def get(self):
builder_path = self.Get('cl_builder_path')
return path.join(
builder_path,
'var/cache/calculate/video_drivers')
class VariableClBuilderVideodrvSet(Variable):
"""
Нужно ли скачивать пакеты в дистрибутив для установки проприетарных
драйверов во время загрузки
"""
type = "bool"
opt = ["--video", "-V"]
value = "off"
def init(self):
self.label = _("Include proprietary video drivers")
self.help = _("include proprietary video drivers")
class VariableClBuilderSourceFilename(Variable):
"""
Названия файла исходного дистрибутива
"""
type = "file"
element = 'file'
opt = ["--source"]
metavalue = "SOURCE"
untrusted = True
def init(self):
self.label = _("Source image")
self.help = _("source image")
def check(self, isoimage):
"""Set image file"""
if self.Get('cl_action') in Actions.NewAssemble and not isoimage:
raise VariableError(_("You need to select a source image"))
shortname = self.Get('os_builder_linux_shortname')
build = self.Get('os_builder_linux_build')
arch = self.Get('os_builder_arch_machine')
local_arch = self.Get('os_arch_machine')
if not build or not shortname or not arch:
raise VariableError(_("Wrong image file"))
if local_arch == "i686" and arch != local_arch:
raise VariableError(
_("Unable to assemble the system {what} from {local}").format(
what=arch, local=local_arch))
def humanReadable(self):
fullname = self.Get('os_builder_linux_name')
subname = self.Get('os_builder_linux_subname')
ver = self.Get('os_builder_linux_ver')
if subname:
subname = " %s" % subname
if ver:
ver = " %s"%ver
arch = self.Get('os_builder_arch_machine')
build = self.Get('os_builder_linux_build')
return "{fullname}{ver} {arch} {build}".format(
fullname="%s%s" % (fullname, subname),
build=build, ver=ver, arch=arch)
def get(self):
if self.Get('os_root_type') == 'livecd':
return '/run/initramfs/live'
return ""
class VariableClBuilderSource(ReadonlyVariable):
"""
Объект исходного дистрибутива для разворачивания сборки
"""
type = "object"
def get(self):
"""Get image file from distributive repository"""
try:
filename = self.Get('cl_builder_source_filename')
if filename:
return distr.Distributive.fromFile(filename)
except distr.DistributiveError:
pass
return ""
def humanReadable(self):
filename = self.Get('cl_builder_source')
if filename:
return filename.getType()
return filename
class VariableClBuilderPreparePath(Variable):
"""
Путь по умолчанию для собираемой системы
"""
value = "/var/calculate/builder"
class VariableClBuilderDiskDev(Variable):
"""
Диск или директория, куда будет развёрнут образ
"""
type = "choiceedit"
untrusted = True
opt = ["-d", "--disk"]
metavalue = "DEST"
def init(self):
self.label = _("Build location")
self.help = _("partition or directory intended for build")
def get_builder_image_dn(self):
if self.Get('os_root_type') != "livecd":
default_path = self.Get('cl_builder_prepare_path')
for i in range(1,9999):
dn = "image%d"%i
full_dn = path.join(default_path, dn)
if not path.exists(full_dn) or not isMount(full_dn):
return full_dn
else:
return ""
return ""
def get(self):
ds = self.Get('cl_builder_device_spool')
return ds.get() or self.get_builder_image_dn()
def choice(self):
devices = self.Select(
'install.os_disk_dev',
where='install.os_disk_mount', eq='')
devices = [x for x in devices if not isMount(x)]
default_dn = self.get_builder_image_dn()
if default_dn:
return [default_dn] + devices
else:
return devices
def check(self, value):
if not value:
raise VariableError(
_("You need to select a destination for build"))
if value.startswith("/dev"):
cnDisk = getUdevDeviceInfo(name=value).get('DEVNAME', value)
if cnDisk not in self.Get('install.os_disk_dev'):
raise VariableError(_("Wrong device '%s'") % value)
if not value.startswith('/'):
raise VariableError(
_("Wrong directory '%s'") % value)
if isMount(value):
raise VariableError(
_("Destination '%s' is already in use") % value)
class DiskFreeHelper(ReadonlyVariable):
"""
Переменные содержащие свободное место на дисках
"""
type = "int"
def get_free_for(self, dn):
try:
dfdn = dn
while True:
dfProcess = process("/bin/df", "--output=avail", dfdn)
data = dfProcess.readlines()
if len(data) > 1:
return int(data[1].strip()) * 1024
if dfdn == '/':
return 0
dfdn = path.dirname(dfdn)
except ValueError:
return 0
return 0
def humanReadable(self):
value = self.Get()
if not value:
value = "0"
return humanreadableSize(int(value))
class VariableClBuilderDiskSize(DiskFreeHelper):
"""
"""
def init(self):
self.label = _("Free disk space")
@is_action(Actions.Prepare)
def get(self):
device = self.Get('cl_builder_disk_dev')
if device:
if device.startswith('/dev/'):
return self.Select('install.os_disk_size',
where='install.os_disk_dev',
eq=device, limit=1) or "0"
else:
return str(self.get_free_for(device))
return "0"
class VariableClBuilderPrepareFreeSize(DiskFreeHelper):
"""
Свободное место используемое для подготовки образа
"""
def init(self):
self.label = _("Free disk space for ISO building")
@is_action(Actions.Image)
def get(self):
dn = self.Get('cl_builder_iso_base_path')
return str(self.get_free_for(dn))
class VariableClBuilderImageFreeSize(DiskFreeHelper):
"""
Свободное место на диске, где создается iso образ
"""
def init(self):
self.label = _("Free disk space for ISO image")
@is_action(Actions.Image)
def get(self):
dn = self.Get('cl_builder_image_filename')
return str(self.get_free_for(dn))
class VariableClBuilderLayeredSet(Variable):
"""
Сборка будет выполняться в слое
"""
type = "bool"
opt = ["--layers"]
kernel_opt = "CONFIG_OVERLAY_FS"
def init(self):
self.help = _("use layers for build")
self.label = _("Use layers for build")
def check_kernel_option(self):
"""
Проверить возможность ядра использовать overlay fs
"""
return (
self.kernel_opt in self.Get('install.os_install_kernel_config'))
def get(self):
try:
self.check_on()
return "on"
except VariableError:
return "off"
def check_on(self):
if not self.check_kernel_option():
raise VariableError(
_("You need kernel with %s for use layers")%self.kernel_opt)
if self.Get('cl_builder_disk_dev').startswith('/dev'):
raise VariableError(
_("Layers are used for building in a directory only"))
if isinstance(self.Get('cl_builder_source'),
distr.ArchiveDistributive):
raise VariableError(
_("Layers are used for building from ISO image"))
def check(self, value):
if value == "on":
self.check_on()
class VariableClBuilderPath(ReadonlyVariable):
"""
Путь, где будет собираться дистрбутив
"""
def get(self):
image = self.Get('cl_builder_target')
if image:
return image.getDirectory()
return ""
class VariableClBuilderTarget(Variable):
"""
Объект собираемого дистрибутива
"""
type = "object"
def get_create(self):
builder_disk_dev = self.Get('cl_builder_disk_dev')
if not builder_disk_dev:
return ""
build_id = self.Get('cl_builder_id')
build_id_path = self.Get('cl_builder_id_path')
mount_dir = path.join(distr.DefaultMountPath.BaseMountPath,
build_id_path)
source = self.Get('cl_builder_source_filename')
if self.GetBool('cl_builder_layered_set'):
dist_obj = distr.LayeredDistributive(mount_dir, builder_disk_dev,
source)
return dist_obj
else:
if builder_disk_dev.startswith('/dev'):
dist_obj = distr.PartitionDistributive(builder_disk_dev,
mdirectory=mount_dir)
return dist_obj
else:
dist_obj = distr.DirectoryDistributive(builder_disk_dev,
mdirectory=mount_dir)
return dist_obj
def get_worked(self):
build = self.Get('cl_builder_build')
if build:
dist_obj = build.distributive
return dist_obj
return ""
def get(self):
action = self.Get('cl_action')
if action in Actions.NewAssemble:
return self.get_create()
elif action in Actions.WorkAssemble:
return self.get_worked()
elif action in Actions.BrokenAssemble:
return self.get_worked()
else:
return ""
class VariableClBuilderClearSet(Variable):
"""
Очистить дистрибутив при отключении сборки
"""
type = "bool"
value = "on"
opt = ["--clear"]
def init(self):
self.label = _("Clear after unmount")
self.help = _("clear data after unmount")
class VariableClBuilderBuild(Variable):
"""
Объект сборки
"""
type = "object"
def get_create(self):
distr = self.Get('cl_builder_target')
if not distr:
return ""
storage = self.Get('cl_builder_storage')
buildid = self.Get('cl_builder_id')
build = Build(buildid, distr, storage)
return build
def get_worked(self):
storage = self.Get('cl_builder_storage')
buildid = self.Get('cl_builder_id')
build = storage.get_build(buildid)
if build and build.distributive:
build.distributive.reserve()
for child in build.distributive.childs:
child.reserve()
return build or ""
def get(self):
action = self.Get('cl_action')
if action in Actions.NewAssemble:
return self.get_create()
if action in Actions.WorkAssemble:
return self.get_worked()
elif action in Actions.BrokenAssemble:
return self.get_worked()
return ""
class VariableClBuilderNewId(BaseBuildId):
"""
Id сборки при развертывании
"""
value = ""
untrusted = True
def get(self):
return self.Get('cl_builder_profile_name')
def check(self, value):
if not value and self.Get('cl_builder_source_filename'):
raise VariableError(_("Please specify the id"))
if value and not re.match("^[A-Za-z][A-Za-z0-9/:_-]+$", value):
raise VariableError(_("Wrong symbols in build ID"))
if value in self.Get('cl_builder_storage'):
raise VariableError(_("Assemble %s already exists")%value)
class VariableClBuilderPreparedId(BaseBuildId):
"""
Id развёрнутой сборки
"""
type = "choice"
untrusted = True
@as_list
def available(self):
bs = self.Get('cl_builder_storage')
action = self.Get('cl_action')
for x in bs:
build = bs.get_build(x)
if (build and (action == Actions.Break or
build.status == Build.Status.Worked)):
yield x
def get(self):
l = self.available()
if l and len(l) == 1:
return l[0]
return ""
@as_list
def choice(self):
bs = self.Get('cl_builder_storage')
for x in bs:
build = bs.get_build(x)
if build:
if build.status == Build.Status.Broken:
yield (x, "%s (%s)" % (x, _("broken")))
else:
yield (x, x)
def check(self, value):
if not value:
raise VariableError(_("Please select the assemble id"))
l = self.available()
if not l:
raise VariableError(_("Assemble %s is not found") % value)
if (self.Get('cl_builder_build').status == Build.Status.Broken and
self.Get('cl_action') != Actions.Break):
raise VariableError(
_("Assemble %s is broken, try to restore build") % value)
class VariableClBuilderBrokenId(BaseBuildId):
"""
Id развёрнутой сборки
"""
type = "choice"
untrusted = True
@as_list
def available(self):
bs = self.Get('cl_builder_storage')
for x in bs:
build = bs.get_build(x)
if build and build.status == Build.Status.Broken:
yield x
@is_action(Actions.Restore)
def get(self):
l = self.available()
if l and len(l) == 1:
return l[0]
return ""
@as_list
@is_action(Actions.Restore, default_value=[])
def choice(self):
bs = self.Get('cl_builder_storage')
for x in bs:
build = bs.get_build(x)
if build.status == Build.Status.Broken:
yield (x, "%s (%s)" % (x, _("broken")))
def check(self, value):
if not value:
raise VariableError(_("Please select the assemble id"))
l = self.available()
if not l:
raise VariableError(_("Assemble %s is not found") % value)
class VariableClBuilderIdPath(ReadonlyVariable):
"""
Преобразование сборки id в имя походящее для путей
"""
def get(self):
build_id = self.Get('cl_builder_id')
if build_id:
return re.sub("[/:]", "_", self.Get('cl_builder_id'))
return ""
class VariableClBuilderId(ReadonlyVariable):
"""
Общий id сборки
"""
def get(self):
action = self.Get('cl_action')
if action in Actions.NewAssemble:
return self.Get('cl_builder_new_id')
elif action in Actions.WorkAssemble:
return self.Get('cl_builder_prepared_id')
elif action in Actions.BrokenAssemble:
return self.Get('cl_builder_broken_id')
class VariableOsBuilderMakeopts(Variable):
"""
Параметры MAKEOPTS
"""
def get(self):
return self.Get('install.os_install_makeopts')
class VariableClBuilderBuildpkgSet(Variable):
"""
Собирать бинарные пакеты в сборке
"""
type = "bool"
value = "off"
class VariableClBuilderBasePath(Variable):
"""
Базовый путь до сборок (директория, куда будут помещены готовые
iso образы, бинарные пакеты и т.д.)
"""
value = "/var/calculate/remote/assemble"
class VariableClBuilderParentPath(ReadonlyVariable):
"""
Путь в ".." до родительской системы
"""
def get(self):
builder_path = self.Get('cl_builder_path')
return ("../"*len(filter(None,
builder_path.split('/'))))[:-1]
class VariableClBuilderStageSet(ReadonlyVariable):
"""
Разворачиваемый образ является stage (Gentoo системой)
"""
type = "bool"
def get(self):
return ("on"
if self.Get('os_builder_linux_shortname') == "Gentoo"
else "off")
class VariableClBuilderPkgdir(Variable):
"""
Путь собираемых бинарных архивов
"""
def fallback(self):
return path.join(self.Get('cl_builder_base_path'),
self.Get('cl_builder_id_path'), "packages")
def get(self):
action = self.Get('cl_action')
if action in Actions.NewAssemble:
return self.fallback()
elif action in Actions.WorkAssemble:
build = self.Get('cl_builder_build')
return build.pkgdir or self.fallback()
else:
return ""
class VariableClBuilderAction(ReadonlyVariable):
"""
Дополнительное действие по созданию образа: iso, squash.
"""
value = ""
class VariableClBuilderImageFilename(Variable):
"""
Название iso образа
"""
opt = ["--iso"]
value = ""
metavalue = "IMAGE"
untrusted = True
def init(self):
self.label = _("Image path")
self.help = _("set image path")
def check(self, value):
if not value:
raise VariableError(_("You must specify image filename"))
def _isoname(self):
shortname = self.Get('os_builder_linux_shortname').lower()
buildnumber = self.Get('os_builder_linux_build')
arch = self.Get('os_builder_arch_machine')
return "%s-%s-%s.iso" % (shortname, buildnumber,
arch)
def get(self):
if self.Get('os_root_type') != 'livecd':
base_dn = self.Get('cl_builder_base_path')
build_id = self.Get('cl_builder_id')
build_id_path = self.Get('cl_builder_id_path')
if build_id:
imagename = self._isoname()
return path.join(base_dn, build_id_path, "linux", imagename)
else:
build_id = self.Get('cl_builder_id')
base_dn = '/run/initramfs/live/iso'
if build_id:
imagename = self._isoname()
return path.join(base_dn, imagename)
return ""
class VariableClBuilderIsoBasePath(Variable):
"""
Базовый путь, где будут подготавливаться данные, которые будут запакованы в iso
"""
livecd_value = '/run/initramfs/live/tmp'
default_value = "/var/calculate/tmp"
def get(self):
if self.Get('os_root_type') == 'livecd':
return self.livecd_value
return self.default_value
class VariableClBuilderIsoPath(ReadonlyVariable):
"""
Путь, где будут подготавливаться данные, которые будут запакованы в iso
"""
def get(self):
base_dn = self.Get('cl_builder_iso_base_path')
build_id = self.Get('cl_builder_id')
build_id_path = self.Get('cl_builder_id_path')
if build_id:
dn = "iso-%s" % build_id_path
directory = path.join(base_dn, dn)
new_dn = directory
for i in range(0, 9999):
if not path.exists(new_dn):
return new_dn
else:
new_dn = "%s.%04d" % (directory, i)
return new_dn
return ""
class VariableClBuilderSquashPath(ReadonlyVariable):
"""
Путь от iso до содержимого squash
"""
@is_action(Actions.Image)
def get(self):
return path.relpath(self.Get('cl_builder_path'),
self.Get('cl_builder_iso_path'))
class VariableClBuilderImage(ReadonlyVariable):
"""
Создаваемый образ
"""
@is_action(Actions.Image)
def get(self):
image_name = self.Get('cl_builder_image_filename')
bdn = self.Get('cl_builder_iso_path')
exclude_list = self.Get('cl_builder_squash_exclude')
iso = distr.IsoDistributive(image_name, bdirectory=bdn,
vol_id=self.Get('cl_builder_iso_label'),
exclude=exclude_list,
compress=self.Get('cl_builder_compress'))
return iso
class VariableClBuilderLiveSet(Variable):
"""
Вызывать только live шаблоны при первой загрузке
"""
type = "bool"
value = "on"
class VariableClBuilderCdname(ReadonlyVariable):
"""
Type of iso (CD/DVD)
"""
@is_action(Actions.Image)
def get(self):
squashfile = pathJoin(self.Get('cl_builder_iso_path'),
self.Get('cl_builder_current_squash'))
kernelfile = pathJoin(self.Get('cl_builder_iso_path'),
self.Get('cl_builder_squash_path'),
'boot',
self.Get('cl_builder_kernel'))
initrdfile = pathJoin(self.Get('cl_builder_iso_path'),
self.Get('cl_builder_squash_path'),
'boot',
self.Get('cl_builder_initrd_install'))
if os.access(squashfile, os.R_OK) and os.access(kernelfile, os.R_OK) and \
os.access(initrdfile, os.R_OK):
isosize = path.getsize(squashfile) + path.getsize(kernelfile) + \
path.getsize(initrdfile) + 2 * 1024 * 1024
if isosize > 700 * 1024 * 1024:
return "DVD"
else:
return "CD"
return ""
class VariableClBuilderIsoLabel(Variable):
"""
LABEL для iso
"""
@is_action(Actions.Image)
def get(self):
return "%s-%s" % (self.Get('os_builder_linux_shortname').upper(),
self.Get('os_builder_linux_build'))
class VariableClBuilderRootParam(Variable):
"""
параметр root= для livecd
"""
@is_action(Actions.Image)
def get(self):
return "live:LABEL=%s" % self.Get('cl_builder_iso_label')
class VariableClBuilderCurrentSquash(ReadonlyVariable):
"""
Создаваемый livecd.squash
"""
value = "livecd.squashfs"
class VariableClBuilderKernelCmd(ReadonlyVariable):
"""
Параметры по умолчанию для calcboot
"""
value = ""
class KernelInfo(ReadonlyVariable):
def get_current_kernel_src(self, prefix):
src_path = "usr/src"
current_linux_src = path.join(src_path, "linux")
symlink_kernel = path.join(prefix, current_linux_src)
if not path.exists(symlink_kernel) or not path.islink(symlink_kernel):
raise ValueError("Failed to determine current kernel version")
return path.join(src_path, os.readlink(symlink_kernel))
class VariableClBuilderKernelConfig(KernelInfo):
"""
Конфиг ядра
"""
def get(self):
prefix = self.Get('cl_builder_path')
if prefix:
kernel_src = self.get_current_kernel_src(prefix)
config_path = path.join(kernel_src, ".config")
return KernelConfig(path.join(prefix, config_path))
return ""
class VariableClBuilderKernelVer(KernelInfo):
"""
Текущая версия ядра
"""
def init(self):
self.label = _("Kernel version")
def get(self):
prefix = self.Get('cl_builder_path')
if prefix:
current_src = self.get_current_kernel_src(prefix)
src = path.join(prefix,current_src)
return self.get_src_kernel_version(src)
def get_config_version(self, configfile):
re_config = re.compile("Automatically generated file;.*\n"
".*?Linux/\S+\s+(\S+)\s", re.M)
if path.exists(configfile):
with open(configfile) as f:
match = re_config.search(f.read(200))
if match:
return match.group(1)
def get_src_kernel_version(self, kernel_src):
"""
Get version of kernel from .config
"""
config_path = path.join(kernel_src, ".config")
makefile_path = path.join(kernel_src, "Makefile")
# get version from config
version = self.get_config_version(config_path)
if version:
return version
# 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 ""
class KernelData(ReadonlyVariable):
"""
Данные о текущем ядре
"""
kernel_object = "kernel"
file_description = ""
def filter(self, x, version=None):
return x
def list(self, prefix='/', bootdir='boot'):
boot_dir = path.join(prefix, bootdir)
return self.get_files_by_type(boot_dir, self.file_description)
def get(self):
prefix = self.Get('cl_builder_path')
version = self.Get('cl_builder_kernel_ver')
obj_file = max_default(
self.filter(self.list(prefix), version=version),
key=path.getmtime,
default="")
if obj_file:
obj_file = path.basename(obj_file)
return obj_file
def get_files_by_type(self, pathname, descr):
ftype = typeFile(magic=0x4).getMType
for x in listDirectory(pathname, fullPath=True):
if descr in ftype(x):
yield x
class VariableClBuilderInitrdInstall(KernelData):
"""
Текущий initrd
"""
file_description = "ASCII cpio archive"
def init(self):
self.label = _("Init RAM fs")
def filter(self, iterable, version=None):
for fn in iterable:
if InitrdFile(fn).get_kernel_version() == version:
yield fn
class VariableClBuilderKernel(KernelData):
"""
Текущее ядро
"""
file_description = "boot executable bzImage"
def init(self):
self.label = _("Kernel file")
def filter(self, iterable, version=None):
ftype = typeFile(magic=0x4).getMType
re_kver = re.compile("bzImage, version (\S+)\s")
for fn in iterable:
m = re_kver.search(ftype(fn))
if m.group(1) == version:
yield fn
class VariableClBuilderTemplateLocation(Variable):
"""
Устанавливаются только дистрибутивные шаблоны
"""
type = "list"
def get(self):
return [x for x in self.Get('main.cl_template_location')
if x not in ('remote', 'local')]
class VariableClBuilderOutdateSet(ReadonlyVariable):
"""
Флаг устанавливаемый в ходе обновления репозиториев,
сообщающий что хотя бы один из запланированных репозиториев
обновлен и следует обновляет различные метаданные
Если обновляются прочие оверлеи - данные считаются что устарели
"""
type = "bool"
def get(self):
if (self.Get('update.cl_update_other_set') == 'on' and
self.Get('cl_builder_other_rep_name')):
return "on"
return "off"
class VariableClBuilderBranchData(TableVariable):
"""
Выбор веток репозиториев до которых необходимо обновиться
"""
opt = ["--branch"]
metavalue = 'BRANCHES'
untrusted = True
source = ["cl_builder_branch_rep",
"cl_builder_branch_name"]
def init(self):
self.help = _("set branches for repository (REPOSITORY:BRANCH)")
self.label = _("Repositories branches")
def raiseReadonlyIndexError(self, fieldname="", variablename="", value=""):
"""
Неизвестный оврелей
"""
raise VariableError(_("Repository %s not found") % value)
class VariableClBuilderBranchRep(ReadonlyVariable):
"""
Список доступных репозиториев
"""
type = "list"
def init(self):
self.label = _("Repositories")
def get(self):
dv = self.Get('cl_builder_linux_datavars')
if dv:
return dv.Get('cl_update_rep_name')
return []
class VariableClBuilderBranchName(Variable):
"""
Список доступных репозиторием
"""
type = "choiceedit-list"
def init(self):
self.label = _("Branches")
def choice(self):
return [
Git.Reference.Tag,
Git.Reference.Master,
Git.Reference.Develop,
Git.Reference.Update]
def get(self):
dv = self.Get('cl_builder_linux_datavars')
if dv:
if "getbinpkg" in self.Get('cl_features'):
return [Git.Reference.Tag for x in dv.Get('cl_update_rep_name')]
else:
branch = self.Get('cl_update_branch')
return [branch for x in dv.Get('cl_update_rep_name')]
return []
class VariableClBuilderCompress(Variable):
"""
Тип сжатия образа squash
"""
type = "choice"
opt = ["-c", "--compress"]
metavalue = "COMPRESS"
untrusted = True
def init(self):
self.label = _("Compressor")
self.help = _("set the compressor")
def choice(self):
config_param_prefix = "CONFIG_SQUASHFS_%s"
kernel_config = self.Get('cl_builder_kernel_config')
params = {"xz": "XZ",
"lzma": "XZ",
"lzo": "LZO",
"gzip": "ZLIB"}
def generator():
for compress in getSquashList():
if compress in params:
if config_param_prefix % params[compress] in kernel_config:
yield compress
else:
yield compress
weight = {'xz':2, 'gzip':1}
return list(sorted(generator(),
key=lambda x: (-weight.get(x, 0), x)))
def get(self):
values = self.choice()
if values:
return values[0]
return ""
class VariableClBuilderIsohybridSet(Variable):
"""
Преобразовать полученный iso образ в гибридный
"""
type = "bool"
opt = ["--isohybrid"]
value = "on"
def init(self):
self.help = _("create the ISO image with isohybrid")
self.label = _("ISO hybrid feature")
class VariableClBuilderKeepTreeSet(Variable):
"""
Не удалять ебилды из портежей о оверлеев
"""
type = "bool"
opt = ["--keep-tree"]
value = "off"
def init(self):
self.help = _("keep portage tree in image")
self.label = _("Keep portage tree")
class VariableClBuilderSquashExclude(ReadonlyVariable):
"""
Список файлов, которые не будут запакованы в livecd.squashfs
"""
type = "list"
def get(self):
builder_path = self.Get('cl_builder_path')
keep_tree = self.GetBool('cl_builder_keep_tree_set')
excludes = ["", "metadata", "profiles/templates/deprecated"]
important = [".git", "distfiles", "packages", "eclass", "metadata",
"profiles", "layout.conf"]
def generator():
for rep_dn in self.Get('cl_builder_repository_location'):
for exclude_dn in excludes:
dn = pathJoin(builder_path, rep_dn, exclude_dn)
for exclude_name in (x for x in listDirectory(dn)
if x not in important):
yield path.join(rep_dn, exclude_dn, exclude_name)[1:]
if not keep_tree and builder_path:
return list(generator())
return []
class VariableClBuilderPrelinkSet(Variable):
"""
Выполнять ли prelink
"""
type = "bool"
opt = ["--prelink"]
def init(self):
self.help = _("perform prelink")
self.label = _("Perform prelink")
def get(self):
return "on" if self.GetBool('cl_builder_binary_set') else "off"
class VariableClBuilderRebuildChangedSet(Variable):
"""
Выполнять ли prelink
"""
type = "bool"
opt = ["--rebuild-changed-packages"]
value = "on"
def init(self):
self.help = _("rebuild changed packages")
self.label = _("Rebuild changed packages")