|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
# Copyright 2015-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 sys
|
|
|
import re
|
|
|
from os import path
|
|
|
from calculate.install import distr
|
|
|
from calculate.install.distr import DistributiveError
|
|
|
from calculate.lib.datavars import (ReadonlyVariable, VariableError,
|
|
|
ReadonlyTableVariable, FieldValue,
|
|
|
HumanReadable, Variable)
|
|
|
from calculate.lib.utils.files import pathJoin
|
|
|
from calculate.lib.utils.tools import ignore
|
|
|
from calculate.lib.variables import env
|
|
|
from calculate.update.variables import update
|
|
|
from calculate.lib.variables import system, linux
|
|
|
from .action import Actions
|
|
|
|
|
|
from calculate.lib.cl_lang import setLocalTranslate
|
|
|
import datetime
|
|
|
|
|
|
_ = lambda x: x
|
|
|
setLocalTranslate('cl_builder3', sys.modules[__name__])
|
|
|
|
|
|
|
|
|
class BuilderLinux(ReadonlyVariable):
|
|
|
# variable for get current system info (example: os_linux_shortname)
|
|
|
variable = ""
|
|
|
|
|
|
def get_fallback(self):
|
|
|
return ""
|
|
|
|
|
|
def get(self):
|
|
|
try:
|
|
|
dv = self.Get('cl_builder_linux_datavars')
|
|
|
if dv:
|
|
|
return dv[self.variable]
|
|
|
except VariableError as e:
|
|
|
pass
|
|
|
return self.get_fallback()
|
|
|
|
|
|
|
|
|
class DataVarsBuilderLinux(linux.LinuxDataVars):
|
|
|
"""
|
|
|
Упрощенная модель переменных для собираемого образа
|
|
|
"""
|
|
|
|
|
|
def variables(self):
|
|
|
l = super(DataVarsBuilderLinux, self).variables()
|
|
|
return l + [linux.VariableClProfileSystem(),
|
|
|
env.VariableClRepositoryData(),
|
|
|
env.VariableClRepositoryName(),
|
|
|
env.VariableClRepositoryLocation(),
|
|
|
env.VariableClTemplateLocation(),
|
|
|
env.VariableClTemplatePath(),
|
|
|
env.VariableClPkgdir(),
|
|
|
env.VariableClDistdir(),
|
|
|
env.VariableClEmergeConfig(systemRoot=self.systemRoot),
|
|
|
env.VariableClEmergeInfo(systemRoot=self.systemRoot),
|
|
|
env.VariableClFeatures(),
|
|
|
env.VariableClEmergeDefaultOpts(),
|
|
|
env.VariableClEnvLocation(),
|
|
|
env.VariableClEnvData(),
|
|
|
env.VariableClEnvPath(),
|
|
|
env.VariableClEbuildPhase(),
|
|
|
update.VariableClUpdateReposStorage(section="update"),
|
|
|
update.VariableClUpdateReposconf(section="update"),
|
|
|
update.VariableClUpdateReposconfDir(section="update"),
|
|
|
update.VariableClUpdateUsetagSet(section="update"),
|
|
|
update.VariableClUpdateGpgForce(section="update"),
|
|
|
update.VariableClUpdateGpgKeys(section="update"),
|
|
|
update.VariableClUpdateBinhostBase(section="update"),
|
|
|
update.VariableClUpdateBinhostBaseSet(section="update"),
|
|
|
update.VariableClUpdateWithBdepsSet(section="update"),
|
|
|
update.VariableClUpdateRepData(section="update"),
|
|
|
update.VariableClUpdateRepPath(section="update"),
|
|
|
update.VariableClUpdateRepName(section="update"),
|
|
|
update.VariableClUpdateRepUrl(section="update"),
|
|
|
update.VariableClUpdateRep(section="update"),
|
|
|
update.VariableClUpdateRepRev(section="update"),
|
|
|
update.VariableClUpdateBranch(section="update",
|
|
|
arch_var="os_profile_arch_machine"),
|
|
|
update.VariableClUpdateBranchName(section="update"),
|
|
|
update.VariableClProfileRepository(section="update"),
|
|
|
update.VariableClUpdateBinhost(section="update"),
|
|
|
update.VariableClUpdateBinhostData(section="update"),
|
|
|
update.VariableClUpdateBinhostHost(section="update"),
|
|
|
update.VariableClUpdateBinhostRecheckSet(section="update"),
|
|
|
update.VariableClUpdateBinhostRevisions(section="update"),
|
|
|
update.VariableClUpdateBinhostTime(section="update"),
|
|
|
update.VariableClUpdateBinhostTimestamp(section="update"),
|
|
|
update.VariableClUpdateLastTimestamp(section="update"),
|
|
|
update.VariableClUpdateBinhostTimeout(section="update"),
|
|
|
update.VariableClUpdateBinhostList(section="update"),
|
|
|
update.VariableClUpdateBinhostUnstableList(section="update"),
|
|
|
update.VariableClUpdateBinhostData(section="update"),
|
|
|
update.VariableClUpdateBinhostStableOptSet(section="update"),
|
|
|
update.VariableClUpdateBinhostStableSet(section="update"),
|
|
|
update.VariableClUpdateBinhostTimestampPath(
|
|
|
section="update"),
|
|
|
update.VariableClUpdateBinhostRevisionPath(
|
|
|
section="update"),
|
|
|
VariableOsProfileArchMachine(systemRoot=self.systemRoot),
|
|
|
system.VariableOsArchMachineGentoo()]
|
|
|
|
|
|
@classmethod
|
|
|
def StageInformation(cls, image, fn):
|
|
|
c = {}
|
|
|
if isinstance(image, distr.ContainerDistributive):
|
|
|
c = image.get_information()
|
|
|
else:
|
|
|
re_stage = re.compile(r"stage(\d)-(amd64|x86)-(\d{8}).tar.\w+")
|
|
|
m = re_stage.search(fn)
|
|
|
if m:
|
|
|
map_arch = {'amd64': 'x86_64', 'x86': 'i686'}
|
|
|
c = {'os_linux_build': m.group(3),
|
|
|
'os_arch_machine': map_arch[m.group(2)],
|
|
|
'os_linux_shortname': 'Gentoo',
|
|
|
'os_linux_subname': "Stage%s" % m.group(1),
|
|
|
'cl_profile_name': 'Gentoo profile',
|
|
|
'os_linux_name': 'Gentoo'}
|
|
|
obj = cls(cache=c)
|
|
|
for vn in obj.allVars.keys():
|
|
|
if vn not in obj.cache:
|
|
|
obj.cache[vn] = ''
|
|
|
return obj
|
|
|
|
|
|
def flCalculateEnv(self, systemRoot):
|
|
|
for inifile in self.Get('cl_env_path'):
|
|
|
self.flIniFileFrom(pathJoin(systemRoot, inifile),
|
|
|
system_root=systemRoot)
|
|
|
|
|
|
def __repr__(self):
|
|
|
return "Builder variables"
|
|
|
|
|
|
|
|
|
class VariableClBuilderBinarySet(ReadonlyVariable):
|
|
|
"""
|
|
|
Собираемый дистрибутив - бинарный FEATURES="getbinpkg"
|
|
|
"""
|
|
|
|
|
|
def get(self):
|
|
|
dv = self.Get('cl_builder_linux_datavars')
|
|
|
if dv:
|
|
|
if "getbinpkg" in dv.Get('cl_features'):
|
|
|
return "on"
|
|
|
return "off"
|
|
|
|
|
|
class VariableClBuilderGpgForce(BuilderLinux, update.VariableClUpdateGpgForce):
|
|
|
"""
|
|
|
Использовать GPG проверку
|
|
|
"""
|
|
|
variable = "cl_update_gpg_force"
|
|
|
mode = Variable.Writable
|
|
|
|
|
|
def get_fallback(self):
|
|
|
return "force"
|
|
|
|
|
|
class VariableClBuilderBinhost(BuilderLinux, update.VariableClUpdateBinhost):
|
|
|
"""
|
|
|
Принудительное действие с eix-update
|
|
|
"""
|
|
|
variable = "cl_update_binhost"
|
|
|
|
|
|
def get_fallback(self):
|
|
|
return ""
|
|
|
|
|
|
class VariableClBuilderUsetagSet(ReadonlyVariable):
|
|
|
"""
|
|
|
Собираемый дистрибутив использует тэги при синхронизации репозиториев
|
|
|
"""
|
|
|
|
|
|
def get(self):
|
|
|
dv = self.Get('cl_builder_linux_datavars')
|
|
|
if dv:
|
|
|
return dv.Get('cl_update_usetag_set')
|
|
|
return "off"
|
|
|
|
|
|
|
|
|
class VariableClBuilderLinuxDatavars(ReadonlyVariable):
|
|
|
"""
|
|
|
Переменные дистрибутива
|
|
|
"""
|
|
|
|
|
|
def source_data(self):
|
|
|
image = self.Get('cl_builder_source')
|
|
|
image_fn = self.Get('cl_builder_source_filename')
|
|
|
return self.get_data(image, image_fn=image_fn, source=True)
|
|
|
|
|
|
def prepare_vars(self, dvbl):
|
|
|
dvbl['cl_update_binhost_recheck_set'] = \
|
|
|
self.Get('update.cl_update_binhost_recheck_set')
|
|
|
if self.Get('cl_action') not in (
|
|
|
Actions.Update, Actions.ChangeProfile) or \
|
|
|
not self.GetBool('cl_builder_binhost_scan_set'):
|
|
|
dvbl.cache['cl_update_binhost_data'] = [[]]
|
|
|
dvbl.prepare_all()
|
|
|
|
|
|
def get_data(self, image, image_fn=None, source=False):
|
|
|
if image:
|
|
|
if isinstance(image, distr.ArchiveDistributive):
|
|
|
return DataVarsBuilderLinux.StageInformation(image, image_fn)
|
|
|
with image:
|
|
|
with ignore(DistributiveError):
|
|
|
distr_dn = image.getDirectory()
|
|
|
dvbl = DataVarsBuilderLinux(systemRoot=distr_dn)
|
|
|
self.prepare_vars(dvbl)
|
|
|
return dvbl
|
|
|
else:
|
|
|
return ""
|
|
|
|
|
|
def target_data(self):
|
|
|
image = self.Get('cl_builder_target')
|
|
|
return self.get_data(image, image_fn=None)
|
|
|
|
|
|
def get(self):
|
|
|
"""Get by distroinfo or current info"""
|
|
|
if self.Get('cl_action') in Actions.NewAssemble:
|
|
|
return self.source_data()
|
|
|
elif self.Get('cl_action') in Actions.WorkAssemble:
|
|
|
return self.target_data()
|
|
|
return ""
|
|
|
|
|
|
|
|
|
class VariableOsBuilderLinuxShortname(BuilderLinux):
|
|
|
"""Shortname of system"""
|
|
|
variable = "os_linux_shortname"
|
|
|
|
|
|
def init(self):
|
|
|
self.label = _("Building short name")
|
|
|
|
|
|
|
|
|
class VariableOsBuilderLinuxVer(BuilderLinux):
|
|
|
"""Shortname of system"""
|
|
|
variable = "os_linux_ver"
|
|
|
|
|
|
def init(self):
|
|
|
self.label = _("Building system version")
|
|
|
|
|
|
|
|
|
class VariableOsBuilderLinuxBuild(BuilderLinux):
|
|
|
"""Shortname of system"""
|
|
|
variable = "os_linux_build"
|
|
|
|
|
|
def init(self):
|
|
|
self.label = _("Build version")
|
|
|
|
|
|
def get(self):
|
|
|
action = self.Get('cl_action')
|
|
|
if action == Actions.Image:
|
|
|
curdate = datetime.datetime.now()
|
|
|
return "%04d%02d%02d" % (curdate.year, curdate.month, curdate.day)
|
|
|
else:
|
|
|
return BuilderLinux.get(self)
|
|
|
|
|
|
|
|
|
class VariableOsBuilderArchMachine(BuilderLinux):
|
|
|
"""Shortname of system"""
|
|
|
variable = "os_arch_machine"
|
|
|
|
|
|
def get_fallback(self):
|
|
|
prefix = self.Get('cl_builder_path')
|
|
|
if prefix:
|
|
|
if path.exists(path.join(prefix, 'lib64')):
|
|
|
return 'x86_64'
|
|
|
else:
|
|
|
return 'i686'
|
|
|
return ""
|
|
|
|
|
|
|
|
|
class VariableOsProfileArchMachine(ReadonlyVariable):
|
|
|
systemRoot = "/"
|
|
|
|
|
|
def get(self):
|
|
|
if path.exists(path.join(self.systemRoot, 'lib64')):
|
|
|
return 'x86_64'
|
|
|
else:
|
|
|
return 'i686'
|
|
|
|
|
|
|
|
|
class VariableOsBuilderLinuxFiles(BuilderLinux):
|
|
|
"""Shortname of system"""
|
|
|
variable = "os_linux_files"
|
|
|
|
|
|
|
|
|
class VariableOsBuilderLinuxName(BuilderLinux):
|
|
|
"""
|
|
|
Install distro name
|
|
|
"""
|
|
|
variable = "os_linux_name"
|
|
|
|
|
|
def init(self):
|
|
|
self.label = _("System name")
|
|
|
|
|
|
|
|
|
class VariableClBuilderProfileSystem(BuilderLinux):
|
|
|
variable = "cl_profile_system"
|
|
|
|
|
|
|
|
|
class VariableOsBuilderLinuxSystem(BuilderLinux):
|
|
|
"""
|
|
|
Install system name
|
|
|
"""
|
|
|
|
|
|
def init(self):
|
|
|
self.label = _("System type")
|
|
|
|
|
|
variable = "os_linux_system"
|
|
|
|
|
|
|
|
|
class VariableOsBuilderLinuxFullname(ReadonlyVariable):
|
|
|
"""
|
|
|
Полное название системы
|
|
|
"""
|
|
|
fullname_format = "{name} {ver}{subname} {arch} {build}"
|
|
|
|
|
|
def init(self):
|
|
|
self.label = _("System")
|
|
|
|
|
|
def get(self):
|
|
|
name = self.Get('os_builder_linux_name')
|
|
|
subname = self.Get('os_builder_linux_subname')
|
|
|
if subname:
|
|
|
subname = " %s" % subname
|
|
|
ver = self.Get('os_builder_linux_ver')
|
|
|
build = self.Get('os_builder_linux_build')
|
|
|
arch = self.Get('os_builder_arch_machine')
|
|
|
return self.fullname_format.format(
|
|
|
name=name, ver=ver, subname=subname, arch=arch, build=build)
|
|
|
|
|
|
|
|
|
class VariableOsBuilderLinuxSubname(BuilderLinux):
|
|
|
"""
|
|
|
Install subname
|
|
|
"""
|
|
|
variable = "os_linux_subname"
|
|
|
|
|
|
def init(self):
|
|
|
self.label = _("Subname")
|
|
|
|
|
|
def humanReadable(self):
|
|
|
return self.Get() or _("no")
|
|
|
|
|
|
class VariableClBuilderGpgKeys(BuilderLinux):
|
|
|
"""
|
|
|
GPG keys
|
|
|
"""
|
|
|
type = Variable.Types.List
|
|
|
variable = "cl_update_gpg_keys"
|
|
|
|
|
|
def get_fallback(self):
|
|
|
return []
|
|
|
|
|
|
class VariableClBuilderBinhostRevisionPath(BuilderLinux):
|
|
|
"""
|
|
|
Путь до revision файлов
|
|
|
"""
|
|
|
variable = "cl_update_binhost_revision_path"
|
|
|
type = Variable.Types.List
|
|
|
|
|
|
def get_fallback(self):
|
|
|
value = [
|
|
|
"grp/ini.env"
|
|
|
]
|
|
|
|
|
|
class VariableClBuilderBinhostTimestampPath(BuilderLinux):
|
|
|
"""
|
|
|
Путь до файла timestamp
|
|
|
"""
|
|
|
variable = "cl_update_binhost_timestamp_path"
|
|
|
type = Variable.Types.List
|
|
|
|
|
|
def get_fallback(self):
|
|
|
value = "timestamp"
|
|
|
|
|
|
|
|
|
class VariableClBuilderLastTimestamp(BuilderLinux):
|
|
|
"""
|
|
|
Путь до файла timestamp
|
|
|
"""
|
|
|
variable = "cl_update_last_timestamp"
|
|
|
|
|
|
def get_fallback(self):
|
|
|
value = "0"
|
|
|
|
|
|
|
|
|
class VariableClBuilderPortdirOverlay(ReadonlyVariable):
|
|
|
"""
|
|
|
Пути оверлеев в собираемом образе относительно точки монтирования
|
|
|
"""
|
|
|
|
|
|
def get(self):
|
|
|
return [location
|
|
|
for name, location in
|
|
|
filter(None, self.Get('builder.cl_builder_repository_data'))
|
|
|
if name not in ("portage", "gentoo")]
|
|
|
|
|
|
|
|
|
class VariableClBuilderOtherRepData(update.VariableClUpdateOtherRepData):
|
|
|
"""
|
|
|
Информация о прочих репозиториях
|
|
|
"""
|
|
|
source = ['builder.cl_builder_other_rep_name',
|
|
|
'builder.cl_builder_other_rep_path']
|
|
|
|
|
|
portdir_overlay = "builder.cl_builder_portdir_overlay"
|
|
|
|
|
|
|
|
|
class VariableClBuilderOtherRepName(FieldValue, ReadonlyVariable):
|
|
|
"""
|
|
|
Список имен прочих репозиториев
|
|
|
"""
|
|
|
type = "list"
|
|
|
source_variable = "builder.cl_builder_other_rep_data"
|
|
|
column = 0
|
|
|
|
|
|
|
|
|
class VariableClBuilderOtherRepPath(FieldValue, ReadonlyVariable):
|
|
|
"""
|
|
|
Список путей до прочих репозиториев
|
|
|
"""
|
|
|
type = "list"
|
|
|
source_variable = "builder.cl_builder_other_rep_data"
|
|
|
column = 1
|
|
|
|
|
|
|
|
|
class VariableClBuilderRepositoryData(ReadonlyTableVariable):
|
|
|
"""
|
|
|
"""
|
|
|
source = ["cl_repository_name", "cl_repository_location"]
|
|
|
|
|
|
def get(self, hr=HumanReadable.No):
|
|
|
try:
|
|
|
dv = self.Get('cl_builder_linux_datavars')
|
|
|
if dv:
|
|
|
return dv.Get('cl_repository_data')
|
|
|
except VariableError:
|
|
|
pass
|
|
|
return [[]]
|
|
|
|
|
|
|
|
|
class VariableClBuilderRepositoryName(FieldValue, ReadonlyVariable):
|
|
|
"""
|
|
|
"""
|
|
|
type = "list"
|
|
|
source_variable = "cl_builder_repository_data"
|
|
|
column = 0
|
|
|
|
|
|
|
|
|
class VariableClBuilderRepositoryLocation(FieldValue, ReadonlyVariable):
|
|
|
"""
|
|
|
"""
|
|
|
type = "list"
|
|
|
source_variable = "cl_builder_repository_data"
|
|
|
column = 1
|
|
|
|
|
|
|
|
|
class VariableClBuilderSyncOverlayRep(ReadonlyVariable):
|
|
|
"""
|
|
|
Обновляемые репозитории (исключая portage)
|
|
|
"""
|
|
|
type = "list"
|
|
|
|
|
|
def get(self):
|
|
|
action = self.Get('cl_action')
|
|
|
if action in Actions.ChangeProfile:
|
|
|
dv = self.Get('cl_builder_profile_datavars')
|
|
|
else:
|
|
|
dv = self.Get('cl_builder_linux_datavars')
|
|
|
if dv:
|
|
|
return list(filter(lambda x: x not in ("portage", "gentoo"),
|
|
|
dv.Get('cl_repository_name')))
|
|
|
else:
|
|
|
return []
|
|
|
|
|
|
|
|
|
class VariableClBuilderLinuxDistdir(ReadonlyVariable):
|
|
|
"""
|
|
|
Полный путь до DISTDIR собираемой системы относительно текущего корня
|
|
|
"""
|
|
|
|
|
|
def get(self):
|
|
|
fallback_distdir = '/var/calculate/remote/distfiles'
|
|
|
dv = self.Get('cl_builder_linux_datavars')
|
|
|
builder_path = self.Get('cl_builder_path')
|
|
|
if dv:
|
|
|
return pathJoin(builder_path, dv.Get('cl_distdir'))
|
|
|
return pathJoin(builder_path, fallback_distdir)
|
|
|
|
|
|
|
|
|
class VariableClBuilderLinuxPkgdir(ReadonlyVariable):
|
|
|
"""
|
|
|
Полный путь до PKGDIR собираемой системы относительно текущего корня
|
|
|
"""
|
|
|
|
|
|
def get(self):
|
|
|
fallback_pkgdir = '/var/calculate/remote/packages'
|
|
|
dv = self.Get('cl_builder_linux_datavars')
|
|
|
builder_path = self.Get('cl_builder_path')
|
|
|
if dv:
|
|
|
return pathJoin(builder_path, dv.Get('cl_pkgdir'))
|
|
|
return pathJoin(builder_path, fallback_pkgdir)
|
|
|
|
|
|
|
|
|
class VariableClBuilderBinhostBaseSet(ReadonlyVariable):
|
|
|
"""
|
|
|
Сборка использует базовый бинарный хост
|
|
|
"""
|
|
|
type = Variable.Types.Boolean
|
|
|
|
|
|
def get(self):
|
|
|
dv = self.Get('cl_builder_linux_datavars')
|
|
|
if dv:
|
|
|
return dv.Get('cl_update_binhost_base_set')
|
|
|
return Variable.Off
|
|
|
|
|
|
|
|
|
class VariableClBuilderBinhostBase(ReadonlyVariable):
|
|
|
"""
|
|
|
Адрес базового бинарного хоста в приоритете берётся базовый хост собирающей
|
|
|
системы, если не получилось, то из собираемой системы
|
|
|
"""
|
|
|
def get(self):
|
|
|
host_binhost_base = self.Get('update.cl_update_binhost_base')
|
|
|
if host_binhost_base:
|
|
|
return host_binhost_base
|
|
|
dv = self.Get('cl_builder_linux_datavars')
|
|
|
if dv:
|
|
|
return dv.Get('cl_update_binhost_base')
|
|
|
return ""
|
|
|
|
|
|
class VariableClBuilderPortageBinhost(ReadonlyVariable):
|
|
|
"""
|
|
|
Прописываемый в /etc/portage/make.conf/binhost репозиторий
|
|
|
"""
|
|
|
value_format = "{update.cl_update_binhost}/grp/{builder.os_builder_arch_machine}"
|
|
|
|