加入强制降级系统软件包版本的模式
This commit is contained in:
parent
4d4111b6b0
commit
9c0507adcd
|
@ -276,7 +276,7 @@ class UpdateList():
|
|||
except Exception as e:
|
||||
logging.error(e)
|
||||
|
||||
def _split_package_id(package):
|
||||
def _split_package_id(self,package):
|
||||
"""Return the name, the version number and the release of the
|
||||
specified package."""
|
||||
if "=" in package:
|
||||
|
@ -290,68 +290,56 @@ class UpdateList():
|
|||
version = release = None
|
||||
return name, version, release
|
||||
|
||||
def _mark_packages_for_downgrade(self, packages, resolver):
|
||||
"""Mark packages for downgrade."""
|
||||
for pkg_name, pkg_ver, pkg_rel in [self._split_package_id(pkg)
|
||||
for pkg in packages]:
|
||||
try:
|
||||
pkg = self.cache[pkg_name]
|
||||
except KeyError:
|
||||
pass
|
||||
# raise TransactionFailed(ERROR_NO_PACKAGE,
|
||||
# _("Package %s isn't available"),
|
||||
# pkg_name)
|
||||
if not pkg.is_installed:
|
||||
pass
|
||||
# raise TransactionFailed(ERROR_PACKAGE_NOT_INSTALLED,
|
||||
# _("Package %s isn't installed"),
|
||||
# pkg_name)
|
||||
auto = pkg.is_auto_installed
|
||||
|
||||
if pkg_ver:
|
||||
if pkg.installed and pkg.installed.version < pkg_ver:
|
||||
pass
|
||||
# FIXME: We need a new error enum
|
||||
# raise TransactionFailed(ERROR_NO_PACKAGE,
|
||||
# _("The former version %s of %s "
|
||||
# "is already installed"),
|
||||
# pkg.installed.version, pkg.name)
|
||||
elif pkg.installed and pkg.installed.version == pkg_ver:
|
||||
pass
|
||||
# raise TransactionFailed(ERROR_PACKAGE_ALREADY_INSTALLED,
|
||||
# _("The version %s of %s "
|
||||
# "is already installed"),
|
||||
# pkg.installed.version, pkg.name)
|
||||
try:
|
||||
pkg.candidate = pkg.versions[pkg_ver]
|
||||
except KeyError:
|
||||
pass
|
||||
# raise TransactionFailed(ERROR_NO_PACKAGE,
|
||||
# _("The version %s of %s isn't "
|
||||
# "available"), pkg_ver, pkg_name)
|
||||
else:
|
||||
pass
|
||||
# raise TransactionFailed(ERROR_NO_PACKAGE,
|
||||
# _("You need to specify a version to "
|
||||
# "downgrade %s to"),
|
||||
# pkg_name)
|
||||
|
||||
# pkg.mark_install(False, False, True)
|
||||
# pkg.mark_auto(auto)
|
||||
# resolver.clear(pkg)
|
||||
# resolver.protect(pkg)
|
||||
|
||||
def _make_downgrade(self,cache,data):
|
||||
downgrade_pkgs = data["force_downgrade"]
|
||||
def _make_downgrade(self,cache,downgrade_pkgs):
|
||||
output_downgrade = []
|
||||
adjust_pkgs = []
|
||||
for pkg_name, pkg_ver, pkg_rel in [self._split_package_id(pkg)
|
||||
for pkg in downgrade_pkgs]:
|
||||
try:
|
||||
pkg = cache[pkg_name]
|
||||
except KeyError:
|
||||
logging.warning("Package %s isn't available",pkg_name)
|
||||
continue
|
||||
if not pkg.is_installed:
|
||||
logging.warning("Package %s isn't installed",pkg_name)
|
||||
pass
|
||||
|
||||
if pkg_ver:
|
||||
if pkg.installed and pkg.installed.version < pkg_ver:
|
||||
logging.warning("The former version %s of %s is already installed",pkg.installed.version, pkg.name)
|
||||
continue
|
||||
elif pkg.installed and pkg.installed.version == pkg_ver:
|
||||
logging.warning("The version %s of %s is already installed",pkg.installed.version, pkg.name)
|
||||
continue
|
||||
|
||||
try:
|
||||
pkg.candidate = pkg.versions[pkg_ver]
|
||||
except KeyError:
|
||||
logging.warning("The version %s of %s isn't available",pkg_ver, pkg_name)
|
||||
continue
|
||||
|
||||
output_downgrade.append(pkg_name)
|
||||
adjust_pkgs.append(pkg_name+'='+pkg_ver)
|
||||
|
||||
return output_downgrade,adjust_pkgs
|
||||
|
||||
def _get_downgrade_list(self,cache,data):
|
||||
downgrade_pkgs = []
|
||||
|
||||
try:
|
||||
downgrade_raw = data['force_downgrade']
|
||||
except Exception as e:
|
||||
downgrade_raw = []
|
||||
|
||||
for pkg_name, pkg_ver, pkg_rel in [self._split_package_id(pkg)
|
||||
for pkg in downgrade_raw]:
|
||||
|
||||
if pkg_name in cache:
|
||||
downgrade_pkgs.append(pkg_name)
|
||||
else:
|
||||
logging.warning("Package %s isn't available",pkg_name)
|
||||
continue
|
||||
|
||||
return downgrade_raw,downgrade_pkgs
|
||||
|
||||
def _make_groups_upgrade(self,cache,group_list, pkgs_upgrade = []):
|
||||
try:
|
||||
|
@ -385,17 +373,34 @@ class UpdateList():
|
|||
if not group_name in group_list:
|
||||
continue
|
||||
upgrade_pkgs_list = data['upgrade_list']
|
||||
|
||||
#检查包是否在cache中 以及是否已经安装 没有安装的话才添加到列表
|
||||
new_install_list = self._check_pkg_in_cache(cache,data['install_list'])
|
||||
|
||||
downgrade_raw,downgrade_pkgs = self._get_downgrade_list(cache,data)
|
||||
#被降级的软件包优先级最高
|
||||
for pkg in downgrade_pkgs:
|
||||
if pkg in upgrade_pkgs_list:
|
||||
upgrade_pkgs_list.remove(pkg)
|
||||
if pkg in new_install_list:
|
||||
new_install_list.remove(pkg)
|
||||
if pkg in self.upgrade_meta.single_pkgs:
|
||||
self.upgrade_meta.single_pkgs.remove(pkg)
|
||||
|
||||
#进行交集 升级列表
|
||||
new_upgrade_list = list(set(pkgs_upgrade) & set(upgrade_pkgs_list))
|
||||
|
||||
#进行源过滤
|
||||
new_install_list,new_upgrade_list,adjust_pkgs = self._make_fiter_origin([cache[pkg] for pkg in new_install_list + new_upgrade_list],False)
|
||||
|
||||
self.upgrade_meta.adjust_pkgs.extend(adjust_pkgs)
|
||||
|
||||
#在总升级列表中移除这些包
|
||||
for pkg in new_upgrade_list:
|
||||
pkgs_upgrade.remove(pkg)
|
||||
|
||||
downgrade_pkg,adjust_pkgs = self._make_downgrade(cache,downgrade_raw)
|
||||
self.upgrade_meta.adjust_pkgs.extend(adjust_pkgs)
|
||||
new_upgrade_list.extend(downgrade_pkg)
|
||||
|
||||
#单包的优先级最高 从组中剔除此包
|
||||
for pkg in self.upgrade_meta.single_pkgs:
|
||||
if pkg in new_install_list:
|
||||
|
@ -404,9 +409,7 @@ class UpdateList():
|
|||
#判断当前是否可升级或者新装的包
|
||||
if len(new_install_list) == 0 and len(new_upgrade_list) == 0:
|
||||
continue
|
||||
#在总升级列表中移除这些包
|
||||
for pkg in new_upgrade_list:
|
||||
pkgs_upgrade.remove(pkg)
|
||||
|
||||
#3、生成升级的包列表JSON
|
||||
upgrade_pkgs_json = self._make_pkg_info_json(cache,new_upgrade_list)
|
||||
#2、生成安装的软件列表
|
||||
|
|
|
@ -36,6 +36,7 @@ class UpdateManager():
|
|||
BACKEND_PKG_NAME = 'kylin-system-updater'
|
||||
FRONTEND_PKG_NAME = "kylin-update-frontend"
|
||||
GROUPS_PKG_NAME = 'kylin-update-desktop-config'
|
||||
SOURCES_UPDATE_NAME = "kylin-software-properties"
|
||||
APTD_PKG_NAME = "aptdaemon"
|
||||
RUN_UNATTENDED_UPGRADE = '/var/run/unattended-upgrades.pid'
|
||||
RETRY_LIMIT_NUM = 2
|
||||
|
|
|
@ -158,13 +158,13 @@ class InstallBackendAptdaemon(InstallBackend):
|
|||
raise
|
||||
|
||||
@inline_callbacks
|
||||
def commit(self,model,pkgs_install, pkgs_upgrade, pkgs_remove,pkgs_purge = []):
|
||||
def commit(self,model,pkgs_install, pkgs_upgrade, pkgs_remove,pkgs_downgrade = []):
|
||||
"""Commit a list of package adds and removes"""
|
||||
try:
|
||||
reinstall = downgrade = []
|
||||
reinstall = purge = []
|
||||
trans = yield self.client.commit_packages(
|
||||
pkgs_install, reinstall, pkgs_remove, purge = pkgs_purge, upgrade = pkgs_upgrade,
|
||||
downgrade = downgrade,download = model, defer=True)
|
||||
pkgs_install, reinstall, pkgs_remove, purge = purge, upgrade = pkgs_upgrade,
|
||||
downgrade = pkgs_downgrade,download = model, defer=True)
|
||||
self.window_main.dbusController.transaction = trans
|
||||
|
||||
yield self._show_transaction(trans, self.action,
|
||||
|
|
|
@ -148,8 +148,9 @@ class InstallBackend():
|
|||
#拿到升级列表
|
||||
self.now_upgrade.make_upgrade_content(partial_upgrade_list)
|
||||
|
||||
pkgs_install,pkgs_upgrade,pkgs_remove = self._get_mark_from_cache(self.cache,self.upgrade_data.adjust_pkgs,self.action_mode)
|
||||
logging.info("INSTALL install:%d , upgrade:%d remove:%d",len(pkgs_install),len(pkgs_upgrade),len(pkgs_remove))
|
||||
pkgs_install,pkgs_upgrade,pkgs_remove,pkgs_downgrade = self._get_mark_from_cache(self.cache,self.upgrade_data.adjust_pkgs,self.action_mode)
|
||||
logging.info("INSTALL install:%d , upgrade:%d remove:%d pkgs_downgrade:%d",len(pkgs_install),\
|
||||
len(pkgs_upgrade),len(pkgs_remove),len(pkgs_downgrade))
|
||||
|
||||
#当下载数量大于200个包时 就认为属于大版本升级 开启重试机制
|
||||
if len(pkgs_install) + len(pkgs_upgrade) > 100:
|
||||
|
@ -157,7 +158,7 @@ class InstallBackend():
|
|||
self.now_upgrade.version_upgrade = True
|
||||
|
||||
#检查是否存在可升级的包
|
||||
if len(pkgs_install) == 0 and len(pkgs_upgrade) == 0 and len(pkgs_remove) == 0:
|
||||
if len(pkgs_install) == 0 and len(pkgs_upgrade) == 0 and len(pkgs_remove) == 0 and len(pkgs_downgrade) == 0:
|
||||
raise UpdateBaseError(ERROR_NOT_UPGRADE_PACKAGES)
|
||||
|
||||
# if self.action_mode == self.MODE_INSTALL_SINGLE:
|
||||
|
@ -172,10 +173,10 @@ class InstallBackend():
|
|||
self.window_main.collector.Upgrade_Process_Msg(self.action, {"appname":ul})
|
||||
|
||||
if self.action == self.ACTION_INSTALL:
|
||||
self.commit(self.action,pkgs_install, pkgs_upgrade, pkgs_remove)
|
||||
self.commit(self.action,pkgs_install, pkgs_upgrade, pkgs_remove,pkgs_downgrade)
|
||||
elif self.action == self.ACTION_DOWNLOADONLY:
|
||||
self._update_to_config(self.now_upgrade,pkgs_install,pkgs_upgrade,pkgs_remove)
|
||||
self.commit(self.action,pkgs_install, pkgs_upgrade, pkgs_remove)
|
||||
self.commit(self.action,pkgs_install, pkgs_upgrade, pkgs_remove,pkgs_downgrade)
|
||||
|
||||
elif self.action == self.ACTION_INSTALL_SHUTDOWN:
|
||||
self.now_upgrade,pkgs_install,pkgs_upgrade,pkgs_remove = self._config_to_upgrade()
|
||||
|
@ -202,8 +203,8 @@ class InstallBackend():
|
|||
#获取要升级和安装的包列表
|
||||
pkgs_install,pkgs_upgrade = self._make_pkgs_list(self.cache,self.upgrade_data.groups_pkgs,self.now_upgrade.upgrade_groups,self.now_upgrade.single_pkgs)
|
||||
#计算解决依赖关系
|
||||
delete_pkgs,delete_desc = self._make_problem_resolver(self.cache,pkgs_install,pkgs_upgrade)
|
||||
pkgs_install,pkgs_upgrade,pkgs_remove = self._get_mark_from_cache(self.cache,self.upgrade_data.adjust_pkgs,self.action_mode)
|
||||
delete_pkgs,delete_desc = self._make_problem_resolver(self.cache,pkgs_install,pkgs_upgrade,self.upgrade_data.adjust_pkgs)
|
||||
pkgs_install,pkgs_upgrade,pkgs_remove,pkgs_downgrade = self._get_mark_from_cache(self.cache,self.upgrade_data.adjust_pkgs,self.action_mode)
|
||||
|
||||
if len(pkgs_remove) != len(delete_pkgs):
|
||||
logging.warning("Simulation of the deletion package list:%s",str(delete_pkgs))
|
||||
|
@ -220,13 +221,14 @@ class InstallBackend():
|
|||
except Exception as e:
|
||||
logging.error(str(e))
|
||||
raise UpdateBaseError(ERROR_RESOLVER_FAILED,desc= str(e))
|
||||
pkgs_install,pkgs_upgrade,pkgs_remove = self._get_mark_from_cache(self.cache,self.upgrade_data.adjust_pkgs,self.action_mode)
|
||||
pkgs_install,pkgs_upgrade,pkgs_remove,pkgs_downgrade = self._get_mark_from_cache(self.cache,self.upgrade_data.adjust_pkgs,self.action_mode)
|
||||
|
||||
self.window_main.collector.Generate_Msg(self.now_upgrade.upgrade_groups+self.now_upgrade.single_pkgs, self.action_mode)
|
||||
for ul in self.window_main.collector.upgrade_list:
|
||||
self.window_main.collector.Upgrade_Process_Msg(self.action, {"appname":ul})
|
||||
|
||||
logging.info("RESOLVER install:%d , upgrade:%d remove:%d",len(pkgs_install),len(pkgs_upgrade),len(pkgs_remove))
|
||||
logging.info("RESOLVER install:%d , upgrade:%d remove:%d pkgs_downgrade:%d",len(pkgs_install),len(pkgs_upgrade),\
|
||||
len(pkgs_remove),len(pkgs_downgrade))
|
||||
is_remove_pkgs = len(pkgs_remove) != 0
|
||||
|
||||
#添加关于删除包的描述信息
|
||||
|
@ -292,7 +294,7 @@ class InstallBackend():
|
|||
"""Remove all downloaded files.t"""
|
||||
raise NotImplementedError
|
||||
|
||||
def commit(self,model,pkgs_install, pkgs_upgrade, pkgs_remove,pkgs_purge = []):
|
||||
def commit(self,model,pkgs_install, pkgs_upgrade, pkgs_remove,pkgs_downgrade = []):
|
||||
"""Commit the cache changes """
|
||||
raise NotImplementedError
|
||||
|
||||
|
@ -317,6 +319,7 @@ class InstallBackend():
|
|||
pkgs_install = []
|
||||
pkgs_upgrade = []
|
||||
pkgs_remove = []
|
||||
pkgs_downgrade = []
|
||||
|
||||
#全盘升级不做任何的调整
|
||||
if upgrade_mode == self.MODE_INSTALL_SYSTEM or upgrade_mode == self.MODE_INSTALL_SINGLE:
|
||||
|
@ -342,9 +345,11 @@ class InstallBackend():
|
|||
pkgs_upgrade.append(pkg.name)
|
||||
elif pkg.marked_delete:
|
||||
pkgs_remove.append(pkg.name)
|
||||
elif pkg.marked_downgrade:
|
||||
pkgs_downgrade.append(pkg.name+'='+pkg.candidate.source_version)
|
||||
except KeyError:
|
||||
pass
|
||||
return pkgs_install,pkgs_upgrade,pkgs_remove
|
||||
return pkgs_install,pkgs_upgrade,pkgs_remove,pkgs_downgrade
|
||||
|
||||
#获取当前升级的升级列表
|
||||
def _make_groups_list(self,upgrade_data,_upgrade_mode,partial_upgrade_list):
|
||||
|
@ -417,13 +422,26 @@ class InstallBackend():
|
|||
pass
|
||||
return all_deps
|
||||
|
||||
def _split_package_id(self,package):
|
||||
"""Return the name, the version number and the release of the
|
||||
specified package."""
|
||||
if "=" in package:
|
||||
name, version = package.split("=", 1)
|
||||
release = None
|
||||
elif "/" in package:
|
||||
name, release = package.split("/", 1)
|
||||
version = None
|
||||
else:
|
||||
name = package
|
||||
version = release = None
|
||||
return name, version, release
|
||||
|
||||
#将获取本次升级的包 进行计算依赖关系 解决依赖问题
|
||||
def _make_problem_resolver(self,cache,pkgs_install = [],pkgs_upgrade = []):
|
||||
def _make_problem_resolver(self,cache,pkgs_install = [],pkgs_upgrade = [],adjust_pkgs = []):
|
||||
last_broken_count = 0
|
||||
#计算出来的需要删除的包列表
|
||||
delete_pkgs = []
|
||||
delete_desc = []
|
||||
fresh_cache = Cache()
|
||||
try:
|
||||
logging.info("ProblemResolver install:%d , upgrade:%d",len(pkgs_install),len(pkgs_upgrade))
|
||||
logging.info("Start calculating dependencies...")
|
||||
|
@ -433,12 +451,21 @@ class InstallBackend():
|
|||
if cache.get_changes():
|
||||
cache.clear()
|
||||
resolver = apt.cache.ProblemResolver(cache)
|
||||
#调整候选版本强制更改版本
|
||||
for pkg_name, pkg_ver, pkg_rel in [self._split_package_id(pkg)
|
||||
for pkg in adjust_pkgs]:
|
||||
try:
|
||||
pkg = cache[pkg_name]
|
||||
pkg.candidate = pkg.versions[pkg_ver]
|
||||
except KeyError:
|
||||
logging.warning("The version %s of %s isn't available",pkg_ver, pkg_name)
|
||||
continue
|
||||
|
||||
#标记计算所有需要安装的
|
||||
for pkg in pkgs_upgrade + pkgs_install:
|
||||
|
||||
pkg_cache = cache[pkg]
|
||||
#将第二个参数调整为False 当为True时就不能检查缺少依赖的包 默认自动移除掉了
|
||||
#将第二个参数调整为False 当为True时就不能检查缺少依赖的包 默认自动移除掉了
|
||||
pkg_cache.mark_install(False, False, True)
|
||||
|
||||
#将可自动升级的标记为自动安装
|
||||
|
@ -452,6 +479,7 @@ class InstallBackend():
|
|||
if cache._depcache.broken_count != last_broken_count and \
|
||||
self.window_main.configs_cover.getWithDefault("ConfigPkgStatus", "check_resover_remove", False) == True:
|
||||
last_broken_count = cache._depcache.broken_count
|
||||
fresh_cache = Cache()
|
||||
tmp_pkgs,tmp_desc = self._emulate_calcul_delete(pkg,fresh_cache)
|
||||
delete_pkgs.extend(tmp_pkgs)
|
||||
delete_desc.extend(tmp_desc)
|
||||
|
|
Loading…
Reference in New Issue