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()
Example #3
0
 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
Example #4
0
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
Example #5
0
 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
Example #6
0
    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()
Example #7
0
    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()
Example #8
0
    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()
Example #9
0
 def __init__(self, cache):
     # type: (Cache) -> None
     self._resolver = apt_pkg.ProblemResolver(cache._depcache)
     self._cache = cache
Example #10
0
    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")
Example #11
0
 def __init__(self, cache):
     self._resolver = apt_pkg.ProblemResolver(cache._depcache)
     self._cache = cache