Добавлена поддержка создания контейнеров

parent ba9da952f9
commit f511841212

@ -26,14 +26,17 @@ from calculate.core.setup_package import ChainProgressTemplate
from calculate.lib.cl_template import templateFunction, SystemIni
from calculate.lib.datavars import DataVars, Variable
from calculate.lib.utils.colortext import (TextState, get_color_print)
from calculate.lib.utils.common import CmdlineParams
from calculate.lib.utils.common import CmdlineParams, getTupleVersion
from calculate.lib.utils.portage import BinaryPackage, get_binary_file
from calculate.lib.utils.files import (
pathJoin, PercentProgress, getProgPath, process, STDOUT, removeDir,
makeDirectory, writeFile, readLinesFile, chmod, chown, FilePermission,
find, FindFileType, removeFileWithEmptyDirectory, check_rw,
tar_xz_directory,
copyWithPath, countFiles, listDirectory, getRunCommands, isMount, readFile)
from calculate.lib.utils.git import Git
from calculate.builder.variables.action import Actions
from hashlib import sha256
from calculate.lib.utils.portage import (Layman, EmergeLog, EmergeLogNamedTask,
InstalledPackageInfo, EbuildInfoError,
EbuildInfo, ChrootEix, getRequires,
@ -43,6 +46,8 @@ from calculate.lib.utils.portage import (Layman, EmergeLog, EmergeLogNamedTask,
hide_packages, unhide_packages,
LibraryProviders,
PackageError, getInstalledAtom)
from calculate.lib.utils.tools import ReverseKey
from itertools import groupby
from calculate.update.emerge_parser import (EmergeParser,
EmergeError, EmergeCommand, Chroot,
Linux32, CommandExecutor,
@ -52,7 +57,7 @@ from calculate.update.update_tasks import EmergeMark
from .build_storage import Build
from calculate.update.update import Update
from calculate.install.distr import (Distributive, IsoDistributive,
DistributiveError)
DistributiveError, ContainerDistributive)
import shutil
from functools import partial
import os
@ -81,6 +86,7 @@ class Builder(Update):
Image = "builder_image"
Profile = "builder_profile"
UpdateMenu = "update_livemenu"
Container = "builder_container"
All = (Prepare, Break, Update, Restore, Image, Profile)
def init(self):
@ -157,6 +163,107 @@ class Builder(Update):
self.startTask(_("Pack ISO image"))
self.addProgress()
def prepare_container_data(self, dn):
"""
Подготовить мета данные rootfs.tar.xz
:param dn:
:return:
"""
self.set_builder_action(Actions.ImageContainer)
root_path = path.relpath(dn, self.clVars.Get('cl_builder_path'))
self.applyTemplates(self.clVars.Get('cl_builder_target'),
False, False, root_path)
self.endTask()
return True
def pack_container_data(self, dn, image):
"""
Запаковать содержимое в dn к образу root.tar.xz
:param dn:
:param image:
:return:
"""
for fn in listDirectory(dn, fullPath=True):
if path.isdir(fn):
fn_basename = path.basename(fn)
tar_xz_directory(fn,
path.join(image.basedirectory,
"%s.tar.xz") % fn_basename)
else:
fn_basename = path.basename(fn)
shutil.copy(fn, path.join(image, fn_basename))
return True
def create_digest_container(self, image):
"""
Создать контрольную сумму для файлов контейнера
:param dn:
:return:
"""
sumfn = "SHA256SUMS"
with writeFile(path.join(image.basedirectory, sumfn)) as f_sum:
for fn in listDirectory(image.basedirectory, fullPath=True):
if fn.endswith(sumfn):
continue
kb = 1024
hasher = sha256()
with open(fn) as f:
b = True
while b:
b = f.read(512 * kb)
hasher.update(b)
digest = hasher.hexdigest()
f_sum.write("%s %s\n" % (digest, path.basename(fn)))
return True
def update_http_meta(self, dn):
"""
Обновить индексный файл для lxc-download (meta/1.0/index-system)
:param dn:
:return:
"""
data = []
re_subbuild = re.compile("\/[^-]+-[^-]+-(\d+)-[^-]+$", re.I)
for container_dn in listDirectory(dn, fullPath=True):
with ContainerDistributive(container_dn) as distro:
info = distro.get_information()
if not info['cl_profile_name']:
continue
match_subbuild = re_subbuild.search(container_dn)
if match_subbuild:
subbuild = int(match_subbuild.group(1))
else:
subbuild = 0
data.append({
'dist': info['os_linux_shortname'],
'release': info['os_linux_ver'],
'arch': info['os_arch_machine'],
'variant': "default",
'build': info['os_linux_build'],
'fn': path.join("container", path.basename(container_dn)),
'subbuild': subbuild
})
def sort_key(info):
return (ReverseKey(getTupleVersion(info['release'])),
info['arch'],
info['dist'], ReverseKey(info['build']),
ReverseKey(info['subbuild']),
ReverseKey(info['fn']))
data.sort(key=sort_key)
with writeFile(path.join(dn, 'meta/1.0/index-system')) as f:
for k, grps in groupby(data, lambda x: (x['dist'],
x['release'],
x['arch'],
x['variant'])):
f.write("{dist};{release};{arch};"
"{variant};{build};{fn}\n".format(**grps.next()))
return True
def remove_container_data(self, dn):
removeDir(dn)
return True
def prepare_image(self, image):
image.eventPrepareIso.connect(self.prepare_iso)
return True

@ -18,6 +18,7 @@ import sys
from calculate.core.server.func import Action, Tasks
from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate
from calculate.lib.cl_template import TemplatesError
from calculate.lib.datavars import DataVarsError
from calculate.lib.utils.files import FilesError
from calculate.lib.variables.system import RootType
from calculate.update.emerge_parser import EmergeError
@ -38,7 +39,7 @@ class ClBuilderImageAction(Action):
"""
# ошибки, которые отображаются без подробностей
native_error = (DistributiveError, FilesError, UpdateError,
TemplatesError,
TemplatesError, DataVarsError,
BuilderError, GitError, EmergeError)
successMessage = __("Image created successfully")
@ -184,6 +185,27 @@ class ClBuilderImageAction(Action):
'message': __("Creating package list"),
'method': 'Builder.create_package_list(cl_builder_path,'
'cl_builder_image_filename)',
'condition': lambda Get: Get('cl_builder_container_set') == 'off'
},
{'name': 'container_data',
'condition': lambda Get: Get('cl_builder_container_set') == 'on'
},
{'name': 'container_data:prepare_container_data',
'message': __('Preparing container meta data'),
'method': 'Builder.prepare_container_data('
'cl_builder_container_data_path)',
},
{'name': 'prepare_container_data:pack_container_data',
'method': 'Builder.pack_container_data('
'cl_builder_container_data_path,cl_builder_image)',
},
{'name': 'pack_container_data:digest_container_data',
'message': __('Calculating SHA256 checksum'),
'method': 'Builder.create_digest_container(cl_builder_image)',
},
{'name': 'prepare_container_data!:clear_container_data',
'method': 'Builder.remove_container_data('
'cl_builder_container_data_path)'
},
{'name': 'umount_system!:mount_system',
'warning': _("Restore build system resources"),
@ -216,6 +238,10 @@ class ClBuilderImageAction(Action):
'condition': lambda Get: (
Get('builder.cl_builder_livemenu_path') != "")
},
{'name': 'pack_container_data:update_meta_index',
'message': __('Updating containers index'),
'method': 'Builder.update_http_meta(cl_builder_container_path)',
},
]
},
{'name': 'failed',

@ -87,7 +87,7 @@ class ClBuilderProfileAction(Action):
'tasks': [
{'name': 'sync_reps',
'foreach': 'cl_builder_profile_sync_rep',
'message': __("Syncing the {eachvar:capitalize} repository"),
'message': __("Checking the {eachvar:capitalize} repository"),
'method': 'Builder.syncRepositories(eachvar)',
},
{'name': 'regen_cache',

@ -37,6 +37,7 @@ class Actions(object):
ImageSquash = "squash"
ImageIso = "iso"
ImageContainer = "container"
ImageMenu = "menu"
PrepareAssemble = "prepare"
@ -66,6 +67,19 @@ class VariableAcBuilderIso(ActionVariable):
return "off"
class VariableAcBuilderContainer(ActionVariable):
"""
Действие выполняемое при подготовке метаданных контейнера
"""
def action(self, cl_action):
image_action = self.Get('cl_builder_action')
if (cl_action == Actions.Image and
image_action in (Actions.ImageContainer,)):
return "on"
return "off"
class VariableAcBuilderSetup(ActionVariable):
"""
Action variable which has value "on" for setup build directory
@ -77,7 +91,7 @@ class VariableAcBuilderSetup(ActionVariable):
return "on"
image_action = self.Get('cl_builder_action')
if (cl_action in (Actions.Image,) and
image_action == Actions.PrepareAssemble):
image_action == Actions.PrepareAssemble):
return "on"
return "off"
@ -92,6 +106,6 @@ class VariableAcBuilderPrepare(ActionVariable):
return "on"
image_action = self.Get('cl_builder_action')
if (cl_action in (Actions.Image,) and
image_action == Actions.PrepareAssemble):
image_action == Actions.PrepareAssemble):
return "on"
return "off"

@ -20,19 +20,21 @@ from os import path
import os
import re
from calculate.install.distr import DistributiveError, IsoDistributive
from calculate.install.variables.kernel import KernelConfig
from calculate.install.variables.kernel import KernelConfig, VariableInterface
from calculate.lib.utils.dracut import Dracut
from calculate.lib.utils.grub import GrubCommand
from calculate.lib.utils.portage import getSquashList
from calculate.lib.utils.portage import getSquashList, isPkgInstalled
from calculate.lib.variables.system import RootType
from .action import Actions
import linux as vars_linux
import datetime
from calculate.install import distr
from calculate.lib.utils.device import getUdevDeviceInfo, humanreadableSize
from calculate.lib.utils.files import (isMount, process, typeFile,
listDirectory,
pathJoin, readFile, check_rw)
from calculate.lib.utils.kernel import InitrdFile
from calculate.lib.utils.text import _u8
from calculate.lib.utils.tools import max_default
from calculate.lib.utils.git import Git
from ..build_storage import BuildStorage, Build
@ -51,7 +53,6 @@ setLocalTranslate('cl_builder3', sys.modules[__name__])
__ = getLazyLocalTranslate(_)
def is_action(*available_action, **action_kwargs):
def decorator(func):
@wraps(func)
@ -66,6 +67,56 @@ def is_action(*available_action, **action_kwargs):
return decorator
class IsoTypeHelper(VariableInterface):
"""
Вспомогательный объект для переменных контейнера
"""
def uncompatible(self):
if self.GetBool("cl_builder_container_set"):
return _("This option is not compatible with container image")
return ""
class ContainerHelper(VariableInterface):
"""
Вспомогательный объект для переменных контейнера
"""
def uncompatible(self):
if not self.GetBool("cl_builder_container_set"):
return _("This option is not compatible with ISO image")
return ""
class ImagePathHelper(VariableInterface):
"""
Создание временного каталога для подготовки образа
"""
@property
def base_dn(self):
return self.Get('cl_builder_iso_base_path')
@property
def build_id(self):
return self.Get('cl_builder_id')
@property
def build_id_path(self):
return self.Get('cl_builder_id_path')
prefix = ""
def get(self):
if self.build_id:
dn = "%s%s" % (self.prefix, self.build_id_path)
directory = path.join(self.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 VariableClBuilderStorage(ReadonlyVariable):
type = "object"
@ -120,7 +171,7 @@ class VariableClBuilderVideoDriverPath(Variable):
'var/cache/calculate/video_drivers')
class VariableClBuilderVideodrvSet(Variable):
class VariableClBuilderVideodrvSet(IsoTypeHelper, Variable):
"""
Нужно ли скачивать пакеты в дистрибутив для установки проприетарных
драйверов во время загрузки
@ -340,7 +391,7 @@ class VariableClBuilderDiskSize(DiskFreeHelper):
return "0"
class VariableClBuilderPrepareFreeSize(DiskFreeHelper):
class VariableClBuilderPrepareFreeSize(IsoTypeHelper, DiskFreeHelper):
"""
Свободное место используемое для подготовки образа
"""
@ -354,7 +405,7 @@ class VariableClBuilderPrepareFreeSize(DiskFreeHelper):
return str(self.get_free_for(dn))
class VariableClBuilderImageFreeSize(DiskFreeHelper):
class VariableClBuilderImageFreeSize(IsoTypeHelper, DiskFreeHelper):
"""
Свободное место на диске, где создается iso образ
"""
@ -368,6 +419,20 @@ class VariableClBuilderImageFreeSize(DiskFreeHelper):
return str(self.get_free_for(dn))
class VariableClBuilderContainerFreeSize(ContainerHelper, DiskFreeHelper):
"""
Свободное место на диске, где создается iso образ
"""
def init(self):
self.label = _("Free disk space for container 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):
"""
Сборка будет выполняться в слое
@ -551,7 +616,7 @@ class VariableClBuilderNewId(BaseBuildId):
if value and not re.match("^[A-Za-z][A-Za-z0-9/:_+-]+$", value):
raise VariableError(_("Wrong symbols in the build ID"))
if value in self.Get('cl_builder_storage'):
raise VariableError(_("Build %s already exists") % value)
raise VariableError(_("Build %s already exists") % _u8(value))
class VariableClBuilderPreparedId(BaseBuildId):
@ -586,6 +651,16 @@ class VariableClBuilderPreparedId(BaseBuildId):
else:
yield (x, x)
def _is_iso_compatible(self):
prefix = self.Get('cl_builder_path')
if len(self.Get('cl_builder_kernel_config')):
for pn in ('sys-kernel/calculate-sources', 'sys-kernel/dracut',
'media-gfx/gfxboot-themes-calculate', 'sys-boot/grub'):
if not isPkgInstalled(pn, prefix=prefix):
return False
return True
return False
def check(self, value):
if not value:
raise VariableError(_("Please select the build ID"))
@ -597,6 +672,20 @@ class VariableClBuilderPreparedId(BaseBuildId):
raise VariableError(
_("Build %s is broken, try to restore build") % value)
image_type = self.Get('cl_builder_image_type')
if image_type == "iso":
if not self._is_iso_compatible():
prefix = self.Get('cl_builder_path')
for pn in ('sys-kernel/calculate-sources', 'sys-kernel/dracut',
'media-gfx/gfxboot-themes-calculate',
'sys-boot/grub'):
if not isPkgInstalled(pn, prefix=prefix):
raise VariableError(
_("Build without %s can be container only") % pn)
raise VariableError(
_("Build without kernel can be container only"))
class VariableClBuilderBrokenId(BaseBuildId):
"""
@ -745,13 +834,28 @@ class VariableClBuilderImagePath(Variable):
value = '/var/calculate/linux'
class VariableClBuilderContainerPath(Variable):
"""
Путь по умолчанию для образов LXC
"""
value = '/var/calculate/container'
class VariableClBuilderConainterIndexPath(Variable):
"""
Путь по умолчанию для создания индекса контейнеров
"""
value = "{cl_builder_container_path}/meta/1.0/index-system"
class VariableClBuilderImageFilename(Variable):
"""
Название iso образа
"""
opt = ["--iso"]
opt = ["--image"]
metavalue = "IMAGE"
untrusted = True
check_after = "cl_builder_container_set"
def init(self):
self.label = _("Image path")
@ -761,28 +865,31 @@ class VariableClBuilderImageFilename(Variable):
if self.Get('cl_builder_id'):
if not value:
raise VariableError(_("You must specify image filename"))
if not value.endswith(".iso"):
raise VariableError(_("You must specify image filename with "
"'iso' suffix"))
if path.isdir(value):
raise VariableError(_("The image shouldn't be a directory"))
for line in process("/bin/losetup", "-j", value):
lodev, op, line = line.partition(":")
if lodev:
raise VariableError(
_("Image %s is already used") % value)
if not self.GetBool("cl_builder_container_set"):
if not value.endswith(".iso"):
raise VariableError(_("You must specify image filename with "
"'iso' suffix"))
if path.isdir(value):
raise VariableError(_("The image shouldn't be a directory"))
for line in process("/bin/losetup", "-j", value):
lodev, op, line = line.partition(":")
if lodev:
raise VariableError(
_("Image %s is already used") % value)
elif path.exists(value) and not path.isdir(value):
raise VariableError(_("The image should be a directory"))
def _isoname(self, dn, rewrite=False, addon_dn=None):
def _isoname(self, dn, rewrite=False, addon_dn=None, suffix=".iso"):
shortname = self.Get('os_builder_linux_shortname').lower()
buildnumber = self.Get('os_builder_linux_build')
arch = self.Get('os_builder_arch_machine')
for i in range(0, 999):
if i:
isoname = "%s-%s-%d-%s.iso" % (shortname, buildnumber,
i, arch)
isoname = "%s-%s-%d-%s%s" % (shortname, buildnumber,
i, arch, suffix)
else:
isoname = "%s-%s-%s.iso" % (shortname, buildnumber,
arch)
isoname = "%s-%s-%s%s" % (shortname, buildnumber,
arch, suffix)
fullname = ""
for i_dn in filter(None, (addon_dn, dn)):
fullname = path.join(i_dn, isoname)
@ -793,7 +900,10 @@ class VariableClBuilderImageFilename(Variable):
def get(self):
build_id = self.Get('cl_builder_id')
base_dn = self.Get('cl_builder_image_path')
if self.GetBool('cl_builder_container_set'):
base_dn = self.Get('cl_builder_container_path')
else:
base_dn = self.Get('cl_builder_image_path')
if build_id:
root_type_ext = self.Get('os_root_type_ext')
@ -807,6 +917,8 @@ class VariableClBuilderImageFilename(Variable):
raise VariableError(
_("Failed to determine the isoscan path"))
return self._isoname(base_dn, rewrite=False)
elif self.GetBool('cl_builder_container_set'):
return self._isoname(base_dn, rewrite=False, suffix='')
else:
return self._isoname(base_dn, rewrite=False)
return ""
@ -827,26 +939,11 @@ class VariableClBuilderIsoBasePath(Variable):
return self.default_value
class VariableClBuilderIsoPath(ReadonlyVariable):
class VariableClBuilderIsoPath(ImagePathHelper, 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 ""
prefix = "iso-"
class VariableClBuilderSquashPath(ReadonlyVariable):
@ -871,12 +968,19 @@ class VariableClBuilderImage(ReadonlyVariable):
bdn = self.Get('cl_builder_iso_path')
exclude_list = self.Get('cl_builder_squash_exclude')
include_list = self.Get('cl_builder_video_ebuilds')
iso = distr.IsoDistributive(image_name, bdirectory=bdn,
vol_id=self.Get('cl_builder_iso_label'),
exclude=exclude_list,
include=include_list,
compress=self.Get('cl_builder_compress'))
return iso
if self.GetBool('cl_builder_container_set'):
image = distr.ContainerDistributive(
image_name,
exclude=exclude_list,
include=include_list)
else:
image = distr.IsoDistributive(
image_name, bdirectory=bdn,
vol_id=self.Get('cl_builder_iso_label'),
exclude=exclude_list,
include=include_list,
compress=self.Get('cl_builder_compress'))
return image
class VariableClBuilderLiveSet(Variable):
@ -1211,7 +1315,7 @@ class VariableClBuilderBranchName(Variable):
return []
class VariableClBuilderCompress(Variable):
class VariableClBuilderCompress(IsoTypeHelper, Variable):
"""
Тип сжатия образа squash
"""
@ -1219,7 +1323,7 @@ class VariableClBuilderCompress(Variable):
opt = ["-c", "--compress"]
metavalue = "COMPRESS"
untrusted = True
check_after = ["cl_builder_id"]
check_after = ["cl_builder_id", "cl_builder_container_set"]
def init(self):
self.label = _("Compressor")
@ -1244,28 +1348,42 @@ class VariableClBuilderCompress(Variable):
weight = {'xz': 2, 'gzip': 1}
return list(sorted(generator(),
key=lambda x: (-weight.get(x, 0), x)))
ret = list(sorted(generator(),
key=lambda x: (-weight.get(x, 0), x)))
if not ret:
return [""]
return ret
def get(self):
if self.GetBool("cl_builder_container_set"):
return "xz"
values = self.choice()
if values:
return values[0]
return ""
class VariableClBuilderIsohybridSet(Variable):
class VariableClBuilderIsohybridSet(IsoTypeHelper, Variable):
"""
Преобразовать полученный iso образ в гибридный
"""
type = "bool"
opt = ["--isohybrid"]
value = "on"
check_after = ["cl_builder_container_set"]
def init(self):
self.help = _("create the ISO image with isohybrid")
self.label = _("ISO hybrid feature")
def check(self, value):
if self.GetBool("cl_builder_container_set") and value != "off":
raise VariableError(_("Iso hybrid is uncompatible with container"))
def get(self):
if self.GetBool("cl_builder_container_set"):
return "off"
return "on"
class VariableClBuilderKeepTreeSet(Variable):
"""
@ -1713,3 +1831,105 @@ class VariableClBuilderUpdateThemesSet(Variable):
def init(self):
self.label = _("Update themes")
self.help = _("update themes")
class VariableClBuilderImageType(Variable):
"""
Тип собираемого образа
"""
type = "choice"
def init(self):
self.label = _("Image type")
self.help = _("set image type")
def choice(self):
return (("container", _("Container")),
("iso", _("ISO")))
class VariableClBuilderContainerSet(ReadonlyVariable):
"""
Запаковать образ как LXC контейнер
"""
type = "bool"
def get(self):
if self.Get('cl_builder_image_type') == 'container':
return 'on'
return 'off'
class VariableClBuilderContainerDist(Variable):
"""
Название операционной системы
"""
value = "calculate"
class VariableClBuilderContainerRelease(Variable):
"""
Версия ОС контейнера
"""
def get(self):
return self.Get('os_builder_linux_ver')
class VariableClBuilderContainerArch(Variable):
"""
Архитектура ОС в контейнере
"""
def get(self):
return self.Get('os_builder_arch_machine_gentoo')
class VariableClBuilderContainerVariant(Variable):
"""
Variant of image
"""
value = "default"
class VariableClBuilderContainerExpiryTimestamp(Variable):
"""
Expire date
"""
month = 60 * 60 * 24 * 30
type = "int"
def get(self):
return str(int(self.Get('cl_builder_container_create_timestamp')) +
self.month)
class VariableClBuilderContainerCreateTimestamp(Variable):
"""
Expire date
"""
type = "int"
def get(self):
return datetime.datetime.now().strftime("%s")
class VariableClBuilderContainerDate(Variable):
"""
Creation date of image
"""
def get(self):
ts = int(self.Get('cl_builder_container_create_timestamp'))
return datetime.datetime.fromtimestamp(ts).strftime("%Y%m%d_%H:%M")
class VariableClBuilderContainerBasePath(Variable):
"""
Базовый путь для подготовки архивов meta.tar.xz lxd.tar.xz
"""
value = "/var/calculate/tmp"
class VariableClBuilderContainerDataPath(ImagePathHelper, Variable):
"""
Путь где будут подготавливаться данные для контейнера
"""
@property
def base_dn(self):
return self.Get('cl_builder_container_base_path')
prefix = "lxc-"

@ -108,19 +108,21 @@ class DataVarsBuilderLinux(linux.LinuxDataVars):
system.VariableOsArchMachineGentoo()]
@classmethod
def StageInformation(cls, fn):
re_stage = re.compile("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'}
def StageInformation(cls, image, fn):
c = {}
if isinstance(image, distr.ContainerDistributive):
c = image.get_information()
else:
c = {}
re_stage = re.compile("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:
@ -174,7 +176,7 @@ class VariableClBuilderLinuxDatavars(ReadonlyVariable):
def get_data(self, image, image_fn=None, source=False):
if image:
if isinstance(image, distr.ArchiveDistributive):
return DataVarsBuilderLinux.StageInformation(image_fn)
return DataVarsBuilderLinux.StageInformation(image, image_fn)
with image:
with ignore(DistributiveError):
distr_dn = image.getDirectory()

@ -16,6 +16,7 @@
import sys
from os import path
from calculate.install import distr
from calculate.lib.datavars import (ReadonlyVariable, FieldValue)
from calculate.lib.variables import linux as lib_linux
from calculate.lib.variables import system as lib_system
@ -135,6 +136,15 @@ class VariableClBuilderProfileName(lib_linux.VariableClProfileName):
def init(self):
self.label = _("System profile")
def get(self):
action = self.Get('cl_action')
if action == Actions.Prepare:
source = self.Get('cl_builder_source')
if isinstance(source, distr.ContainerDistributive):
return source.get_information().get("cl_profile_name",
_("Unknown"))
return super(VariableClBuilderProfileName, self).get()
class VariableClBuilderProfileRepoName(update.VariableClUpdateProfileRepoName):
"""

@ -328,6 +328,71 @@ class Wsdl(WsdlBase):
'cl_dispatch_conf'),
next_label=_("Run"))],
},
{
# идентификатор метода
'method_name': Builder.Method.Container,
# категория метода
'category': __('Builder'),
# заголовок метода
'title': __("Create the Container"),
# иконка для графической консоли
'image': 'calculate-builder-image,media-optical,media-optical-data',
# метод присутствует в графической консоли
'gui': True,
# консольная команда
'command': 'cl-builder-container',
# права для запуска метода
'rights': ['build'],
# объект содержащий модули для действия
'logic': {'Builder': Builder,
'Install': Install},
# описание действия
'action': ClBuilderImageAction,
# объект переменных
'datavars': "builder",
'native_error': (VariableError, DataVarsError, EmergeError,
InstallError, BuilderError, GitError),
# значения по умолчанию для переменных этого метода
'setvars': {'cl_action!': BuilderActions.Image,
'cl_builder_image_type': 'container',
'cl_dispatch_conf_default': 'usenew'},
# описание груп (список лямбда функций)
'groups': [
lambda group: group(_("Create the Container"),
normal=('cl_builder_prepared_id',
'cl_builder_image_filename',
),
brief=('cl_builder_prepared_id',
'os_builder_linux_fullname',
'os_builder_linux_shortname',
'os_builder_linux_subname',
'os_builder_linux_system',
'os_builder_linux_ver',
'os_builder_linux_build',
'cl_builder_image_filename',
'cl_builder_keep_tree_set',
'cl_builder_prelink_set',
'cl_builder_container_free_size'
),
hide=('cl_templates_locate',
'cl_verbose_set',
'cl_dispatch_conf'
'cl_builder_prepared_id',
'cl_builder_image_filename',
'cl_builder_keep_tree_set',
'cl_builder_prelink_set',
),
expert=(
'cl_builder_keep_tree_set',
'cl_builder_prelink_set',
'cl_builder_binhost_stable_set',
'cl_templates_locate',
'cl_verbose_set',
'cl_dispatch_conf'),
next_label=_("Next"))],
'brief': {'next': __("Run"),
'name': __("Create the Container")}
},
{
# идентификатор метода
'method_name': Builder.Method.Image,
@ -354,6 +419,7 @@ class Wsdl(WsdlBase):
InstallError, BuilderError, GitError),
# значения по умолчанию для переменных этого метода
'setvars': {'cl_action!': BuilderActions.Image,
'cl_builder_image_type': 'iso',
'cl_dispatch_conf_default': 'usenew'},
# описание груп (список лямбда функций)
'groups': [

Loading…
Cancel
Save