def toggle_from_items(self, items): self.setBusy(True) actiongroup = apt_pkg.ActionGroup(self.cache._depcache) # Deselect all updates if any are selected keep_packages = any([item.is_selected() for item in items]) for item in items: try: if keep_packages: item.pkg.mark_keep() elif item.pkg.name not in self.list.held_back: if not item.to_remove: item.pkg.mark_install() else: item.pkg.mark_delete() except SystemError: pass # check if we left breakage if self.cache._depcache.broken_count: Fix = apt_pkg.ProblemResolver(self.cache._depcache) Fix.resolve_by_keep() self.updates_changed() self.treeview_update.queue_draw() del actiongroup self.setBusy(False)
def checkbox_changed(self): # item is either a apt.package.Package or a str (for the headers) pkg = self.checkbox_tree_updates.getCurrent() descr = "" if hasattr(pkg, "name"): need_refresh = False name = pkg.name if self.options.show_description: descr = getattr(pkg.candidate, "description", None) else: descr = self.get_news_and_changelog(pkg) # check if it is a wanted package selected = self.checkbox_tree_updates.getEntryValue(pkg)[1] marked_install_upgrade = pkg.marked_install or pkg.marked_upgrade if not selected and marked_install_upgrade: need_refresh = True pkg.mark_keep() if selected and not marked_install_upgrade: if not (name in self.list.held_back): # FIXME: properly deal with "fromUser" here need_refresh = True pkg.mark_install() # fixup any problems if self.cache._depcache.broken_count: need_refresh = True Fix = apt_pkg.ProblemResolver(self.cache._depcache) Fix.resolve_by_keep() # update the list UI to reflect the cache state if need_refresh: self.updateSelectionStates() self.textview_changes.setText(descr) self.updateUI()
def _restore_package_selection_in_cache(self, statefile, cache, protect_installed=False): # reinstall packages missing = set() pkgs = set() # procted installed pkgs resolver = apt_pkg.ProblemResolver(cache._depcache) if protect_installed: for pkg in cache: if pkg.is_installed: resolver.protect(pkg._pkg) # get the installed.pkgs data with tarfile.open(statefile) as tar: f = tar.extractfile(self.TARPREFIX + "var/lib/apt-clone/installed.pkgs") # the actiongroup will help libapt to speed up the following loop with cache.actiongroup(): for line in f.readlines(): line = line.strip().decode('utf-8') if line.startswith("#") or line == "": continue (name, version, auto) = line.split() pkgs.add(name) auto_installed = int(auto) from_user = not auto_installed if name in cache: try: # special mode, most useful for release-upgrades if protect_installed: cache[name].mark_install(from_user=from_user, auto_fix=False) if cache.broken_count > 0: resolver.resolve() if not cache[name].marked_install: raise SystemError( "pkg %s not marked upgrade" % name) else: # normal mode, this assume the system is consistent cache[name].mark_install(from_user=from_user) except SystemError as e: logging.warning("can't add %s (%s)" % (name, e)) missing.add(name) # ensure the auto install info is cache[name].mark_auto(auto_installed) # check what is broken and try to fix if cache.broken_count > 0: resolver.resolve() # now go over and see what is missing for pkg in pkgs: if not pkg in cache: missing.add(pkg) continue if not (cache[pkg].is_installed or cache[pkg].marked_install): missing.add(pkg) return missing
def main(): apt_pkg.init() cache = apt_pkg.Cache() depcache = apt_pkg.DepCache(cache) depcache.init() i = 0 all = cache.package_count print "Running DepCache test on all packages" print "(trying to install each and then mark it keep again):" # first, get all pkgs for pkg in cache.packages: i += 1 x = pkg.name # then get each version ver = depcache.get_candidate_ver(pkg) if ver is not None: depcache.mark_install(pkg) if depcache.broken_count > 0: fixer = apt_pkg.ProblemResolver(depcache) fixer.clear(pkg) fixer.protect(pkg) # we first try to resolve the problem # with the package that should be installed # protected try: fixer.resolve(True) except SystemError: # the pkg seems to be broken, the # returns a exception fixer.clear(pkg) fixer.resolve(True) if not depcache.marked_install(pkg): print "broken in archive: %s " % pkg.name fixer = None if depcache.inst_count == 0: if depcache.is_upgradable(pkg): print "Error marking %s for install" % x for p in cache.packages: if depcache.marked_install(p) or depcache.marked_upgrade(p): depcache.mark_keep(p) if depcache.inst_count != 0: print "Error undoing the selection for %s" % x print "\r%i/%i=%.3f%% " % (i, all, (float(i) / float(all) * 100)), print print "Trying upgrade:" depcache.upgrade() print "To install: %s " % depcache.inst_count print "To remove: %s " % depcache.del_count print "Kept back: %s " % depcache.keep_count print "Trying DistUpgrade:" depcache.upgrade(True) print "To install: %s " % depcache.inst_count print "To remove: %s " % depcache.del_count print "Kept back: %s " % depcache.keep_count
def _preprocess_package_changes(self): version_changes = self._version_installs[:] version_changes.extend(self._version_removals) if (not version_changes and not self._global_upgrade): return [] already_broken_packages = self._get_broken_packages() fixer = apt_pkg.ProblemResolver(self._cache._depcache) self._preprocess_installs(fixer) self._preprocess_global_upgrade() self._preprocess_removes(fixer) self._resolve_broken_packages(fixer, already_broken_packages) return version_changes
def change_status(self, id, reason): """ Keeps a package, and tries to fix eventual problems. """ with self.cache.actiongroup(): self.cache.cache_pre_change() package = self.id_with_packages[id][0] # Change status if reason == "keep": self.cache._depcache.mark_keep(package._pkg) elif reason == "remove": self.cache._depcache.mark_delete(package._pkg) elif reason in ("install", "downgrade", "upgrade"): auto = package.is_auto_installed self.cache._depcache.mark_install( package._pkg, True, True, ) package.mark_auto(auto) # Fix eventual problems if self.cache._depcache.broken_count > 0: fixer = apt_pkg.ProblemResolver(self.cache._depcache) fixer.clear(package._pkg) fixer.protect(package._pkg) try: if reason == "keep": fixer.resolve_by_keep() else: # FIXME: What if a new package is marked? self.cache._depcache.fix_broken() fixer.resolve(True) except SystemError: # Unable to resolve. # This sucks, but we have nothing to do except reloading # the previous state. self.restore_working_state(package, reason) finally: # Clear state again fixer.clear(package._pkg) self.cache.cache_post_change()
def mark_delete(self, auto_fix=True, purge=False): """Mark a package for deletion. If *auto_fix* is ``True``, the resolver will be run, trying to fix broken packages. This is the default. If *purge* is ``True``, remove the configuration files of the package as well. The default is to keep the configuration. """ self._pcache.cache_pre_change() self._pcache._depcache.mark_delete(self._pkg, purge) # try to fix broken stuffsta if auto_fix and self._pcache._depcache.broken_count > 0: fix = apt_pkg.ProblemResolver(self._pcache._depcache) fix.clear(self._pkg) fix.protect(self._pkg) fix.remove(self._pkg) fix.install_protect() fix.resolve() self._pcache.cache_post_change()
def mark_install(self, auto_fix=True, auto_inst=True, from_user=True): """Mark a package for install. If *autoFix* is ``True``, the resolver will be run, trying to fix broken packages. This is the default. If *autoInst* is ``True``, the dependencies of the packages will be installed automatically. This is the default. If *fromUser* is ``True``, this package will not be marked as automatically installed. This is the default. Set it to False if you want to be able to automatically remove the package at a later stage when no other package depends on it. """ self._pcache.cache_pre_change() self._pcache._depcache.mark_install(self._pkg, auto_inst, from_user) # try to fix broken stuff if auto_fix and self._pcache._depcache.broken_count > 0: fixer = apt_pkg.ProblemResolver(self._pcache._depcache) fixer.clear(self._pkg) fixer.protect(self._pkg) fixer.resolve(True) self._pcache.cache_post_change()
def __init__(self, cache): # type: (Cache) -> None self._resolver = apt_pkg.ProblemResolver(cache._depcache) self._cache = cache
def install(self): """ Installs the updates. """ if not self.cache: return False package_manager = apt_pkg.PackageManager(self.cache._depcache) # Once the installation has been completed, there are three # possible actions to do: # - If the status is pm.RESULT_COMPLETED, the installation # was successful and we can go home # - If the status is pm.RESULT_INCOMPLETE or pm.RESULT_FAILED, # we try again, fixing the possible broken packages. # libchannels will re-try the operation for maximum 5 tries. # - If the status is unknown, listeners are notified and # everything ends here. # Notify progress listeners that the installation is starting self.packages_install_progress.start_update() tries = 0 while tries < self.MAX_TRIES: # Run the fetch operation again, just to be sure if not self.fetch(package_manager): return # Then run the actual installation process res = self.packages_install_progress.run(package_manager) #res = package_manager.do_install() if res in (package_manager.RESULT_INCOMPLETE, package_manager.RESULT_FAILED): logger.warning( "System update %s, trying again (%s/%s)" % ("incomplete" if res == package_manager.RESULT_INCOMPLETE else "failed", tries + 1, self.MAX_TRIES)) # Dpkg journal dirty? if self.cache.dpkg_journal_dirty: subprocess.call(["dpkg", "configure", "--all"]) # FIXME: add check for core packages # Broken packages? #if self.cache._depcache.broken_count > 0: if True: fixer = apt_pkg.ProblemResolver(self.cache._depcache) fixer.resolve(True) # FIXME: should notify this? self.fetch(package_manager) self.packages_install_progress.run(package_manager) # Restore working state for the next upgrade run self.restore_working_state() elif res == package_manager.RESULT_COMPLETED: # Everything completed successfully logger.info("Clearing cache") self.clear() logger.info("System update completed") self.packages_install_progress.finish_update() return else: # Unknown error. logger.error("Unknown error: %s" % res) self.packages_install_failure_callback("Unknown error: %s" % res) return tries += 1 # If we are here, the installation process failed and we were # unable to continue. logger.error("System upgrade failed: MAX_TRIES reached") self.packages_install_failure_callback( "System upgrade failed: MAX_TRIES reached")
def __init__(self, cache): self._resolver = apt_pkg.ProblemResolver(cache._depcache) self._cache = cache