|
|
|
@ -24,7 +24,7 @@ from calculate.core.server.gen_pid import search_worked_process
|
|
|
|
|
from calculate.core.setup_cache import Cache as SetupCache
|
|
|
|
|
from calculate.core.server.func import MethodsInterface
|
|
|
|
|
from calculate.lib.cl_template import SystemIni, LayeredIni
|
|
|
|
|
from calculate.lib.datavars import DataVarsError, VariableError
|
|
|
|
|
from calculate.lib.datavars import DataVarsError, VariableError, Variable
|
|
|
|
|
|
|
|
|
|
from calculate.lib.utils.tools import AddonError
|
|
|
|
|
from calculate.lib.utils.colortext.palette import TextState
|
|
|
|
@ -32,12 +32,16 @@ from calculate.lib.utils.colortext import get_color_print
|
|
|
|
|
from calculate.update.emerge_parser import RevdepPercentBlock
|
|
|
|
|
from calculate.update.datavars import DataVarsUpdate
|
|
|
|
|
from calculate.update.update_info import UpdateInfo
|
|
|
|
|
from calculate.lib.utils.binhosts import fetch_packages
|
|
|
|
|
from calculate.lib.utils.binhosts import (Binhosts, BinhostSignError,
|
|
|
|
|
BinhostError, PackagesIndex, DAYS)
|
|
|
|
|
from calculate.lib.utils.gpg import GPG, GPGError
|
|
|
|
|
from calculate.lib.cl_log import log
|
|
|
|
|
import hashlib
|
|
|
|
|
import re
|
|
|
|
|
import shutil
|
|
|
|
|
from collections import MutableSet
|
|
|
|
|
from contextlib import contextmanager
|
|
|
|
|
import tempfile
|
|
|
|
|
|
|
|
|
|
from calculate.lib.utils.git import Git, GitError, MTimeKeeper, NotGitError
|
|
|
|
|
from calculate.lib.utils.portage import (Layman, EmergeLog,
|
|
|
|
@ -52,7 +56,7 @@ Colors = TextState.Colors
|
|
|
|
|
from calculate.lib.utils.files import (getProgPath, STDOUT, removeDir,
|
|
|
|
|
PercentProgress, process, getRunCommands,
|
|
|
|
|
readFile, listDirectory, pathJoin,
|
|
|
|
|
find, FindFileType,
|
|
|
|
|
find, FindFileType,quite_unlink,
|
|
|
|
|
writeFile, makeDirectory)
|
|
|
|
|
import emerge_parser
|
|
|
|
|
import logging
|
|
|
|
@ -151,6 +155,8 @@ class Update(MethodsInterface):
|
|
|
|
|
self.refresh_binhost = False
|
|
|
|
|
self.pkgnum = None
|
|
|
|
|
self.pkgnummax = None
|
|
|
|
|
self.gpgdata_md5 = []
|
|
|
|
|
self.gpg_changed = False
|
|
|
|
|
|
|
|
|
|
def get_prog_path(self, program_name):
|
|
|
|
|
return getProgPath(program_name)
|
|
|
|
@ -217,7 +223,7 @@ class Update(MethodsInterface):
|
|
|
|
|
status = git.getStatusInfo(rpath)
|
|
|
|
|
if not status or status['files']:
|
|
|
|
|
need_update = True
|
|
|
|
|
except GitError:
|
|
|
|
|
except GitError as e:
|
|
|
|
|
need_update = True
|
|
|
|
|
if need_update:
|
|
|
|
|
if not notask:
|
|
|
|
@ -236,6 +242,8 @@ class Update(MethodsInterface):
|
|
|
|
|
dv.Set('cl_update_outdate_set', 'on', force=True)
|
|
|
|
|
finally:
|
|
|
|
|
self.unstash_cache(rpath, name)
|
|
|
|
|
# TODO: debug1
|
|
|
|
|
#dv.Set('cl_update_outdate_set', 'on', force=True)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def raiseOutdate(self):
|
|
|
|
@ -1213,28 +1221,23 @@ class Update(MethodsInterface):
|
|
|
|
|
cache.update(force=True)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def check_binhost(self, write_binhost=True):
|
|
|
|
|
def get_bin_cache_filename(self):
|
|
|
|
|
return pathJoin(self.clVars.Get('cl_chroot_path'),
|
|
|
|
|
LayeredIni.IniPath.Grp)
|
|
|
|
|
|
|
|
|
|
def update_local_info_binhost(self, write_binhost=True):
|
|
|
|
|
"""
|
|
|
|
|
Проверить, что доступен хотя бы один из binhost'ов
|
|
|
|
|
:return:
|
|
|
|
|
"""
|
|
|
|
|
hosts = self.clVars.Get("update.cl_update_binhost_host")
|
|
|
|
|
datas = self.clVars.Get("update.cl_update_binhost_revisions")
|
|
|
|
|
bin_cache_fn = pathJoin(self.clVars.Get('cl_chroot_path'),
|
|
|
|
|
LayeredIni.IniPath.Grp)
|
|
|
|
|
if not hosts:
|
|
|
|
|
self.clVars.Delete('cl_update_binhost', location="system")
|
|
|
|
|
try:
|
|
|
|
|
if path.exists(bin_cache_fn):
|
|
|
|
|
os.unlink(bin_cache_fn)
|
|
|
|
|
except OSError:
|
|
|
|
|
raise UpdateError(
|
|
|
|
|
_("Failed to remove cached ini.env of binary repository"))
|
|
|
|
|
|
|
|
|
|
self.delete_binhost()
|
|
|
|
|
raise UpdateError(_("Failed to find the server with "
|
|
|
|
|
"appropriate updates"))
|
|
|
|
|
else:
|
|
|
|
|
with writeFile(bin_cache_fn) as f:
|
|
|
|
|
with writeFile(self.get_bin_cache_filename()) as f:
|
|
|
|
|
f.write(datas[0].strip()+"\n")
|
|
|
|
|
if write_binhost:
|
|
|
|
|
if hosts[0] != self.clVars.Get('update.cl_update_binhost'):
|
|
|
|
@ -1275,33 +1278,53 @@ class Update(MethodsInterface):
|
|
|
|
|
self.clVars.Get('cl_update_binhost'))
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def delete_binhost(self):
|
|
|
|
|
self.clVars.Delete('cl_update_binhost', location="system")
|
|
|
|
|
try:
|
|
|
|
|
bin_cache_fn = self.get_bin_cache_filename()
|
|
|
|
|
if path.exists(bin_cache_fn):
|
|
|
|
|
os.unlink(bin_cache_fn)
|
|
|
|
|
except OSError:
|
|
|
|
|
raise UpdateError(
|
|
|
|
|
_("Failed to remove cached ini.env of binary repository"))
|
|
|
|
|
try:
|
|
|
|
|
for varname in ('cl_update_package_cache', 'cl_update_package_cache_sign'):
|
|
|
|
|
fn = self.clVars.Get(varname)
|
|
|
|
|
if path.exists(fn):
|
|
|
|
|
os.unlink(fn)
|
|
|
|
|
except OSError:
|
|
|
|
|
raise UpdateError(
|
|
|
|
|
_("Failed to remove cached Package index"))
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def update_binhost_list(self):
|
|
|
|
|
"""
|
|
|
|
|
Обновить список binhost'ов после обновления до master веток
|
|
|
|
|
:return:
|
|
|
|
|
"""
|
|
|
|
|
dv = DataVarsUpdate()
|
|
|
|
|
changes = False
|
|
|
|
|
try:
|
|
|
|
|
dv = DataVarsUpdate()
|
|
|
|
|
dv.importUpdate()
|
|
|
|
|
dv.flIniFile()
|
|
|
|
|
changes = False
|
|
|
|
|
for varname in ('update.cl_update_binhost_list',
|
|
|
|
|
'update.cl_update_binhost_unstable_list',
|
|
|
|
|
'update.cl_update_binhost_timestamp_path',
|
|
|
|
|
'update.cl_update_gpg_keys',
|
|
|
|
|
'cl_update_binhost_revision_path'):
|
|
|
|
|
new_value = dv.Get(varname)
|
|
|
|
|
old_value = self.clVars.Get(varname)
|
|
|
|
|
if new_value != old_value:
|
|
|
|
|
changes = True
|
|
|
|
|
self.clVars.Set(varname, new_value, force=True)
|
|
|
|
|
if not changes:
|
|
|
|
|
self.clVars.Delete('cl_update_binhost', location="system")
|
|
|
|
|
raise UpdateError(_("Failed to find the server with "
|
|
|
|
|
"appropriate updates"))
|
|
|
|
|
self.clVars.Set(varname, new_value, force=True)
|
|
|
|
|
except DataVarsError:
|
|
|
|
|
self.clVars.Delete('cl_update_binhost', location="system")
|
|
|
|
|
raise UpdateError(_("Failed to find the server with "
|
|
|
|
|
"appropriate updates"))
|
|
|
|
|
raise UpdateError(_("Failed to get values for binhost search"))
|
|
|
|
|
|
|
|
|
|
if self.is_gpg_changed():
|
|
|
|
|
self.prepare_gpg()
|
|
|
|
|
elif not changes:
|
|
|
|
|
return False
|
|
|
|
|
self.create_binhost_data()
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def drop_binhosts(self, dv):
|
|
|
|
@ -1316,8 +1339,271 @@ class Update(MethodsInterface):
|
|
|
|
|
dv.Invalidate('update.cl_update_rep_rev')
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def download_packages(self, url_binhost, packages_fn):
|
|
|
|
|
fetch_packages(url_binhost, packages_fn)
|
|
|
|
|
def is_gpg_changed(self):
|
|
|
|
|
"""
|
|
|
|
|
Проверить изменились ли открытые ключи
|
|
|
|
|
"""
|
|
|
|
|
gpg_force = self.clVars.Get('cl_update_gpg_force')
|
|
|
|
|
if gpg_force == "skip":
|
|
|
|
|
return False
|
|
|
|
|
gpg_keys = self.clVars.Get('cl_update_gpg_keys')
|
|
|
|
|
gpgdata = ""
|
|
|
|
|
for keyfn in gpg_keys:
|
|
|
|
|
if path.exists(keyfn):
|
|
|
|
|
gpgdata += readFile(keyfn)
|
|
|
|
|
new_gpgdata_md5 = hashlib.md5(gpgdata).hexdigest()
|
|
|
|
|
return all(new_gpgdata_md5 != x for x in self.gpgdata_md5)
|
|
|
|
|
|
|
|
|
|
def prepare_gpg(self):
|
|
|
|
|
"""
|
|
|
|
|
Получить объект для проверки подписи, либо получить заглушку
|
|
|
|
|
"""
|
|
|
|
|
gpg_force = self.clVars.Get('cl_update_gpg_force')
|
|
|
|
|
gpg_keys = self.clVars.Get('cl_update_gpg_keys')
|
|
|
|
|
if gpg_force == "skip":
|
|
|
|
|
return True
|
|
|
|
|
gpg = GPG(tempfile.mkdtemp(dir="/var/calculate/tmp/update",
|
|
|
|
|
prefix="gpg-"))
|
|
|
|
|
gpgdata = ""
|
|
|
|
|
for keyfn in gpg_keys:
|
|
|
|
|
if path.exists(keyfn):
|
|
|
|
|
try:
|
|
|
|
|
key = readFile(keyfn)
|
|
|
|
|
gpgdata += key
|
|
|
|
|
gpg.import_key(key)
|
|
|
|
|
except GPGError as e:
|
|
|
|
|
self.printWARNING(_("Failed to load public keys from '%s' "
|
|
|
|
|
"for signature checking") % keyfn)
|
|
|
|
|
self.gpgdata_md5.append(hashlib.md5(gpgdata).hexdigest())
|
|
|
|
|
if len(self.gpgdata_md5) > 1:
|
|
|
|
|
self.gpg_changed = True
|
|
|
|
|
if not gpg.count_public():
|
|
|
|
|
if gpg_force == "force":
|
|
|
|
|
raise UpdateError(_("Public keys for Packages signature checking not found"))
|
|
|
|
|
else:
|
|
|
|
|
return True
|
|
|
|
|
oldgpg = self.clVars.Get('update.cl_update_gpg')
|
|
|
|
|
if oldgpg:
|
|
|
|
|
oldgpg.close()
|
|
|
|
|
self.clVars.Set('update.cl_update_gpg', gpg, force=True)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def download_packages(self, url_binhost, packages_fn, packages_sign_fn, gpg):
|
|
|
|
|
quite_unlink(packages_fn)
|
|
|
|
|
orig_packages = Binhosts.fetch_packages(url_binhost)
|
|
|
|
|
try:
|
|
|
|
|
with writeFile(packages_fn) as f:
|
|
|
|
|
pi = PackagesIndex(orig_packages)
|
|
|
|
|
pi["TTL"] = str(30 * DAYS)
|
|
|
|
|
pi["DOWNLOAD_TIMESTAMP"] = str(int(time.time()))
|
|
|
|
|
pi.write(f)
|
|
|
|
|
with writeFile("/tmp/Packages.org") as f:
|
|
|
|
|
f.write(orig_packages)
|
|
|
|
|
#pi = PackagesIndex(orig_packages)
|
|
|
|
|
#pi.write(f)
|
|
|
|
|
except (OSError, IOError):
|
|
|
|
|
raise UpdateError(_("Failed to save Packages"))
|
|
|
|
|
self.endTask(True)
|
|
|
|
|
self.startTask(_("Check packages index signature"))
|
|
|
|
|
if not gpg:
|
|
|
|
|
self.endTask("skip")
|
|
|
|
|
self.clVars.Set('cl_update_package_cache_set', Variable.Off, force=True)
|
|
|
|
|
return True
|
|
|
|
|
try:
|
|
|
|
|
Binhosts.check_packages_signature(
|
|
|
|
|
url_binhost, orig_packages, gpg)
|
|
|
|
|
with writeFile(packages_sign_fn) as f:
|
|
|
|
|
f.write(Binhosts.fetch_packages_sign(url_binhost))
|
|
|
|
|
except BinhostSignError:
|
|
|
|
|
for fn in (packages_fn, packages_sign_fn):
|
|
|
|
|
if path.exists(fn):
|
|
|
|
|
try:
|
|
|
|
|
os.unlink(fn)
|
|
|
|
|
except OSError:
|
|
|
|
|
pass
|
|
|
|
|
self.clVars.Set("update.cl_update_bad_sign_set", Variable.On)
|
|
|
|
|
self.clVars.Set('update.cl_update_binhost_recheck_set', Variable.On)
|
|
|
|
|
self.clVars.Set('cl_update_package_cache_set', Variable.Off, force=True)
|
|
|
|
|
raise
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
class Reason(object):
|
|
|
|
|
WrongBinhost = "wrong_binhost"
|
|
|
|
|
Outdated = "outdated"
|
|
|
|
|
Updating = "updating"
|
|
|
|
|
BadEnv = "badenv"
|
|
|
|
|
EnvNotFound = "noenv"
|
|
|
|
|
UnknownError = "unknown"
|
|
|
|
|
BadSign = "badsign"
|
|
|
|
|
Skip = "skip"
|
|
|
|
|
SkipSlower = "skipslower"
|
|
|
|
|
Success = "success"
|
|
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
|
def humanReadable(reason):
|
|
|
|
|
return {
|
|
|
|
|
Update.Reason.WrongBinhost: "FAILED (Wrong binhost)",
|
|
|
|
|
Update.Reason.Outdated: "OUTDATED",
|
|
|
|
|
Update.Reason.Updating: "UPDATING",
|
|
|
|
|
Update.Reason.BadEnv: "FAILED (Bad env)",
|
|
|
|
|
Update.Reason.EnvNotFound: "FAILED (Env not found)",
|
|
|
|
|
Update.Reason.UnknownError: "FAILED (Unknown error)",
|
|
|
|
|
Update.Reason.BadSign: "FAILED (Bad sign)",
|
|
|
|
|
Update.Reason.Skip: "SKIP",
|
|
|
|
|
Update.Reason.SkipSlower: "",
|
|
|
|
|
Update.Reason.Success: ""
|
|
|
|
|
}.get(reason,reason)
|
|
|
|
|
|
|
|
|
|
def _get_binhost_logger(self):
|
|
|
|
|
return log("binhost-scan.log",
|
|
|
|
|
filename=pathJoin(
|
|
|
|
|
self.clVars.Get('cl_chroot_path'),
|
|
|
|
|
"/var/log/calculate/binhost-scan.log"),
|
|
|
|
|
formatter="%(message)s")
|
|
|
|
|
|
|
|
|
|
def create_binhost_data(self):
|
|
|
|
|
dv = self.clVars
|
|
|
|
|
last_ts = dv.Get('cl_update_last_timestamp')
|
|
|
|
|
if dv.GetBool('cl_update_binhost_stable_opt_set'):
|
|
|
|
|
binhost_list = dv.Get('cl_update_binhost_list')
|
|
|
|
|
else:
|
|
|
|
|
binhost_list = dv.Get('cl_update_binhost_unstable_list')
|
|
|
|
|
self.binhosts_data = Binhosts(
|
|
|
|
|
dv.GetInteger('cl_update_binhost_timeout'),
|
|
|
|
|
dv.Get('cl_update_binhost_revision_path'),
|
|
|
|
|
dv.Get('cl_update_binhost_timestamp_path'),
|
|
|
|
|
last_ts, binhost_list,
|
|
|
|
|
dv.Get('os_arch_machine'),
|
|
|
|
|
gpg=dv.Get('cl_update_gpg'))
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def _search_best_binhost(self, binhosts_data, stabilization):
|
|
|
|
|
if not self.clVars.Get('cl_ebuild_phase'):
|
|
|
|
|
logger = self._get_binhost_logger()
|
|
|
|
|
if logger:
|
|
|
|
|
logger.info(
|
|
|
|
|
"Started scan on: {date}, current timestamp: {ts}".format(
|
|
|
|
|
date=time.ctime(), ts=binhosts_data.last_ts))
|
|
|
|
|
retval = []
|
|
|
|
|
skip_check_status = False
|
|
|
|
|
for binhost in sorted(binhosts_data.get_binhosts(), reverse=True):
|
|
|
|
|
host = binhost.host
|
|
|
|
|
if not binhost.valid:
|
|
|
|
|
reason = self.Reason.WrongBinhost
|
|
|
|
|
elif binhost.outdated:
|
|
|
|
|
reason = self.Reason.Outdated
|
|
|
|
|
elif not skip_check_status:
|
|
|
|
|
status = binhost.status
|
|
|
|
|
if status is not binhosts_data.BinhostStatus.Success:
|
|
|
|
|
errors = {
|
|
|
|
|
binhosts_data.BinhostStatus.Updating: self.Reason.Updating,
|
|
|
|
|
binhosts_data.BinhostStatus.BadEnv: self.Reason.BadEnv,
|
|
|
|
|
binhosts_data.BinhostStatus.EnvNotFound: self.Reason.EnvNotFound
|
|
|
|
|
}
|
|
|
|
|
reason = errors.get(status, self.Reason.UnknownError)
|
|
|
|
|
elif binhost.bad_sign:
|
|
|
|
|
reason = self.Reason.BadSign
|
|
|
|
|
else:
|
|
|
|
|
# SUCCESS
|
|
|
|
|
if not binhost.downgraded or stabilization:
|
|
|
|
|
host = "-> %s" % host
|
|
|
|
|
reason = self.Reason.Success
|
|
|
|
|
else:
|
|
|
|
|
reason = self.Reason.Skip
|
|
|
|
|
elif binhost.downgraded:
|
|
|
|
|
reason = self.Reason.Skip
|
|
|
|
|
else:
|
|
|
|
|
reason = self.Reason.SkipSlower
|
|
|
|
|
|
|
|
|
|
if reason == self.Reason.Success:
|
|
|
|
|
retval.append([binhost.host, binhost.data,
|
|
|
|
|
str(binhost.timestamp),
|
|
|
|
|
str(binhost.duration)])
|
|
|
|
|
skip_check_status = True
|
|
|
|
|
logger.info("{host:<60} {speed:<7} {timestamp:<10} {reason}".format(
|
|
|
|
|
host=host, speed=float(binhost.duration) / 1000.0,
|
|
|
|
|
timestamp=binhost.timestamp,
|
|
|
|
|
reason=Update.Reason.humanReadable(reason)))
|
|
|
|
|
if not retval:
|
|
|
|
|
raise UpdateError(_("Failed to find the server with appropriate updates"))
|
|
|
|
|
return retval
|
|
|
|
|
|
|
|
|
|
def check_current_binhost(self, binhost_url):
|
|
|
|
|
"""
|
|
|
|
|
Проверка текущего сервера обновлений на валидность
|
|
|
|
|
"""
|
|
|
|
|
if not binhost_url in self.binhosts_data.binhost_list:
|
|
|
|
|
raise UpdateError(_("Current binhost is absent in list of update servers"))
|
|
|
|
|
binhost = self.binhosts_data.get_binhost(binhost_url)
|
|
|
|
|
|
|
|
|
|
if binhost.valid and not binhost.outdated and not binhost.downgraded:
|
|
|
|
|
if binhost.status == self.binhosts_data.BinhostStatus.Success:
|
|
|
|
|
self.clVars.Set('update.cl_update_binhost_data',
|
|
|
|
|
[[binhost.host, binhost.data,
|
|
|
|
|
str(binhost.timestamp),
|
|
|
|
|
str(binhost.duration)]],
|
|
|
|
|
force=True)
|
|
|
|
|
self.endTask()
|
|
|
|
|
else:
|
|
|
|
|
if not binhost.valid:
|
|
|
|
|
raise UpdateError(
|
|
|
|
|
_("Current binhost {} is not valid").format(binhost_url))
|
|
|
|
|
elif binhost.outdated:
|
|
|
|
|
raise UpdateError(
|
|
|
|
|
_("Current binhost {} is outdated").format(binhost_url))
|
|
|
|
|
elif binhost.downgraded:
|
|
|
|
|
raise UpdateError(
|
|
|
|
|
_("Current binhost {} was downgraded").format(binhost_url))
|
|
|
|
|
if self.binhosts_data.gpg:
|
|
|
|
|
packages_fn = self.clVars.Get('cl_update_package_cache')
|
|
|
|
|
packages_sign_fn = self.clVars.Get('cl_update_package_cache_sign')
|
|
|
|
|
if path.exists(packages_fn) and path.exists(packages_sign_fn):
|
|
|
|
|
packages_sign = readFile(packages_sign_fn)
|
|
|
|
|
pi = PackagesIndex(readFile(packages_fn))
|
|
|
|
|
pi.clean()
|
|
|
|
|
try:
|
|
|
|
|
Binhosts.check_packages_signature(
|
|
|
|
|
None, pi.get_value(), self.binhosts_data.gpg,
|
|
|
|
|
sign=packages_sign)
|
|
|
|
|
except BinhostSignError:
|
|
|
|
|
for fn in (packages_fn, packages_sign_fn):
|
|
|
|
|
if path.exists(fn):
|
|
|
|
|
try:
|
|
|
|
|
os.unlink(fn)
|
|
|
|
|
except OSError:
|
|
|
|
|
pass
|
|
|
|
|
raise UpdateError(
|
|
|
|
|
_("Current binhost {} has wrong signature").format(
|
|
|
|
|
binhost_url))
|
|
|
|
|
else:
|
|
|
|
|
if binhost.bad_sign:
|
|
|
|
|
raise UpdateError(
|
|
|
|
|
_("Current binhost {} has wrong signature").format(
|
|
|
|
|
binhost_url))
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def detect_best_binhost(self):
|
|
|
|
|
# выполняется переход с серверов unstable обновлней на stable
|
|
|
|
|
# в этом случае не важно, что бинари могут старее текущих
|
|
|
|
|
if (self.clVars.GetBool('cl_update_binhost_stable_opt_set') and
|
|
|
|
|
not self.clVars.GetBool('cl_update_binhost_stable_set')):
|
|
|
|
|
stabilization = True
|
|
|
|
|
else:
|
|
|
|
|
stabilization = False
|
|
|
|
|
|
|
|
|
|
self.startTask("Searching new binhost")
|
|
|
|
|
retval = self._search_best_binhost(self.binhosts_data, stabilization)
|
|
|
|
|
|
|
|
|
|
self.clVars.Set('update.cl_update_binhost_data',
|
|
|
|
|
retval or Variable.EmptyTable, force=True)
|
|
|
|
|
|
|
|
|
|
self.endTask()
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def check_sign_change(self):
|
|
|
|
|
if self.gpg_changed:
|
|
|
|
|
self.printWARNING(_("Public GPG key was updated"))
|
|
|
|
|
self.gpg_changed = False
|
|
|
|
|
self.clVars.Set('update.cl_update_outdate_set', Variable.On, force=True)
|
|
|
|
|
return True
|
|
|
|
|
return False
|
|
|
|
|