Beispiel #1
0
    def fetch_archives(
            self,
            progress=None,  # type: Optional[AcquireProgress]
            fetcher=None,  # type: Optional[apt_pkg.Acquire]
            allow_unauthenticated=None,  # type: Optional[bool]
    ):
        # type: (...) -> int
        """Fetch the archives for all packages marked for install/upgrade.

        You can specify either an :class:`apt.progress.base.AcquireProgress()`
        object for the parameter *progress*, or specify an already
        existing :class:`apt_pkg.Acquire` object for the parameter *fetcher*.

        The return value of the function is undefined. If an error occurred,
        an exception of type :class:`FetchFailedException` or
        :class:`FetchCancelledException` is raised.

        The keyword-only parameter *allow_unauthenticated* specifies whether
        to allow unauthenticated downloads. If not specified, it defaults to
        the configuration option `APT::Get::AllowUnauthenticated`.

        .. versionadded:: 0.8.0
        """
        if progress is not None and fetcher is not None:
            raise ValueError("Takes a progress or a an Acquire object")
        if progress is None:
            progress = apt.progress.text.AcquireProgress()
        if fetcher is None:
            fetcher = apt_pkg.Acquire(progress)

        with self._archive_lock:
            return self._fetch_archives(fetcher,
                                        apt_pkg.PackageManager(self._depcache),
                                        allow_unauthenticated)
Beispiel #2
0
    def TSexec_download(self):
        downloaded = []
        success = False
        if not self.updatePkgDatabase():
            self.logger.error("Could not update apt package database")
        else:
            self.TSpurge_pkgs()
            self.update_progress("Downloading")
            self.apt_cache.upgrade()
            required = self.apt_cache.required_download / (1024 * 1024)
            downloaded = [pkg.name for pkg in self.apt_cache.get_changes()]
            self.logger.debug(
                "%d upgradable packages, %.1fMB required download space" %
                (len(downloaded), required))

            # Download packages
            pm = apt_pkg.PackageManager(self.apt_cache._depcache)
            fetcher = apt_pkg.Acquire(GetAcquireProgress(self))
            try:
                self.apt_cache._fetch_archives(fetcher, pm)
                success = True
            except Exception:
                self.logger.error(traceback.format_exc())

        if success:
            self.update_progress("Ready to install")
            self.logger.info("Successfully downloaded %s packages" %
                             len(downloaded))
        else:
            self.update_progress("Download failure")
            self.logger.error("Failed downloading packages!")

        return downloaded
Beispiel #3
0
    def fetch_archives(self, progress=None, fetcher=None):
        # type: (AcquireProgress, apt_pkg.Acquire) -> int
        """Fetch the archives for all packages marked for install/upgrade.

        You can specify either an :class:`apt.progress.base.AcquireProgress()`
        object for the parameter *progress*, or specify an already
        existing :class:`apt_pkg.Acquire` object for the parameter *fetcher*.

        The return value of the function is undefined. If an error occurred,
        an exception of type :class:`FetchFailedException` or
        :class:`FetchCancelledException` is raised.

        .. versionadded:: 0.8.0
        """
        if progress is not None and fetcher is not None:
            raise ValueError("Takes a progress or a an Acquire object")
        if progress is None:
            progress = apt.progress.text.AcquireProgress()
        if fetcher is None:
            fetcher = apt_pkg.Acquire(progress)

        self._get_archive_lock(fetcher)

        return self._fetch_archives(fetcher,
                                    apt_pkg.PackageManager(self._depcache))
Beispiel #4
0
    def commit(
            self,
            fetch_progress=None,  # type: Optional[AcquireProgress]
            install_progress=None,  # type: Optional[InstallProgress]
            allow_unauthenticated=None,  # type: Optional[bool]
    ):
        # type: (...) -> bool
        """Apply the marked changes to the cache.

        The first parameter, *fetch_progress*, refers to a FetchProgress()
        object as found in apt.progress, the default being
        apt.progress.FetchProgress().

        The second parameter, *install_progress*, is a
        apt.progress.InstallProgress() object.

        The keyword-only parameter *allow_unauthenticated* specifies whether
        to allow unauthenticated downloads. If not specified, it defaults to
        the configuration option `APT::Get::AllowUnauthenticated`.
        """
        # FIXME:
        # use the new acquire/pkgmanager interface here,
        # raise exceptions when a download or install fails
        # and send proper error strings to the application.
        # Current a failed download will just display "error"
        # which is less than optimal!

        if fetch_progress is None:
            fetch_progress = apt.progress.base.AcquireProgress()
        if install_progress is None:
            install_progress = apt.progress.base.InstallProgress()

        assert install_progress is not None

        with apt_pkg.SystemLock():
            pm = apt_pkg.PackageManager(self._depcache)
            fetcher = apt_pkg.Acquire(fetch_progress)
            with self._archive_lock:
                while True:
                    # fetch archives first
                    res = self._fetch_archives(fetcher, pm,
                                               allow_unauthenticated)

                    # then install
                    res = self.install_archives(pm, install_progress)
                    if res == pm.RESULT_COMPLETED:
                        break
                    elif res == pm.RESULT_FAILED:
                        raise SystemError("installArchives() failed")
                    elif res == pm.RESULT_INCOMPLETE:
                        pass
                    else:
                        raise SystemError("internal-error: unknown result "
                                          "code from InstallArchives: %s" %
                                          res)
                    # reload the fetcher for media swaping
                    fetcher.shutdown()
        return (res == pm.RESULT_COMPLETED)
Beispiel #5
0
 def required_download(self):
     """Get the size of the packages that are required to download."""
     if self._records is None:
         raise CacheClosedException(
             "Cache object used after close() called")
     pm = apt_pkg.PackageManager(self._depcache)
     fetcher = apt_pkg.Acquire()
     pm.get_archives(fetcher, self._list, self._records)
     return fetcher.fetch_needed
Beispiel #6
0
 def downloadArchives(self):
     pkgAcquire, pkgSourceList = apt_pkg.Acquire(), apt_pkg.SourceList()
     self.logger.verbose("Reading main source lists...")
     pkgSourceList.read_main_list()
     self.logger.verbose("Downloading archives...")
     self.pkgManager = apt_pkg.PackageManager(self.depCache)
     self.pkgManager.get_archives(pkgAcquire, pkgSourceList,
                                  apt_pkg.PackageRecords(self.pkgCache))
     pkgAcquire.run()
     [package.update(install=False) for package in self.pkgList.values()]
Beispiel #7
0
def _test():
    # type: () -> None
    """Internal test code."""
    print("Cache self test")
    apt_pkg.init()
    cache = Cache(apt.progress.text.OpProgress())
    cache.connect2("cache_pre_change", cache_pre_changed)
    cache.connect2("cache_post_change", cache_post_changed)
    print(("aptitude" in cache))
    pkg = cache["aptitude"]
    print(pkg.name)
    print(len(cache))

    for pkgname in cache.keys():
        assert cache[pkgname].name == pkgname

    cache.upgrade()
    changes = cache.get_changes()
    print(len(changes))
    for pkg in changes:
        assert pkg.name

    # see if fetching works
    for dirname in ["/tmp/pytest", "/tmp/pytest/partial"]:
        if not os.path.exists(dirname):
            os.mkdir(dirname)
    apt_pkg.config.set("Dir::Cache::Archives", "/tmp/pytest")
    pm = apt_pkg.PackageManager(cache._depcache)
    fetcher = apt_pkg.Acquire(apt.progress.text.AcquireProgress())
    cache._fetch_archives(fetcher, pm, None)
    #sys.exit(1)

    print("Testing filtered cache (argument is old cache)")
    filtered = FilteredCache(cache)
    filtered.cache.connect2("cache_pre_change", cache_pre_changed)
    filtered.cache.connect2("cache_post_change", cache_post_changed)
    filtered.cache.upgrade()
    filtered.set_filter(MarkedChangesFilter())
    print(len(filtered))
    for pkgname in filtered.keys():
        assert pkgname == filtered[pkgname].name

    print(len(filtered))

    print("Testing filtered cache (no argument)")
    filtered = FilteredCache(progress=apt.progress.base.OpProgress())
    filtered.cache.connect2("cache_pre_change", cache_pre_changed)
    filtered.cache.connect2("cache_post_change", cache_post_changed)
    filtered.cache.upgrade()
    filtered.set_filter(MarkedChangesFilter())
    print(len(filtered))
    for pkgname in filtered.keys():
        assert pkgname == filtered[pkgname].name

    print(len(filtered))
Beispiel #8
0
    def commit(self, fetch_progress=None, install_progress=None):
        # type: (AcquireProgress, InstallProgress) -> bool
        """Apply the marked changes to the cache.

        The first parameter, *fetch_progress*, refers to a FetchProgress()
        object as found in apt.progress, the default being
        apt.progress.FetchProgress().

        The second parameter, *install_progress*, is a
        apt.progress.InstallProgress() object.
        """
        # FIXME:
        # use the new acquire/pkgmanager interface here,
        # raise exceptions when a download or install fails
        # and send proper error strings to the application.
        # Current a failed download will just display "error"
        # which is less than optimal!

        if fetch_progress is None:
            fetch_progress = apt.progress.base.AcquireProgress()
        if install_progress is None:
            install_progress = apt.progress.base.InstallProgress()

        assert install_progress is not None

        with apt_pkg.SystemLock():
            pm = apt_pkg.PackageManager(self._depcache)
            fetcher = apt_pkg.Acquire(fetch_progress)
            self._get_archive_lock(fetcher)

            while True:
                # fetch archives first
                res = self._fetch_archives(fetcher, pm)

                # then install
                res = self.install_archives(pm, install_progress)
                if res == pm.RESULT_COMPLETED:
                    break
                elif res == pm.RESULT_FAILED:
                    raise SystemError("installArchives() failed")
                elif res == pm.RESULT_INCOMPLETE:
                    pass
                else:
                    raise SystemError("internal-error: unknown result code "
                                      "from InstallArchives: %s" % res)
                # reload the fetcher for media swaping
                fetcher.shutdown()
        return (res == pm.RESULT_COMPLETED)
Beispiel #9
0
    def TSdownload_pkgs(self, pkglist):
        '''Uses python-apt to download available packages'''
        results = {}
        self.set_state('DL')
        apt_cache = self.apt_cache
        apt_cache.open(None)

        pm = apt_pkg.PackageManager(apt_cache._depcache)
        fetcher = apt_pkg.Acquire(GetAcquireProgress(self))

        for pkg_name in pkglist:
            # mark packages for upgrade/install
            pkg = apt_cache[pkg_name]
            if pkg.isUpgradable:
                pkg.markUpgrade()
            elif not pkg.isInstalled:
                pkg.markInstall()

        try:
            apt_cache._fetch_archives(fetcher, pm)
            return True
        except:
            self.logger.error(traceback.format_exc())
            return False
Beispiel #10
0
    def commit_with_verify(self, cache, fetch_progress, install_progress):
        # Hack around occasional undetected download errors in apt by doing
        # our own verification pass at the end.  See
        # https://bugs.launchpad.net/bugs/922949.  Unfortunately this means
        # clone-and-hacking most of cache.commit ...
        pm = apt_pkg.PackageManager(cache._depcache)
        fetcher = apt_pkg.Acquire(fetch_progress)
        while True:
            # fetch archives first
            res = cache._fetch_archives(fetcher, pm)

            # manually verify all the downloads
            syslog.syslog('Verifying downloads ...')
            for item in fetcher.items:
                with open(item.destfile, 'rb') as destfile:
                    st = os.fstat(destfile.fileno())
                    if st.st_size != item.filesize:
                        osextras.unlink_force(item.destfile)
                        raise IOError(
                            "%s size mismatch: %ld != %ld" %
                            (item.destfile, st.st_size, item.filesize))

                    # Mapping back to the package object is an utter pain.
                    # If we fail to find one, it's entirely possible it's a
                    # programming error and not a download error, so skip
                    # verification in such cases rather than failing.
                    destfile_base = os.path.basename(item.destfile)
                    try:
                        name, version, arch = destfile_base.split('_')
                        version = version.replace('%3a', ':')
                        arch = arch.split('.')[0]
                        if arch == 'all':
                            fullname = name
                        else:
                            fullname = '%s:%s' % (name, arch)
                            # This syntax only works on systems configured
                            # for multiarch, so check and fall back to the
                            # single-architecture syntax.
                            if fullname not in cache:
                                fullname = name
                        candidate = cache[fullname].versions[version]
                    except (KeyError, ValueError) as e:
                        syslog.syslog(
                            'Failed to find package object for %s: %s' %
                            (item.destfile, e))
                        continue

                    if candidate.sha256 is not None:
                        sha256 = hashlib.sha256()
                        for chunk in iter(lambda: destfile.read(16384), b''):
                            sha256.update(chunk)
                        if sha256.hexdigest() != candidate.sha256:
                            osextras.unlink_force(item.destfile)
                            raise IOError(
                                "%s SHA256 checksum mismatch: %s != %s" %
                                (item.destfile, sha256.hexdigest(),
                                 candidate.sha256))
            syslog.syslog('Downloads verified successfully')

            # then install
            res = cache.install_archives(pm, install_progress)
            if res == pm.RESULT_COMPLETED:
                break
            elif res == pm.RESULT_FAILED:
                raise SystemError("installArchives() failed")
            elif res == pm.RESULT_INCOMPLETE:
                pass
            else:
                raise SystemError("internal-error: unknown result code "
                                  "from InstallArchives: %s" % res)
            # reload the fetcher for media swapping
            fetcher.shutdown()
        return (res == pm.RESULT_COMPLETED)
 def required_download(self):
     """ get the size of the packages that are required to download """
     pm = apt_pkg.PackageManager(self._depcache)
     fetcher = apt_pkg.Acquire()
     pm.get_archives(fetcher, self._list, self._records)
     return fetcher.fetch_needed
Beispiel #12
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")
import apt_pkg

deps = []
misspkg = "bison"

# reporting progress
progress = apt.progress.base.OpProgress()
# apt cache
cache = apt_pkg.Cache(progress)
# get the package
pkg = cache[misspkg]
deps.append(misspkg)

depcache = apt_pkg.DepCache(cache)
depcache.init(progress)
pkgmanager = apt_pkg.PackageManager(depcache)


def resolve(pkg, store):
    versions = pkg.version_list
    print(" - Got total {} versions of the package {}".format(
        len(versions), pkg.name))

    for i, v in enumerate(versions[0:1]):
        # print("\nThe {} of all versions: --- {} to be download--- \n"
        # .format(i+1, v.downloadable))
        # get dependencies of thie package version
        depends = v.depends_list.get("Depends")
        if depends:
            for d in depends:
                # get name of the pkg
Beispiel #14
0
#apt_pkg.config.set("Debug::pkgDPkgPM","1");
#apt_pkg.config.set("Debug::pkgPackageManager","1");
#apt_pkg.config.set("Debug::pkgDPkgProgressReporting","1");

cache = apt_pkg.Cache()
depcache = apt_pkg.DepCache(cache)

recs = apt_pkg.PackageRecords(cache)
list = apt_pkg.SourceList()
list.read_main_list()

# show the amount fetch needed for a dist-upgrade
depcache.upgrade(True)
progress = apt.progress.text.AcquireProgress()
fetcher = apt_pkg.Acquire(progress)
pm = apt_pkg.PackageManager(depcache)
pm.get_archives(fetcher, list, recs)
print "%s (%s)" % (apt_pkg.size_to_str(
    fetcher.fetch_needed), fetcher.fetch_needed)
actiongroup = apt_pkg.ActionGroup(depcache)
for pkg in cache.packages:
    depcache.mark_keep(pkg)

try:
    os.mkdir("/tmp/pyapt-test")
    os.mkdir("/tmp/pyapt-test/partial")
except OSError:
    pass
apt_pkg.config.set("Dir::Cache::archives", "/tmp/pyapt-test")

pkg = cache["3ddesktop"]