优化依赖计算器的计算方法 从单包计算升级到整体软件包的标记计算,以及在这个过程中模拟计算删除的描述信息

This commit is contained in:
wangsong 2022-04-22 15:23:54 +08:00
parent e8e6345190
commit c8ae83dbdf
2 changed files with 88 additions and 58 deletions

View File

@ -7,7 +7,7 @@ import logging
import os
from gettext import gettext as _
import apt
import apt,apt_pkg
from SystemUpdater.Core.utils import (
unLockedEnableShutdown,
check_free_space,
@ -184,7 +184,15 @@ class InstallBackend():
#计算解决依赖关系
_success,delete_pkgs,delete_desc,header,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)
pkgs_remove = delete_pkgs
if len(pkgs_remove) != len(delete_pkgs):
logging.warning("Simulation of the deletion package list:%s",str(delete_pkgs))
logging.warning("ProblemResolver of the deletion package list:%s",str(pkgs_remove))
#删除描述设备为空
delete_desc = []
else:
pkgs_remove = delete_pkgs
else:
# 使用全盘升级 全盘使用dist-upgrade
try:
@ -202,16 +210,17 @@ class InstallBackend():
#添加关于删除包的描述信息
for pkg in pkgs_remove:
#当属于全盘升级时 删除的原因全部写为空格
if self.action_mode == self.MODE_INSTALL_SYSTEM:
delete_desc.append(' ')
pkg_obj = self.cache[pkg]
app = self.window_main.update_list._get_application_for_package(pkg_obj)
if app is not None:
raw_description.append(app.get_display_name())
else:
raw_description.append(getattr(pkg_obj.candidate, "summary", ''))
#补充删除描述
if pkgs_remove != [] and delete_desc == []:
for pkg in pkgs_remove:
delete_desc.append("依赖计算器计算结果")
#解锁后端状态
self.window_main.is_working = self.ACTION_DEFUALT_STATUS
@ -354,22 +363,29 @@ class InstallBackend():
logging.error(str(e))
return [],[]
#计算升级或者安装这个包 是否存在需要卸载某个包
def _make_delete_pkgs(self,cache,all_delete_pkgs):
deleted_pkgs = []
try:
for pkg_obj in cache.get_changes():
if pkg_obj.marked_delete:
if pkg_obj.name in all_delete_pkgs:
continue
else:
deleted_pkgs.append(pkg_obj.name)
all_delete_pkgs.append(pkg_obj.name)
return deleted_pkgs
except Exception as e:
logging.error(str(e))
return []
def _installed_dependencies(self, pkg_name, all_deps=None):
"""Recursively return all installed dependencies of a given package."""
# FIXME: Should be part of python-apt, since it makes use of non-public
# API. Perhaps by adding a recursive argument to
# apt.package.Version.get_dependencies()
if not all_deps:
all_deps = set()
if pkg_name not in self.cache:
return all_deps
cur = self.cache[pkg_name]._pkg.current_ver
if not cur:
return all_deps
for sec in ("PreDepends", "Depends", "Recommends"):
try:
for dep in cur.depends_list[sec]:
dep_name = dep[0].target_pkg.name
if dep_name not in all_deps:
all_deps.add(dep_name)
all_deps |= self._installed_dependencies(dep_name,
all_deps)
except KeyError:
pass
return all_deps
#将获取本次升级的包 进行计算依赖关系 解决依赖问题
def _make_problem_resolver(self,cache,pkgs_install = [],pkgs_upgrade = []):
@ -377,9 +393,14 @@ class InstallBackend():
header = ''
desc = ''
del_exception = False
#记录出现异常的包
exception_pkg = ''
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...")
@ -390,48 +411,30 @@ class InstallBackend():
cache.clear()
resolver = apt.cache.ProblemResolver(cache)
#计算出来的需要删除的包列表
all_delete_pkgs = []
all_delete_desc = []
#标记计算所有需要安装的
for pkg in pkgs_upgrade + pkgs_install:
exception_pkg = pkg
pkg_cache = cache[pkg]
pkg_cache.mark_install()
pkg_cache.mark_install(False, True, True)
#将可自动升级的标记为自动安装
if pkg_cache.is_upgradable == True:
auto = pkg_cache.is_auto_installed
pkg_cache.mark_auto(auto)
resolver.clear(pkg_cache)
resolver.protect(pkg_cache)
# 计算标记计算安装和升级的包 状态没有发生变化 说明存在问题 重新进行计算
#此处处理为了避免mark_install(True,False,True) 和 mark_install(True,True,True) 两种出现的存在依赖问题的包不能提示异常
if pkg_cache.marked_upgrade == False and pkg_cache.marked_install == False:
logging.warning("Problems calculating %s package dependencies and Recalculate...",pkg)
pkg_cache.mark_install(True,False,True)
resolver.clear(pkg_cache)
resolver.protect(pkg_cache)
# 一般在上面就会直接异常退出了 走异常处理了出现依赖错误问题,其他当计算后还是存在相等的问题 就单提出错误 继续之后动作 记录这个包
if pkg_cache.marked_upgrade == False and pkg_cache.marked_install == False:
logging.error("Error: Problems calculating %s package dependencies...",pkg)
#计算删除包的描述
wouldDelete = cache._depcache.del_count
if del_exception == False and wouldDelete > len(all_delete_pkgs):
deleted_pkgs = self._make_delete_pkgs(cache,all_delete_pkgs)
if deleted_pkgs == []:
del_exception == True
else:
for d_pkg in deleted_pkgs:
delete_desc = str(d_pkg) + _(" Will be deleted Due to Install or Upgrade ") + str(pkg)
all_delete_desc.append(delete_desc)
logging.warning(delete_desc)
#出现破损的原因有 升级一个包需要安装其他的包或者需要删除其他的软件包
if cache._depcache.broken_count != last_broken_count and \
self.window_main.configs.getWithDefault("ConfigPkgStatus", "check_resover_remove", False) == True:
last_broken_count = cache._depcache.broken_count
tmp_pkgs,tmp_desc = self._emulate_calcul_delete(pkg,fresh_cache)
delete_pkgs.extend(tmp_pkgs)
delete_desc.extend(tmp_desc)
resolver.resolve()
return _success,all_delete_pkgs,all_delete_desc,header,desc
return _success,delete_pkgs,delete_desc,header,desc
except Exception as e:
_success = False
header = _("Could not calculate the upgrade")
@ -444,7 +447,33 @@ class InstallBackend():
desc ='\n' + msg
logging.error('\n' + msg)
return _success,[],[],header,desc
def _emulate_calcul_delete(self,pkg,cache):
try:
deleted_pkgs = []
delete_desc = []
fresh_cache = cache
fresh_cache.clear()
fresh_pkg = fresh_cache[pkg]
fresh_pkg.mark_install(True,True,True)
wouldDelete = fresh_cache._depcache.del_count
if wouldDelete > 0:
for pkg_obj in cache.get_changes():
if pkg_obj.marked_delete:
deleted_pkgs.append(pkg_obj.name)
for d_pkg in deleted_pkgs:
tmp_desc = str(d_pkg) + _(" Will be deleted Due to Install or Upgrade ") + str(pkg)
delete_desc.append(tmp_desc)
logging.warning(tmp_desc)
return deleted_pkgs,delete_desc
except Exception as e:
logging.error("Package("+pkg+") "+ str(e))
return [],[]
#调用aptdeamon结束之后处理的地方 不管是出错还是正常都在此处理
def _action_done(self, action, is_cancelled,success, error_string,error_desc):
#后端的状态 到空闲状态

View File

@ -7,6 +7,7 @@ isclosefilter = False
[ConfigPkgStatus]
check_selfupgrade = True
check_resover_remove = True
[InstallMode]
shutdown_install = True