diff --git a/backend/SystemUpdater/backend/__init__.py b/backend/SystemUpdater/backend/__init__.py index 42051c4..cf61d27 100644 --- a/backend/SystemUpdater/backend/__init__.py +++ b/backend/SystemUpdater/backend/__init__.py @@ -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): #后端的状态 到空闲状态 diff --git a/backend/data/system-updater.conf b/backend/data/system-updater.conf index 0b9c838..07c8b14 100644 --- a/backend/data/system-updater.conf +++ b/backend/data/system-updater.conf @@ -7,6 +7,7 @@ isclosefilter = False [ConfigPkgStatus] check_selfupgrade = True +check_resover_remove = True [InstallMode] shutdown_install = True