Множественные изменения для использования с calculate-assemble

develop
Mike Khiretskiy 9 years ago
parent f61f898d3c
commit abb1c37275

@ -39,6 +39,7 @@ from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate, _
setLocalTranslate('cl_update3', sys.modules[__name__]) setLocalTranslate('cl_update3', sys.modules[__name__])
__ = getLazyLocalTranslate(_) __ = getLazyLocalTranslate(_)
linux_term_env = {'TERM':'linux'}
class EmergeError(Exception): class EmergeError(Exception):
""" """
@ -50,8 +51,6 @@ class EmergeNeedRootError(EmergeError):
pass pass
env_terminal_linux = {'TERM':'linux'}
class CommandExecutor(object): class CommandExecutor(object):
""" """
Запуск программы для объекта Emerge Запуск программы для объекта Emerge
@ -61,8 +60,8 @@ class CommandExecutor(object):
def __init__(self, cmd, params, env=None, cwd=None, logfile=None): def __init__(self, cmd, params, env=None, cwd=None, logfile=None):
self.cwd = cwd self.cwd = cwd
self.env = env or dict(os.environ) self.env = env or dict(os.environ)
self.env.update({'EINFO_QUIET':'NO'}) self.env.update({'EINFO_QUIET': 'NO'})
self.env.update(env_terminal_linux) self.env.update(linux_term_env)
self.cmd = cmd self.cmd = cmd
self.params = params self.params = params
self.child = None self.child = None
@ -96,6 +95,27 @@ class CommandExecutor(object):
self.child.send(s) 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): class EmergeCommand(CommandExecutor):
""" """
Запуск emerge для последующего анализирования Запуск emerge для последующего анализирования
@ -105,7 +125,7 @@ class EmergeCommand(CommandExecutor):
cmd = getProgPath("/usr/bin/emerge") cmd = getProgPath("/usr/bin/emerge")
def __init__(self, packages, extra_params=None, env=None, cwd=None, 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 [] extra_params = extra_params or []
self.child = None self.child = None
self.packages = packages self.packages = packages
@ -118,9 +138,11 @@ class EmergeCommand(CommandExecutor):
'EMERGE_DEFAULT_OPTS': re.sub(r'(?:^|\s)(--columns)(?=\s|$)','', 'EMERGE_DEFAULT_OPTS': re.sub(r'(?:^|\s)(--columns)(?=\s|$)','',
emerge_default_opts) emerge_default_opts)
} }
if use:
default_env["USE"] = use
default_env.update(os.environ) default_env.update(os.environ)
self.env = env or default_env self.env = env or default_env
self.env.update(env_terminal_linux) self.env.update(linux_term_env)
self.cwd = cwd self.cwd = cwd
if logfile: if logfile:
self.logfile = logfile self.logfile = logfile
@ -133,9 +155,37 @@ class EmergeCommand(CommandExecutor):
return self.child 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): class EmergeInformationBlock(object):
_color_block = "(?:\033\[[^m]+?m)?" _color_block = "(?:\033\[[^m]+?m)?"
_new_line = "\r*\n" _new_line = "(?:\r*\n)"
token = None token = None
end_token = ["\n"] end_token = ["\n"]
re_block = None re_block = None
@ -445,6 +495,7 @@ class FetchingTarball(NotifierInformationBlock):
def notify(self, observer, groups): def notify(self, observer, groups):
observer(groups[0]) observer(groups[0])
class InstallingPackage(NotifierInformationBlock): class InstallingPackage(NotifierInformationBlock):
""" """
Запуск устанавливаемого пакета Запуск устанавливаемого пакета

@ -82,9 +82,8 @@ class RepositoryStorageSet(RepositoryStorage):
""" """
Набор хранилищ репозиториев Набор хранилищ репозиториев
""" """
def __init__(self): def __init__(self, *storages):
self.storages = [LocalStorage('/var/lib/layman'), self.storages = storages
CacheStorage('/var/calculate/tmp/update')]
def get_profiles(self, url, branch=DEFAULT_BRANCH): def get_profiles(self, url, branch=DEFAULT_BRANCH):
""" """

@ -13,6 +13,7 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
from functools import wraps, partial
import random import random
import sys import sys
@ -32,8 +33,9 @@ from calculate.update.datavars import DataVarsUpdate
from calculate.update.update_info import UpdateInfo from calculate.update.update_info import UpdateInfo
from calculate.lib.cl_log import log from calculate.lib.cl_log import log
import re import re
from itertools import chain
from collections import MutableSet from collections import MutableSet
from mock import self
from update_tasks import EmergeMark
from calculate.lib.utils.portage import (Git, Layman, EmergeLog, GitError, from calculate.lib.utils.portage import (Git, Layman, EmergeLog, GitError,
EmergeLogNamedTask, PackageList, EmergeLogNamedTask, PackageList,
@ -48,7 +50,8 @@ from calculate.lib.utils.files import (getProgPath, STDOUT, removeDir,
readFile, listDirectory) readFile, listDirectory)
import emerge_parser import emerge_parser
import logging 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, from calculate.lib.cl_lang import (setLocalTranslate, getLazyLocalTranslate,
RegexpLocalization, _) RegexpLocalization, _)
@ -63,18 +66,19 @@ class OverlayOwnCache(MutableSet):
""" """
Сет оверлеев с интегрированным кэшем Сет оверлеев с интегрированным кэшем
""" """
def __init__(self, initvalue=()): def __init__(self, dv=None):
pass self.dv = dv
def __get_overlays(self): 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()] return [x.strip() for x in own_cache_value.split(',') if x.strip()]
def __write_overlays(self, overlays): def __write_overlays(self, overlays):
if not overlays: if not overlays:
SystemIni().delVar('update', 'own_cache') SystemIni(self.dv).delVar('update', 'own_cache')
else: else:
SystemIni().setVar('update', {'own_cache': ",".join(overlays)}) SystemIni(self.dv).setVar('update',
{'own_cache': ",".join(overlays)})
def __contains__(self, item): def __contains__(self, item):
return item in self.__get_overlays() return item in self.__get_overlays()
@ -101,6 +105,21 @@ class OverlayOwnCache(MutableSet):
self.__write_overlays(overlays) 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): class Update(object):
"""Основной объект для выполнения действий связанных с обновлением системы """Основной объект для выполнения действий связанных с обновлением системы
@ -119,6 +138,9 @@ class Update(object):
self.clVars.Get('update.cl_update_rep_path'))) self.clVars.Get('update.cl_update_rep_path')))
self.update_map = {} self.update_map = {}
def get_prog_path(self, progname):
return getProgPath(progname)
def _syncRepository(self, name, url, rpath, revision, branch, def _syncRepository(self, name, url, rpath, revision, branch,
cb_progress=None): cb_progress=None):
""" """
@ -131,36 +153,58 @@ class Update(object):
self.stash_cache(rpath, name) self.stash_cache(rpath, name)
if not git.checkExistsRep(rpath): if not git.checkExistsRep(rpath):
if revision == "last": if revision == "last":
git.cloneRepository(url, rpath, branch, git.cloneTagRepository(url, rpath, branch,
cb_progress=cb_progress) cb_progress=cb_progress)
else: else:
git.cloneRevRepository(url, rpath, branch, revision, git.cloneTagRepository(url, rpath, revision,
cb_progress=cb_progress) cb_progress=cb_progress)
info_outdate = True info_outdate = True
else: else:
# если нужно обновиться до конкретной ревизии
if revision != "last": if revision != "last":
if revision == git.getCurrentCommit(rpath): try:
if git.getBranch(rpath) == branch: need_update = False
return False tag_cr = git.getCommit(rpath, revision)
# получить изменения из удаленного репозитория cr = git.getCurrentCommit(rpath)
git.fetchRepository(rpath, cb_progress=cb_progress) if tag_cr != cr:
# если текущая ветка не соответствует нужной need_update = True
repInfo = git.getStatusInfo(rpath) except GitError:
if repInfo['branch'] != branch: need_update = True
# меняем ветку if need_update:
info_outdate = True git.updateTagRepository(url, rpath, revision,
git.checkoutBranch(rpath, branch) cb_progress=cb_progress)
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 info_outdate = True
else: else:
git.resetRepository(rpath, to_rev=revision) try:
info_outdate = True 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: if info_outdate:
dv.Set('cl_update_outdate_set', 'on', force=True) dv.Set('cl_update_outdate_set', 'on', force=True)
finally: finally:
@ -247,6 +291,7 @@ class Update(object):
self.endTask() self.endTask()
return True return True
@variable_module("update")
def syncRepositories(self, repname, clean_on_error=True): def syncRepositories(self, repname, clean_on_error=True):
""" """
Синхронизировать репозитории Синхронизировать репозитории
@ -259,6 +304,11 @@ class Update(object):
if not url or not rpath: if not url or not rpath:
raise UpdateError(_("Configuration variables for repositories " raise UpdateError(_("Configuration variables for repositories "
"are not setup")) "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() self.addProgress()
if clean_on_error: if clean_on_error:
try: try:
@ -266,7 +316,7 @@ class Update(object):
dv.Get('cl_update_layman_make'), dv.Get('cl_update_layman_make'),
dv.Get('cl_update_layman_conf')) dv.Get('cl_update_layman_conf'))
if repname != "portage": if repname != "portage":
layman.add(repname, url, rpath) layman.add(repname, url, rpath_orig)
if not self._syncRepository(repname, url, rpath, revision, branch, if not self._syncRepository(repname, url, rpath, revision, branch,
cb_progress=self.setProgress): cb_progress=self.setProgress):
return "skip" return "skip"
@ -279,8 +329,8 @@ class Update(object):
self.startTask( self.startTask(
_("Re-fetching the {name} repository").format(name=repname)) _("Re-fetching the {name} repository").format(name=repname))
self.addProgress() self.addProgress()
rpath_new = "%s_new" % rpath
try: try:
rpath_new = "%s_new" % rpath
self._syncRepository(repname, url, rpath_new, revision, self._syncRepository(repname, url, rpath_new, revision,
branch, cb_progress=self.setProgress) branch, cb_progress=self.setProgress)
removeDir(rpath) removeDir(rpath)
@ -300,7 +350,9 @@ class Update(object):
dv.Get('cl_update_layman_make'), dv.Get('cl_update_layman_make'),
dv.Get('cl_update_layman_conf')) dv.Get('cl_update_layman_conf'))
if repname != "portage": 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 return True
metadata_cache_names = ("metadata/md5-cache", "metadata/cache") metadata_cache_names = ("metadata/md5-cache", "metadata/cache")
@ -311,7 +363,7 @@ class Update(object):
""" """
if name in ("portage",): if name in ("portage",):
return return
if not name in OverlayOwnCache(): if not name in OverlayOwnCache(self.clVars):
for cachename in self.metadata_cache_names: for cachename in self.metadata_cache_names:
cachedir = path.join(rpath, cachename) cachedir = path.join(rpath, cachename)
if path.exists(cachedir): if path.exists(cachedir):
@ -332,7 +384,7 @@ class Update(object):
if name in ("portage",): if name in ("portage",):
return return
cachenames = self.metadata_cache_names 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): if any(path.exists(path.join(rpath, x)) for x in cachenames):
for cachename in cachenames: for cachename in cachenames:
cachedir_s = path.join(path.dirname(rpath), cachedir_s = path.join(path.dirname(rpath),
@ -342,7 +394,7 @@ class Update(object):
removeDir(cachedir_s) removeDir(cachedir_s)
except BaseException as e: except BaseException as e:
pass pass
OverlayOwnCache().add(name) OverlayOwnCache(self.clVars).add(name)
else: else:
for cachename in cachenames: for cachename in cachenames:
cachedir = path.join(rpath, cachename) cachedir = path.join(rpath, cachename)
@ -355,14 +407,14 @@ class Update(object):
pass pass
else: else:
if all(not path.exists(path.join(rpath, x)) for x in cachenames): 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): def syncLaymanRepository(self, repname):
""" """
Обновить репозиторий через layman Обновить репозиторий через layman
""" """
layman = getProgPath('/usr/bin/layman') layman = self.get_prog_path('/usr/bin/layman')
if not layman: if not layman:
raise UpdateError(_("The Layman tool is not found")) raise UpdateError(_("The Layman tool is not found"))
rpath = self.clVars.Select('cl_update_other_rep_path', rpath = self.clVars.Select('cl_update_other_rep_path',
@ -386,11 +438,15 @@ class Update(object):
self.unstash_cache(rpath, laymanname) self.unstash_cache(rpath, laymanname)
return True 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): def regenCache(self, repname):
""" """
Обновить кэш метаданных репозитория Обновить кэш метаданных репозитория
""" """
egenCache = getProgPath('/usr/bin/egencache') egenCache = self.get_prog_path('/usr/bin/egencache')
if not egenCache: if not egenCache:
raise UpdateError(_("The Portage tool is not found")) raise UpdateError(_("The Portage tool is not found"))
if repname in self.clVars.Get('cl_update_rep_name'): 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} " raise UpdateError(_("Failed to update the cache of the {rname} "
"repository").format(rname=repname)) "repository").format(rname=repname))
cpu_num = self.clVars.Get('hr_cpu_num') cpu_num = self.clVars.Get('hr_cpu_num')
if repname in OverlayOwnCache(): if repname in OverlayOwnCache(self.clVars):
self.printWARNING( self.printWARNING(
_("Repository %s has its own cache") % repname.capitalize()) _("Repository %s has its own cache") % repname.capitalize())
else: else:
self.startTask(_("Updating the %s repository cache") % self.startTask(_("Updating the %s repository cache") %
repname.capitalize()) repname.capitalize())
p = process(egenCache, "--repo=%s" % repname, "--update", p = self._regenCache_process(egenCache, repname, cpu_num)
"--jobs=%s" % cpu_num, stderr=STDOUT)
if p.failed(): if p.failed():
raise UpdateError(_("Failed to update the cache of the {rname} " raise UpdateError(_("Failed to update the cache of the {rname} "
"repository").format(rname=repname), "repository").format(rname=repname),
@ -425,7 +480,7 @@ class Update(object):
""" """
Выполнить egencache и emerge --metadata Выполнить egencache и emerge --metadata
""" """
emerge = getProgPath("/usr/bin/emerge") emerge = self.get_prog_path("/usr/bin/emerge")
if not emerge: if not emerge:
raise UpdateError(_("The Emerge tool is not found")) raise UpdateError(_("The Emerge tool is not found"))
self.addProgress() self.addProgress()
@ -440,7 +495,10 @@ class Update(object):
raise UpdateError(_("Failed to update metadata"), addon=data) raise UpdateError(_("Failed to update metadata"), addon=data)
return True 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 для репозиторием Выполенине eix-update для репозиторием
@ -448,12 +506,12 @@ class Update(object):
обновлялись, если cl_update_eixsync_force==auto, либо обновлялись, если cl_update_eixsync_force==auto, либо
все, если cl_update_eixupdate_force==force все, если cl_update_eixupdate_force==force
""" """
eixupdate = getProgPath("/usr/bin/eix-update") eixupdate = self.get_prog_path("/usr/bin/eix-update")
if not eixupdate: if not eixupdate:
raise UpdateError(_("The Eix tool is not found")) raise UpdateError(_("The Eix tool is not found"))
self.addProgress() self.addProgress()
countRep = len(self.clVars.Get('main.cl_portdir_overlay'))+1 countRep = len(repositroies)
p = PercentProgress(eixupdate, "-F", part=countRep or 1, atty=True) p = self._eixUpdateCommand(eixupdate, countRep)
for perc in p.progress(): for perc in p.progress():
self.setProgress(perc) self.setProgress(perc)
if p.failed(): if p.failed():
@ -552,7 +610,7 @@ class Update(object):
""" """
Запуск команды, которая подразумевает выполнение emerge Запуск команды, которая подразумевает выполнение emerge
""" """
cmd_path = getProgPath(cmd) cmd_path = self.get_prog_path(cmd)
if not cmd_path: if not cmd_path:
raise UpdateError(_("Failed to find the %s command") % cmd) raise UpdateError(_("Failed to find the %s command") % cmd)
with EmergeParser( with EmergeParser(
@ -564,7 +622,7 @@ class Update(object):
""" """
Запуск revdep-rebulid Запуск revdep-rebulid
""" """
cmd_path = getProgPath(cmd) cmd_path = self.get_prog_path(cmd)
if not cmd_path: if not cmd_path:
raise UpdateError(_("Failed to find the %s command") % cmd) raise UpdateError(_("Failed to find the %s command") % cmd)
with EmergeParser( 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( self.printPre(self._emerge_translate(
emerge.uninstall_packages.verbose_result)) emerge.uninstall_packages.verbose_result))
else: else:
@ -677,9 +735,7 @@ class Update(object):
Получить список обновляемых пакетов @world из кэша Получить список обновляемых пакетов @world из кэша
""" """
if "@world" in packages: if "@world" in packages:
from calculate.update.utils.cl_update import ClUpdateAction elog = EmergeLog(EmergeLogNamedTask(EmergeMark.Premerge))
elog = EmergeLog(
EmergeLogNamedTask(ClUpdateAction.log_names['premerge']))
if check and (elog.list or elog.remove_list): if check and (elog.list or elog.remove_list):
self.emerge_cache.drop_cache( self.emerge_cache.drop_cache(
"Some packages was installed or removed") "Some packages was installed or removed")
@ -697,9 +753,7 @@ class Update(object):
premerge premerge
""" """
self.emerge_cache.set_cache(pkg_list) self.emerge_cache.set_cache(pkg_list)
from calculate.update.utils.cl_update import ClUpdateAction elog = EmergeLog(EmergeLogNamedTask(EmergeMark.Premerge))
elog = EmergeLog(
EmergeLogNamedTask(ClUpdateAction.log_names['premerge']))
elog.mark_end_task(), elog.mark_end_task(),
def mark_schedule(self): def mark_schedule(self):
@ -812,10 +866,15 @@ class Update(object):
error = "<br/>".join(str(error).split('<br/>')[-lines_num:]) error = "<br/>".join(str(error).split('<br/>')[-lines_num:])
self.printPre(self._emerge_translate(error)) 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') deo = self.clVars.Get('cl_emerge_default_opts')
if not packages: if not packages:
packages = [param] packages = [param]
@ -825,8 +884,9 @@ class Update(object):
if not packages: if not packages:
return True return True
extra_params = [param] extra_params = [param]
with EmergeParser(EmergeCommand(list(packages), emerge_default_opts=deo, with EmergeParser(command_class(list(packages), emerge_default_opts=deo,
extra_params=extra_params)) as emerge: extra_params=extra_params,
use=use)) as emerge:
try: try:
emerge.question.action = lambda x: False emerge.question.action = lambda x: False
emerge.run() emerge.run()
@ -911,22 +971,23 @@ class Update(object):
return decor return decor
def migrateCacheRepository(self, url, branch): def migrateCacheRepository(self, url, branch, storage):
rep_set = self.clVars.Get('cl_update_profile_storage') """
rep = rep_set.get_repository(url, branch) Перенести репозиторий из кэша в локальный
"""
rep = storage.get_repository(url, branch)
if rep: if rep:
rep.storage = rep_set.storages[0] rep.storage = storage.storages[0]
self.clVars.Invalidate('cl_update_profile_storage') self.clVars.Invalidate('cl_update_profile_storage')
return True return True
def reconfigureProfileVars(self): def reconfigureProfileVars(self, profile_dv, chroot):
""" """
Синхронизировать репозитории Синхронизировать репозитории
""" """
dv = self.clVars dv = self.clVars
profile_dv = dv.Get('cl_update_profile_datavars')
try: try:
if not profile_dv: if not profile_dv:
raise UpdateError( raise UpdateError(
@ -937,17 +998,22 @@ class Update(object):
'cl_update_rep_name', 'cl_update_rep_name',
'cl_update_branch_name', 'cl_update_branch_name',
'cl_profile_system', 'cl_profile_system',
'cl_update_layman_storage',
'cl_update_rep'): '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) 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")) raise UpdateError(_("Wrong profile"))
return True return True
def setProfile(self): def setProfile(self, profile_shortname):
profile = self.clVars.Select('cl_profile_path', profile = self.clVars.Select('cl_update_profile_path',
where='cl_profile_shortname', where='cl_update_profile_shortname',
eq=self.clVars.Get('cl_update_profile_system'), limit=1) eq=profile_shortname, limit=1)
if not profile: if not profile:
raise UpdateError(_("Failed to determine profile %s") % raise UpdateError(_("Failed to determine profile %s") %
self.clVars.Get('cl_update_profile_system')) self.clVars.Get('cl_update_profile_system'))

@ -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"

@ -37,7 +37,7 @@ class ClSetupUpdateAction(Action):
interruptMessage = __("Configuration manually interrupted") interruptMessage = __("Configuration manually interrupted")
# список задач для дейсвия # список задач для действия
tasks = [ tasks = [
{'name': 'set_variables', {'name': 'set_variables',
'method': 'Update.setAutocheckParams(cl_update_autocheck_set,' 'method': 'Update.setAutocheckParams(cl_update_autocheck_set,'

@ -23,6 +23,7 @@ from calculate.update.update import UpdateError
from calculate.update.emerge_parser import EmergeError from calculate.update.emerge_parser import EmergeError
from calculate.lib.utils.portage import GitError, Eix, EmergeLog, \ from calculate.lib.utils.portage import GitError, Eix, EmergeLog, \
EmergeLogNamedTask, PackageList EmergeLogNamedTask, PackageList
from ..update_tasks import EmergeMark
setLocalTranslate('cl_update3', sys.modules[__name__]) setLocalTranslate('cl_update3', sys.modules[__name__])
__ = getLazyLocalTranslate(_) __ = getLazyLocalTranslate(_)
@ -53,6 +54,7 @@ class ClUpdateAction(Action):
return func return func
def need_upgrade(pkg): def need_upgrade(pkg):
# TODO: возможно функция не работает
def func(): def func():
return bool(Eix(pkg, Eix.Option.Upgrade).get_packages()) return bool(Eix(pkg, Eix.Option.Upgrade).get_packages())
return func return func
@ -60,16 +62,6 @@ class ClUpdateAction(Action):
def pkg_color(text): def pkg_color(text):
return 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 = [ emerge_tasks = [
{'name': 'premerge_group', {'name': 'premerge_group',
'group': __("Checking for updates"), 'group': __("Checking for updates"),
@ -93,7 +85,7 @@ class ClUpdateAction(Action):
'tasks': [ 'tasks': [
{'name': 'update:update_world', {'name': 'update:update_world',
'message': __("Calculating dependencies"), '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'), 'to a Python upgrade'),
'method': 'Update.emergelike("python-updater")', 'method': 'Update.emergelike("python-updater")',
'condition': was_installed('dev-lang/python$', 'condition': was_installed('dev-lang/python$',
log_names['python_updater']), EmergeMark.PythonUpdater),
'decoration': 'Update.update_task("%s")' % log_names[ 'decoration': 'Update.update_task("%s")' %
'python_updater'] EmergeMark.PythonUpdater
}, },
] ]
}, },
@ -119,9 +111,8 @@ class ClUpdateAction(Action):
'broken due to a perl upgrade'), 'broken due to a perl upgrade'),
'method': 'Update.emergelike("perl-cleaner", "all")', 'method': 'Update.emergelike("perl-cleaner", "all")',
'condition': was_installed('dev-lang/perl$', 'condition': was_installed('dev-lang/perl$',
log_names['perl_cleaner']), EmergeMark.PerlCleaner),
'decoration': 'Update.update_task("%s")' % log_names[ 'decoration': 'Update.update_task("%s")' % EmergeMark.PerlCleaner
'perl_cleaner']
}, },
] ]
}, },
@ -131,8 +122,8 @@ class ClUpdateAction(Action):
{'name': 'update_other:update_depclean', {'name': 'update_other:update_depclean',
'message': __("Calculating dependencies"), 'message': __("Calculating dependencies"),
'method': 'Update.depclean()', 'method': 'Update.depclean()',
'condition': need_depclean('.*', log_names['depclean']), 'condition': need_depclean('.*', EmergeMark.Depclean),
'decoration': 'Update.update_task("%s")' % log_names['depclean'] 'decoration': 'Update.update_task("%s")' % EmergeMark.Depclean
}, },
] ]
}, },
@ -141,34 +132,35 @@ class ClUpdateAction(Action):
'tasks': [ 'tasks': [
{'name': 'update_other:module_rebuild', {'name': 'update_other:module_rebuild',
'message': __('Updating Kernel modules'), 'message': __('Updating Kernel modules'),
'method': 'Update.emerge("@module-rebuild")', 'method': 'Update.emerge("","@module-rebuild")',
'condition': was_installed('sys-kernel/.*source', 'condition': was_installed('sys-kernel/.*source',
log_names['kernel_modules']), EmergeMark.KernelModules),
'decoration': 'Update.update_task("%s")' % log_names[ 'decoration': 'Update.update_task("%s")' %
'kernel_modules'] EmergeMark.KernelModules
}, },
{'name': 'update_other:x11_module_rebuild', {'name': 'update_other:x11_module_rebuild',
'message': __('Updating X.Org server modules'), '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', 'condition': was_installed('x11-base/xorg-server',
log_names['xorg_modules']), EmergeMark.XorgModules),
'decoration': 'Update.update_task("%s")' % log_names[ 'decoration': 'Update.update_task("%s")' %
'xorg_modules'] EmergeMark.XorgModules
}, },
{'name': 'update_other:preserved_rebuild', {'name': 'update_other:preserved_rebuild',
'message': __('Updating preserved libraries'), 'message': __('Updating preserved libraries'),
'method': 'Update.emerge("@preserved-rebuild")', 'method': 'Update.emerge("","@preserved-rebuild")',
'condition': was_installed('.*', log_names['preserved_libs']), 'condition': was_installed('.*', EmergeMark.PreservedLibs),
'decoration': 'Update.update_task("%s")' % log_names[ 'decoration': 'Update.update_task("%s")' %
'preserved_libs'] EmergeMark.PreservedLibs
}, },
{'name': 'update_other:revdev_rebuild', {'name': 'update_other:revdev_rebuild',
'message': __('Checking reverse dependencies'), 'message': __('Checking reverse dependencies'),
'method': 'Update.revdep_rebuild("revdep-rebuild")', 'method': 'Update.revdep_rebuild("revdep-rebuild")',
'condition': lambda Get:(Get('cl_update_skip_rb_set') == 'off' 'condition': lambda Get:(Get('cl_update_skip_rb_set') == 'off'
and ClUpdateAction.was_installed('.*', and ClUpdateAction.was_installed('.*',
ClUpdateAction.log_names['revdep'])()), EmergeMark.RevdepRebuild)()),
'decoration': 'Update.update_task("%s")' % log_names['revdep'] 'decoration': 'Update.update_task("%s")' %
EmergeMark.RevdepRebuild
}, },
{'name': 'update_other:dispatch_conf_end', {'name': 'update_other:dispatch_conf_end',
'message': __("Updating configuration files"), 'message': __("Updating configuration files"),
@ -183,7 +175,7 @@ class ClUpdateAction(Action):
} }
] ]
# список задач для дейсвия # список задач для действия
tasks = [ tasks = [
{'name': 'check_schedule', {'name': 'check_schedule',
'method': 'Update.checkSchedule(cl_update_autocheck_interval,' 'method': 'Update.checkSchedule(cl_update_autocheck_interval,'
@ -233,7 +225,7 @@ class ClUpdateAction(Action):
}, },
{'name': 'eix_update', {'name': 'eix_update',
'message': __("Updating the eix cache"), 'message': __("Updating the eix cache"),
'method': 'Update.eixUpdate()', 'method': 'Update.eixUpdate(cl_repository_name)',
'condition': ( 'condition': (
lambda Get: (Get('cl_update_outdate_set') == 'on' and lambda Get: (Get('cl_update_outdate_set') == 'on' and
Get('cl_update_eixupdate_force') != 'skip' or Get('cl_update_eixupdate_force') != 'skip' or

@ -37,19 +37,25 @@ class ClUpdateProfileAction(Action):
interruptMessage = __("Profile update manually interrupted") interruptMessage = __("Profile update manually interrupted")
# список задач для дейсвия # список задач для действия
tasks = [ tasks = [
{'name': 'migrate_repository', {'name': 'migrate_repository',
'method': 'Update.migrateCacheRepository(' '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"), 'message': __("Repository transfer"),
'condition': lambda Get: not ( 'condition': lambda Get: not (
Get('cl_update_profile_storage').is_local( Get('cl_update_profile_storage').is_local(
Get('cl_update_profile_rep'), Get('cl_update_profile_url'),
Get('cl_update_profile_branch'))) Get('cl_update_profile_branch')))
}, },
{'name': 'reconfigure_vars1',
'method': 'Update.invalidateVariables("cl_update_profile_storage")',
'depend': Tasks.has('migrate_repository')
},
{'name': 'reconfigure_vars', {'name': 'reconfigure_vars',
'method': 'Update.reconfigureProfileVars()' 'method': 'Update.reconfigureProfileVars(cl_update_profile_datavars,'
'cl_chroot_path)'
}, },
{'name': 'reps_synchronization', {'name': 'reps_synchronization',
'group': __("Repositories synchronization"), 'group': __("Repositories synchronization"),
@ -80,7 +86,9 @@ class ClUpdateProfileAction(Action):
}, },
{'name': 'eix_update', {'name': 'eix_update',
'message': __("Updating the eix cache"), 'message': __("Updating the eix cache"),
'method': 'Update.eixUpdate()', # TODO: необходимо добавить опцию --changes-pkg emerge world
# TODO: возможно стоит использовать переменные от нового профиля
'method': 'Update.eixUpdate(cl_repository_name)',
'condition': ( 'condition': (
lambda Get: (Get('cl_update_outdate_set') == 'on' and lambda Get: (Get('cl_update_outdate_set') == 'on' and
Get('cl_update_eixupdate_force') != 'skip' or Get('cl_update_eixupdate_force') != 'skip' or
@ -101,7 +109,7 @@ class ClUpdateProfileAction(Action):
'tasks': [ 'tasks': [
{'name': 'set_profile', {'name': 'set_profile',
'message': __("Switching to profile {cl_update_profile_system}"), 'message': __("Switching to profile {cl_update_profile_system}"),
'method': 'Update.setProfile()' 'method': 'Update.setProfile(cl_update_profile_system)'
}, },
{'name': 'revision', {'name': 'revision',
'message': __("Fixing the settings"), 'message': __("Fixing the settings"),

@ -23,18 +23,21 @@ from calculate.lib.datavars import (Variable, VariableError,
SimpleDataVars, DataVarsError) SimpleDataVars, DataVarsError)
from calculate.lib.utils.portage import searchProfile from calculate.lib.utils.portage import searchProfile
from calculate.lib.utils.files import readLinesFile, readFile, makeDirectory, \ 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.cl_lang import setLocalTranslate
from calculate.lib.utils.text import simplify_profiles from calculate.lib.utils.text import simplify_profiles
from calculate.lib.utils.portage import Git, GitError, Layman 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, \ from calculate.lib.variables import linux as lib_linux
VariableOsLinuxSubname, VariableOsLinuxVer, VariableOsLinuxShortname from calculate.lib.variables import env
from calculate.lib.variables.env import VariableClTemplateLocation
from calculate.update.update_info import UpdateInfo from calculate.update.update_info import UpdateInfo
from functools import partial
_ = lambda x:x
setLocalTranslate('cl_update3', sys.modules[__name__]) setLocalTranslate('cl_update3', sys.modules[__name__])
@ -107,7 +110,7 @@ class VariableClUpdateRep(Variable):
value = "rev" value = "rev"
def choice(self): def choice(self):
return ["last","rev"] return ["last", "rev"]
class VariableClUpdateRepData(ReadonlyTableVariable): class VariableClUpdateRepData(ReadonlyTableVariable):
""" """
@ -133,35 +136,46 @@ class VariableClUpdateRepUrl(Variable):
type = "list" type = "list"
value = [] 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 Путь к репозиториям layman
""" """
param_name = "storage"
fallback_value = "var/lib/layman"
def get(self): def get(self):
laymanConf = "/etc/layman/layman.cfg" cp = self.Get('cl_update_layman_config')
reStorage = re.compile("^storage\s*:\s*(\S+)") res = cp.get('MAIN', self.param_name, fallback=self.fallback_value)
if path.exists(laymanConf): return pathJoin(self.Get('cl_chroot_path'), res)
for line in readLinesFile(laymanConf):
match = reStorage.search(line)
if match:
return match.group(1)
return "/var/lib/layman"
class VariableClUpdateRepPath(ReadonlyVariable): class VariableClUpdateRepPath(ReadonlyVariable):
""" """
Пути до репозиториев Пути до репозиториев
""" """
type = "list" type = "list"
mapPath = {'portage':'/usr/portage'} mapPath = {'portage':'usr/portage'}
def get(self): def get(self):
repPath = self.Get('cl_update_layman_storage') repPath = self.Get('cl_update_layman_storage')
chroot_path = self.Get('cl_chroot_path')
def generatePaths(names): def generatePaths(names):
for name in names: for name in names:
if name in self.mapPath: if name in self.mapPath:
yield self.mapPath[name] yield path.join(chroot_path, self.mapPath[name])
else: else:
yield path.join(repPath,name) yield path.join(repPath, name)
return list(generatePaths(self.Get('cl_update_rep_name'))) return list(generatePaths(self.Get('cl_update_rep_name')))
class VariableClUpdateRepRev(Variable): class VariableClUpdateRepRev(Variable):
@ -171,6 +185,13 @@ class VariableClUpdateRepRev(Variable):
type = "list" type = "list"
def get(self): def get(self):
"""
Если cl_update_rep=rev, то профиль просматривается на нахождене
в нем rev файла (используется более частный вариант,
как с calculate.env), файл содержит строки ключ=значение, где
ключ - название репозитория, значение - ревизия до которой нужно
обновиться
"""
if self.Get('cl_update_rep') == 'rev': if self.Get('cl_update_rep') == 'rev':
revPaths = searchProfile(self.Get('cl_profile_system'), revPaths = searchProfile(self.Get('cl_profile_system'),
"rev") "rev")
@ -409,25 +430,26 @@ class VariableClUpdateOtherRepPath(FieldValue,ReadonlyVariable):
source_variable = "cl_update_other_rep_data" source_variable = "cl_update_other_rep_data"
column = 1 column = 1
class VariableClUpdateLaymanInstalled(Variable): class VariableClUpdateLaymanInstalled(VariableClUpdateLaymanStorage):
""" """
Путь до файла layman installed.xml Путь до файла layman installed.xml
""" """
# TODO: извлечь из layman.cfg param_name = "installed"
value = "/var/lib/layman/installed.xml" fallback_value = "var/lib/layman/installed.xml"
class VariableClUpdateLaymanMake(Variable): class VariableClUpdateLaymanMake(VariableClUpdateLaymanStorage):
""" """
Путь до файла make.conf изменяемого layman`ом Путь до файла make.conf изменяемого layman`ом
""" """
# TODO: извлечь из layman.cfg param_name = "make_conf"
value = "/var/lib/layman/make.conf" fallback_value = "var/lib/layman/make.conf"
class VariableClUpdateLaymanConf(Variable): class VariableClUpdateLaymanConf(VariableClUpdateLaymanStorage):
""" """
Путь до конфигурационного файла репозиториев для layman Путь до конфигурационного файла репозиториев для layman
""" """
value = "/etc/portage/repos.conf/layman.conf" param_name = "repos_conf"
fallback_value = "etc/portage/repos.conf/layman.conf"
class VariableClUpdatePretendSet(Variable): class VariableClUpdatePretendSet(Variable):
""" """
@ -480,7 +502,9 @@ class VariableClUpdateProfileStorage(ReadonlyVariable):
type = "object" type = "object"
def get(self): def get(self):
return RepositoryStorageSet() return RepositoryStorageSet(
LocalStorage('/var/lib/layman'),
CacheStorage('/var/calculate/tmp/update'))
class VariableClUpdateRepHost(Variable): class VariableClUpdateRepHost(Variable):
type = "list" type = "list"
@ -493,11 +517,14 @@ class VariableClUpdateRepHostUrl(Variable):
class VariableClUpdateProfileDatavars(ReadonlyVariable): class VariableClUpdateProfileDatavars(ReadonlyVariable):
type = "object" type = "object"
profile = "cl_update_profile_system"
profiles_path = "cl_update_profile_path"
profiles_shortname = "cl_update_profile_shortname"
def get(self): def get(self):
profile = self.Get('cl_update_profile_system') profile = self.Get(self.profile)
path_profile = self.Select('cl_profile_path', path_profile = self.Select(self.profiles_path,
where='cl_profile_shortname', where=self.profiles_shortname,
eq=profile, limit=1) eq=profile, limit=1)
if path_profile: if path_profile:
return DataVarsUpdateProfile(path_profile) return DataVarsUpdateProfile(path_profile)
@ -510,8 +537,10 @@ class VariableClUpdateProfileLinuxFullname(ReadonlyVariable):
def init(self): def init(self):
self.label = _("Distribution name") self.label = _("Distribution name")
datavars = "cl_update_profile_datavars"
def get(self): def get(self):
dv = self.Get('cl_update_profile_datavars') dv = self.Get(self.datavars)
if dv: if dv:
try: try:
subname = dv.Get('os_linux_subname') subname = dv.Get('os_linux_subname')
@ -531,21 +560,25 @@ class VariableClUpdateProfileDependData(ReadonlyTableVariable):
source = ['cl_update_profile_depend_name', source = ['cl_update_profile_depend_name',
'cl_update_profile_depend_url'] 'cl_update_profile_depend_url']
datavars = "cl_update_profile_datavars"
def init(self): def init(self):
self.label = _("Used repositories") self.label = _("Used repositories")
@staticmethod @staticmethod
def url_like(url1, url2): def url_like(url1, url2):
match1 = VariableClUpdateProfileRep.re_url.search(url1) match1 = VariableClUpdateProfileUrl.re_url.search(url1)
match2 = VariableClUpdateProfileRep.re_url.search(url2) match2 = VariableClUpdateProfileUrl.re_url.search(url2)
if match1 and match2: if match1 and match2:
return match1.group(2).lower() == match2.group(2).lower() return match1.group(2).lower() == match2.group(2).lower()
return False return False
def get(self, hr=False): def get(self, hr=False):
dv = self.Get('cl_update_profile_datavars') dv = self.Get(self.datavars)
url = self.Get('cl_update_profile_rep').lower() # TODO: неиспользуемая переменная возможно
# испольуется для инициализации
#url = self.Get('cl_update_profile_url').lower()
if dv: if dv:
return reversed(zip(dv.Get('cl_update_rep_name'), return reversed(zip(dv.Get('cl_update_rep_name'),
dv.Get('cl_update_rep_url'))) dv.Get('cl_update_rep_url')))
@ -564,6 +597,8 @@ class VariableClUpdateTemplatesLocate(Variable):
untrusted = True untrusted = True
check_after = ['cl_update_profile_system'] check_after = ['cl_update_profile_system']
profile_datevars = "update.cl_update_profile_datavars"
descriptionMap = {'overlay': _('Overlay templates'), descriptionMap = {'overlay': _('Overlay templates'),
'local': _('Local templates'), 'local': _('Local templates'),
'calculate': _("Calculate overlay templates"), 'calculate': _("Calculate overlay templates"),
@ -578,15 +613,16 @@ class VariableClUpdateTemplatesLocate(Variable):
%",".join(self.get()) %",".join(self.get())
def get(self): def get(self):
dv = self.Get('update.cl_update_profile_datavars') dv = self.Get(self.profile_datevars)
if dv: if dv:
return dv.Get('cl_template_location') + ['clt'] return dv.Get('cl_template_location') + ['clt']
else: else:
return self.Get('cl_templates_locate') return self.Get('cl_templates_locate')
def choice(self): def choice(self):
return map(lambda x:(x,self.descriptionMap.get(x,_("%s overlay templates")%x)), descr = lambda x: self.descriptionMap.get(x,
self.get()) _("%s overlay templates" % x))
return map(lambda x: (x, descr(x)), self.get())
class VariableClUpdateProfileDependName(FieldValue, ReadonlyVariable): class VariableClUpdateProfileDependName(FieldValue, ReadonlyVariable):
type = "list" type = "list"
@ -652,9 +688,9 @@ class VariableClUpdateProfileLinuxName(ReadonlyVariable):
dv.Get('os_linux_name') dv.Get('os_linux_name')
return "" return ""
class VariableClUpdateProfileRep(Variable): class VariableClUpdateProfileUrl(Variable):
""" """
Текущий репозиторий URL текущего репозитория
""" """
untrusted = True untrusted = True
check_after = ["cl_update_profile_branch"] check_after = ["cl_update_profile_branch"]
@ -662,6 +698,17 @@ class VariableClUpdateProfileRep(Variable):
opt = ["--url"] opt = ["--url"]
metavalue = "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): def init(self):
self.label = _("Profile repository") self.label = _("Profile repository")
self.help = _("set the profile repository") self.help = _("set the profile repository")
@ -685,12 +732,12 @@ class VariableClUpdateProfileRep(Variable):
def url_by_shortname(self, value): def url_by_shortname(self, value):
match = self.re_shortname.match(value) match = self.re_shortname.match(value)
if not match.group(1): if not match.group(1):
template = self.Get('cl_update_rep_host_url') template = self.Get('update.cl_update_rep_host_url')
if template: if template:
template = template[0] template = template[0]
else: else:
template = self.Select('cl_update_rep_host_url', template = self.Select('update.cl_update_rep_host_url',
where='cl_update_rep_host', where='update.cl_update_rep_host',
eq=match.group(1), limit=1) eq=match.group(1), limit=1)
if not template: if not template:
raise VariableError(_("Failed to determine the repository host")) raise VariableError(_("Failed to determine the repository host"))
@ -709,32 +756,38 @@ class VariableClUpdateProfileRep(Variable):
if not value: if not value:
raise VariableError("Need to specify profile repository") raise VariableError("Need to specify profile repository")
try: try:
branch = self.Get('cl_update_profile_branch') branch = self.Get(self.branch)
self.Get('cl_update_profile_storage').get_profiles(value, branch) self.Get(self.storage).get_profiles(value, branch)
except GitError as e: except GitError as e:
raise VariableError(str(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) raise VariableError(_("Repository %s has no profiles")%value)
def get(self): def get(self):
try: try:
profile = self.Get('cl_profile_system') profile = self.Get(self.profile)
while profile != '/' and ".git" not in listDirectory(profile): if profile:
profile = path.dirname(profile) while (profile != self.current_root and
if profile == '/': ".git" not in listDirectory(profile)):
return "" profile = path.dirname(profile)
git = Git() if profile == self.current_root:
return git.get_url(profile, "origin") or "" return ""
git = Git()
return git.get_url(profile, "origin") or ""
except: except:
return "git://git.calculate.ru/calculate/distros.git" pass
return self.default_url
class VariableClUpdateProfileRepoName(ReadonlyVariable): class VariableClUpdateProfileRepoName(ReadonlyVariable):
def init(self): def init(self):
self.label = _("Repository name") self.label = _("Repository name")
storage = "cl_update_profile_storage"
url = "cl_update_profile_url"
def get(self): def get(self):
rep_set = self.Get('cl_update_profile_storage') rep_set = self.Get(self.storage)
url = self.Get('cl_update_profile_rep') url = self.Get(self.url)
rep = rep_set.get_repository(url, branch=None) rep = rep_set.get_repository(url, branch=None)
if rep: if rep:
return rep.repo_name return rep.repo_name
@ -751,6 +804,9 @@ class VariableClUpdateProfileBranch(Variable):
opt = ["--branch"] opt = ["--branch"]
metavalue = "BRANCH" metavalue = "BRANCH"
storage = "cl_update_profile_storage"
url = "cl_update_profile_url"
def init(self): def init(self):
self.label = _("Repository branch") self.label = _("Repository branch")
self.help = _("set the repository branch") self.help = _("set the repository branch")
@ -759,14 +815,14 @@ class VariableClUpdateProfileBranch(Variable):
pass pass
## TODO: проверка ветки ## TODO: проверка ветки
#try: #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) # self.Get('cl_update_profile_storage').get_profiles(url, value)
#except GitError as e: #except GitError as e:
# raise VariableError(str(e)) # raise VariableError(str(e))
def get(self): def get(self):
rep_set = self.Get('cl_update_profile_storage') rep_set = self.Get(self.storage)
url = self.Get('cl_update_profile_rep') url = self.Get(self.url)
#print url, rep_set.is_local(url, branch=None) #print url, rep_set.is_local(url, branch=None)
if rep_set.is_local(url, branch=None): if rep_set.is_local(url, branch=None):
rep = rep_set.get_repository(url, branch=None) rep = rep_set.get_repository(url, branch=None)
@ -775,87 +831,121 @@ class VariableClUpdateProfileBranch(Variable):
return DEFAULT_BRANCH return DEFAULT_BRANCH
class VariableClProfileSystem(ReadonlyVariable): class VariableClProfileRepository(ReadonlyVariable):
""" """
Профиль системы (симлинк /etc/make.profile') Репозиторий из которого будут получены профили
""" """
type = "object"
def get(self): def get(self):
try: try:
make_profile = self.Get('cl_make_profile') profile_dn = self.Get('cl_profile_system')
return path.normpath( while profile_dn != '/' and ".git" not in listDirectory(profile_dn):
path.join(path.dirname(make_profile), profile_dn = path.dirname(profile_dn)
os.readlink(make_profile))) if profile_dn == '/':
return ""
ls = LocalStorage(path.dirname(profile_dn))
return ProfileRepository(path.basename(profile_dn), ls)
except: except:
raise VariableError(_("Failed to determine the system profile")) return ""
class VariableClProfileData(ReadonlyTableVariable): 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): def get(self, hr=False):
url = self.Get('cl_update_profile_rep') rep = self.Get(self.repository)
if not url: if not rep:
return [[]]
profiles = rep.get_profiles()
if not profiles:
return [[]] 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: try:
rep_set = self.Get('cl_update_profile_storage') rep_set = self.Get(self.storage)
branch = self.Get('cl_update_profile_branch') branch = self.Get(self.branch)
rep = rep_set.get_repository(url, 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() rep.sync()
profiles = rep_set.get_profiles(url, branch) return rep_set.get_repository(url, branch) or ""
except GitError: except GitError:
return [[]] 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 [[]]
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" type = "list"
source_variable = "cl_profile_data" source_variable = "cl_update_profile_data"
column = 0 column = 0
class VariableClProfileShortname(FieldValue, ReadonlyVariable): class VariableClUpdateProfileShortname(FieldValue, ReadonlyVariable):
""" """
Упрощенное название профиля Упрощенное название профиля
""" """
type = "list" type = "list"
source_variable = "cl_profile_data" source_variable = "cl_update_profile_data"
column = 1 column = 1
class VariableClProfilePath(FieldValue, ReadonlyVariable): class VariableClUpdateProfilePath(FieldValue, ReadonlyVariable):
""" """
Путь от корня до профиля Путь от корня до профиля
""" """
type = "list" type = "list"
source_variable = "cl_profile_data" source_variable = "cl_update_profile_data"
column = 2 column = 2
class VariableClProfileArch(FieldValue, ReadonlyVariable): class VariableClUpdateProfileArch(FieldValue, ReadonlyVariable):
""" """
Архитектура профиля Архитектура профиля
""" """
type = "list" type = "list"
source_variable = "cl_profile_data" source_variable = "cl_update_profile_data"
column = 3 column = 3
class VariableClUpdateProfileSystem(Variable): class VariableClUpdateProfileSystem(Variable):
@ -867,6 +957,14 @@ class VariableClUpdateProfileSystem(Variable):
untrusted = True untrusted = True
metavalue = "PROFILE" 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): def init(self):
self.label = _("System profile") self.label = _("System profile")
self.help = _("set the system profile") self.help = _("set the system profile")
@ -874,12 +972,12 @@ class VariableClUpdateProfileSystem(Variable):
def check(self, profile): def check(self, profile):
if not profile: if not profile:
raise VariableError(_("You must specify the profile")) raise VariableError(_("You must specify the profile"))
path_profile = self.Select('cl_profile_path', path_profile = self.Select(self.profiles_path,
where='cl_profile_shortname', where=self.profiles_shortname,
eq=profile, limit=1)
profile_fullname = self.Select('cl_profile_fullname',
where='cl_profile_shortname',
eq=profile, limit=1) eq=profile, limit=1)
profile_fullname = self.Select(self.profiles_fullname,
where=self.profiles_shortname,
eq=profile, limit=1)
if path_profile: if path_profile:
dv = DataVarsUpdateProfile(path_profile) dv = DataVarsUpdateProfile(path_profile)
if ":" in profile_fullname: if ":" in profile_fullname:
@ -888,48 +986,49 @@ class VariableClUpdateProfileSystem(Variable):
repo_name = "" repo_name = ""
try: try:
if (not dv.Get('cl_update_rep_name') or if (not dv.Get('cl_update_rep_name') or
not dv.Get('cl_update_rep_url')): not dv.Get('cl_update_rep_url')):
raise VariableError(_("Repository variables " raise VariableError(
"were not configured for the profile")) _("Repository variables "
"were not configured for the profile"))
if not dv.Get('os_linux_name'): if not dv.Get('os_linux_name'):
raise VariableError("") 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( raise VariableError(
_("Overlay %s is not specified in cl_update_rep_name")% _("Overlay %s is not specified "
repo_name) "in cl_update_rep_name") % repo_name)
except (DataVarsError,VariableError) as e: except (DataVarsError,VariableError) as e:
if str(e): if str(e):
message = ". " + str(e) message = ". " + str(e)
else: else:
message = "" message = ""
raise VariableError(_("The selected profile is not Calculate") raise VariableError(_("The selected profile is not Calculate")
+message) + message)
else: else:
raise VariableError(_("Wrong Calculate profile")) raise VariableError(_("Wrong Calculate profile"))
def get(self): def get(self):
try: try:
profile_system = self.Get('cl_profile_system') profile_system = self.Get(self.profile)
profile = self.Select('cl_profile_shortname', profile = self.Select(self.profiles_shortname,
where='cl_profile_path', where=self.profiles_path,
eq=profile_system, limit=1) eq=profile_system, limit=1)
if profile: if profile:
return profile return profile
except VariableError: except VariableError:
pass pass
shortname = self.Get('cl_profile_shortname') shortname = self.Get(self.profiles_shortname)
if len(shortname) == 1: if len(shortname) == 1:
return shortname[0] return shortname[0]
return "" return ""
def choice(self): def choice(self):
url = self.Get('cl_update_profile_rep') url = self.Get(self.url)
if not url: if not url:
return [] return []
arch = self.Get('os_arch_machine_gentoo') arch = self.Get(self.gentoo_arch)
profiles = zip(*self.Select(['cl_profile_shortname', profiles = zip(*self.Select([self.profiles_shortname,
'cl_profile_fullname'], self.profiles_fullname],
where='cl_profile_arch', eq=arch)) where=self.profiles_arch, eq=arch))
if profiles: if profiles:
short_name, full_name = profiles short_name, full_name = profiles
return zip(short_name, full_name) return zip(short_name, full_name)
@ -944,23 +1043,31 @@ class DataVarsUpdateProfile(SimpleDataVars):
'cl_update_rep_path', 'cl_update_rep_path',
'cl_update_rep_rev', 'cl_update_rep_rev',
'cl_update_branch_name'] 'cl_update_branch_name']
def __init__(self, profile): def __init__(self, profile, chroot_path='/'):
SimpleDataVars.__init__(self, SimpleDataVars.__init__(self,
VariableOsLinuxName(), lib_linux.VariableOsLinuxName(),
VariableOsLinuxShortname(), lib_linux.VariableOsLinuxShortname(),
VariableOsLinuxSubname(), lib_linux.VariableOsLinuxSubname(),
VariableOsLinuxVer(), lib_linux.VariableOsLinuxVer(),
VariableClTemplateLocation(), lib_linux.VariableClProfileSystem(),
env.VariableClRepositoryData(),
env.VariableClRepositoryName(),
env.VariableClRepositoryLocation(),
env.VariableClChrootPath(),
env.VariableClTemplateLocation(),
env.VariableClTemplatePath(),
env.VariableClEmergeConfig(systemRoot=chroot_path),
VariableClUpdateRepData(section="update"), VariableClUpdateRepData(section="update"),
VariableClUpdateRepPath(section="update"), VariableClUpdateRepPath(section="update"),
VariableClUpdateRepRev(section="update"), VariableClUpdateRepRev(section="update"),
VariableClUpdateBranchName(section="update"), VariableClUpdateBranchName(section="update"),
VariableClProfileSystem(section="update"), VariableClUpdateLaymanConfig(section="update"),
VariableClUpdateLaymanStorage(section="update"), VariableClUpdateLaymanStorage(section="update"),
VariableClUpdateRepName(section="update"), VariableClUpdateRepName(section="update"),
VariableClUpdateRep(section="update"), VariableClUpdateRep(section="update"),
VariableClUpdateRepUrl(section="update")) VariableClUpdateRepUrl(section="update"))
self.cache['cl_profile_system'] = profile self.cache['cl_profile_system'] = profile
self.cache['cl_chroot_path'] = chroot_path
self.flIniFileFrom(profile) self.flIniFileFrom(profile)
def __repr__(self): def __repr__(self):
@ -1023,6 +1130,7 @@ class VariableClUpdateAutocheckScheduleSet(Variable):
self.label = _("Consider the autocheck schedule") self.label = _("Consider the autocheck schedule")
self.help = _("consider the autocheck schedule") self.help = _("consider the autocheck schedule")
class VariableClUpdateEmergelistSet(Variable): class VariableClUpdateEmergelistSet(Variable):
""" """
Вывести список пакетов в формате emerge Вывести список пакетов в формате emerge
@ -1035,6 +1143,7 @@ class VariableClUpdateEmergelistSet(Variable):
self.label = _("Emerge-like packages list") self.label = _("Emerge-like packages list")
self.help = _("display the packages list in emerge format") self.help = _("display the packages list in emerge format")
class VariableClUpdateKernelVersion(ReadonlyVariable): class VariableClUpdateKernelVersion(ReadonlyVariable):
""" """
Текущая версия ядра Текущая версия ядра
@ -1042,6 +1151,7 @@ class VariableClUpdateKernelVersion(ReadonlyVariable):
def get(self): def get(self):
return process('/bin/uname','-r').read().strip() return process('/bin/uname','-r').read().strip()
class VariableClUpdateKernelSrcPath(ReadonlyVariable): class VariableClUpdateKernelSrcPath(ReadonlyVariable):
""" """
Каталог содержащий исходный код текущего ядра Каталог содержащий исходный код текущего ядра
@ -1106,12 +1216,14 @@ class VariableClUpdateCleanpkgSet(Variable):
self.label = _("Clean obsolete programs archives") self.label = _("Clean obsolete programs archives")
self.help = _("clean obsolete programs archives") self.help = _("clean obsolete programs archives")
class VariableClUpdateOutdatedKernelPath(Variable): class VariableClUpdateOutdatedKernelPath(Variable):
""" """
Файл-флаг наличия устаревшего, неудаленного ядра Файл-флаг наличия устаревшего, неудаленного ядра
""" """
value = "/var/lib/calculate/calculate-update/outdated_kernel" value = "/var/lib/calculate/calculate-update/outdated_kernel"
class VariableClUpdateSkipRbSet(Variable): class VariableClUpdateSkipRbSet(Variable):
""" """
Пропусить revdep-rebuild Пропусить revdep-rebuild
@ -1125,6 +1237,7 @@ class VariableClUpdateSkipRbSet(Variable):
self.label = _("Skip reverse dependencies check") self.label = _("Skip reverse dependencies check")
self.help = _("skip reverse dependencies check") self.help = _("skip reverse dependencies check")
class VariableClUpdateOutdatedKernelSet(ReadonlyVariable): class VariableClUpdateOutdatedKernelSet(ReadonlyVariable):
""" """
Есть наличие устаревшего ядра Есть наличие устаревшего ядра

@ -113,9 +113,9 @@ class Wsdl(WsdlBase):
'groups': [ 'groups': [
lambda group: group(_("Repository"), lambda group: group(_("Repository"),
brief=('cl_update_profile_repo_name',), brief=('cl_update_profile_repo_name',),
hide=('cl_update_profile_rep', hide=('cl_update_profile_url',
'cl_update_profile_sync_set'), 'cl_update_profile_sync_set'),
normal=('cl_update_profile_rep',), normal=('cl_update_profile_url',),
expert=('cl_update_profile_sync_set', expert=('cl_update_profile_sync_set',
'cl_update_profile_branch')), 'cl_update_profile_branch')),
lambda group: group(_("Profile"), lambda group: group(_("Profile"),

Loading…
Cancel
Save