Множественные изменения

Mike Khiretskiy 9 years ago
parent 22703407d2
commit 08bbdc6142

@ -20,6 +20,7 @@ import os
import sys
from os import path
from calculate.lib.datavars import SimpleDataVars, Variable
from calculate.install.distr import Distributive
from calculate.lib.cl_lang import (setLocalTranslate, getLazyLocalTranslate, _)
import time
@ -33,13 +34,33 @@ from .datavars import builder_data
setLocalTranslate('cl_builder3', sys.modules[__name__])
__ = getLazyLocalTranslate(_)
UTF8 = 'utf-8'
class Build(object):
"""
Сборка
"""
class Status(object):
WORKED, REGISTERED, REMOVED, BROKEN, UNREGISTERED = range(5)
Worked, Registered, Removed, Broken, Unregistered = range(5)
class Parameter(object):
HashId = "hash"
Directory = "directory"
PkgDir = "pkgdir"
References = "references"
types = {HashId: Variable.Types.String,
Directory: Variable.Types.String,
References: Variable.Types.List,
PkgDir: Variable.Types.String,
}
attrs = {'pkgdir': PkgDir,
'references': References}
class Branches:
Stable = "master"
Unstable = "update"
def __init__(self, build_id, distributive, parent, restore=False):
"""
@ -50,10 +71,12 @@ class Build(object):
self.parent = parent
self.id = build_id
self.pkgdir = ""
self.default_branch = Build.Branches.Stable
self.references = []
self._hash = None
if not restore:
self.parent.reserve_id(self.id)
self.status = Build.Status.REGISTERED
self.status = Build.Status.Registered
@property
def build_hash(self):
@ -65,14 +88,17 @@ class Build(object):
self._hash = hash_info
return self._hash
def set_overlays(self, overlays):
self.references = [self.default_branch for x in overlays]
@property
def directory(self):
return self.distributive.getDirectory()
def generate_hash_id(self):
assemble_name = (self.id +
self.distributive.getType().decode('utf-8')
+ unicode(time.time())).encode('utf-8')
self.distributive.getType().decode(UTF8)
+ unicode(time.time())).encode(UTF8)
return hashlib.sha1(assemble_name).hexdigest()
def save(self):
@ -80,16 +106,16 @@ class Build(object):
Сохранить сборку
"""
self.parent.save_build(self)
self.status = Build.Status.WORKED
self.status = Build.Status.Worked
def remove(self):
"""
Удалить сборку
"""
if self.status in (Build.Status.REGISTERED, Build.Status.WORKED,
Build.Status.BROKEN):
if self.status in (Build.Status.Registered, Build.Status.Worked,
Build.Status.Broken):
self.parent.remove_build(self)
self.status = Build.Status.REMOVED
self.status = Build.Status.Removed
self.id = None
self._hash = None
@ -129,7 +155,7 @@ class BuildStorage(object):
def _get_ini(self):
ini = ConfigParser()
ini.read(self.ini_file, encoding='utf-8')
ini.read(self.ini_file, encoding=UTF8)
return ini
def _get_ini_with_lock(self):
@ -166,14 +192,15 @@ class BuildStorage(object):
:param build: сборка
:return:
"""
build_directory = build.distributive.getDirectory()
build_id = build.id
build_hash = build.build_hash
build_pkgdir = build.pkgdir
d = {Build.Parameter.Directory: build.distributive.getDirectory(),
Build.Parameter.HashId: build.build_hash}
for k, v in Build.Parameter.attrs.items():
d[v] = SimpleDataVars.serialize(Build.Parameter.types[v],
getattr(build, k))
with self.modify_ini() as ini:
ini[build_id]['hash'] = build_hash
ini[build_id]['directory'] = build_directory
ini[build_id]['pkgdir'] = build_pkgdir
for k, v in d.items():
ini[build_id][k] = v
mount_dump_file = self.get_dump_name(build.build_hash)
with writeFile(mount_dump_file) as f:
@ -190,7 +217,8 @@ class BuildStorage(object):
:return:
"""
ini = self._get_ini_with_lock()
hashes = [ini.get(x, 'hash', fallback="").encode('utf-8') for x in ini]
hashes = [ini.get(x, Build.Parameter.HashId,
fallback="").encode(UTF8) for x in ini]
for fn in listDirectory(self.data_dir):
if fn not in hashes:
try:
@ -200,7 +228,7 @@ class BuildStorage(object):
def __iter__(self):
ini = self._get_ini_with_lock()
return iter([x.encode('utf-8') for x in ini if x != 'DEFAULT'])
return iter([x.encode(UTF8) for x in ini if x != 'DEFAULT'])
def clear_unmounted(self):
"""
@ -209,22 +237,23 @@ class BuildStorage(object):
:return:
"""
with self.modify_ini() as ini:
dist_dirs = [(x.encode('utf-8'),
ini.get(x, 'directory',
fallback="").encode('utf-8'))
dist_dirs = [(x.encode(UTF8),
ini.get(x, Build.Parameter.Directory,
fallback="").encode(UTF8))
for x in ini.keys()]
for k, v in dist_dirs:
if v is None or not isMount(v):
ini.remove_section(k)
def get_build_hash(self, build_id):
return self._get_ini_with_lock().get(build_id, 'hash', fallback=None)
return self._get_ini_with_lock().get(build_id, Build.Parameter.HashId,
fallback=None)
def get_build(self, build_id):
ini = self._get_ini_with_lock()
build_hash = ini.get(build_id, 'hash', fallback=None)
build_hash = ini.get(build_id, Build.Parameter.HashId, fallback=None)
if build_hash:
build_dir = ini.get(build_id, 'directory')
build_dir = ini.get(build_id, Build.Parameter.Directory)
data = readFile(self.get_dump_name(build_hash))
if data:
try:
@ -236,10 +265,14 @@ class BuildStorage(object):
build = Build(build_id, dist, self, restore=True)
proc_build_dir = path.join(build_dir, 'proc')
if isMount(build_dir) and isMount(proc_build_dir):
build.status = build.Status.WORKED
build.status = build.Status.Worked
else:
build.status = build.Status.BROKEN
build.pkgdir = ini.get(build_id, 'pkgdir', fallback=None)
build.status = build.Status.Broken
for param_name, ini_name in Build.Parameter.attrs.items():
value = ini.get(build_id, ini_name, fallback="")
value = SimpleDataVars.unserialize(
Build.Parameter.types[ini_name], value)
setattr(build, param_name, value)
return build
def remove_build(self, build):

@ -13,23 +13,42 @@
# 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.
from itertools import chain
import sys
import time
from calculate.lib.datavars import DataVars
from calculate.lib.utils.colortext import TextState, get_color_print, \
convert_console_to_xml
from calculate.lib.utils.files import (
pathJoin, PercentProgress, getProgPath, process, STDOUT, removeDir,
makeDirectory, writeFile, readLinesFile, chmod, chown, FilePermission,
find, FindFileType, removeFileWithEmptyDirectory,
copyWithPath)
from calculate.lib.utils.portage import Layman, EmergeLog, EmergeLogNamedTask, \
InstalledPackageInfo, EbuildInfoError, EbuildInfo, ChrootEix
from calculate.update.emerge_parser import EmergeParser, \
EmergeError, ChrootEmergeCommand, ChrootCommandExecutor
from .build_storage import Build
from calculate.update.update import Update
from calculate.install.distr import Distributive
import os
from os import path
from .datavars import BuilderError
from .emerge_fetch import EmergeFetcher, EmergeFetcherError
from calculate.lib.cl_lang import (setLocalTranslate, getLazyLocalTranslate, _)
setLocalTranslate('cl_builder3', sys.modules[__name__])
__ = getLazyLocalTranslate(_)
class Builder(object):
class Builder(Update):
"""Основной объект для выполнения действий связанных со сборкой системы
"""
def init(self):
pass
self.pretend_package_list = {}
self.update_map = {}
self.color_print = get_color_print()
def mount_target(self, target):
dir_distro = target.convertToDirectory()
@ -65,8 +84,11 @@ class Builder(object):
build.restore()
return True
def save_build(self, build):
def save_build(self, build, dv):
build.pkgdir = self.clVars.Get('cl_builder_pkgdir')
if dv:
overlays = dv.Get('cl_update_rep_name')
build.set_overlays(overlays)
build.save()
return True
@ -87,3 +109,567 @@ class Builder(object):
def prepare_image(self, image):
image.eventPrepareIso.connect(self.prepare_iso)
return True
#def test_builder(self):
# path_chroot = self.clVars.Get('cl_builder_path')
# d1 = dict(zip(
# map(lambda x: pathJoin(path_chroot, x),
# self.clVars.Get('cl_builder_repository_location')),
# self.clVars.Get('cl_builder_repository_name')))
# print d1
# d2 = dict(zip(self.clVars.Get('update.cl_update_rep_path'),
# self.clVars.Get('update.cl_update_rep_name')))
# print d2
# print "!!!!!!",self.clVars.Get('cl_builder_linux_datavars').Get('cl_update_rep_path')
# print "!!!!!!",self.clVars.Get('cl_builder_profile_datavars').Get('cl_update_rep_path')
# return True
def remove_repositories(self, repname):
dv = self.clVars.Get('cl_builder_linux_datavars')
rpath = dv.Select("cl_update_rep_path",
where="cl_update_rep_name", eq=repname, limit=1)
chroot_path = path.normpath(self.clVars.Get('cl_chroot_path'))
rpath_orig = rpath[len(chroot_path):]
layman = Layman(self.clVars.Get('update.cl_update_layman_installed'),
self.clVars.Get('update.cl_update_layman_make'),
self.clVars.Get('update.cl_update_layman_conf'))
if repname != "portage":
layman.remove(repname, rpath_orig)
removeDir(rpath)
return True
def set_profile(self, profile_shortname, chroot_path):
profile = self.clVars.Select('cl_builder_profile_path',
where='cl_builder_profile_shortname',
eq=profile_shortname, limit=1)
if not profile:
raise BuilderError(_("Failed to determine profile %s") %
profile_shortname)
chroot_join = lambda x: path.join(chroot_path, x)
profile_path = path.relpath(profile, chroot_join('etc/portage'))
try:
for rm_fn in filter(path.lexists,
(chroot_join('etc/make.profile'),
chroot_join('etc/portage/make.profile'))):
os.unlink(rm_fn)
os.symlink(profile_path, chroot_join('etc/portage/make.profile'))
except (OSError,IOError) as e:
print str(e)
raise BuilderError(_("Failed to set the profile: %s")%str(e))
return True
def apply_templates(self,target=None,useClt=None,cltFilter=False,root=None,
useDispatch=True, action="merge", distro_dv=None):
"""
Применить шаблоны.
Args:
target: дистрибутив, куда необходимо выполнить шаблоны (/ по умолчанию)
useClt: использовать clt шаблоны
cltFilter: применять фильтр на clt шаблоны
root: каталог, куда будут наложны шаблоны (cl_root_path)
"""
from calculate.lib.cl_template import (TemplatesError,
ProgressTemplate)
if target is None:
chroot = '/'
elif isinstance(target, Distributive):
chroot = target.getDirectory()
else:
chroot = target
if root is None:
root = '/'
elif isinstance(root, Distributive):
root = root.getDirectory()
clVars = DataVars()
clTempl = None
try:
clVars.importData()
# TODO: использование параметра -T
if distro_dv:
clVars.Set('cl_template_path_use',
[pathJoin(chroot, x) for x in distro_dv.Get('cl_template_path')],
force=True)
clVars.Set('cl_env_path',
[pathJoin(chroot, x) for x in clVars.Get('cl_env_path')],
force=True)
clVars.Set('cl_make_profile', path.join(chroot,
'etc/portage/make.profile'), force=True)
clVars.Set('cl_action', action, force=True)
clVars.Set('cl_verbose_set', self.clVars.Get('cl_verbose_set'))
clVars.Set('cl_chroot_status', 'on', force=True)
#clVars.Set("cl_dispatch_conf", self.clVars.Get('cl_dispatch_conf'),
# force=True)
clVars.flIniFile()
cltFilter=True if cltFilter in (True,"on") else False
clVars.Set("cl_chroot_path", chroot, True)
clVars.Set("cl_root_path", root, True)
# определение каталогов содержащих шаблоны
dirs_list, files_list = ([],[])
useClt = useClt in ("on", True)
self.addProgress()
nullProgress = lambda *args,**kw:None
dispatch = self.dispatchConf if useDispatch else None
clTempl = ProgressTemplate(nullProgress,clVars,
cltObj=useClt,
cltFilter=cltFilter,
printSUCCESS=self.printSUCCESS,
printWARNING=self.printWARNING,
askConfirm=self.askConfirm,
dispatchConf=dispatch,
printERROR=self.printERROR)
def execute_command(cmd, lang):
chroot_cmd = getProgPath("/usr/bin/chroot", )
chroot_path = self.clVars.Get('cl_builder_path')
return process(chroot_cmd, chroot_path,
cmd, lang=lang, envdict=dict(os.environ))
# замена выполения команд: вместо оычного запуска - запуск через
# /usr/bin/chroot
clTempl.execute_command = execute_command
clTempl.applyTemplates()
if clTempl.hasError():
if clTempl.getError():
raise TemplatesError(clTempl.getError())
finally:
clVars.close()
if clTempl:
if clTempl.cltObj:
clTempl.cltObj.closeFiles()
clTempl.closeFiles()
return True
def get_prog_path(self, progname):
chroot_path = self.clVars.Get('builder.cl_builder_path')
return getProgPath(progname, chroot_path)
def _eixUpdateCommand(self, eix_cmd, countRep):
chroot_path = self.clVars.Get('cl_builder_path')
return PercentProgress("/usr/bin/chroot", chroot_path, eix_cmd,
"-F", part=countRep or 1, atty=True)
def regenCache(self, repname):
with self.clVars.useDefaultModule("update"):
return super(Builder, self).regenCache(repname)
def syncRepositories(self, repname, clean_on_error=True):
with self.clVars.useDefaultModule("update"):
return super(Builder, self).syncRepositories(repname)
def _regenCache_process(self, progname, repname, cpu_num):
chroot_path = self.clVars.Get('builder.cl_builder_path')
return process("/usr/bin/chroot", chroot_path,
progname, "--repo=%s" % repname, "--update",
"--jobs=%s" % cpu_num, stderr=STDOUT)
def clear_log(self, builder_id):
logname = "build-%s" % builder_id
mainlog = self.clVars.Get('core.cl_log_path')
logpath = path.join(mainlog, logname)
if path.exists(logpath):
removeDir(logpath)
makeDirectory(logpath)
return True
def _get_log_file(self):
logname = "build-%s/%s" % (self.clVars.Get('cl_builder_id'),
self.clVars.Get('cl_task_name'))
mainlog = self.clVars.Get('core.cl_log_path')
return path.join(mainlog, logname)
def emerge_ask(self, param, *packages):
"""
Вывести информацию об обновлении
"""
deo = self.clVars.Get('cl_emerge_default_opts')
param = [param]
chroot_path = self.clVars.Get('cl_builder_path')
logfile = self._get_log_file()
with EmergeParser(ChrootEmergeCommand(chroot_path,
list(packages),
emerge_default_opts=deo,
extra_params=param,
logfile=logfile
)) as emerge:
try:
emerge.question.action = lambda x: False
emerge.run()
if emerge.install_packages.list:
emergelike = self.clVars.Get(
'update.cl_update_emergelist_set') == 'on'
self._display_install_package(emerge, emergelike)
answer = self.askConfirm(
_("Would you like to merge these packages?"), "yes")
if answer == "no":
emerge.command.send("no\n")
raise KeyboardInterrupt
else:
self.printSUCCESS("Nothing to merge")
except EmergeError as e:
self.set_need_update(False)
self.emerge_cache.drop_cache("Emerge error")
self._display_install_package(emerge, emergelike=True)
self._display_error(emerge.prepare_error)
raise
self._startEmerging(emerge)
return True
def depclean(self):
"""
Выполнить очистку системы от лишних пакетов
"""
deo = self.clVars.Get('cl_emerge_default_opts')
chroot_path = self.clVars.Get('cl_builder_path')
logfile = self._get_log_file()
with EmergeParser(
ChrootEmergeCommand(chroot_path, ["--depclean", "--ask=y"],
logfile=logfile,
emerge_default_opts=deo)) as emerge:
try:
emerge.question.action = lambda x: False
emerge.run()
if emerge.uninstall_packages.list:
self._display_remove_list(emerge)
if (self.askConfirm(
_("Would you like to unmerge these unused packages "
"(recommended)?")) != 'yes'):
return True
self._startEmerging(emerge)
else:
self.printSUCCESS("Nothing to unmerge")
except EmergeError:
self._display_error(emerge.prepare_error)
raise
return True
def chroot_command(self, builder_path, command, *params):
"""
Выполенине eix-update для репозиторием
eix-update выполнятется только для тех репозиториев, которые
обновлялись, если cl_update_eixsync_force==auto, либо
все, если cl_update_eixupdate_force==force
"""
cmdpath = self.get_prog_path(command)
if not cmdpath:
return "skip"
#raise BuilderError(_("The %s tool is not found")%command)
p = process("/usr/bin/chroot",
*([builder_path, cmdpath] + list(params)),
stderr=STDOUT)
with writeFile(self._get_log_file()) as f:
f.write(p.read())
if p.failed():
raise BuilderError(_("Failed to execute %s")%command)
return True
def update_task(self, task_name):
"""
Декоратор для добавления меток запуска и останова задачи
"""
def decor(f):
def wrapper(*args, **kwargs):
logger = EmergeLog(EmergeLogNamedTask(task_name),
prefix=self.clVars.Get('cl_builder_path'))
logger.mark_begin_task()
ret = f(*args, **kwargs)
if ret:
logger.mark_end_task()
return ret
return wrapper
return decor
def rebuild_changed_packages(self, builder_path, repository_data):
"""
Пересобрать изменённые пакеты
"""
var_db_path = path.join(builder_path, 'var/db/pkg')
map_rep = {k: pathJoin(builder_path, v)
for k, v in repository_data}
def rebuild_generator():
for pkg in InstalledPackageInfo.get_install_packages(var_db_path):
try:
if pkg['repository'] not in map_rep:
yield pkg.atom
elif pkg != EbuildInfo(pkg.atom,
map_rep[pkg['repository']]):
yield pkg.atom
except EbuildInfoError:
yield pkg.atom
rebuild_list = map(lambda x: "=%s" % x, rebuild_generator())
if rebuild_list:
return self.emerge_ask("-1", *rebuild_list)
return True
class Driver(object):
Package = None
Id = None
def __init__(self, builder_path="/"):
self.builder_path = builder_path
def generate(self):
raise StopIteration
def __iter__(self):
yield (self.Id, '', self.Package)
for x in self.generate():
yield x
class NvidiaDriver(Driver):
Id = 'nvidia-drivers'
Package = 'x11-drivers/nvidia-drivers'
Eclass = 'usr/portage/eclass/nvidia-driver.eclass'
SkipVers = ('71', '96', '173', '304')
def generate(self):
nvidia_eclass = path.join(self.builder_path, self.Eclass)
mask_prefix = "mask_"
for mask in (x for x in readLinesFile(nvidia_eclass)
if x.startswith(mask_prefix)):
# пропустить сборку для 71, 96 и 173
if any(mask.startswith("%s%s" % (mask_prefix, x))
for x in self.SkipVers):
continue
mask = mask.partition('=')[2].strip("\n")
yield (self.Id, mask, mask.replace('>=', '<'))
class AtiDriver(Driver):
Id = 'ati-drivers'
Package = 'x11-drivers/ati-drivers'
def pretend_package_install(self, atom, chroot_path, logfile=None):
"""
Получить список пакетов для установки
:return: список пакетов
"""
if atom not in self.pretend_package_list:
emerge = EmergeParser(ChrootEmergeCommand(
chroot_path, [atom], extra_params=['-pv', '--ask=n'],
logfile=logfile))
emerge.question.default_answer = "n"
emerge.run()
self.pretend_package_list[atom] = list(emerge.install_packages.list)
return self.pretend_package_list[atom]
def _display_video_install_package(self, package_list, drv_name):
"""
Отобразить список устанавливаемых пакетов, если пакет не бинарный
и не является непосредственно видеодрайвером - то он отмечен красной
"*"
:param package_list: список пакетов
:param drv_name: имя драйвера (PN)
:return:
"""
#asterisk = self.color_print.bold("*")
#ebuild_wrong = TextState.Colors.RED
ebuild_color = TextState.Colors.GREEN
binary_color = TextState.Colors.PURPLE
output_package_list = ", ".join(
self.color_print.foreground(binary_color)(str(x))
if x['binary'] else
self.color_print.foreground(ebuild_color)(str(x))
for x in package_list if x['PN'] != drv_name
)
wrong_package = any(not x['binary'] and x['PN'] != drv_name
for x in package_list)
if wrong_package:
self.printERROR(_("Depends %s")%output_package_list)
else:
self.printSUCCESS(_("Depends %s")%output_package_list)
def fetch_drivers(self, builder_path, builder_distdir, builder_pkgdir):
"""
Скачать файлы для установки видеодрайверов
:param builder_path:
:param builder_distdir:
:param builder_pkgdir:
:return:
"""
distrdir_perm = (FilePermission.SetGid |
FilePermission.UserAll |
FilePermission.GroupRead |
FilePermission.GroupExecute |
FilePermission.OtherRead |
FilePermission.OtherExecute)
portage_group = 250
root_user = 0
logfile = self._get_log_file()
driver_list = list(chain(self.NvidiaDriver(builder_path),
self.AtiDriver(builder_path)))
distrdir = path.join(builder_path, 'usr/portage/distfiles')
pkgdir = path.join(builder_path, 'usr/portage/packages')
for target_dn in (distrdir, pkgdir):
makeDirectory(target_dn)
chmod(target_dn, distrdir_perm)
chown(target_dn, root_user, portage_group)
# TODO: /var/calculate/remote возможно тоже должен монтировать для образов
pkgdir_files = []
distdir_files = []
repeat_driver_list = []
while driver_list or repeat_driver_list:
drv_name, drv_mask, drv_atom = driver_list.pop(0)
self.startTask(_("Calculating dependencies for %s") %
drv_atom.strip('"').replace("<", "&lt;"))
package_list = self.pretend_package_install(drv_atom, builder_path,
logfile=logfile)
binary_map = {str(x): x['binary'] for x in package_list}
self._display_video_install_package(package_list, drv_name)
self.startTask(_("Fetching binary packages and sources tarballs") %
[x for x in package_list if x['PN'] == drv_name][0])
ef = EmergeFetcher(ChrootEmergeCommand(
builder_path, ["=%s" % x for x in package_list],
extra_params=["-Of", "--ask=n"]))
try:
for package in ef:
pkg_name = str(package)
if binary_map.get(pkg_name, False):
for fn in package.files:
pkgdir_files.append("%s/%s"%(package['CATEGORY'],
fn))
else:
for fn in package.files:
distdir_files.append(fn)
except EmergeFetcherError:
repeat_driver_list.append([drv_name, drv_mask, drv_atom])
if not driver_list and repeat_driver_list:
driver_list = repeat_driver_list
repeat_driver_list = []
self.printWARNING(_("Waiting for unlock %s")
% driver_list[0][0])
time.sleep(10)
self.startTask(_("Cleaning and copying driver files"))
for source_dn, source, target_dn, target in [
(builder_distdir, distdir_files,
distrdir, find(distrdir,
filetype=FindFileType.RegularFile,
fullpath=False)),
(builder_pkgdir, pkgdir_files,
pkgdir, find(pkgdir,
filetype=FindFileType.RegularFile,
fullpath=False))]:
# удаляем все ненужные файлы
for fn in target:
if fn not in source:
removeFileWithEmptyDirectory(path.join(target_dn, fn),
stopDirectory=target_dn)
# копируем отсутствующие файлы
for fn in source:
if fn not in target:
copyWithPath(path.join(source_dn, fn),
target_dn, prefix=source_dn)
return True
def create_video_data(self, builder_path, repository_data):
driver_list = list(chain(self.NvidiaDriver(builder_path),
self.AtiDriver(builder_path)))
logfile = self._get_log_file()
cache_file = self.clVars.Get('builder.cl_builder_video_driver_path')
map_rep = dict(repository_data)
with writeFile(cache_file) as f:
for drv_name, drv_mask, drv_atom in driver_list:
package_list = self.pretend_package_install(
drv_atom, builder_path, logfile=logfile)
for package in package_list:
if package['binary']:
s = "{category} {pn} {pv} binary {drv} {mask}\n".format(
category=package['CATEGORY'],
pn=package['PN'],
pv=package['PVR'],
drv=drv_name,
mask=drv_mask.strip('"'))
f.write(s)
else:
if package['REPO'] not in map_rep:
raise BuilderError(
_("Failed to determine path "
"for %s repository") % package['REPO'])
s = "{category} {pn} {pv} {dn} {drv} {mask}\n".format(
category=package['CATEGORY'],
pn=package['PN'],
pv=package['PV'],
dn=map_rep[package['REPO']],
drv=drv_name,
mask=drv_mask.strip('"'))
f.write(s)
return True
def remove_video_drivers(self, builder_path):
"""
Удалить данные и архивы для установки видео драйверов
:param builder_path: путь до сборки
:return:
"""
cache_file = self.clVars.Get('builder.cl_builder_video_driver_path')
if path.exists(cache_file):
removeFileWithEmptyDirectory(cache_file)
distrdir = path.join(builder_path, 'usr/portage/distfiles')
pkgdir = path.join(builder_path, 'usr/portage/packages')
for target_dn, target in [
(distrdir, find(distrdir,
fullpath=False)),
(pkgdir, find(pkgdir,
fullpath=False))]:
# удаляем все найденные файлы
for fn in target:
removeFileWithEmptyDirectory(path.join(target_dn, fn),
stopDirectory=target_dn)
return True
def reading_news(self, builder_path):
"""
'Прочитать' новости
:param builder_path: путь до сборки
:return:
"""
eselect_command = "/usr/bin/eselect"
p = process("/usr/bin/chroot",
*[builder_path, eselect_command, "--colour=yes",
"news", "read", "new"],
stderr=STDOUT)
self.printPre(convert_console_to_xml(
p.read()).replace(" ", "&nbsp;&nbsp;"))
return True
def check_obsolete(self, builder_path):
chroot_eix = ChrootEix(builder_path, [], ChrootEix.Option.TestObsolete)
l = chroot_eix.get_packages()
if l:
self.printERROR("Obsolete packages list:")
mult = self.color_print.bold("*")
for pkg in l:
self.printDefault(
"&nbsp;{mult} {package}".format(
mult=mult, package=pkg['CATEGORY/PN']))
return True
def emergelike(self, builder_path, cmd, *params):
"""
Запуск команды, которая подразумевает выполнение emerge
"""
cmd_path = self.get_prog_path(cmd)
logfile = self._get_log_file()
if not cmd_path:
raise BuilderError(_("Failed to find the %s command") % cmd)
with EmergeParser(
ChrootCommandExecutor(builder_path,
cmd_path, params,
logfile=logfile)) as emerge:
self._startEmerging(emerge)
return True

@ -0,0 +1,62 @@
# -*- 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 re
import sys
from calculate.update.emerge_parser import EmergeInformationBlock
from calculate.lib.utils.portage import EmergePackage
from calculate.lib.cl_lang import (setLocalTranslate, getLazyLocalTranslate, _)
setLocalTranslate('cl_builder3', sys.modules[__name__])
__ = getLazyLocalTranslate(_)
class EmergePackageFetch(EmergePackage):
files = []
class EmergeFetcherError(Exception):
pass
class EmergeFetcher(object):
_color_block = EmergeInformationBlock._color_block
_new_line = EmergeInformationBlock._new_line
re_fetching = re.compile(
">>> Fetching \({c}\d+{c} of {c}\d+{c}\) {c}(.*?){c}{nl}(.*?)"
"(?=>>> Fetching|$)".format(c=_color_block, nl=_new_line), re.S)
re_filename = re.compile("^{c} [*] {c}(\S+).*;-\)".format(c=_color_block),
re.M)
def __init__(self, emerge_command):
"""
:param package_list: список пакетов типа (EmergeUpdateInfo)
:return:
"""
self.emerge_command = emerge_command
def parse(self, data):
if "is already locked by another fetcher" in data:
raise EmergeFetcherError(
_("File is already locked by another fetcher."))
for package, block in self.re_fetching.findall(data):
ep = EmergePackageFetch(package)
ep.files = [x for x in self.re_filename.findall(block)]
yield ep
def __iter__(self):
child = self.emerge_command.execute()
for i in self.parse(child.read()):
yield i

@ -26,7 +26,7 @@ setLocalTranslate('cl_builder3', sys.modules[__name__])
__ = getLazyLocalTranslate(_)
class ClBuilderCreateAction(Action):
class ClBuilderPrepareAction(Action):
"""
Действие обновление конфигурационных файлов
"""
@ -63,7 +63,8 @@ class ClBuilderCreateAction(Action):
},
# save
{'name': 'save',
'method': 'Builder.save_build(cl_builder_build)',
'method': 'Builder.save_build(cl_builder_build,'
'cl_builder_linux_datavars)',
},
# закрепить подключенные данные
{'name': 'detach',

@ -0,0 +1,146 @@
# -*- 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 calculate.core.server.func import Action, Tasks
from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate
from calculate.lib.utils.files import FilesError, isMount
from calculate.update.update import UpdateError
from ..datavars import BuilderError
from calculate.lib.utils.portage import GitError, isPkgInstalled
from calculate.install.distr import DistributiveError
setLocalTranslate('cl_builder3', sys.modules[__name__])
__ = getLazyLocalTranslate(_)
class ClBuilderProfileAction(Action):
"""
Действие обновление конфигурационных файлов
"""
# ошибки, которые отображаются без подробностей
native_error = (DistributiveError, FilesError, UpdateError,
BuilderError, GitError)
successMessage = __("The profile was successfully updated")
failedMessage = __("Failed to update the profile")
interruptMessage = __("Profile update manually interrupted")
# список задач для действия
tasks = [
{'name': 'migrate_repository',
'method': 'Builder.migrateCacheRepository('
'cl_builder_profile_url,cl_builder_profile_branch,'
'cl_builder_profile_storage)',
'message': __("Repository transfer"),
'condition': lambda Get: not (
Get('cl_builder_profile_storage').is_local(
Get('cl_builder_profile_url'),
Get('cl_builder_profile_branch')))
},
{'name': 'reconfigure_vars1',
'method': 'Builder.invalidateVariables("cl_builder_profile_storage")',
'depend': Tasks.has('migrate_repository')
},
{'name': 'reconfigure_vars',
'method': 'Builder.reconfigureProfileVars(cl_builder_profile_datavars,'
'cl_builder_path)'
},
{'name': 'remove_old_reps',
'foreach': 'cl_builder_remove_rep',
'message': __("Remove the {eachvar:capitalize} repository"),
'method': 'Builder.remove_repositories(eachvar)'
},
{'name': 'reps_synchronization',
'group': __("Repositories synchronization"),
'tasks': [
{'name': 'sync_reps',
'foreach': 'cl_builder_profile_sync_rep',
'message': __("Syncing the {eachvar:capitalize} repository"),
'method': 'Builder.syncRepositories(eachvar)',
#'condition': lambda Get: Get('cl_update_profile_sync_rep')
},
{'name': 'regen_cache',
'foreach': 'cl_builder_sync_overlay_rep',
'message': __("Updating the {eachvar:capitalize} repository cache"),
'essential': False,
'method': 'Builder.regenCache(eachvar)',
#'condition': (
# lambda Get: (Get('cl_update_outdate_set') == 'on' and
# Get('cl_update_metadata_force') != 'skip' or
# Get('cl_update_metadata_force') == 'force'))
},
{'name': 'eix_update',
'message': __("Updating the eix cache"),
'method': 'Builder.eixUpdate(cl_builder_repository_name)',
#'condition': (
# lambda Get: (Get('cl_update_outdate_set') == 'on' and
# Get('cl_update_eixupdate_force') != 'skip' or
# Get('cl_update_eixupdate_force') == 'force'))
},
# save
{'name': 'save',
'method': 'Builder.save_build(cl_builder_build,'
'cl_builder_profile_datavars)',
},
# сообщение удачного завершения при обновлении репозиториев
{'name': 'success_syncrep',
'message': __("Synchronization finished"),
'depend': (Tasks.success() & Tasks.has_any("sync_reps",
"sync_other_reps",
"emerge_metadata",
"eix_update")),
}
]
},
{'name': 'reps_synchronization',
'group': __("Setting up the profile"),
'tasks': [
{'name': 'set_profile',
'message': __("Switching to profile "
"{cl_builder_profile_system_shortname}"),
'method': 'Builder.set_profile('
'cl_builder_profile_system_shortname,cl_builder_path)'
},
{'name': 'merge_utils',
'message': __("Calculating dependencies"),
'method': 'Builder.emerge("-console -pxe","-1","sys-apps/calculate-utils")',
# TODO: возможно добавить параметр необходимости установки
'condition': lambda Get: not isPkgInstalled(
'sys-apps/calculate-utils', Get('cl_builder_path'))
},
{'name': 'reconfigure',
'message': __("Reconfigure the settings"),
'method': 'Builder.apply_templates(cl_builder_path,'
'cl_template_clt_set,True,None,False,"merge",'
'cl_builder_profile_datavars)',
'condition': lambda Get: Get('cl_templates_locate')
},
{'name': 'fix_settings',
'message': __("Fixing the settings"),
'method': 'Builder.apply_templates(cl_builder_path,'
'cl_template_clt_set,True,None,False,"sync",'
'cl_builder_profile_datavars)',
'condition': lambda Get: Get('cl_templates_locate')
},
{'name': 'dispatch_conf',
'message': __("Updating configuration files"),
'method':'Builder.dispatchConf(None,cl_builder_path)',
'condition': lambda Get: Get('cl_dispatch_conf') != 'skip'
},
]
}
]

@ -52,7 +52,8 @@ class ClBuilderRestoreAction(Action):
# save
{'name': 'save',
'message': __("Save distro"),
'method': 'Builder.save_build(cl_builder_build)',
'method': 'Builder.save_build(cl_builder_build,'
'cl_builder_linux_datavars)',
},
# закрепить подключенные данные
{'name': 'detach',

@ -0,0 +1,247 @@
# -*- 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 calculate.core.server.func import Action, Tasks
from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate
from calculate.lib.utils.files import FilesError, isMount
from calculate.update.emerge_parser import EmergeError
from calculate.update.update import UpdateError
from ..datavars import BuilderError
from calculate.lib.utils.portage import GitError, isPkgInstalled, \
EmergeLogNamedTask, PackageList, EmergeLog
from calculate.install.distr import DistributiveError
from os import path
from calculate.update.update_tasks import EmergeMark
setLocalTranslate('cl_builder3', sys.modules[__name__])
__ = getLazyLocalTranslate(_)
class ClBuilderUpdateAction(Action):
"""
Действие обновление конфигурационных файлов
"""
# ошибки, которые отображаются без подробностей
native_error = (DistributiveError, FilesError, UpdateError,
BuilderError, GitError, EmergeError)
successMessage = __("The system was successfully updated")
failedMessage = __("Failed to update the system")
interruptMessage = __("System update manually interrupted")
def was_installed(pkg, task_name):
def func(Get):
task = EmergeLog(EmergeLogNamedTask(task_name),
prefix=Get('cl_builder_path'))
return bool(PackageList(task.list)[pkg])
return func
def need_depclean(pkg, task_name):
def func(Get):
task = EmergeLog(EmergeLogNamedTask(task_name),
prefix=Get('cl_builder_path'))
return bool(PackageList(task.list)[pkg])
return func
# список задач для действия
tasks = [
{'name': 'clear_log',
'method': 'Builder.clear_log(cl_builder_id)',
},
{'name': 'apply_template',
'message': __("Configuring build"),
'method': 'Builder.applyTemplates(cl_builder_target,False,False,None)',
},
{'name': 'invalidate_vars',
'method': 'Builder.invalidateVariables("cl_builder_linux_datavars")'
},
{'name': 'reconfigure_vars',
'method': 'Builder.reconfigureProfileVars(cl_builder_linux_datavars,'
'cl_builder_path)'
},
{'name': 'reps_synchronization',
'group': __("Repositories synchronization"),
'tasks': [
{'name': 'sync_reps',
'foreach': 'cl_builder_profile_sync_rep',
'message': __("Syncing the {eachvar:capitalize} repository"),
'method': 'Builder.syncRepositories(eachvar)',
},
{'name': 'regen_cache',
'foreach': 'cl_builder_sync_overlay_rep',
'message': __("Updating the {eachvar:capitalize} repository cache"),
'essential': False,
'method': 'Builder.regenCache(eachvar)',
},
{'name': 'eix_update',
'message': __("Updating the eix cache"),
'method': 'Builder.eixUpdate(cl_builder_repository_name)',
},
# сообщение удачного завершения при обновлении репозиториев
{'name': 'success_syncrep',
'message': __("Synchronization finished"),
'depend': (Tasks.success() & Tasks.has_any("sync_reps",
"sync_other_reps",
"emerge_metadata",
"eix_update")),
}
]
},
{'name': 'reps_synchronization',
'group': __("System configuration"),
'tasks': [
{'name': 'revision',
'message': __("Fixing the settings"),
'method': 'Builder.apply_templates(cl_builder_path,'
'cl_template_clt_set,True,None,False,"sync",'
'cl_builder_linux_datavars)',
'condition': lambda Get: Get('cl_templates_locate')
},
{'name': 'dispatch_conf',
'message': __("Updating configuration files"),
'method': 'Builder.dispatchConf(None,cl_builder_path)',
'condition': lambda Get: Get('cl_dispatch_conf') != 'skip'
},
]
},
{'name': 'emerge_update_world',
'group': __("Updating packages"),
'tasks': [
{'name': 'update_world',
'message': __("Calculating dependencies"),
'method': 'Builder.emerge_ask("-uDN", "--changed-deps",'
'"--with-bdeps=y", "@world")'
}
]
},
{'name': 'group_changed_packages',
'group': __("Rebuild modified packages"),
'tasks': [
{'name': 'changed_packages',
'message': __("Calculating dependencies"),
'method': 'Builder.rebuild_changed_packages(cl_builder_path,'
'cl_builder_repository_data)'
}
]
},
{'name': 'update_python',
'group': __("Updating Python"),
'tasks': [
{'name': 'python_updater',
'message': __('Find & rebuild packages broken due '
'to a Python upgrade'),
'method': 'Builder.emergelike(cl_builder_path,"python-updater")',
'condition': was_installed('dev-lang/python$',
EmergeMark.PythonUpdater),
'decoration': 'Builder.update_task("%s")' %
EmergeMark.PythonUpdater
},
]
},
{'name': 'update_perl',
'group': __("Updating Perl"),
'tasks': [
{'name': 'perl_cleaner',
'message': __('Find & rebuild packages and Perl header files '
'broken due to a perl upgrade'),
'method': 'Builder.emergelike(cl_builder_path,"perl-cleaner",'
'"all")',
'condition': was_installed('dev-lang/perl$',
EmergeMark.PerlCleaner),
'decoration': 'Builder.update_task("%s")' % EmergeMark.PerlCleaner
},
]
},
{'name': 'depclean',
'group': __("Cleaning the system from needless packages"),
'tasks': [
{'name': 'update_depclean',
'message': __("Calculating dependencies"),
'method': 'Builder.depclean()',
'condition': need_depclean('.*', EmergeMark.Depclean),
'decoration': 'Builder.update_task("%s")' % EmergeMark.Depclean
},
]
},
{'name': 'update_world:update_modules',
'group': __("Rebuilding dependent modules"),
'tasks': [
{'name': 'update_world:module_rebuild',
'message': __('Updating Kernel modules'),
'method': 'Builder.emerge("","@module-rebuild")',
'condition': was_installed('sys-kernel/.*source',
EmergeMark.KernelModules),
'decoration': 'Builder.update_task("%s")' %
EmergeMark.KernelModules
},
{'name': 'update_world:x11_module_rebuild',
'message': __('Updating X.Org server modules'),
'method': 'Builder.emerge("","@x11-module-rebuild")',
'condition': was_installed('x11-base/xorg-server',
EmergeMark.XorgModules),
'decoration': 'Builder.update_task("%s")' % EmergeMark.XorgModules
},
{'name': 'update_world:preserved_rebuild',
'message': __('Updating preserved libraries'),
'method': 'Builder.emerge("","@preserved-rebuild")',
'condition': was_installed('.*', EmergeMark.PreservedLibs),
'decoration': 'Builder.update_task("%s")' %
EmergeMark.PreservedLibs
},
{'name': 'update_world:dispatch_conf_end',
'message': __("Updating configuration files"),
'method':'Builder.dispatchConf()',
'condition': lambda Get: Get('cl_dispatch_conf') != 'skip'
},
]
},
{'name': 'prelink',
'message': __("Executing prelink"),
'method': 'Builder.chroot_command(cl_builder_path,"prelink",'
'"-afmR")',
'condition': was_installed('.*', EmergeMark.Prelink),
'decoration': 'Builder.update_task("%s")' % EmergeMark.Prelink
},
{'name': 'fetch_video_drivers',
'group': __("Fetching video drivers"),
'tasks': [
{'name': 'fetch_drivers',
'method': 'Builder.fetch_drivers(cl_builder_path,'
'cl_builder_linux_distdir,cl_builder_linux_pkgdir)',
'condition': lambda Get: Get('cl_builder_videodrv_set') == 'on'
},
{'name': 'create_video_data',
'message': __("Creating install video driver data"),
'method': 'Builder.create_video_data(cl_builder_path,'
'cl_builder_repository_data)',
'condition': lambda Get: Get('cl_builder_videodrv_set') == 'on'
},
]
},
{'name': 'remove_video_drivers',
'method': 'Builder.remove_video_drivers(cl_builder_path)',
'condition': lambda Get: Get('cl_builder_videodrv_set') == 'off'
},
{'name': 'reading_news',
'method': 'Builder.reading_news(cl_builder_path)'
},
{'name': 'check_obsolete',
'method': 'Builder.check_obsolete(cl_builder_path)'
}
]

@ -21,6 +21,20 @@ from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_builder3', sys.modules[__name__])
class Actions:
Prepare = "prepare"
Image = "image"
Break = "break"
Restore = "restore"
Update = "assemble_update"
ChangeProfile = "builder_profile"
NewAssemble = (Prepare,)
WorkAssemble = (Image, Break, ChangeProfile, Update)
BrokenAssemble = (Restore,)
ImageSquash = "squash"
ImageIso = "iso"
class VariableAcBuilderSquash(ReadonlyVariable):
"""
@ -29,7 +43,7 @@ class VariableAcBuilderSquash(ReadonlyVariable):
def get(self):
action = self.Get("cl_action")
image_action = self.Get('cl_builder_action')
if action == 'image' and image_action == "squash":
if action == Actions.Image and image_action == Actions.ImageSquash:
return "on"
return "off"
@ -41,7 +55,7 @@ class VariableAcBuilderIso(ReadonlyVariable):
def get(self):
action = self.Get("cl_action")
image_action = self.Get('cl_builder_action')
if action == 'image' and image_action == "iso":
if action == Actions.Image and image_action == Actions.ImageIso:
return "on"
return "off"
@ -52,7 +66,8 @@ class VariableAcBuilderSetup(ReadonlyVariable):
"""
def get(self):
action = self.Get('cl_action')
if action in ("create",):
if (action in (Actions.Prepare, Actions.Update) and
not self.GetBool('cl_builder_stage_set')):
return "on"
return "off"
@ -63,6 +78,6 @@ class VariableAcBuilderPrepare(ReadonlyVariable):
"""
def get(self):
action = self.Get('cl_action')
if action in ("create",):
if action in (Actions.Prepare, Actions.Update):
return "on"
return "off"

@ -18,6 +18,7 @@ import sys
from os import path
import os
import re
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, \
@ -29,6 +30,8 @@ from ..drive_spool import DriveSpool
from calculate.lib.datavars import Variable, VariableError, ReadonlyVariable
from functools import wraps
_ = lambda x:x
from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_builder3',sys.modules[__name__])
@ -94,6 +97,31 @@ class BaseBuildId(Variable):
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"]
def init(self):
self.label = _("Fetch video drivers")
self.help = _("fetch video drivers")
def get(self):
fn = self.Get("cl_builder_video_driver_path")
return "on" if path.exists(fn) else "off"
class VariableClBuilderSourceFilename(Variable):
"""
@ -111,7 +139,7 @@ class VariableClBuilderSourceFilename(Variable):
def check(self, isoimage):
"""Set image file"""
if self.Get('cl_action') == 'create' and not isoimage:
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')
@ -220,9 +248,10 @@ class VariableClBuilderDiskSize(ReadonlyVariable):
def get(self):
action = self.Get('cl_action')
if action == 'create':
if action in Actions.NewAssemble:
return self.get_create()
elif action in ('break', 'restore'):
elif action in (Actions.Break, Actions.Restore):
# TODO: disk size для остальных
return
def humanReadable(self):
@ -299,9 +328,11 @@ class VariableClBuilderTarget(Variable):
def get(self):
action = self.Get('cl_action')
if action == 'create':
if action in Actions.NewAssemble:
return self.get_create()
elif action in ('break', 'restore', 'image'):
elif action in Actions.WorkAssemble:
return self.get_worked()
elif action in Actions.BrokenAssemble:
return self.get_worked()
else:
return ""
@ -347,9 +378,11 @@ class VariableClBuilderBuild(Variable):
def get(self):
action = self.Get('cl_action')
if action == 'create':
if action in Actions.NewAssemble:
return self.get_create()
if action in ('break', 'restore', 'image'):
if action in Actions.WorkAssemble:
return self.get_worked()
elif action in Actions.BrokenAssemble:
return self.get_worked()
return ""
@ -381,8 +414,8 @@ class VariableClBuilderPreparedId(BaseBuildId):
action = self.Get('cl_action')
for x in bs:
build = bs.get_build(x)
if (build and (action == 'break' or
build.status == Build.Status.WORKED)):
if (build and (action == Actions.Break or
build.status == Build.Status.Worked)):
yield x
def get(self):
@ -397,7 +430,7 @@ class VariableClBuilderPreparedId(BaseBuildId):
for x in bs:
build = bs.get_build(x)
if build:
if build.status == Build.Status.BROKEN:
if build.status == Build.Status.Broken:
yield (x, "%s (%s)" % (x, _("broken")))
else:
yield (x, x)
@ -408,8 +441,8 @@ class VariableClBuilderPreparedId(BaseBuildId):
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') != 'break'):
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)
@ -426,10 +459,10 @@ class VariableClBuilderBrokenId(BaseBuildId):
bs = self.Get('cl_builder_storage')
for x in bs:
build = bs.get_build(x)
if build and build.status == Build.Status.BROKEN:
if build and build.status == Build.Status.Broken:
yield x
@is_action('restore')
@is_action(Actions.Restore)
def get(self):
l = self.available()
if l and len(l) == 1:
@ -437,12 +470,12 @@ class VariableClBuilderBrokenId(BaseBuildId):
return ""
@as_list
@is_action('restore', default_value=[])
@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:
if build.status == Build.Status.Broken:
yield (x, "%s (%s)" % (x, _("broken")))
def check(self, value):
@ -459,11 +492,11 @@ class VariableClBuilderId(ReadonlyVariable):
"""
def get(self):
action = self.Get('cl_action')
if action == 'create':
if action in Actions.NewAssemble:
return self.Get('cl_builder_new_id')
elif action in ('break', 'image'):
elif action in Actions.WorkAssemble:
return self.Get('cl_builder_prepared_id')
elif action == 'restore':
elif action in Actions.BrokenAssemble:
return self.Get('cl_builder_broken_id')
@ -500,6 +533,16 @@ class VariableClBuilderParentPath(ReadonlyVariable):
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):
"""
@ -511,9 +554,9 @@ class VariableClBuilderPkgdir(Variable):
def get(self):
action = self.Get('cl_action')
if action == 'create':
if action in Actions.NewAssemble:
return self.fallback()
elif action in ('restore', 'image'):
elif action in Actions.WorkAssemble:
build = self.Get('cl_builder_build')
return build.pkgdir or self.fallback()
else:
@ -583,7 +626,7 @@ class VariableClBuilderSquashPath(ReadonlyVariable):
"""
Путь от iso до содержимого squash
"""
@is_action('image')
@is_action(Actions.Image)
def get(self):
return path.relpath(self.Get('cl_builder_path'),
self.Get('cl_builder_iso_path'))
@ -593,7 +636,7 @@ class VariableClBuilderImage(ReadonlyVariable):
"""
Создаваемый образ
"""
@is_action('image')
@is_action(Actions.Image)
def get(self):
image_name = self.Get('cl_builder_image_filename')
bdn = self.Get('cl_builder_iso_path')
@ -614,7 +657,7 @@ class VariableClBuilderCdname(ReadonlyVariable):
"""
Type of iso (CD/DVD)
"""
@is_action("image")
@is_action(Actions.Image)
def get(self):
squashfile = pathJoin(self.Get('cl_builder_iso_path'),
self.Get('cl_builder_current_squash'))
@ -641,7 +684,7 @@ class VariableClBuilderIsoLabel(Variable):
"""
LABEL для iso
"""
@is_action("image")
@is_action(Actions.Image)
def get(self):
return "%s-%s" % (self.Get('os_builder_linux_shortname').upper(),
self.Get('os_builder_linux_build'))
@ -652,7 +695,7 @@ class VariableClBuilderRootParam(Variable):
параметр root= для livecd
"""
@is_action("image")
@is_action(Actions.Image)
def get(self):
return "live:LABEL=%s" % self.Get('cl_builder_iso_label')
@ -796,16 +839,29 @@ 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 VariableClBuilderBranchName(Variable):
"""
Ветки оверлеев используемые для сборки системы
"""
type = "list"
def get(self):
# TODO: заглушка
return self.Get('update.cl_update_branch_name')
action = self.Get('cl_action')
default_branch = Build.Branches.Stable
if action == Actions.ChangeProfile:
pass
else:
build = self.Get('cl_builder_build')
if build and build.references:
return build.references
dv = self.Get('cl_builder_linux_datavars')
if dv:
return map(lambda x: default_branch,
dv.Get('cl_update_rep_name'))
return []

@ -20,11 +20,15 @@ from os import path
import re
from calculate.install import distr
from calculate.install.distr import DistributiveError
from calculate.lib.datavars import ReadonlyVariable, SimpleDataVars
from calculate.lib.datavars import ReadonlyVariable, SimpleDataVars, \
VariableError, ReadonlyTableVariable, FieldValue
from calculate.lib.utils.files import pathJoin
from calculate.lib.utils.tools import ignore
from calculate.lib.variables import linux
from calculate.lib.variables import env
from calculate.update.variables import update
from calculate.lib.variables import system
from calculate.lib.variables import system, linux
from .action import Actions
from calculate.lib.cl_lang import setLocalTranslate
import datetime
@ -38,7 +42,10 @@ class BuilderLinux(ReadonlyVariable):
variable = ""
def get(self):
dv = self.Get('cl_builder_linux_datavars')
try:
dv = self.Get('cl_builder_linux_datavars')
except VariableError:
return ""
if dv:
return dv[self.variable]
else:
@ -50,10 +57,26 @@ class DataVarsBuilderLinux(linux.LinuxDataVars):
"""
def variables(self):
l = super(DataVarsBuilderLinux, self).variables()
return l + [update.VariableClProfileSystem(),
update.VariableClProfileRepository(),
system.VariableOsArchMachineGentoo(),
update.VariableClProfileData()]
return l + [linux.VariableClProfileSystem(),
env.VariableClRepositoryData(),
env.VariableClRepositoryName(),
env.VariableClRepositoryLocation(),
env.VariableClTemplateLocation(),
env.VariableClTemplatePath(),
env.VariableClPkgdir(),
env.VariableClDistdir(),
env.VariableClEmergeConfig(systemRoot=self.systemRoot),
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.VariableClUpdateBranchName(section="update"),
update.VariableClUpdateLaymanConfig(section="update"),
update.VariableClUpdateLaymanStorage(section="update"),
update.VariableClProfileRepository(section="update"),
system.VariableOsArchMachineGentoo()]
@classmethod
def StageInformation(cls, fn):
@ -107,9 +130,9 @@ class VariableClBuilderLinuxDatavars(ReadonlyVariable):
def get(self):
"""Get by distroinfo or current info"""
if self.Get('cl_action') == 'create':
if self.Get('cl_action') in Actions.NewAssemble:
return self.source_data()
elif self.Get('cl_action') in ('break', 'restore', 'image'):
elif self.Get('cl_action') in Actions.WorkAssemble:
return self.target_data()
return ""
@ -132,7 +155,7 @@ class VariableOsBuilderLinuxBuild(BuilderLinux):
def get(self):
action = self.Get('cl_action')
if action == 'image':
if action == Actions.Image:
curdate = datetime.datetime.now()
return "%04d%02d%02d" % (curdate.year, curdate.month, curdate.day)
else:
@ -156,6 +179,21 @@ class VariableOsBuilderLinuxName(BuilderLinux):
variable = "os_linux_name"
class VariableClBuilderProfileSystem(BuilderLinux):
variable = "cl_profile_system"
#def get(self):
# action = self.Get('cl_action')
# if action == 'create':
# shortname = self.Get('cl_builder_profile_system_shortname')
# profile = self.Select('cl_builder_profile_path',
# where="cl_builder_profile_shortname",
# eq=shortname, limit=1)
# if profile:
# return profile
# return ""
class VariableOsBuilderLinuxSystem(BuilderLinux):
"""
Install system name
@ -168,3 +206,74 @@ class VariableOsBuilderLinuxSubname(BuilderLinux):
Install subname
"""
variable = "os_linux_subname"
class VariableClBuilderRepositoryData(ReadonlyTableVariable):
"""
"""
source = ["cl_repository_name", "cl_repository_location"]
def get(self):
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 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)

@ -19,14 +19,17 @@ import os
from os import path
from calculate.lib.datavars import (ReadonlyVariable, FieldValue, VariableError,
DataVarsError, Variable)
from calculate.lib.utils.files import listDirectory
from calculate.lib.utils.portage import GitError
from calculate.lib.variables import linux as lib_linux
from calculate.lib.variables import system as lib_system
from calculate.install import distr
from calculate.update.variables import update
from calculate.update import profile as update_profile
from calculate.lib.cl_lang import setLocalTranslate
from calculate.update.variables.update import DataVarsUpdateProfile
setLocalTranslate('cl_builder3', sys.modules[__name__])
@ -34,7 +37,10 @@ class VariableClBuilderProfileStorage(ReadonlyVariable):
type = "object"
def get(self):
builder_path = self.Get('cl_builder_path')
builder_ls = path.join(builder_path, "var/lib/layman")
return update_profile.RepositoryStorageSet(
update_profile.LocalStorage(builder_ls),
update_profile.CacheStorage('/var/calculate/tmp/update'))
@ -44,76 +50,21 @@ class VariableClBuilderProfileUrl(update.VariableClUpdateProfileUrl):
"""
check_after = ["cl_builder_profile_branch"]
def check(self, value):
action = self.Get('cl_action')
if not value and action == 'create':
branch = self.Get('cl_builder_profile_branch')
if branch != update_profile.DEFAULT_BRANCH:
raise VariableError("Need to specify profile repository")
return
if not value:
raise VariableError("Need to specify profile repository")
try:
branch = self.Get('cl_builder_profile_branch')
self.Get('cl_builder_profile_storage').get_profiles(value, branch)
except GitError as e:
raise VariableError(str(e))
if not self.Get('cl_builder_profile_shortname'):
raise VariableError(_("Repository %s has no profiles")%value)
def get(self):
action = self.Get('cl_action')
if action == 'create':
return ""
if action in ("image"):
return update.VariableClUpdateProfileUrl.get(self)
return ""
profile = "builder.cl_builder_profile_system"
branch = "builder.cl_builder_profile_branch"
storage = "builder.cl_builder_profile_storage"
profiles_shortname = 'builder.cl_builder_profile_shortname'
class VariableClBuilderProfileBranch(update.VariableClUpdateProfileBranch):
"""
Текущая ветка репозитория
"""
untrusted = True
def get(self):
action = self.Get('cl_action')
if action in ("image"):
pass
#rep_set = self.Get('cl_update_profile_storage')
#url = self.Get('cl_update_profile_url')
##print url, rep_set.is_local(url, branch=None)
#if rep_set.is_local(url, branch=None):
# rep = rep_set.get_repository(url, branch=None)
# git = Git()
# return git.getBranch(rep.directory)
return update_profile.DEFAULT_BRANCH
class VariableClProfileCacheRepository(ReadonlyVariable):
"""
Репозиторий из которого будет извлечён список профилей
"""
type = "object"
storage = "builder.cl_builder_profile_storage"
url = "builder.cl_builder_profile_url"
def get(self):
url = self.Get('cl_builder_profile_url')
if not url:
return ""
try:
rep_set = self.Get('cl_builder_profile_storage')
branch = self.Get('cl_builder_profile_branch')
rep = rep_set.get_repository(url, branch)
#if rep and self.Get('cl_update_profile_sync_set') == 'on':
if rep:
rep.sync()
return rep_set.get_repository(url, branch) or ""
except GitError:
return ""
class VariableClProfileCacheData(update.VariableClProfileData):
source = []
repository = "cl_profile_cache_repository"
class VariableClBuilderProfileData(update.VariableClProfileData):
type = "table"
@ -122,18 +73,7 @@ class VariableClBuilderProfileData(update.VariableClProfileData):
"cl_builder_profile_path",
"cl_builder_profile_arch"]
def init(self):
self.label = "test"
def get(self, hr=False):
url = self.Get('cl_builder_profile_url')
if not url:
dv = self.Get('cl_builder_linux_datavars')
if dv:
return dv['cl_profile_data']
return [[]]
else:
return self.Get('cl_profile_cache_data')
repository = "builder.cl_builder_profile_repository"
class VariableClBuilderProfileFullname(FieldValue, ReadonlyVariable):
@ -172,159 +112,133 @@ class VariableClBuilderProfileArch(FieldValue, ReadonlyVariable):
column = 3
class VariableClBuilderProfileSystemShortname(Variable):
class VariableClBuilderProfileName(lib_linux.VariableClProfileName):
"""
Профиль системы
Install subname
"""
type = "choice"
opt = ["--profile"]
untrusted = True
metavalue = "PROFILE"
source_var = "cl_builder_profile_system"
def init(self):
self.label = _("System profile")
self.help = _("set the system profile")
def check_profile(self, path_profile, profile_fullname):
if path_profile:
dv = update.DataVarsUpdateProfile(path_profile)
if ":" in profile_fullname:
repo_name = profile_fullname.partition(":")[0]
else:
repo_name = ""
try:
if (not dv.Get('cl_update_rep_name') or
not dv.Get('cl_update_rep_url')):
raise VariableError(_("Repository variables "
"were not configured for the profile"))
if not dv.Get('os_linux_name'):
raise VariableError("")
if repo_name not in list(dv.Get('cl_update_rep_name')):
raise VariableError(
_("Overlay %s is not specified in cl_update_rep_name")%
repo_name)
except (DataVarsError, VariableError) as e:
if str(e):
message = ". " + str(e)
else:
message = ""
raise VariableError(_("The selected profile is not Calculate")
+ message)
else:
raise VariableError(_("Wrong Calculate profile"))
def check(self, profile):
if not profile:
raise VariableError(_("You must specify the profile"))
action = self.Get('cl_action')
if action == 'create':
url = self.Get('cl_builder_profile_url')
# внеший репозиторий профилей
if url:
path_profile, profile_fullname = \
path_profile = self.Select(
'cl_builder_profile_path',
where='cl_builder_profile_shortname',
eq=profile, limit=1)
profile_fullname = self.Select(
'cl_builder_profile_fullname',
where='cl_builder_profile_shortname',
eq=profile, limit=1)
self.check_profile(path_profile, profile_fullname)
# репозиторий в образе
else:
self.check_inner_profile(profile)
def check_inner_profile(self, profile):
"""
Проверка профиля находящегося в репозитории образа системы
"""
image = self.Get('cl_builder_source')
dv = self.Get('cl_builder_linux_datavars')
if not image or not dv:
raise VariableError(_("Failed to check profile: "
"wrong source"))
if image:
if isinstance(image, distr.ArchiveDistributive):
raise VariableError(_("Unavailable to use profile from "
"stage distributive"))
with image:
try:
distr_dn = image.getDirectory()
profile_dn = self.Select(
'cl_builder_profile_path',
where="cl_builder_profile_shortname",
eq=profile, limit=1)
profile_fullname = self.Select(
'cl_builder_profile_fullname',
where="cl_builder_profile_shortname",
eq=profile, limit=1)
if not profile_dn:
raise VariableError()
profile_dn = dv.change_root(profile_dn, distr_dn)
self.check_profile(profile_dn, profile_fullname)
except distr.DistributiveError:
raise VariableError(_("Failed to check profile: "
"failed to mount source"))
def get_by_url(self):
shortname = self.Get('cl_builder_profile_shortname')
if len(shortname) == 1:
return shortname[0]
return ""
class VariableClBuilderProfileRepoName(update.VariableClUpdateProfileRepoName):
"""
Название репозитория
"""
storage = "builder.cl_builder_profile_storage"
url = "builder.cl_builder_profile_url"
def get_from_image(self):
dv = self.Get('cl_builder_linux_datavars')
if dv:
try:
profile_system = dv["cl_profile_system"]
for (fullname, shortname,
_path, arch) in dv.Get('cl_profile_data'):
if _path == profile_system:
return shortname
except VariableError:
pass
return ""
class VariableClBuilderProfileRepository(
update.VariableClUpdateProfileRepository):
"""
Репозиторий из которого будет извлечён список профилей
"""
type = "object"
url = "builder.cl_builder_profile_url"
storage = "builder.cl_builder_profile_storage"
branch = "builder.cl_builder_profile_branch"
def get(self):
action = self.Get('cl_action')
if action == 'create':
url = self.Get('cl_builder_profile_url')
if url:
return self.get_by_url()
else:
return self.get_from_image()
return ""
def choice(self):
arch = self.Get('os_arch_machine_gentoo')
profiles = zip(*self.Select(['cl_builder_profile_shortname',
'cl_builder_profile_fullname'],
where='cl_builder_profile_arch', eq=arch))
if profiles:
short_name, full_name = profiles
return zip(short_name, full_name)
return []
class VariableClBuilderTemplatesLocate(update.VariableClUpdateTemplatesLocate):
"""
Выбранные типы хранилищ шаблонов
"""
check_after = ['cl_builder_profile_system']
profile_datevars = "builder.cl_builder_profile_datavars"
class VariableClBuilderProfileSystem(ReadonlyVariable):
class VariableClBuilderProfileDatavars(update.VariableClUpdateProfileDatavars):
type = "object"
profile = "builder.cl_builder_profile_system_shortname"
profiles_path = "builder.cl_builder_profile_path"
profiles_shortname = "builder.cl_builder_profile_shortname"
def get(self):
action = self.Get('cl_action')
if action == 'create':
shortname = self.Get('cl_builder_profile_system_shortname')
profile = self.Select('cl_builder_profile_path',
where="cl_builder_profile_shortname",
eq=shortname, limit=1)
if profile:
return profile
profile = self.Get(self.profile)
path_profile = self.Select(self.profiles_path,
where=self.profiles_shortname,
eq=profile, limit=1)
#print self.Get(self.profiles_path)
#print self.Get(self.profiles_shortname)
#print profile
builder_path = self.Get('cl_builder_path')
#print "BUILDER_PATH", builder_path
if path_profile:
return DataVarsUpdateProfile(path_profile, builder_path)
return ""
class VariableClBuilderProfileSystemShortname(
update.VariableClUpdateProfileSystem):
"""
Выбираемый профиль
"""
opt = ["cl_builder_profile_system_shortname"]
class VariableClBuilderProfileName(lib_linux.VariableClProfileName):
profiles_path = "builder.cl_builder_profile_path"
profiles_shortname = "builder.cl_builder_profile_shortname"
profiles_fullname = "builder.cl_builder_profile_fullname"
profiles_arch = "builder.cl_builder_profile_arch"
profile = "builder.cl_builder_profile_system"
url = "builder.cl_builder_profile_url"
gentoo_arch = 'builder.os_builder_arch_machine_gentoo'
class VariableOsBuilderArchMachineGentoo(lib_system.VariableOsArchMachineGentoo):
"""
Install subname
Архитектура пакетов
"""
source_var = "cl_builder_profile_system"
source_arch = "builder.os_builder_arch_machine"
class VariableClBuilderProfileLinuxFullname(
update.VariableClUpdateProfileLinuxFullname):
"""
Имя системы в профиле
"""
datavars = "builder.cl_builder_profile_datavars"
class VariableClBuilderProfileDependData(
update.VariableClUpdateProfileDependData):
"""
Зависимые репозитории
"""
source = ['cl_builder_profile_depend_name',
'cl_builder_profile_depend_url']
datavars = "cl_builder_profile_datavars"
class VariableClBuilderProfileDependName(FieldValue, ReadonlyVariable):
type = "list"
source_variable = "cl_builder_profile_depend_data"
column = 0
def init(self):
self.label = _("System profile")
self.label = _("Name")
class VariableClBuilderProfileDependUrl(FieldValue, ReadonlyVariable):
type = "list"
source_variable = "cl_builder_profile_depend_data"
column = 1
def init(self):
self.label = _("URL")
class VariableClBuilderProfileSyncRep(ReadonlyVariable):
type = "list"
def get(self):
return list(reversed(self.Get('update.cl_update_rep_name')))
class VariableClBuilderRemoveRep(ReadonlyVariable):
def get(self):
dv_builder_linux = self.Get('cl_builder_linux_datavars')
dv_builder_profile = self.Get('cl_builder_profile_datavars')
if dv_builder_linux and dv_builder_profile:
return list(set(dv_builder_linux.Get('cl_update_rep_name')) -
set(dv_builder_profile.Get('cl_update_rep_name')))
else:
return []

@ -16,15 +16,20 @@
import sys
from calculate.lib.datavars import VariableError,DataVarsError,DataVars
from calculate.lib.datavars import VariableError, DataVarsError, DataVars
from calculate.core.server.func import WsdlBase
from calculate.install.install import InstallError, Install
from calculate.update.emerge_parser import EmergeError
from .builder import Builder
from calculate.update.update import Update, UpdateError
from .datavars import BuilderError
from .variables.action import Actions as BuilderActions
from calculate.lib.utils.portage import GitError
from utils.cl_builder_create import ClBuilderCreateAction
from utils.cl_builder_prepare import ClBuilderPrepareAction
from utils.cl_builder_profile import ClBuilderProfileAction
from utils.cl_builder_break import ClBuilderBreakAction
from utils.cl_builder_update import ClBuilderUpdateAction
from utils.cl_builder_restore import ClBuilderRestoreAction
from utils.cl_builder_image import ClBuilderImageAction
from calculate.lib.cl_lang import setLocalTranslate,getLazyLocalTranslate
@ -39,7 +44,7 @@ class Wsdl(WsdlBase):
#
{
# идентификатор метода
'method_name': "builder_create",
'method_name': "builder_prepare",
# категория метода
'category': __('Builder'),
# заголовок метода
@ -49,20 +54,20 @@ class Wsdl(WsdlBase):
# метод присутствует в графической консоли
'gui': True,
# консольная команда
'command': 'cl-builder-create',
'command': 'cl-builder-prepare',
# права для запуска метода
'rights': ['build'],
# объект содержащий модули для действия
'logic': {'Builder': Builder,
'Install': Install},
# описание действия
'action': ClBuilderCreateAction,
'action': ClBuilderPrepareAction,
# объект переменных
'datavars': "builder",
'native_error': (VariableError, DataVarsError,
InstallError, BuilderError, GitError),
# значения по умолчанию для переменных этого метода
'setvars': {'cl_action!': 'create',
'setvars': {'cl_action!': BuilderActions.Prepare,
'cl_dispatch_conf': 'usenew'},
# описание груп (список лямбда функций)
'groups': [
@ -70,9 +75,6 @@ class Wsdl(WsdlBase):
normal=('cl_builder_source_filename',
'cl_builder_new_id',
'cl_builder_disk_dev',
'cl_builder_profile_url',
'cl_builder_profile_branch',
'cl_builder_profile_system_shortname',
'cl_builder_layered_set'),
expert=('cl_templates_locate',
'cl_verbose_set',
@ -83,7 +85,6 @@ class Wsdl(WsdlBase):
brief=('os_builder_linux_ver',
'os_builder_linux_system',
'cl_builder_disk_size',
'cl_builder_profile_data',
'cl_builder_profile_name'),
next_label=_("Perform"))],
'brief': {'next': __("Perform"),
@ -114,7 +115,7 @@ class Wsdl(WsdlBase):
'native_error': (VariableError, DataVarsError,
InstallError, BuilderError, GitError),
# значения по умолчанию для переменных этого метода
'setvars': {'cl_action!': 'break'},
'setvars': {'cl_action!': BuilderActions.Break},
# описание груп (список лямбда функций)
'groups': [
lambda group: group(_("Break the assemble"),
@ -124,6 +125,42 @@ class Wsdl(WsdlBase):
'cl_verbose_set', 'cl_dispatch_conf'),
next_label=_("Perform"))]
},
{
# идентификатор метода
'method_name': "builder_update",
# категория метода
'category': __('Builder'),
# заголовок метода
'title': __("Update the assemble"),
# иконка для графической консоли
'image': 'calculate-update',
# метод присутствует в графической консоли
'gui': True,
# консольная команда
'command': 'cl-builder-update',
# права для запуска метода
'rights': ['build'],
# объект содержащий модули для действия
'logic': {'Builder': Builder,
'Install': Install},
# описание действия
'action': ClBuilderUpdateAction,
# объект переменных
'datavars': "builder",
'native_error': (VariableError, DataVarsError,
InstallError, BuilderError, GitError),
# значения по умолчанию для переменных этого метода
'setvars': {'cl_action!': BuilderActions.Update,
'cl_dispatch_conf': 'usenew'},
# описание груп (список лямбда функций)
'groups': [
lambda group: group(_("Update the assemble"),
normal=('cl_builder_prepared_id',
'cl_builder_videodrv_set',),
expert=('cl_templates_locate',
'cl_verbose_set', 'cl_dispatch_conf'),
next_label=_("Perform"))]
},
{
# идентификатор метода
'method_name': "builder_restore",
@ -149,7 +186,7 @@ class Wsdl(WsdlBase):
'native_error': (VariableError, DataVarsError,
InstallError, BuilderError, GitError),
# значения по умолчанию для переменных этого метода
'setvars': {'cl_action!': 'restore'},
'setvars': {'cl_action!': BuilderActions.Restore},
# описание груп (список лямбда функций)
'groups': [
lambda group: group(_("Break the assemble"),
@ -180,10 +217,10 @@ class Wsdl(WsdlBase):
'action': ClBuilderImageAction,
# объект переменных
'datavars': "builder",
'native_error': (VariableError, DataVarsError,
'native_error': (VariableError, DataVarsError, EmergeError,
InstallError, BuilderError, GitError),
# значения по умолчанию для переменных этого метода
'setvars': {'cl_action!': 'image',
'setvars': {'cl_action!': BuilderActions.Image,
'cl_dispatch_conf': 'usenew'},
# описание груп (список лямбда функций)
'groups': [
@ -202,5 +239,58 @@ class Wsdl(WsdlBase):
next_label=_("Perform")),],
'brief': {'next': __("Perform"),
'name': __("Create the image")}
}
},
#
# Сменить профиль
#
{
# идентификатор метода
'method_name': "builder_profile",
# категория метода
'category': __('Builder'),
# заголовок метода
'title': __("Change the Assemble Profile"),
# иконка для графической консоли
'image': 'extension',
# метод присутствует в графической консоли
'gui': True,
# консольная команда
'command': 'cl-builder-profile',
# права для запуска метода
'rights': ['builder'],
# объект содержащий модули для действия
'logic': {'Builder': Builder},
# описание действия
'action': ClBuilderProfileAction,
# объект переменных
'datavars': "builder",
'native_error': (VariableError, DataVarsError, UpdateError,
InstallError, BuilderError, GitError),
# значения по умолчанию для переменных этого метода
'setvars': {'cl_action!': BuilderActions.ChangeProfile},
# описание груп (список лямбда функций)
'groups': [
lambda group: group(_("Repository"),
brief=('cl_builder_profile_repo_name',),
hide=('cl_builder_profile_url',
'update.cl_update_profile_sync_set'),
normal=('cl_builder_profile_url',
'cl_builder_prepared_id'),
expert=('update.cl_update_profile_sync_set',
'cl_builder_profile_branch')),
lambda group: group(_("Profile"),
normal=('cl_builder_profile_system_shortname',
'update.cl_update_world'),
expert=('update.cl_update_skip_setup_set',
'cl_builder_templates_locate',
'cl_verbose_set',
'cl_dispatch_conf'),
hide=('cl_builder_templates_locate',
'cl_verbose_set',
'cl_dispatch_conf'),
brief=('cl_builder_profile_linux_fullname',
'cl_builder_profile_depend_data')
)],
'brief': {'next': __("Perform"),
'name': __("Set the profile")}},
]

Loading…
Cancel
Save