From abb1c372758adee81b578529648924e4642001cc Mon Sep 17 00:00:00 2001 From: Mike Khiretskiy Date: Tue, 4 Aug 2015 11:49:36 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9C=D0=BD=D0=BE=D0=B6=D0=B5=D1=81=D1=82?= =?UTF-8?q?=D0=B2=D0=B5=D0=BD=D0=BD=D1=8B=D0=B5=20=D0=B8=D0=B7=D0=BC=D0=B5?= =?UTF-8?q?=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=B4=D0=BB=D1=8F=20=D0=B8?= =?UTF-8?q?=D1=81=D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D0=BD?= =?UTF-8?q?=D0=B8=D1=8F=20=D1=81=20calculate-assemble?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pym/update/emerge_parser.py | 65 ++++- pym/update/profile.py | 5 +- pym/update/update.py | 206 +++++++++----- pym/update/update_tasks.py | 27 ++ pym/update/utils/cl_setup_update.py | 2 +- pym/update/utils/cl_update.py | 64 ++--- pym/update/utils/cl_update_profile.py | 20 +- pym/update/variables/update.py | 369 +++++++++++++++++--------- pym/update/wsdl_update.py | 4 +- 9 files changed, 509 insertions(+), 253 deletions(-) create mode 100644 pym/update/update_tasks.py diff --git a/pym/update/emerge_parser.py b/pym/update/emerge_parser.py index 8b89398..e070e15 100644 --- a/pym/update/emerge_parser.py +++ b/pym/update/emerge_parser.py @@ -39,6 +39,7 @@ from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate, _ setLocalTranslate('cl_update3', sys.modules[__name__]) __ = getLazyLocalTranslate(_) +linux_term_env = {'TERM':'linux'} class EmergeError(Exception): """ @@ -50,8 +51,6 @@ class EmergeNeedRootError(EmergeError): pass -env_terminal_linux = {'TERM':'linux'} - class CommandExecutor(object): """ Запуск программы для объекта Emerge @@ -61,8 +60,8 @@ class CommandExecutor(object): def __init__(self, cmd, params, env=None, cwd=None, logfile=None): self.cwd = cwd self.env = env or dict(os.environ) - self.env.update({'EINFO_QUIET':'NO'}) - self.env.update(env_terminal_linux) + self.env.update({'EINFO_QUIET': 'NO'}) + self.env.update(linux_term_env) self.cmd = cmd self.params = params self.child = None @@ -96,6 +95,27 @@ class CommandExecutor(object): self.child.send(s) +class ChrootCommandExecutor(CommandExecutor): + """ + Команда запускаемая в chroot + """ + def __init__(self, chroot_path, + cmd, params, env=None, cwd=None, logfile=None): + + self.chroot_path = chroot_path + super(ChrootCommandExecutor, self).__init__(cmd, params, env=env, + cwd=cwd, logfile=logfile) + + def execute(self): + if self.child is None: + chrootCmd = '/usr/bin/chroot' + self.child = pexpect.spawn(chrootCmd, [self.chroot_path, self.cmd] + + list(self.params), + logfile=open(self.logfile, 'w'), + env=self.env, cwd=self.cwd, timeout=None) + return self.child + + class EmergeCommand(CommandExecutor): """ Запуск emerge для последующего анализирования @@ -105,7 +125,7 @@ class EmergeCommand(CommandExecutor): cmd = getProgPath("/usr/bin/emerge") def __init__(self, packages, extra_params=None, env=None, cwd=None, - logfile=None, emerge_default_opts=None): + logfile=None, emerge_default_opts=None, use=""): extra_params = extra_params or [] self.child = None self.packages = packages @@ -118,9 +138,11 @@ class EmergeCommand(CommandExecutor): 'EMERGE_DEFAULT_OPTS': re.sub(r'(?:^|\s)(--columns)(?=\s|$)','', emerge_default_opts) } + if use: + default_env["USE"] = use default_env.update(os.environ) self.env = env or default_env - self.env.update(env_terminal_linux) + self.env.update(linux_term_env) self.cwd = cwd if logfile: self.logfile = logfile @@ -133,9 +155,37 @@ class EmergeCommand(CommandExecutor): return self.child +class ChrootEmergeCommand(EmergeCommand): + def __init__(self, chroot_path, *args, **kw): + self.chroot_path = chroot_path + + super(ChrootEmergeCommand, self).__init__(*args, **kw) + + def execute(self): + if self.child is None: + chrootCmd = '/usr/bin/chroot' + bashCmd = '/bin/bash' + bash_command = ( + "env-update &>/dev/null;" + "source /etc/profile &>/dev/null;" + "{emerge_command} {params} {packages}".format( + emerge_command=self.cmd, + params=" ".join(self.params), + packages=" ".join(self.packages) + )) + # TODO: использование linux32 + self.child = pexpect.spawn(chrootCmd, + [self.chroot_path, bashCmd, + "-c", bash_command], + logfile=open(self.logfile, 'w'), + env=self.env, cwd=self.cwd, + timeout=None) + return self.child + + class EmergeInformationBlock(object): _color_block = "(?:\033\[[^m]+?m)?" - _new_line = "\r*\n" + _new_line = "(?:\r*\n)" token = None end_token = ["\n"] re_block = None @@ -445,6 +495,7 @@ class FetchingTarball(NotifierInformationBlock): def notify(self, observer, groups): observer(groups[0]) + class InstallingPackage(NotifierInformationBlock): """ Запуск устанавливаемого пакета diff --git a/pym/update/profile.py b/pym/update/profile.py index 19699b7..db0e327 100644 --- a/pym/update/profile.py +++ b/pym/update/profile.py @@ -82,9 +82,8 @@ class RepositoryStorageSet(RepositoryStorage): """ Набор хранилищ репозиториев """ - def __init__(self): - self.storages = [LocalStorage('/var/lib/layman'), - CacheStorage('/var/calculate/tmp/update')] + def __init__(self, *storages): + self.storages = storages def get_profiles(self, url, branch=DEFAULT_BRANCH): """ diff --git a/pym/update/update.py b/pym/update/update.py index 7dde4c7..6e06d32 100644 --- a/pym/update/update.py +++ b/pym/update/update.py @@ -13,6 +13,7 @@ # 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 functools import wraps, partial import random import sys @@ -32,8 +33,9 @@ from calculate.update.datavars import DataVarsUpdate from calculate.update.update_info import UpdateInfo from calculate.lib.cl_log import log import re -from itertools import chain from collections import MutableSet +from mock import self +from update_tasks import EmergeMark from calculate.lib.utils.portage import (Git, Layman, EmergeLog, GitError, EmergeLogNamedTask, PackageList, @@ -48,7 +50,8 @@ from calculate.lib.utils.files import (getProgPath, STDOUT, removeDir, readFile, listDirectory) import emerge_parser import logging -from emerge_parser import EmergeParser, EmergeCommand, EmergeError, EmergeCache +from emerge_parser import (EmergeParser, EmergeCommand, EmergeError, + EmergeCache, ChrootEmergeCommand) from calculate.lib.cl_lang import (setLocalTranslate, getLazyLocalTranslate, RegexpLocalization, _) @@ -63,18 +66,19 @@ class OverlayOwnCache(MutableSet): """ Сет оверлеев с интегрированным кэшем """ - def __init__(self, initvalue=()): - pass + def __init__(self, dv=None): + self.dv = dv def __get_overlays(self): - own_cache_value = SystemIni().getVar('update', 'own_cache') or "" + own_cache_value = SystemIni(self.dv).getVar('update', 'own_cache') or "" return [x.strip() for x in own_cache_value.split(',') if x.strip()] def __write_overlays(self, overlays): if not overlays: - SystemIni().delVar('update', 'own_cache') + SystemIni(self.dv).delVar('update', 'own_cache') else: - SystemIni().setVar('update', {'own_cache': ",".join(overlays)}) + SystemIni(self.dv).setVar('update', + {'own_cache': ",".join(overlays)}) def __contains__(self, item): return item in self.__get_overlays() @@ -101,6 +105,21 @@ class OverlayOwnCache(MutableSet): self.__write_overlays(overlays) +def variable_module(var_env): + def variable_module_decor(f): + @wraps(f) + def wrapper(self, *args, **kw): + old_env = self.clVars.defaultModule + try: + self.clVars.defaultModule = var_env + return f(self, *args, **kw) + finally: + self.clVars.defaultModule = old_env + return wrapper + + return variable_module_decor + + class Update(object): """Основной объект для выполнения действий связанных с обновлением системы @@ -119,6 +138,9 @@ class Update(object): self.clVars.Get('update.cl_update_rep_path'))) self.update_map = {} + def get_prog_path(self, progname): + return getProgPath(progname) + def _syncRepository(self, name, url, rpath, revision, branch, cb_progress=None): """ @@ -131,36 +153,58 @@ class Update(object): self.stash_cache(rpath, name) if not git.checkExistsRep(rpath): if revision == "last": - git.cloneRepository(url, rpath, branch, + git.cloneTagRepository(url, rpath, branch, cb_progress=cb_progress) else: - git.cloneRevRepository(url, rpath, branch, revision, + git.cloneTagRepository(url, rpath, revision, cb_progress=cb_progress) info_outdate = True else: - # если нужно обновиться до конкретной ревизии if revision != "last": - if revision == git.getCurrentCommit(rpath): - if git.getBranch(rpath) == branch: - return False - # получить изменения из удаленного репозитория - git.fetchRepository(rpath, cb_progress=cb_progress) - # если текущая ветка не соответствует нужной - repInfo = git.getStatusInfo(rpath) - if repInfo['branch'] != branch: - # меняем ветку - info_outdate = True - git.checkoutBranch(rpath, branch) - if revision == "last": - if git.resetRepository(rpath, to_origin=True): - # если не удалось сбросить - repInfo = git.getStatusInfo(rpath) - if repInfo.get("files", False): - raise GitError("Failed to reset git") + try: + need_update = False + tag_cr = git.getCommit(rpath, revision) + cr = git.getCurrentCommit(rpath) + if tag_cr != cr: + need_update = True + except GitError: + need_update = True + if need_update: + git.updateTagRepository(url, rpath, revision, + cb_progress=cb_progress) info_outdate = True else: - git.resetRepository(rpath, to_rev=revision) - info_outdate = True + try: + old_cr = git.getCurrentCommit(rpath) + except GitError: + old_cr = "" + git.updateTagRepository(url, rpath, branch, + cb_progress=cb_progress) + if old_cr != git.getCurrentCommit(rpath): + info_outdate = True + # если нужно обновиться до конкретной ревизии + #if revision != "last": + # if revision == git.getCurrentCommit(rpath): + # if git.getBranch(rpath) == branch: + # return False + ## получить изменения из удаленного репозитория + #git.fetchRepository(rpath, cb_progress=cb_progress) + ## если текущая ветка не соответствует нужной + #repInfo = git.getStatusInfo(rpath) + #if repInfo['branch'] != branch: + # # меняем ветку + # info_outdate = True + # git.checkoutBranch(rpath, branch) + #if revision == "last": + # if git.resetRepository(rpath, to_origin=True): + # # если не удалось сбросить + # repInfo = git.getStatusInfo(rpath) + # if repInfo.get("files", False): + # raise GitError("Failed to reset git") + # info_outdate = True + #else: + # git.resetRepository(rpath, to_rev=revision) + # info_outdate = True if info_outdate: dv.Set('cl_update_outdate_set', 'on', force=True) finally: @@ -247,6 +291,7 @@ class Update(object): self.endTask() return True + @variable_module("update") def syncRepositories(self, repname, clean_on_error=True): """ Синхронизировать репозитории @@ -259,6 +304,11 @@ class Update(object): if not url or not rpath: raise UpdateError(_("Configuration variables for repositories " "are not setup")) + chroot_path = path.normpath(self.clVars.Get('cl_chroot_path')) + if chroot_path == '/': + rpath_orig = rpath + else: + rpath_orig = rpath[len(chroot_path):] self.addProgress() if clean_on_error: try: @@ -266,7 +316,7 @@ class Update(object): dv.Get('cl_update_layman_make'), dv.Get('cl_update_layman_conf')) if repname != "portage": - layman.add(repname, url, rpath) + layman.add(repname, url, rpath_orig) if not self._syncRepository(repname, url, rpath, revision, branch, cb_progress=self.setProgress): return "skip" @@ -279,8 +329,8 @@ class Update(object): self.startTask( _("Re-fetching the {name} repository").format(name=repname)) self.addProgress() + rpath_new = "%s_new" % rpath try: - rpath_new = "%s_new" % rpath self._syncRepository(repname, url, rpath_new, revision, branch, cb_progress=self.setProgress) removeDir(rpath) @@ -300,7 +350,9 @@ class Update(object): dv.Get('cl_update_layman_make'), dv.Get('cl_update_layman_conf')) if repname != "portage": - layman.add(repname, url, rpath) + # TODO: debug block + #print "EEEE",repname, url, rpath_orig + layman.add(repname, url, rpath_orig) return True metadata_cache_names = ("metadata/md5-cache", "metadata/cache") @@ -311,7 +363,7 @@ class Update(object): """ if name in ("portage",): return - if not name in OverlayOwnCache(): + if not name in OverlayOwnCache(self.clVars): for cachename in self.metadata_cache_names: cachedir = path.join(rpath, cachename) if path.exists(cachedir): @@ -332,7 +384,7 @@ class Update(object): if name in ("portage",): return cachenames = self.metadata_cache_names - if not name in OverlayOwnCache(): + if not name in OverlayOwnCache(self.clVars): if any(path.exists(path.join(rpath, x)) for x in cachenames): for cachename in cachenames: cachedir_s = path.join(path.dirname(rpath), @@ -342,7 +394,7 @@ class Update(object): removeDir(cachedir_s) except BaseException as e: pass - OverlayOwnCache().add(name) + OverlayOwnCache(self.clVars).add(name) else: for cachename in cachenames: cachedir = path.join(rpath, cachename) @@ -355,14 +407,14 @@ class Update(object): pass else: if all(not path.exists(path.join(rpath, x)) for x in cachenames): - OverlayOwnCache().discard(name) + OverlayOwnCache(self.clVars).discard(name) def syncLaymanRepository(self, repname): """ Обновить репозиторий через layman """ - layman = getProgPath('/usr/bin/layman') + layman = self.get_prog_path('/usr/bin/layman') if not layman: raise UpdateError(_("The Layman tool is not found")) rpath = self.clVars.Select('cl_update_other_rep_path', @@ -386,11 +438,15 @@ class Update(object): self.unstash_cache(rpath, laymanname) return True + def _regenCache_process(self, progname, repname, cpu_num): + return process(progname, "--repo=%s" % repname, "--update", + "--jobs=%s" % cpu_num, stderr=STDOUT) + def regenCache(self, repname): """ Обновить кэш метаданных репозитория """ - egenCache = getProgPath('/usr/bin/egencache') + egenCache = self.get_prog_path('/usr/bin/egencache') if not egenCache: raise UpdateError(_("The Portage tool is not found")) if repname in self.clVars.Get('cl_update_rep_name'): @@ -407,14 +463,13 @@ class Update(object): raise UpdateError(_("Failed to update the cache of the {rname} " "repository").format(rname=repname)) cpu_num = self.clVars.Get('hr_cpu_num') - if repname in OverlayOwnCache(): + if repname in OverlayOwnCache(self.clVars): self.printWARNING( _("Repository %s has its own cache") % repname.capitalize()) else: self.startTask(_("Updating the %s repository cache") % repname.capitalize()) - p = process(egenCache, "--repo=%s" % repname, "--update", - "--jobs=%s" % cpu_num, stderr=STDOUT) + p = self._regenCache_process(egenCache, repname, cpu_num) if p.failed(): raise UpdateError(_("Failed to update the cache of the {rname} " "repository").format(rname=repname), @@ -425,7 +480,7 @@ class Update(object): """ Выполнить egencache и emerge --metadata """ - emerge = getProgPath("/usr/bin/emerge") + emerge = self.get_prog_path("/usr/bin/emerge") if not emerge: raise UpdateError(_("The Emerge tool is not found")) self.addProgress() @@ -440,7 +495,10 @@ class Update(object): raise UpdateError(_("Failed to update metadata"), addon=data) return True - def eixUpdate(self): + def _eixUpdateCommand(self, eix_cmd, countRep): + return PercentProgress(eix_cmd, "-F", part=countRep or 1, atty=True) + + def eixUpdate(self, repositroies): """ Выполенине eix-update для репозиторием @@ -448,12 +506,12 @@ class Update(object): обновлялись, если cl_update_eixsync_force==auto, либо все, если cl_update_eixupdate_force==force """ - eixupdate = getProgPath("/usr/bin/eix-update") + eixupdate = self.get_prog_path("/usr/bin/eix-update") if not eixupdate: raise UpdateError(_("The Eix tool is not found")) self.addProgress() - countRep = len(self.clVars.Get('main.cl_portdir_overlay'))+1 - p = PercentProgress(eixupdate, "-F", part=countRep or 1, atty=True) + countRep = len(repositroies) + p = self._eixUpdateCommand(eixupdate, countRep) for perc in p.progress(): self.setProgress(perc) if p.failed(): @@ -552,7 +610,7 @@ class Update(object): """ Запуск команды, которая подразумевает выполнение emerge """ - cmd_path = getProgPath(cmd) + cmd_path = self.get_prog_path(cmd) if not cmd_path: raise UpdateError(_("Failed to find the %s command") % cmd) with EmergeParser( @@ -564,7 +622,7 @@ class Update(object): """ Запуск revdep-rebulid """ - cmd_path = getProgPath(cmd) + cmd_path = self.get_prog_path(cmd) if not cmd_path: raise UpdateError(_("Failed to find the %s command") % cmd) with EmergeParser( @@ -662,7 +720,7 @@ class Update(object): Отобразить список удаляемых пакетов """ # подробный список пакетов - if self.clVars.Get('cl_update_emergelist_set') == 'on': + if self.clVars.Get('update.cl_update_emergelist_set') == 'on': self.printPre(self._emerge_translate( emerge.uninstall_packages.verbose_result)) else: @@ -677,9 +735,7 @@ class Update(object): Получить список обновляемых пакетов @world из кэша """ if "@world" in packages: - from calculate.update.utils.cl_update import ClUpdateAction - elog = EmergeLog( - EmergeLogNamedTask(ClUpdateAction.log_names['premerge'])) + elog = EmergeLog(EmergeLogNamedTask(EmergeMark.Premerge)) if check and (elog.list or elog.remove_list): self.emerge_cache.drop_cache( "Some packages was installed or removed") @@ -697,9 +753,7 @@ class Update(object): premerge """ self.emerge_cache.set_cache(pkg_list) - from calculate.update.utils.cl_update import ClUpdateAction - elog = EmergeLog( - EmergeLogNamedTask(ClUpdateAction.log_names['premerge'])) + elog = EmergeLog(EmergeLogNamedTask(EmergeMark.Premerge)) elog.mark_end_task(), def mark_schedule(self): @@ -812,10 +866,15 @@ class Update(object): error = "
".join(str(error).split('
')[-lines_num:]) self.printPre(self._emerge_translate(error)) - def emerge(self, param, *packages): + def emerge(self, use, param, *packages): """ Выполнить сборку пакета """ + if self.clVars.Get('cl_chroot_path') != '/': + command_class = partial(ChrootEmergeCommand, + self.clVars.Get('cl_chroot_path')) + else: + command_class = EmergeCommand deo = self.clVars.Get('cl_emerge_default_opts') if not packages: packages = [param] @@ -825,8 +884,9 @@ class Update(object): if not packages: return True extra_params = [param] - with EmergeParser(EmergeCommand(list(packages), emerge_default_opts=deo, - extra_params=extra_params)) as emerge: + with EmergeParser(command_class(list(packages), emerge_default_opts=deo, + extra_params=extra_params, + use=use)) as emerge: try: emerge.question.action = lambda x: False emerge.run() @@ -911,22 +971,23 @@ class Update(object): return decor - def migrateCacheRepository(self, url, branch): - rep_set = self.clVars.Get('cl_update_profile_storage') - rep = rep_set.get_repository(url, branch) + def migrateCacheRepository(self, url, branch, storage): + """ + Перенести репозиторий из кэша в локальный + """ + rep = storage.get_repository(url, branch) if rep: - rep.storage = rep_set.storages[0] + rep.storage = storage.storages[0] self.clVars.Invalidate('cl_update_profile_storage') return True - def reconfigureProfileVars(self): + def reconfigureProfileVars(self, profile_dv, chroot): """ Синхронизировать репозитории """ dv = self.clVars - profile_dv = dv.Get('cl_update_profile_datavars') try: if not profile_dv: raise UpdateError( @@ -937,17 +998,22 @@ class Update(object): 'cl_update_rep_name', 'cl_update_branch_name', 'cl_profile_system', - 'cl_update_layman_storage', 'cl_update_rep'): + # TODO: debug block + print var_name, ":", profile_dv.Get(var_name) dv.Set(var_name, profile_dv.Get(var_name), force=True) - except DataVarsError: + dv.Set('cl_chroot_path', chroot, force=True) + # TODO: debug block + print ('cl_builder_branch_name', + self.clVars.Get('cl_builder_branch_name')) + except DataVarsError as e: raise UpdateError(_("Wrong profile")) return True - def setProfile(self): - profile = self.clVars.Select('cl_profile_path', - where='cl_profile_shortname', - eq=self.clVars.Get('cl_update_profile_system'), limit=1) + def setProfile(self, profile_shortname): + profile = self.clVars.Select('cl_update_profile_path', + where='cl_update_profile_shortname', + eq=profile_shortname, limit=1) if not profile: raise UpdateError(_("Failed to determine profile %s") % self.clVars.Get('cl_update_profile_system')) diff --git a/pym/update/update_tasks.py b/pym/update/update_tasks.py new file mode 100644 index 0000000..8ed978f --- /dev/null +++ b/pym/update/update_tasks.py @@ -0,0 +1,27 @@ +#-*- 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. + +class EmergeMark: + Schedule = "schedule" + Premerge = "check updates" + PythonUpdater = "update python modules" + PerlCleaner = "update perl modules" + KernelModules = "update kernel modules" + Depclean = "depclean" + XorgModules = "update xorg modules" + PreservedLibs = "update preserved libs" + RevdepRebuild = "revdep rebuild" + Prelink = "prelink" diff --git a/pym/update/utils/cl_setup_update.py b/pym/update/utils/cl_setup_update.py index 11843fd..31a26e7 100644 --- a/pym/update/utils/cl_setup_update.py +++ b/pym/update/utils/cl_setup_update.py @@ -37,7 +37,7 @@ class ClSetupUpdateAction(Action): interruptMessage = __("Configuration manually interrupted") - # список задач для дейсвия + # список задач для действия tasks = [ {'name': 'set_variables', 'method': 'Update.setAutocheckParams(cl_update_autocheck_set,' diff --git a/pym/update/utils/cl_update.py b/pym/update/utils/cl_update.py index 0a4bdbc..288277b 100644 --- a/pym/update/utils/cl_update.py +++ b/pym/update/utils/cl_update.py @@ -23,6 +23,7 @@ from calculate.update.update import UpdateError from calculate.update.emerge_parser import EmergeError from calculate.lib.utils.portage import GitError, Eix, EmergeLog, \ EmergeLogNamedTask, PackageList +from ..update_tasks import EmergeMark setLocalTranslate('cl_update3', sys.modules[__name__]) __ = getLazyLocalTranslate(_) @@ -53,6 +54,7 @@ class ClUpdateAction(Action): return func def need_upgrade(pkg): + # TODO: возможно функция не работает def func(): return bool(Eix(pkg, Eix.Option.Upgrade).get_packages()) return func @@ -60,16 +62,6 @@ class ClUpdateAction(Action): def pkg_color(text): return text - log_names = {'schedule': "schedule", - 'premerge': "check updates", - 'python_updater': "update python modules", - 'perl_cleaner': "update perl modules", - 'kernel_modules': "update kernel modules", - 'depclean': "depclean", - 'xorg_modules': "update xorg modules", - 'preserved_libs': "update preserved libs", - 'revdep': "revdep rebuild"} - emerge_tasks = [ {'name': 'premerge_group', 'group': __("Checking for updates"), @@ -93,7 +85,7 @@ class ClUpdateAction(Action): 'tasks': [ {'name': 'update:update_world', 'message': __("Calculating dependencies"), - 'method': 'Update.emerge("-uDN","--with-bdeps=y","@world")', + 'method': 'Update.emerge("","-uDN","--with-bdeps=y","@world")', } ] }, @@ -105,9 +97,9 @@ class ClUpdateAction(Action): 'to a Python upgrade'), 'method': 'Update.emergelike("python-updater")', 'condition': was_installed('dev-lang/python$', - log_names['python_updater']), - 'decoration': 'Update.update_task("%s")' % log_names[ - 'python_updater'] + EmergeMark.PythonUpdater), + 'decoration': 'Update.update_task("%s")' % + EmergeMark.PythonUpdater }, ] }, @@ -119,9 +111,8 @@ class ClUpdateAction(Action): 'broken due to a perl upgrade'), 'method': 'Update.emergelike("perl-cleaner", "all")', 'condition': was_installed('dev-lang/perl$', - log_names['perl_cleaner']), - 'decoration': 'Update.update_task("%s")' % log_names[ - 'perl_cleaner'] + EmergeMark.PerlCleaner), + 'decoration': 'Update.update_task("%s")' % EmergeMark.PerlCleaner }, ] }, @@ -131,8 +122,8 @@ class ClUpdateAction(Action): {'name': 'update_other:update_depclean', 'message': __("Calculating dependencies"), 'method': 'Update.depclean()', - 'condition': need_depclean('.*', log_names['depclean']), - 'decoration': 'Update.update_task("%s")' % log_names['depclean'] + 'condition': need_depclean('.*', EmergeMark.Depclean), + 'decoration': 'Update.update_task("%s")' % EmergeMark.Depclean }, ] }, @@ -141,34 +132,35 @@ class ClUpdateAction(Action): 'tasks': [ {'name': 'update_other:module_rebuild', 'message': __('Updating Kernel modules'), - 'method': 'Update.emerge("@module-rebuild")', + 'method': 'Update.emerge("","@module-rebuild")', 'condition': was_installed('sys-kernel/.*source', - log_names['kernel_modules']), - 'decoration': 'Update.update_task("%s")' % log_names[ - 'kernel_modules'] + EmergeMark.KernelModules), + 'decoration': 'Update.update_task("%s")' % + EmergeMark.KernelModules }, {'name': 'update_other:x11_module_rebuild', 'message': __('Updating X.Org server modules'), - 'method': 'Update.emerge("@x11-module-rebuild")', + 'method': 'Update.emerge("","@x11-module-rebuild")', 'condition': was_installed('x11-base/xorg-server', - log_names['xorg_modules']), - 'decoration': 'Update.update_task("%s")' % log_names[ - 'xorg_modules'] + EmergeMark.XorgModules), + 'decoration': 'Update.update_task("%s")' % + EmergeMark.XorgModules }, {'name': 'update_other:preserved_rebuild', 'message': __('Updating preserved libraries'), - 'method': 'Update.emerge("@preserved-rebuild")', - 'condition': was_installed('.*', log_names['preserved_libs']), - 'decoration': 'Update.update_task("%s")' % log_names[ - 'preserved_libs'] + 'method': 'Update.emerge("","@preserved-rebuild")', + 'condition': was_installed('.*', EmergeMark.PreservedLibs), + 'decoration': 'Update.update_task("%s")' % + EmergeMark.PreservedLibs }, {'name': 'update_other:revdev_rebuild', 'message': __('Checking reverse dependencies'), 'method': 'Update.revdep_rebuild("revdep-rebuild")', 'condition': lambda Get:(Get('cl_update_skip_rb_set') == 'off' - and ClUpdateAction.was_installed('.*', - ClUpdateAction.log_names['revdep'])()), - 'decoration': 'Update.update_task("%s")' % log_names['revdep'] + and ClUpdateAction.was_installed('.*', + EmergeMark.RevdepRebuild)()), + 'decoration': 'Update.update_task("%s")' % + EmergeMark.RevdepRebuild }, {'name': 'update_other:dispatch_conf_end', 'message': __("Updating configuration files"), @@ -183,7 +175,7 @@ class ClUpdateAction(Action): } ] - # список задач для дейсвия + # список задач для действия tasks = [ {'name': 'check_schedule', 'method': 'Update.checkSchedule(cl_update_autocheck_interval,' @@ -233,7 +225,7 @@ class ClUpdateAction(Action): }, {'name': 'eix_update', 'message': __("Updating the eix cache"), - 'method': 'Update.eixUpdate()', + 'method': 'Update.eixUpdate(cl_repository_name)', 'condition': ( lambda Get: (Get('cl_update_outdate_set') == 'on' and Get('cl_update_eixupdate_force') != 'skip' or diff --git a/pym/update/utils/cl_update_profile.py b/pym/update/utils/cl_update_profile.py index f56a5a6..e37724b 100644 --- a/pym/update/utils/cl_update_profile.py +++ b/pym/update/utils/cl_update_profile.py @@ -37,19 +37,25 @@ class ClUpdateProfileAction(Action): interruptMessage = __("Profile update manually interrupted") - # список задач для дейсвия + # список задач для действия tasks = [ {'name': 'migrate_repository', 'method': 'Update.migrateCacheRepository(' - 'cl_update_profile_rep,cl_update_profile_branch)', + 'cl_update_profile_url,cl_update_profile_branch,' + 'cl_update_profile_storage)', 'message': __("Repository transfer"), 'condition': lambda Get: not ( Get('cl_update_profile_storage').is_local( - Get('cl_update_profile_rep'), + Get('cl_update_profile_url'), Get('cl_update_profile_branch'))) }, + {'name': 'reconfigure_vars1', + 'method': 'Update.invalidateVariables("cl_update_profile_storage")', + 'depend': Tasks.has('migrate_repository') + }, {'name': 'reconfigure_vars', - 'method': 'Update.reconfigureProfileVars()' + 'method': 'Update.reconfigureProfileVars(cl_update_profile_datavars,' + 'cl_chroot_path)' }, {'name': 'reps_synchronization', 'group': __("Repositories synchronization"), @@ -80,7 +86,9 @@ class ClUpdateProfileAction(Action): }, {'name': 'eix_update', 'message': __("Updating the eix cache"), - 'method': 'Update.eixUpdate()', + # TODO: необходимо добавить опцию --changes-pkg emerge world + # TODO: возможно стоит использовать переменные от нового профиля + 'method': 'Update.eixUpdate(cl_repository_name)', 'condition': ( lambda Get: (Get('cl_update_outdate_set') == 'on' and Get('cl_update_eixupdate_force') != 'skip' or @@ -101,7 +109,7 @@ class ClUpdateProfileAction(Action): 'tasks': [ {'name': 'set_profile', 'message': __("Switching to profile {cl_update_profile_system}"), - 'method': 'Update.setProfile()' + 'method': 'Update.setProfile(cl_update_profile_system)' }, {'name': 'revision', 'message': __("Fixing the settings"), diff --git a/pym/update/variables/update.py b/pym/update/variables/update.py index be3c7f5..3185cb3 100644 --- a/pym/update/variables/update.py +++ b/pym/update/variables/update.py @@ -23,18 +23,21 @@ from calculate.lib.datavars import (Variable, VariableError, SimpleDataVars, DataVarsError) from calculate.lib.utils.portage import searchProfile from calculate.lib.utils.files import readLinesFile, readFile, makeDirectory, \ - listDirectory, process + listDirectory, process, pathJoin +from calculate.lib.configparser import ConfigParser from calculate.lib.cl_lang import setLocalTranslate from calculate.lib.utils.text import simplify_profiles from calculate.lib.utils.portage import Git, GitError, Layman -from calculate.update.profile import RepositoryStorageSet, DEFAULT_BRANCH +from ..profile import RepositoryStorageSet, DEFAULT_BRANCH, \ + LocalStorage, ProfileRepository, CacheStorage -from calculate.lib.variables.linux import VariableOsLinuxName, \ - VariableOsLinuxSubname, VariableOsLinuxVer, VariableOsLinuxShortname -from calculate.lib.variables.env import VariableClTemplateLocation +from calculate.lib.variables import linux as lib_linux +from calculate.lib.variables import env from calculate.update.update_info import UpdateInfo +from functools import partial +_ = lambda x:x setLocalTranslate('cl_update3', sys.modules[__name__]) @@ -107,7 +110,7 @@ class VariableClUpdateRep(Variable): value = "rev" def choice(self): - return ["last","rev"] + return ["last", "rev"] class VariableClUpdateRepData(ReadonlyTableVariable): """ @@ -133,35 +136,46 @@ class VariableClUpdateRepUrl(Variable): type = "list" value = [] -class VariableClUpdateLaymanStorage(ReadonlyVariable): +class VariableClUpdateLaymanConfig(ReadonlyVariable): + """ + Объект конфига layman + """ + type = "object" + + def get(self): + chroot = self.Get('cl_chroot_path') + cp = ConfigParser() + cp.read(path.join(chroot, 'etc/layman/layman.cfg')) + return cp + +class VariableClUpdateLaymanStorage(Variable): """ Путь к репозиториям layman """ + param_name = "storage" + fallback_value = "var/lib/layman" + def get(self): - laymanConf = "/etc/layman/layman.cfg" - reStorage = re.compile("^storage\s*:\s*(\S+)") - if path.exists(laymanConf): - for line in readLinesFile(laymanConf): - match = reStorage.search(line) - if match: - return match.group(1) - return "/var/lib/layman" + cp = self.Get('cl_update_layman_config') + res = cp.get('MAIN', self.param_name, fallback=self.fallback_value) + return pathJoin(self.Get('cl_chroot_path'), res) class VariableClUpdateRepPath(ReadonlyVariable): """ Пути до репозиториев """ type = "list" - mapPath = {'portage':'/usr/portage'} + mapPath = {'portage':'usr/portage'} def get(self): repPath = self.Get('cl_update_layman_storage') + chroot_path = self.Get('cl_chroot_path') def generatePaths(names): for name in names: if name in self.mapPath: - yield self.mapPath[name] + yield path.join(chroot_path, self.mapPath[name]) else: - yield path.join(repPath,name) + yield path.join(repPath, name) return list(generatePaths(self.Get('cl_update_rep_name'))) class VariableClUpdateRepRev(Variable): @@ -171,6 +185,13 @@ class VariableClUpdateRepRev(Variable): type = "list" def get(self): + """ + Если cl_update_rep=rev, то профиль просматривается на нахождене + в нем rev файла (используется более частный вариант, + как с calculate.env), файл содержит строки ключ=значение, где + ключ - название репозитория, значение - ревизия до которой нужно + обновиться + """ if self.Get('cl_update_rep') == 'rev': revPaths = searchProfile(self.Get('cl_profile_system'), "rev") @@ -409,25 +430,26 @@ class VariableClUpdateOtherRepPath(FieldValue,ReadonlyVariable): source_variable = "cl_update_other_rep_data" column = 1 -class VariableClUpdateLaymanInstalled(Variable): +class VariableClUpdateLaymanInstalled(VariableClUpdateLaymanStorage): """ Путь до файла layman installed.xml """ - # TODO: извлечь из layman.cfg - value = "/var/lib/layman/installed.xml" + param_name = "installed" + fallback_value = "var/lib/layman/installed.xml" -class VariableClUpdateLaymanMake(Variable): +class VariableClUpdateLaymanMake(VariableClUpdateLaymanStorage): """ Путь до файла make.conf изменяемого layman`ом """ - # TODO: извлечь из layman.cfg - value = "/var/lib/layman/make.conf" + param_name = "make_conf" + fallback_value = "var/lib/layman/make.conf" -class VariableClUpdateLaymanConf(Variable): +class VariableClUpdateLaymanConf(VariableClUpdateLaymanStorage): """ Путь до конфигурационного файла репозиториев для layman """ - value = "/etc/portage/repos.conf/layman.conf" + param_name = "repos_conf" + fallback_value = "etc/portage/repos.conf/layman.conf" class VariableClUpdatePretendSet(Variable): """ @@ -480,7 +502,9 @@ class VariableClUpdateProfileStorage(ReadonlyVariable): type = "object" def get(self): - return RepositoryStorageSet() + return RepositoryStorageSet( + LocalStorage('/var/lib/layman'), + CacheStorage('/var/calculate/tmp/update')) class VariableClUpdateRepHost(Variable): type = "list" @@ -493,11 +517,14 @@ class VariableClUpdateRepHostUrl(Variable): class VariableClUpdateProfileDatavars(ReadonlyVariable): type = "object" + profile = "cl_update_profile_system" + profiles_path = "cl_update_profile_path" + profiles_shortname = "cl_update_profile_shortname" def get(self): - profile = self.Get('cl_update_profile_system') - path_profile = self.Select('cl_profile_path', - where='cl_profile_shortname', + profile = self.Get(self.profile) + path_profile = self.Select(self.profiles_path, + where=self.profiles_shortname, eq=profile, limit=1) if path_profile: return DataVarsUpdateProfile(path_profile) @@ -510,8 +537,10 @@ class VariableClUpdateProfileLinuxFullname(ReadonlyVariable): def init(self): self.label = _("Distribution name") + datavars = "cl_update_profile_datavars" + def get(self): - dv = self.Get('cl_update_profile_datavars') + dv = self.Get(self.datavars) if dv: try: subname = dv.Get('os_linux_subname') @@ -531,21 +560,25 @@ class VariableClUpdateProfileDependData(ReadonlyTableVariable): source = ['cl_update_profile_depend_name', 'cl_update_profile_depend_url'] + datavars = "cl_update_profile_datavars" + def init(self): self.label = _("Used repositories") @staticmethod def url_like(url1, url2): - match1 = VariableClUpdateProfileRep.re_url.search(url1) - match2 = VariableClUpdateProfileRep.re_url.search(url2) + match1 = VariableClUpdateProfileUrl.re_url.search(url1) + match2 = VariableClUpdateProfileUrl.re_url.search(url2) if match1 and match2: return match1.group(2).lower() == match2.group(2).lower() return False def get(self, hr=False): - dv = self.Get('cl_update_profile_datavars') - url = self.Get('cl_update_profile_rep').lower() + dv = self.Get(self.datavars) + # TODO: неиспользуемая переменная возможно + # испольуется для инициализации + #url = self.Get('cl_update_profile_url').lower() if dv: return reversed(zip(dv.Get('cl_update_rep_name'), dv.Get('cl_update_rep_url'))) @@ -564,6 +597,8 @@ class VariableClUpdateTemplatesLocate(Variable): untrusted = True check_after = ['cl_update_profile_system'] + profile_datevars = "update.cl_update_profile_datavars" + descriptionMap = {'overlay': _('Overlay templates'), 'local': _('Local templates'), 'calculate': _("Calculate overlay templates"), @@ -578,15 +613,16 @@ class VariableClUpdateTemplatesLocate(Variable): %",".join(self.get()) def get(self): - dv = self.Get('update.cl_update_profile_datavars') + dv = self.Get(self.profile_datevars) if dv: return dv.Get('cl_template_location') + ['clt'] else: return self.Get('cl_templates_locate') def choice(self): - return map(lambda x:(x,self.descriptionMap.get(x,_("%s overlay templates")%x)), - self.get()) + descr = lambda x: self.descriptionMap.get(x, + _("%s overlay templates" % x)) + return map(lambda x: (x, descr(x)), self.get()) class VariableClUpdateProfileDependName(FieldValue, ReadonlyVariable): type = "list" @@ -652,9 +688,9 @@ class VariableClUpdateProfileLinuxName(ReadonlyVariable): dv.Get('os_linux_name') return "" -class VariableClUpdateProfileRep(Variable): +class VariableClUpdateProfileUrl(Variable): """ - Текущий репозиторий + URL текущего репозитория """ untrusted = True check_after = ["cl_update_profile_branch"] @@ -662,6 +698,17 @@ class VariableClUpdateProfileRep(Variable): opt = ["--url"] metavalue = "URL" + profile = "cl_profile_system" + branch = "cl_update_profile_branch" + storage = "cl_update_profile_storage" + default_url = "git://git.calculate.ru/calculate/distros.git" + profiles_shortname = 'cl_update_profile_shortname' + + @property + def current_root(self): + return '/' + + def init(self): self.label = _("Profile repository") self.help = _("set the profile repository") @@ -685,12 +732,12 @@ class VariableClUpdateProfileRep(Variable): def url_by_shortname(self, value): match = self.re_shortname.match(value) if not match.group(1): - template = self.Get('cl_update_rep_host_url') + template = self.Get('update.cl_update_rep_host_url') if template: template = template[0] else: - template = self.Select('cl_update_rep_host_url', - where='cl_update_rep_host', + template = self.Select('update.cl_update_rep_host_url', + where='update.cl_update_rep_host', eq=match.group(1), limit=1) if not template: raise VariableError(_("Failed to determine the repository host")) @@ -709,32 +756,38 @@ class VariableClUpdateProfileRep(Variable): if not value: raise VariableError("Need to specify profile repository") try: - branch = self.Get('cl_update_profile_branch') - self.Get('cl_update_profile_storage').get_profiles(value, branch) + branch = self.Get(self.branch) + self.Get(self.storage).get_profiles(value, branch) except GitError as e: raise VariableError(str(e)) - if not self.Get('cl_profile_shortname'): + if not self.Get(self.profiles_shortname): raise VariableError(_("Repository %s has no profiles")%value) def get(self): try: - profile = self.Get('cl_profile_system') - while profile != '/' and ".git" not in listDirectory(profile): - profile = path.dirname(profile) - if profile == '/': - return "" - git = Git() - return git.get_url(profile, "origin") or "" + profile = self.Get(self.profile) + if profile: + while (profile != self.current_root and + ".git" not in listDirectory(profile)): + profile = path.dirname(profile) + if profile == self.current_root: + return "" + git = Git() + return git.get_url(profile, "origin") or "" except: - return "git://git.calculate.ru/calculate/distros.git" + pass + return self.default_url class VariableClUpdateProfileRepoName(ReadonlyVariable): def init(self): self.label = _("Repository name") + storage = "cl_update_profile_storage" + url = "cl_update_profile_url" + def get(self): - rep_set = self.Get('cl_update_profile_storage') - url = self.Get('cl_update_profile_rep') + rep_set = self.Get(self.storage) + url = self.Get(self.url) rep = rep_set.get_repository(url, branch=None) if rep: return rep.repo_name @@ -751,6 +804,9 @@ class VariableClUpdateProfileBranch(Variable): opt = ["--branch"] metavalue = "BRANCH" + storage = "cl_update_profile_storage" + url = "cl_update_profile_url" + def init(self): self.label = _("Repository branch") self.help = _("set the repository branch") @@ -759,14 +815,14 @@ class VariableClUpdateProfileBranch(Variable): pass ## TODO: проверка ветки #try: - # url = self.Get('cl_update_profile_rep') + # url = self.Get('cl_update_profile_url') # self.Get('cl_update_profile_storage').get_profiles(url, value) #except GitError as e: # raise VariableError(str(e)) def get(self): - rep_set = self.Get('cl_update_profile_storage') - url = self.Get('cl_update_profile_rep') + rep_set = self.Get(self.storage) + url = self.Get(self.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) @@ -775,87 +831,121 @@ class VariableClUpdateProfileBranch(Variable): return DEFAULT_BRANCH -class VariableClProfileSystem(ReadonlyVariable): +class VariableClProfileRepository(ReadonlyVariable): """ - Профиль системы (симлинк /etc/make.profile') + Репозиторий из которого будут получены профили """ + type = "object" + def get(self): try: - make_profile = self.Get('cl_make_profile') - return path.normpath( - path.join(path.dirname(make_profile), - os.readlink(make_profile))) + profile_dn = self.Get('cl_profile_system') + while profile_dn != '/' and ".git" not in listDirectory(profile_dn): + profile_dn = path.dirname(profile_dn) + if profile_dn == '/': + return "" + ls = LocalStorage(path.dirname(profile_dn)) + return ProfileRepository(path.basename(profile_dn), ls) except: - raise VariableError(_("Failed to determine the system profile")) + return "" class VariableClProfileData(ReadonlyTableVariable): - source = ["cl_profile_fullname", - "cl_profile_shortname", - "cl_profile_path", - "cl_profile_arch"] + """ + Таблица данных о текущих профилях системы + """ + source = [] + repository = "cl_profile_repository" + + def profile_filter(self, profiles): + arch = self.Get('os_arch_machine_gentoo') + return [x for x in profiles if x.arch == arch] def get(self, hr=False): - url = self.Get('cl_update_profile_rep') - if not url: + rep = self.Get(self.repository) + if not rep: + return [[]] + profiles = rep.get_profiles() + if not profiles: return [[]] + repo_name = profiles[0].repository.repo_name + filtered_profiles = self.profile_filter(profiles) + full_name = [x.profile for x in filtered_profiles] + profile_path = [x.path for x in filtered_profiles] + profile_arch = [x.arch for x in filtered_profiles] + short_name = simplify_profiles(full_name) + full_name = ["%s:%s" % (repo_name, x) for x in full_name] + return zip(full_name, + short_name, + profile_path, + profile_arch) + + setValue = Variable.setValue + +class VariableClUpdateProfileRepository(ReadonlyVariable): + """ + Репозиторий из которого будет извлечён список профилей + """ + type = "object" + url = "cl_update_profile_url" + storage = "cl_update_profile_storage" + branch = "cl_update_profile_branch" + sync_set = "update.cl_update_profile_sync_set" + + def get(self): + url = self.Get(self.url) + if not url: + return "" try: - rep_set = self.Get('cl_update_profile_storage') - branch = self.Get('cl_update_profile_branch') + rep_set = self.Get(self.storage) + branch = self.Get(self.branch) rep = rep_set.get_repository(url, branch) - if rep and self.Get('cl_update_profile_sync_set') == 'on': + if rep and self.Get(self.sync_set) == 'on': rep.sync() - profiles = rep_set.get_profiles(url, branch) + return rep_set.get_repository(url, branch) or "" except GitError: - return [[]] - arch = self.Get('os_arch_machine_gentoo') - if profiles: - repo_name = profiles[0].repository.repo_name - arch_profiles = [x for x in profiles if x.arch == arch] - full_name = [x.profile for x in arch_profiles] - profile_path = [x.path for x in arch_profiles] - profile_arch = [x.arch for x in arch_profiles] - short_name = simplify_profiles(full_name) - full_name = ["%s:%s"%(repo_name,x) for x in full_name] - return zip(full_name, - short_name, - profile_path, - profile_arch) - return [[]] + return "" - setValue = Variable.setValue +class VariableClUpdateProfileData(VariableClProfileData): + source = ["cl_update_profile_fullname", + "cl_update_profile_shortname", + "cl_update_profile_path", + "cl_update_profile_arch"] + + repository = "cl_update_profile_repository" -class VariableClProfileFullname(FieldValue, ReadonlyVariable): + +class VariableClUpdateProfileFullname(FieldValue, ReadonlyVariable): """ Полное название профиля """ type = "list" - source_variable = "cl_profile_data" + source_variable = "cl_update_profile_data" column = 0 -class VariableClProfileShortname(FieldValue, ReadonlyVariable): +class VariableClUpdateProfileShortname(FieldValue, ReadonlyVariable): """ Упрощенное название профиля """ type = "list" - source_variable = "cl_profile_data" + source_variable = "cl_update_profile_data" column = 1 -class VariableClProfilePath(FieldValue, ReadonlyVariable): +class VariableClUpdateProfilePath(FieldValue, ReadonlyVariable): """ Путь от корня до профиля """ type = "list" - source_variable = "cl_profile_data" + source_variable = "cl_update_profile_data" column = 2 -class VariableClProfileArch(FieldValue, ReadonlyVariable): +class VariableClUpdateProfileArch(FieldValue, ReadonlyVariable): """ Архитектура профиля """ type = "list" - source_variable = "cl_profile_data" + source_variable = "cl_update_profile_data" column = 3 class VariableClUpdateProfileSystem(Variable): @@ -867,6 +957,14 @@ class VariableClUpdateProfileSystem(Variable): untrusted = True metavalue = "PROFILE" + profiles_path = "cl_update_profile_path" + profiles_shortname = "cl_update_profile_shortname" + profiles_fullname = "cl_update_profile_fullname" + profiles_arch = "cl_update_profile_arch" + profile = "cl_profile_system" + url = "cl_update_profile_url" + gentoo_arch = 'os_arch_machine_gentoo' + def init(self): self.label = _("System profile") self.help = _("set the system profile") @@ -874,12 +972,12 @@ class VariableClUpdateProfileSystem(Variable): def check(self, profile): if not profile: raise VariableError(_("You must specify the profile")) - path_profile = self.Select('cl_profile_path', - where='cl_profile_shortname', - eq=profile, limit=1) - profile_fullname = self.Select('cl_profile_fullname', - where='cl_profile_shortname', + path_profile = self.Select(self.profiles_path, + where=self.profiles_shortname, eq=profile, limit=1) + profile_fullname = self.Select(self.profiles_fullname, + where=self.profiles_shortname, + eq=profile, limit=1) if path_profile: dv = DataVarsUpdateProfile(path_profile) if ":" in profile_fullname: @@ -888,48 +986,49 @@ class VariableClUpdateProfileSystem(Variable): 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")) + 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(self.Get('cl_update_profile_rep_name')): + 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) + _("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) + + message) else: raise VariableError(_("Wrong Calculate profile")) def get(self): try: - profile_system = self.Get('cl_profile_system') - profile = self.Select('cl_profile_shortname', - where='cl_profile_path', + profile_system = self.Get(self.profile) + profile = self.Select(self.profiles_shortname, + where=self.profiles_path, eq=profile_system, limit=1) if profile: return profile except VariableError: pass - shortname = self.Get('cl_profile_shortname') + shortname = self.Get(self.profiles_shortname) if len(shortname) == 1: return shortname[0] return "" def choice(self): - url = self.Get('cl_update_profile_rep') + url = self.Get(self.url) if not url: return [] - arch = self.Get('os_arch_machine_gentoo') - profiles = zip(*self.Select(['cl_profile_shortname', - 'cl_profile_fullname'], - where='cl_profile_arch', eq=arch)) + arch = self.Get(self.gentoo_arch) + profiles = zip(*self.Select([self.profiles_shortname, + self.profiles_fullname], + where=self.profiles_arch, eq=arch)) if profiles: short_name, full_name = profiles return zip(short_name, full_name) @@ -944,23 +1043,31 @@ class DataVarsUpdateProfile(SimpleDataVars): 'cl_update_rep_path', 'cl_update_rep_rev', 'cl_update_branch_name'] - def __init__(self, profile): + def __init__(self, profile, chroot_path='/'): SimpleDataVars.__init__(self, - VariableOsLinuxName(), - VariableOsLinuxShortname(), - VariableOsLinuxSubname(), - VariableOsLinuxVer(), - VariableClTemplateLocation(), + lib_linux.VariableOsLinuxName(), + lib_linux.VariableOsLinuxShortname(), + lib_linux.VariableOsLinuxSubname(), + lib_linux.VariableOsLinuxVer(), + lib_linux.VariableClProfileSystem(), + env.VariableClRepositoryData(), + env.VariableClRepositoryName(), + env.VariableClRepositoryLocation(), + env.VariableClChrootPath(), + env.VariableClTemplateLocation(), + env.VariableClTemplatePath(), + env.VariableClEmergeConfig(systemRoot=chroot_path), VariableClUpdateRepData(section="update"), VariableClUpdateRepPath(section="update"), VariableClUpdateRepRev(section="update"), VariableClUpdateBranchName(section="update"), - VariableClProfileSystem(section="update"), + VariableClUpdateLaymanConfig(section="update"), VariableClUpdateLaymanStorage(section="update"), VariableClUpdateRepName(section="update"), VariableClUpdateRep(section="update"), VariableClUpdateRepUrl(section="update")) self.cache['cl_profile_system'] = profile + self.cache['cl_chroot_path'] = chroot_path self.flIniFileFrom(profile) def __repr__(self): @@ -1023,6 +1130,7 @@ class VariableClUpdateAutocheckScheduleSet(Variable): self.label = _("Consider the autocheck schedule") self.help = _("consider the autocheck schedule") + class VariableClUpdateEmergelistSet(Variable): """ Вывести список пакетов в формате emerge @@ -1035,6 +1143,7 @@ class VariableClUpdateEmergelistSet(Variable): self.label = _("Emerge-like packages list") self.help = _("display the packages list in emerge format") + class VariableClUpdateKernelVersion(ReadonlyVariable): """ Текущая версия ядра @@ -1042,6 +1151,7 @@ class VariableClUpdateKernelVersion(ReadonlyVariable): def get(self): return process('/bin/uname','-r').read().strip() + class VariableClUpdateKernelSrcPath(ReadonlyVariable): """ Каталог содержащий исходный код текущего ядра @@ -1106,12 +1216,14 @@ class VariableClUpdateCleanpkgSet(Variable): self.label = _("Clean obsolete programs archives") self.help = _("clean obsolete programs archives") + class VariableClUpdateOutdatedKernelPath(Variable): """ Файл-флаг наличия устаревшего, неудаленного ядра """ value = "/var/lib/calculate/calculate-update/outdated_kernel" + class VariableClUpdateSkipRbSet(Variable): """ Пропусить revdep-rebuild @@ -1125,6 +1237,7 @@ class VariableClUpdateSkipRbSet(Variable): self.label = _("Skip reverse dependencies check") self.help = _("skip reverse dependencies check") + class VariableClUpdateOutdatedKernelSet(ReadonlyVariable): """ Есть наличие устаревшего ядра diff --git a/pym/update/wsdl_update.py b/pym/update/wsdl_update.py index 932baf7..f131045 100644 --- a/pym/update/wsdl_update.py +++ b/pym/update/wsdl_update.py @@ -113,9 +113,9 @@ class Wsdl(WsdlBase): 'groups': [ lambda group: group(_("Repository"), brief=('cl_update_profile_repo_name',), - hide=('cl_update_profile_rep', + hide=('cl_update_profile_url', 'cl_update_profile_sync_set'), - normal=('cl_update_profile_rep',), + normal=('cl_update_profile_url',), expert=('cl_update_profile_sync_set', 'cl_update_profile_branch')), lambda group: group(_("Profile"),