|
|
|
|
#-*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
|
|
# Copyright 2014 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.
|
|
|
|
|
from itertools import ifilter
|
|
|
|
|
|
|
|
|
|
import sys
|
|
|
|
|
from os import path
|
|
|
|
|
import os
|
|
|
|
|
import time
|
|
|
|
|
from calculate.core.server.gen_pid import search_worked_process
|
|
|
|
|
|
|
|
|
|
from calculate.lib.utils.tools import AddonError
|
|
|
|
|
from calculate.lib.utils.colortext.palette import TextState
|
|
|
|
|
from calculate.lib.utils.colortext import get_color_print
|
|
|
|
|
from calculate.update.emerge_parser import RevdepPercentBlock
|
|
|
|
|
|
|
|
|
|
from package_tools import Git, Layman,\
|
|
|
|
|
EmergeLogNamedTask, EmergeLog, GitError, \
|
|
|
|
|
PackageInformation, PackageList
|
|
|
|
|
|
|
|
|
|
Colors = TextState.Colors
|
|
|
|
|
from calculate.lib.utils.files import (getProgPath, STDOUT, removeDir,
|
|
|
|
|
PercentProgress, process)
|
|
|
|
|
from calculate.lib.cl_lang import (setLocalTranslate, getLazyLocalTranslate,
|
|
|
|
|
RegexpLocalization, _)
|
|
|
|
|
import emerge_parser
|
|
|
|
|
from emerge_parser import EmergeParser, EmergeCommand, EmergeError, EmergeCache
|
|
|
|
|
|
|
|
|
|
setLocalTranslate('cl_update3', sys.modules[__name__])
|
|
|
|
|
__ = getLazyLocalTranslate(_)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class UpdateError(AddonError):
|
|
|
|
|
"""Update Error"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Update:
|
|
|
|
|
"""Основной объект для выполнения действий связанных с обновлением системы
|
|
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
def init(self):
|
|
|
|
|
commandLog = path.join(self.clVars.Get('core.cl_log_path'),
|
|
|
|
|
'lastcommand.log')
|
|
|
|
|
emerge_parser.CommandExecutor.logfile = commandLog
|
|
|
|
|
self.color_print = get_color_print()
|
|
|
|
|
self.emerge_cache = EmergeCache()
|
|
|
|
|
self.emerge_cache.check_list = (
|
|
|
|
|
self.emerge_cache.check_list +
|
|
|
|
|
map(emerge_parser.GitCheckvalue,
|
|
|
|
|
self.clVars.Get('update.cl_update_rep_path')))
|
|
|
|
|
|
|
|
|
|
def _syncRepository(self, name, url, rpath, revision, branch,
|
|
|
|
|
cb_progress=None):
|
|
|
|
|
"""
|
|
|
|
|
Синхронизировать репозитори
|
|
|
|
|
"""
|
|
|
|
|
dv = self.clVars
|
|
|
|
|
git = Git()
|
|
|
|
|
needMeta = False
|
|
|
|
|
if not git.checkExistsRep(rpath):
|
|
|
|
|
if revision == "last":
|
|
|
|
|
git.cloneRepository(url, rpath, branch,
|
|
|
|
|
cb_progress=cb_progress)
|
|
|
|
|
else:
|
|
|
|
|
git.cloneRevRepository(url, rpath, branch, revision,
|
|
|
|
|
cb_progress=cb_progress)
|
|
|
|
|
needMeta = 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:
|
|
|
|
|
# меняем ветку
|
|
|
|
|
needMeta = 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")
|
|
|
|
|
needMeta = True
|
|
|
|
|
else:
|
|
|
|
|
git.resetRepository(rpath, to_rev=revision)
|
|
|
|
|
needMeta = True
|
|
|
|
|
if needMeta:
|
|
|
|
|
dv.Set('cl_update_outdate_set', 'on', force=True)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def checkRun(self, wait_update):
|
|
|
|
|
"""
|
|
|
|
|
Проверить повторный запуск
|
|
|
|
|
"""
|
|
|
|
|
dv = self.clVars
|
|
|
|
|
if filter(lambda x: os.getpid() != x,
|
|
|
|
|
search_worked_process('update', dv)):
|
|
|
|
|
if not wait_update:
|
|
|
|
|
raise UpdateError(_("Update is already running. "
|
|
|
|
|
"Try to run later."))
|
|
|
|
|
else:
|
|
|
|
|
self.startTask(_("Waiting for another update to be complete"))
|
|
|
|
|
while any(ifilter(lambda x: os.getpid() != x,
|
|
|
|
|
search_worked_process('update', dv))):
|
|
|
|
|
time.sleep(0.3)
|
|
|
|
|
self.endTask()
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def syncRepositories(self, repname, clean_on_error=True):
|
|
|
|
|
"""
|
|
|
|
|
Синхронизировать репозитории
|
|
|
|
|
"""
|
|
|
|
|
dv = self.clVars
|
|
|
|
|
url, rpath, revision, branch = (
|
|
|
|
|
dv.Select(["cl_update_rep_url", "cl_update_rep_path",
|
|
|
|
|
"cl_update_rep_rev", "cl_update_branch_name"],
|
|
|
|
|
where="cl_update_rep_name", eq=repname, limit=1))
|
|
|
|
|
if not url or not rpath:
|
|
|
|
|
raise UpdateError(_("Configuration variables for repositories "
|
|
|
|
|
"are not setup"))
|
|
|
|
|
self.addProgress()
|
|
|
|
|
if clean_on_error:
|
|
|
|
|
try:
|
|
|
|
|
if not self._syncRepository(repname, url, rpath, revision, branch,
|
|
|
|
|
cb_progress=self.setProgress):
|
|
|
|
|
return "skip"
|
|
|
|
|
return True
|
|
|
|
|
except GitError as e:
|
|
|
|
|
if e.addon:
|
|
|
|
|
self.printWARNING(str(e.addon))
|
|
|
|
|
self.printWARNING(str(e))
|
|
|
|
|
self.endTask(False)
|
|
|
|
|
self.startTask(
|
|
|
|
|
_("Re-fetching the {name} repository").format(name=repname))
|
|
|
|
|
self.addProgress()
|
|
|
|
|
try:
|
|
|
|
|
rpath_new = "%s_new" % rpath
|
|
|
|
|
self._syncRepository(repname, url, rpath_new, revision,
|
|
|
|
|
branch, cb_progress=self.setProgress)
|
|
|
|
|
removeDir(rpath)
|
|
|
|
|
os.rename(rpath_new, rpath)
|
|
|
|
|
except OSError:
|
|
|
|
|
raise UpdateError(_("Permission denied to modify the "
|
|
|
|
|
"{repname} repository").format(
|
|
|
|
|
repname=repname))
|
|
|
|
|
finally:
|
|
|
|
|
if path.exists(rpath_new):
|
|
|
|
|
removeDir(rpath_new)
|
|
|
|
|
else:
|
|
|
|
|
if not self._syncRepository(repname, url, rpath, revision, branch):
|
|
|
|
|
return "skip"
|
|
|
|
|
|
|
|
|
|
layman = Layman(dv.Get('cl_update_layman_installed'),
|
|
|
|
|
dv.Get('cl_update_layman_make'))
|
|
|
|
|
if repname != "portage":
|
|
|
|
|
layman.add(repname, url, rpath)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def syncLaymanRepository(self, repname):
|
|
|
|
|
"""
|
|
|
|
|
Обновить репозиторий через layman
|
|
|
|
|
"""
|
|
|
|
|
layman = getProgPath('/usr/bin/layman')
|
|
|
|
|
if not layman:
|
|
|
|
|
raise UpdateError(_("The Layman tool is not found"))
|
|
|
|
|
rpath = self.clVars.Select('cl_update_other_rep_path',
|
|
|
|
|
where='cl_update_other_rep_name', eq=repname,
|
|
|
|
|
limit=1)
|
|
|
|
|
laymanname = path.basename(rpath)
|
|
|
|
|
if Git.is_git(rpath):
|
|
|
|
|
self.addProgress()
|
|
|
|
|
p = PercentProgress(layman, "-s", laymanname, part=1, atty=True)
|
|
|
|
|
for perc in p.progress():
|
|
|
|
|
self.setProgress(perc)
|
|
|
|
|
else:
|
|
|
|
|
p = process(layman, "-s", repname, stderr=STDOUT)
|
|
|
|
|
if p.failed():
|
|
|
|
|
raise UpdateError(
|
|
|
|
|
_("Failed to update the {rname} repository").format(rname=repname),
|
|
|
|
|
addon=p.read())
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def regenCache(self, repname):
|
|
|
|
|
"""
|
|
|
|
|
Обновить кэш метаданных репозитория
|
|
|
|
|
"""
|
|
|
|
|
egenCache = getProgPath('/usr/bin/egencache')
|
|
|
|
|
if not egenCache:
|
|
|
|
|
raise UpdateError(_("The Portage tool is not found"))
|
|
|
|
|
cpu_num = self.clVars.Get('hr_cpu_num')
|
|
|
|
|
p = process(egenCache, "--repo=%s" % repname, "--update",
|
|
|
|
|
"--jobs=%s" % cpu_num, stderr=STDOUT)
|
|
|
|
|
if p.failed():
|
|
|
|
|
raise UpdateError(_("Failed to update the cache of the {rname} "
|
|
|
|
|
"repository").format(rname=repname),
|
|
|
|
|
addon=p.read())
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def emergeMetadata(self):
|
|
|
|
|
"""
|
|
|
|
|
Выполнить egencache и emerge --metadata
|
|
|
|
|
"""
|
|
|
|
|
emerge = getProgPath("/usr/bin/emerge")
|
|
|
|
|
if not emerge:
|
|
|
|
|
raise UpdateError(_("The Emerge tool is not found"))
|
|
|
|
|
self.addProgress()
|
|
|
|
|
p = PercentProgress(emerge, "--metadata", part=1, atty=True)
|
|
|
|
|
for perc in p.progress():
|
|
|
|
|
self.setProgress(perc)
|
|
|
|
|
if p.failed():
|
|
|
|
|
raise UpdateError(_("Failed to update metadata"), addon=p.read())
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def eixUpdate(self):
|
|
|
|
|
"""
|
|
|
|
|
Выполенине eix-update для репозиторием
|
|
|
|
|
|
|
|
|
|
eix-update выполнятется только для тех репозиториев, которые
|
|
|
|
|
обновлялись, если cl_update_eixsync_force==auto, либо
|
|
|
|
|
все, если cl_update_eixupdate_force==force
|
|
|
|
|
"""
|
|
|
|
|
eixupdate = getProgPath("/usr/bin/eix-update")
|
|
|
|
|
if not eixupdate:
|
|
|
|
|
raise UpdateError(_("The Eix tool is not found"))
|
|
|
|
|
self.addProgress()
|
|
|
|
|
excludeList = []
|
|
|
|
|
if self.clVars.Get('cl_update_eixupdate_force') == 'force':
|
|
|
|
|
countRep = len(self.clVars.Get('cl_update_rep_name'))
|
|
|
|
|
else:
|
|
|
|
|
for rep in self.clVars.Get('cl_update_rep_name'):
|
|
|
|
|
# подстановка имен
|
|
|
|
|
mapNames = {'portage': 'gentoo'}
|
|
|
|
|
if not rep in self.clVars.Get('cl_update_sync_rep'):
|
|
|
|
|
excludeList.extend(["-x", mapNames.get(rep, rep)])
|
|
|
|
|
countRep = len(self.clVars.Get('cl_update_sync_rep'))
|
|
|
|
|
if (self.clVars.Get('cl_update_other_set') == 'on' or
|
|
|
|
|
self.clVars.Get('cl_update_eixupdate_force') == 'force'):
|
|
|
|
|
countRep += len(self.clVars.Get('update.cl_update_other_rep_name'))
|
|
|
|
|
else:
|
|
|
|
|
for rep in self.clVars.Get('update.cl_update_other_rep_name'):
|
|
|
|
|
excludeList.extend(['-x', rep])
|
|
|
|
|
p = PercentProgress(eixupdate, "-F", *excludeList, part=countRep or 1,
|
|
|
|
|
atty=True)
|
|
|
|
|
for perc in p.progress():
|
|
|
|
|
self.setProgress(perc)
|
|
|
|
|
if p.failed():
|
|
|
|
|
raise UpdateError(_("Failed to update eix cache"), addon=p.read())
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def is_binary_pkg(self, pkg, binary=None):
|
|
|
|
|
"""
|
|
|
|
|
Является ли пакет бинарным
|
|
|
|
|
"""
|
|
|
|
|
if binary:
|
|
|
|
|
return True
|
|
|
|
|
if 'PN' in pkg and pkg['PN'].endswith('-bin'):
|
|
|
|
|
return True
|
|
|
|
|
if binary is not None:
|
|
|
|
|
return binary
|
|
|
|
|
if "binary" in pkg and pkg['binary']:
|
|
|
|
|
return True
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def _printEmergePackage(self, pkg, binary=False, num=1, max_num=1):
|
|
|
|
|
"""
|
|
|
|
|
Вывод сообщения сборки пакета
|
|
|
|
|
"""
|
|
|
|
|
self.endTask()
|
|
|
|
|
_print = self.color_print
|
|
|
|
|
if max_num > 1:
|
|
|
|
|
one = _print.foreground(Colors.YELLOW).bold("{0}", num)
|
|
|
|
|
two = _print.foreground(Colors.YELLOW).bold("{0}", max_num)
|
|
|
|
|
part = _(" ({current} of {maximum})").format(current=one,
|
|
|
|
|
maximum=two)
|
|
|
|
|
else:
|
|
|
|
|
part = ""
|
|
|
|
|
if self.is_binary_pkg(pkg,binary):
|
|
|
|
|
_print = _print.foreground(Colors.PURPLE)
|
|
|
|
|
else:
|
|
|
|
|
_print = _print.foreground(Colors.GREEN)
|
|
|
|
|
|
|
|
|
|
self.startTask(
|
|
|
|
|
_("Emerging{part} {package}").format(part=part,
|
|
|
|
|
package=_print(str(pkg))))
|
|
|
|
|
|
|
|
|
|
def _printInstallPackage(self, pkg, binary=False):
|
|
|
|
|
"""
|
|
|
|
|
Вывод сообщения установки пакета
|
|
|
|
|
"""
|
|
|
|
|
self.endTask()
|
|
|
|
|
_print = self.color_print
|
|
|
|
|
if self.is_binary_pkg(pkg,binary):
|
|
|
|
|
_print = _print.foreground(Colors.PURPLE)
|
|
|
|
|
else:
|
|
|
|
|
_print = _print.foreground(Colors.GREEN)
|
|
|
|
|
self.startTask(_("Installing %s") %
|
|
|
|
|
_print(str(pkg)))
|
|
|
|
|
|
|
|
|
|
def _printUninstallPackage(self, pkg, num=1, max_num=1):
|
|
|
|
|
"""
|
|
|
|
|
Вывод сообщения удаления пакета
|
|
|
|
|
"""
|
|
|
|
|
self.endTask()
|
|
|
|
|
_print = self.color_print
|
|
|
|
|
if max_num > 1:
|
|
|
|
|
one = _print.foreground(Colors.YELLOW).bold("{0}", num)
|
|
|
|
|
two = _print.foreground(Colors.YELLOW).bold("{0}", max_num)
|
|
|
|
|
part = _(" ({current} of {maximum})").format(current=one,
|
|
|
|
|
maximum=two)
|
|
|
|
|
else:
|
|
|
|
|
part = ""
|
|
|
|
|
_print = _print.foreground(Colors.RED)
|
|
|
|
|
|
|
|
|
|
self.startTask(
|
|
|
|
|
_("Unmerging{part} {package}").format(part=part,
|
|
|
|
|
package=_print.bold(str(pkg))))
|
|
|
|
|
|
|
|
|
|
def emergelike(self, cmd, *params):
|
|
|
|
|
"""
|
|
|
|
|
Запуск команды, которая подразумевает выполнение emerge
|
|
|
|
|
"""
|
|
|
|
|
cmd_path = getProgPath(cmd)
|
|
|
|
|
if not cmd_path:
|
|
|
|
|
raise UpdateError(_("Failed to find the %s command") % cmd)
|
|
|
|
|
with EmergeParser(
|
|
|
|
|
emerge_parser.CommandExecutor(cmd_path, params)) as emerge:
|
|
|
|
|
self._startEmerging(emerge)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def revdep_rebuild(self, cmd, *params):
|
|
|
|
|
"""
|
|
|
|
|
Запуск revdep-rebulid
|
|
|
|
|
"""
|
|
|
|
|
cmd_path = getProgPath(cmd)
|
|
|
|
|
if not cmd_path:
|
|
|
|
|
raise UpdateError(_("Failed to find the %s command") % cmd)
|
|
|
|
|
with EmergeParser(
|
|
|
|
|
emerge_parser.CommandExecutor(cmd_path, params)) as emerge:
|
|
|
|
|
revdep = RevdepPercentBlock(emerge)
|
|
|
|
|
self.addProgress()
|
|
|
|
|
revdep.add_observer(self.setProgress)
|
|
|
|
|
revdep.action = lambda x: (
|
|
|
|
|
self.endTask(), self.startTask(_("Assigning files to packages"))
|
|
|
|
|
if "Assign" in revdep else None)
|
|
|
|
|
self._startEmerging(emerge)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def _display_pretty_package_list(self, pkglist, remove_list=False):
|
|
|
|
|
"""
|
|
|
|
|
Отобразить список пакетов в "удобочитаемом" виде
|
|
|
|
|
"""
|
|
|
|
|
_print = self.color_print
|
|
|
|
|
ebuild_color = TextState.Colors.GREEN
|
|
|
|
|
binary_color = TextState.Colors.PURPLE
|
|
|
|
|
remove_color = TextState.Colors.LIGHT_RED
|
|
|
|
|
for pkg in sorted([PackageInformation.add_info(x) for x in
|
|
|
|
|
pkglist],
|
|
|
|
|
key=lambda y: y['CATEGORY/PN']):
|
|
|
|
|
if remove_list:
|
|
|
|
|
pkgcolor = _print.foreground(remove_color)
|
|
|
|
|
else:
|
|
|
|
|
if self.is_binary_pkg(pkg):
|
|
|
|
|
pkgcolor = _print.foreground(binary_color)
|
|
|
|
|
else:
|
|
|
|
|
pkgcolor = _print.foreground(ebuild_color)
|
|
|
|
|
|
|
|
|
|
if pkg.info['DESCRIPTION']:
|
|
|
|
|
fullname = "%s " % _(pkg.info['DESCRIPTION'])
|
|
|
|
|
fullname = fullname[:1].upper()+fullname[1:]
|
|
|
|
|
else:
|
|
|
|
|
fullname = ""
|
|
|
|
|
shortname = pkgcolor("%s-%s" % (pkg["CATEGORY/PN"], pkg["PVR"]))
|
|
|
|
|
if "SIZE" in pkg and pkg['SIZE'] and pkg["SIZE"] != "0 kB":
|
|
|
|
|
size = " (%s)" % pkg["SIZE"]
|
|
|
|
|
else:
|
|
|
|
|
size = ""
|
|
|
|
|
mult = _print.bold("*")
|
|
|
|
|
self.printDefault(" {mult} {fullname}{shortname}{size}".format(
|
|
|
|
|
mult=mult, fullname=fullname, shortname=shortname, size=size))
|
|
|
|
|
|
|
|
|
|
def _display_install_package(self, emerge):
|
|
|
|
|
"""
|
|
|
|
|
Отобразить список устанавливаемых пакетов
|
|
|
|
|
"""
|
|
|
|
|
# подробный список пакетов
|
|
|
|
|
_print = self.color_print
|
|
|
|
|
if self.clVars.Get('cl_verbose_set') == 'on':
|
|
|
|
|
self.printPre(str(emerge.install_packages))
|
|
|
|
|
else:
|
|
|
|
|
pkglist = emerge.install_packages.list
|
|
|
|
|
self.printSUCCESS(_print(
|
|
|
|
|
_("Listing packages for installation")))
|
|
|
|
|
self._display_pretty_package_list(pkglist)
|
|
|
|
|
if emerge.install_packages.remove_list:
|
|
|
|
|
self.printSUCCESS(_print(
|
|
|
|
|
_("Listing packages for removal")))
|
|
|
|
|
self._display_pretty_package_list(
|
|
|
|
|
emerge.install_packages.remove_list, remove_list=True)
|
|
|
|
|
if str(emerge.download_size) != "0 kB":
|
|
|
|
|
self.printSUCCESS(_("{size} will be downloaded").format(
|
|
|
|
|
size=str(emerge.download_size)))
|
|
|
|
|
|
|
|
|
|
def _display_remove_list(self, emerge):
|
|
|
|
|
"""
|
|
|
|
|
Отобразить список удаляемых пакетов
|
|
|
|
|
"""
|
|
|
|
|
# подробный список пакетов
|
|
|
|
|
if self.clVars.Get('cl_verbose_set') == 'on':
|
|
|
|
|
self.printPre(str(emerge.uninstall_packages))
|
|
|
|
|
else:
|
|
|
|
|
_print = self.color_print
|
|
|
|
|
pkglist = emerge.uninstall_packages.list
|
|
|
|
|
self.printSUCCESS(_print.bold(
|
|
|
|
|
_("Listing packages for removal")))
|
|
|
|
|
self._display_pretty_package_list(pkglist, remove_list=True)
|
|
|
|
|
|
|
|
|
|
def getCacheOnWorld(self, params, packages, check=False):
|
|
|
|
|
"""
|
|
|
|
|
Получить список обновляемых пакетов @world из кэша
|
|
|
|
|
"""
|
|
|
|
|
if "@world" in packages:
|
|
|
|
|
from calculate.update.utils.cl_update import ClUpdateAction
|
|
|
|
|
elog = EmergeLog(
|
|
|
|
|
EmergeLogNamedTask(ClUpdateAction.log_names['premerge']))
|
|
|
|
|
if check and (elog.list or elog.remove_list):
|
|
|
|
|
self.emerge_cache.drop_cache()
|
|
|
|
|
return params, packages
|
|
|
|
|
installed_pkgs = elog.list
|
|
|
|
|
new_packages = self.emerge_cache.get_cached_package_list()
|
|
|
|
|
if new_packages is not None:
|
|
|
|
|
return "-1O", ["=%s" % x for x in new_packages
|
|
|
|
|
if not str(x) in installed_pkgs]
|
|
|
|
|
return params, packages
|
|
|
|
|
|
|
|
|
|
def updateCache(self, pkg_list):
|
|
|
|
|
"""
|
|
|
|
|
Обновить кэш. Оставить отметку в emerge.log о том, выполнено действие
|
|
|
|
|
premerge
|
|
|
|
|
"""
|
|
|
|
|
self.emerge_cache.set_cache(pkg_list)
|
|
|
|
|
from calculate.update.utils.cl_update import ClUpdateAction
|
|
|
|
|
elog = EmergeLog(
|
|
|
|
|
EmergeLogNamedTask(ClUpdateAction.log_names['premerge']))
|
|
|
|
|
elog.mark_end_task(),
|
|
|
|
|
|
|
|
|
|
def premerge(self, param, *packages):
|
|
|
|
|
"""
|
|
|
|
|
Вывести информацию об обновлении
|
|
|
|
|
"""
|
|
|
|
|
param, packages = self.getCacheOnWorld(param, packages, check=True)
|
|
|
|
|
param = [param, "-pv"]
|
|
|
|
|
|
|
|
|
|
if not packages:
|
|
|
|
|
self.printSUCCESS(_("Installed packages are up to date"))
|
|
|
|
|
return True
|
|
|
|
|
with EmergeParser(EmergeCommand(list(packages),
|
|
|
|
|
extra_params=param)) as emerge:
|
|
|
|
|
try:
|
|
|
|
|
emerge.run()
|
|
|
|
|
if "@world" in packages:
|
|
|
|
|
if emerge.install_packages.remove_list:
|
|
|
|
|
self.emerge_cache.drop_cache()
|
|
|
|
|
else:
|
|
|
|
|
self.updateCache(emerge.install_packages.list)
|
|
|
|
|
if not emerge.install_packages.list:
|
|
|
|
|
self.printSUCCESS(_("The system is up to date"))
|
|
|
|
|
return True
|
|
|
|
|
self._display_install_package(emerge)
|
|
|
|
|
except EmergeError:
|
|
|
|
|
self.emerge_cache.drop_cache()
|
|
|
|
|
self.printPre(self._emerge_translate(emerge.prepare_error))
|
|
|
|
|
raise
|
|
|
|
|
if self.clVars.Get('cl_update_pretend_set') == 'on':
|
|
|
|
|
return True
|
|
|
|
|
answer = self.askConfirm(
|
|
|
|
|
_("Would you like to merge these packages?"), "yes")
|
|
|
|
|
if answer == "no":
|
|
|
|
|
raise KeyboardInterrupt
|
|
|
|
|
return "yes"
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def _emerge_translate(self, s):
|
|
|
|
|
"""
|
|
|
|
|
Перевести текст из emerge
|
|
|
|
|
"""
|
|
|
|
|
return RegexpLocalization('cl_emerge').translate(str(s))
|
|
|
|
|
|
|
|
|
|
def setUpToDateCache(self):
|
|
|
|
|
"""
|
|
|
|
|
Установить кэш - "нет пакетов для обновления"
|
|
|
|
|
"""
|
|
|
|
|
self.updateCache(PackageList([]))
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def _startEmerging(self, emerge):
|
|
|
|
|
"""
|
|
|
|
|
Настроить и выполнить emerge
|
|
|
|
|
"""
|
|
|
|
|
emerge.command.send("yes\n")
|
|
|
|
|
emerge.emerging.add_observer(self._printEmergePackage)
|
|
|
|
|
emerge.installing.add_observer(self._printInstallPackage)
|
|
|
|
|
emerge.uninstalling.add_observer(self._printUninstallPackage)
|
|
|
|
|
try:
|
|
|
|
|
emerge.run()
|
|
|
|
|
except EmergeError:
|
|
|
|
|
self.emerge_cache.drop_cache()
|
|
|
|
|
if emerge.emerging_error:
|
|
|
|
|
self.printPre(
|
|
|
|
|
self._emerge_translate(emerge.emerging_error.log))
|
|
|
|
|
else:
|
|
|
|
|
self.printPre(self._emerge_translate(emerge.prepare_error))
|
|
|
|
|
raise
|
|
|
|
|
|
|
|
|
|
def emerge(self, param, *packages):
|
|
|
|
|
"""
|
|
|
|
|
Выполнить сборку пакета
|
|
|
|
|
"""
|
|
|
|
|
if not packages:
|
|
|
|
|
packages = [param]
|
|
|
|
|
extra_params = None
|
|
|
|
|
else:
|
|
|
|
|
param, packages = self.getCacheOnWorld(param, packages)
|
|
|
|
|
if not packages:
|
|
|
|
|
return True
|
|
|
|
|
extra_params = [param]
|
|
|
|
|
with EmergeParser(EmergeCommand(list(packages),
|
|
|
|
|
extra_params=extra_params)) as emerge:
|
|
|
|
|
try:
|
|
|
|
|
emerge.question.action = lambda x: False
|
|
|
|
|
emerge.run()
|
|
|
|
|
if not emerge.install_packages.list:
|
|
|
|
|
return True
|
|
|
|
|
except EmergeError:
|
|
|
|
|
self.emerge_cache.drop_cache()
|
|
|
|
|
self.printPre(self._emerge_translate(emerge.prepare_error))
|
|
|
|
|
raise
|
|
|
|
|
self._startEmerging(emerge)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def depclean(self):
|
|
|
|
|
"""
|
|
|
|
|
Выполнить очистку системы от лишних пакетов
|
|
|
|
|
"""
|
|
|
|
|
with EmergeParser(EmergeCommand(["--depclean"])) as emerge:
|
|
|
|
|
try:
|
|
|
|
|
emerge.question.action = lambda x: False
|
|
|
|
|
emerge.run()
|
|
|
|
|
if not emerge.uninstall_packages.list:
|
|
|
|
|
return True
|
|
|
|
|
self._display_remove_list(emerge)
|
|
|
|
|
except EmergeError:
|
|
|
|
|
self.printPre(self._emerge_translate(emerge.prepare_error))
|
|
|
|
|
raise
|
|
|
|
|
if (self.askConfirm(
|
|
|
|
|
_("Would you like to unmerge these packages?")) != 'yes'):
|
|
|
|
|
return False
|
|
|
|
|
self._startEmerging(emerge)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def update_task(self, task_name):
|
|
|
|
|
"""
|
|
|
|
|
Декоратор для добавления меток запуска и останова задачи
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
def decor(f):
|
|
|
|
|
def wrapper(*args, **kwargs):
|
|
|
|
|
logger = EmergeLog(EmergeLogNamedTask(task_name))
|
|
|
|
|
logger.mark_begin_task()
|
|
|
|
|
ret = f(*args, **kwargs)
|
|
|
|
|
if ret:
|
|
|
|
|
logger.mark_end_task()
|
|
|
|
|
return ret
|
|
|
|
|
|
|
|
|
|
return wrapper
|
|
|
|
|
|
|
|
|
|
return decor
|
|
|
|
|
|