def test_acquire(self): apt_pkg.AcquireFile(apt_pkg.Acquire(), "http://example.com", destdir=self.file_bytes, destfile=self.file_bytes) apt_pkg.AcquireFile(apt_pkg.Acquire(), "http://example.com", destdir=self.file_unicode, destfile=self.file_unicode)
def fetch_binary(self, destdir='', progress=None): """Fetch the binary version of the package. The parameter *destdir* specifies the directory where the package will be fetched to. The parameter *progress* may refer to an apt_pkg.AcquireProgress() object. If not specified or None, apt.progress.text.AcquireProgress() is used. .. versionadded:: 0.7.10 """ base = os.path.basename(self._records.filename) destfile = os.path.join(destdir, base) if _file_is_same(destfile, self.size, self._records.md5_hash): print('Ignoring already existing file: %s' % destfile) return os.path.abspath(destfile) acq = apt_pkg.Acquire(progress or apt.progress.text.AcquireProgress()) acqfile = apt_pkg.AcquireFile(acq, self.uri, self._records.md5_hash, self.size, base, destfile=destfile) acq.run() if acqfile.status != acqfile.STAT_DONE: raise FetchError("The item %r could not be fetched: %s" % (acqfile.destfile, acqfile.error_text)) return os.path.abspath(destfile)
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
def fetch(self, package_manager=None): """ Fetches the updates. """ if not self.cache: return False logger.info("Beginning fetch") acquire_object = apt_pkg.Acquire( progress=self.packages_acquire_progress) try: if not package_manager: self.cache.fetch_archives(fetcher=acquire_object) else: # Handle internally self.cache._fetch_archives(acquire_object, package_manager) acquire_object.shutdown() except apt.cache.FetchCancelledException: # Cancelled logger.info("Fetch cancelled") return False except Exception as err: self.notify_error("Unable to fetch the packages", err) return False return True
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)
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))
def fetch_source(self, destdir="", progress=None, unpack=True): """Get the source code of a package. The parameter *destdir* specifies the directory where the source will be fetched to. The parameter *progress* may refer to an apt_pkg.AcquireProgress() object. If not specified or None, apt.progress.text.AcquireProgress() is used. The parameter *unpack* describes whether the source should be unpacked (``True``) or not (``False``). By default, it is unpacked. If *unpack* is ``True``, the path to the extracted directory is returned. Otherwise, the path to the .dsc file is returned. """ src = apt_pkg.SourceRecords() acq = apt_pkg.Acquire(progress or apt.progress.text.AcquireProgress()) dsc = None record = self._records source_name = record.source_pkg or self.package.shortname source_version = record.source_ver or self._cand.ver_str source_lookup = src.lookup(source_name) while source_lookup and source_version != src.version: source_lookup = src.lookup(source_name) if not source_lookup: raise ValueError("No source for %r" % self) files = list() for md5, size, path, type_ in src.files: base = os.path.basename(path) destfile = os.path.join(destdir, base) if type_ == 'dsc': dsc = destfile if _file_is_same(destfile, size, md5): print('Ignoring already existing file: %s' % destfile) continue files.append( apt_pkg.AcquireFile(acq, src.index.archive_uri(path), md5, size, base, destfile=destfile)) acq.run() for item in acq.items: if item.status != item.STAT_DONE: raise FetchError("The item %r could not be fetched: %s" % (item.destfile, item.error_text)) if unpack: outdir = src.package + '-' + apt_pkg.upstream_version(src.version) outdir = os.path.join(destdir, outdir) subprocess.check_call(["dpkg-source", "-x", dsc, outdir]) return os.path.abspath(outdir) else: return os.path.abspath(dsc)
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)
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
def f_getpkg(pkg): if not path.isdir(aptdir): mkdir(aptdir) p = apt.progress.text.AcquireProgress() c = apt.Cache() u = c[pkg].candidate.uri a = apt_pkg.Acquire(p) acq = apt_pkg.AcquireFile(a, uri=u, destdir=aptdir) a.run()
def test_acquire_hashes(self): hs = apt_pkg.HashString("d41d8cd98f00b204e9800998ecf8427e") hsl = apt_pkg.HashStringList() hsl.append(hs) apt_pkg.AcquireFile(apt_pkg.Acquire(), "http://example.com", hash=hsl, destdir=self.file_unicode, destfile=self.file_unicode) apt_pkg.AcquireFile(apt_pkg.Acquire(), "http://example.com", hash=str(hs), destdir=self.file_unicode, destfile=self.file_unicode) self.assertRaises(TypeError, apt_pkg.AcquireFile, apt_pkg.Acquire(), "http://example.com", hash=hs, destdir=self.file_unicode, destfile=self.file_unicode)
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()]
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))
def main(): apt_pkg.init_config() apt_pkg.init_system() acquire = apt_pkg.Acquire() slist = apt_pkg.SourceList() # Read the list slist.read_main_list() # Add all indexes to the fetcher. slist.get_indexes(acquire, True) # Now print the URI of every item. for item in acquire.items: print(item.desc_uri)
def doFetchArchives(self, name, bargs): fetcher = apt_pkg.Acquire() self.cache[name].mark_install() try: self.cache.fetch_archives(fetcher=fetcher, **bargs) finally: for fname in os.listdir( os.path.join(self.chroot_path, "var/cache/apt/archives")): if fname.endswith(".deb"): os.unlink( os.path.join(self.chroot_path, "var/cache/apt/archives", fname)) self.cache[name].mark_keep()
def test_acquire_file_md5_keyword_backward_compat(self): """ Ensure that both "md5" and "hash" is supported as keyword for AcquireFile """ with warnings.catch_warnings(record=True) as caught_warnings: warnings.simplefilter("always") apt_pkg.AcquireFile(apt_pkg.Acquire(), "http://example.com", destfile=self.file_bytes, md5="abcdef") self.assertEqual(len(caught_warnings), 1) self.assertTrue( issubclass(caught_warnings[0].category, DeprecationWarning)) self.assertIn("md5", str(caught_warnings[0].message)) self.assertIn("hash", str(caught_warnings[0].message)) apt_pkg.AcquireFile( apt_pkg.Acquire(), "http://example.com", destfile=self.file_bytes, hash="sha1:41050ed528554fdd6c6c9a086ddd6bdba5857b21")
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)
def packageList(): import apt_pkg apt_pkg.init_config() apt_pkg.init_system() acquire = apt_pkg.Acquire() slist = apt_pkg.SourceList() slist.read_main_list() slist.get_indexes(acquire, True) output = {"packages": []} # Now print the URI of every item. for item in acquire.items: output["packages"].append(item.desc_uri) pipLog.sharedInstance.debug("APT:" + json.dumps(output)) return sendMessage(json.dumps(output))
def fetch_binary(version, destdir='', progress=None): # type: (str, AcquireProgress) -> str """Fetch the binary version of the package. The parameter *destdir* specifies the directory where the package will be fetched to. The parameter *progress* may refer to an apt_pkg.AcquireProgress() object. If not specified or None, apt.progress.text.AcquireProgress() is used. taken from python-apt-1.8.4 https://salsa.debian.org/apt-team/python-apt/-/blob/1.8.4/apt/package.py --------------------------------------------------------- Copyright (c) 2005-2009 Canonical Author: Michael Vogt <*****@*****.**> --------------------------------------------------------- Then fixed up to use sha256 and pass pycodestyle. """ # pylint: disable=protected-access base = os.path.basename(version._records.filename) destfile = os.path.join(destdir, base) # pylint: disable=protected-access if _file_is_same(destfile, version.size, version._records.sha256_hash): logging.debug('Ignoring already existing file: %s', destfile) return os.path.abspath(destfile) acq = apt_pkg.Acquire(progress or apt.progress.text.AcquireProgress()) # pylint: disable=protected-access acqfile = apt_pkg.AcquireFile(acq, version.uri, "SHA256:" + version._records.sha256_hash, version.size, base, destfile=destfile) acq.run() if acqfile.status != acqfile.STAT_DONE: raise FetchError("The item %r could not be fetched: %s" % (acqfile.destfile, acqfile.error_text)) return os.path.abspath(destfile)
def fetchDistUpgrader(self): " download the tarball with the upgrade script " tmpdir = tempfile.mkdtemp(prefix="ubuntu-release-upgrader-") self.tmpdir = tmpdir os.chdir(tmpdir) logging.debug("using tmpdir: '%s'" % tmpdir) # turn debugging on here (if required) if self.DEBUG > 0: apt_pkg.config.set("Debug::Acquire::http", "1") apt_pkg.config.set("Debug::Acquire::ftp", "1") #os.listdir(tmpdir) fetcher = apt_pkg.Acquire(self._progress) if self.new_dist.upgradeToolSig is not None: uri = self._expandUri(self.new_dist.upgradeToolSig) af1 = apt_pkg.AcquireFile(fetcher, uri, descr=_("Upgrade tool signature")) # reference it here to shut pyflakes up af1 if self.new_dist.upgradeTool is not None: self.uri = self._expandUri(self.new_dist.upgradeTool) af2 = apt_pkg.AcquireFile(fetcher, self.uri, descr=_("Upgrade tool")) # reference it here to shut pyflakes up af2 result = fetcher.run() if result != fetcher.RESULT_CONTINUE: logging.warn("fetch result != continue (%s)" % result) return False # check that both files are really there and non-null for f in [ os.path.basename(self.new_dist.upgradeToolSig), os.path.basename(self.new_dist.upgradeTool) ]: if not (os.path.exists(f) and os.path.getsize(f) > 0): logging.warn("file '%s' missing" % f) return False return True return False
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
#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")
def __init__(self, xml): # pylint: disable=too-many-statements self.xml = xml arch = xml.text("project/buildimage/arch", key="arch") suite = xml.text("project/suite") self.basefs = TmpdirFilesystem() self.initialize_dirs() create_apt_prefs(self.xml, self.basefs) mirror = self.xml.create_apt_sources_list(build_sources=True, initvm=False) self.basefs.write_file("etc/apt/sources.list", 0o644, mirror) self.setup_gpg() self.import_keys() apt_pkg.config.set("APT::Architecture", arch) apt_pkg.config.set("APT::Architectures", arch) apt_pkg.config.set("Acquire::http::Proxy::127.0.0.1", "DIRECT") apt_pkg.config.set("APT::Install-Recommends", "0") apt_pkg.config.set("Dir::Etc", self.basefs.fname('/')) apt_pkg.config.set("Dir::Etc::Trusted", self.basefs.fname('/etc/apt/trusted.gpg')) apt_pkg.config.set("Dir::Etc::TrustedParts", self.basefs.fname('/etc/apt/trusted.gpg.d')) apt_pkg.config.set("APT::Cache-Limit", "0") apt_pkg.config.set("APT::Cache-Start", "32505856") apt_pkg.config.set("APT::Cache-Grow", "2097152") apt_pkg.config.set("Dir::State", self.basefs.fname("state")) apt_pkg.config.set("Dir::State::status", self.basefs.fname("state/status")) apt_pkg.config.set("Dir::Cache", self.basefs.fname("cache")) apt_pkg.config.set("Dir::Cache::archives", self.basefs.fname("cache/archives")) apt_pkg.config.set("Dir::Etc", self.basefs.fname("etc/apt")) apt_pkg.config.set("Dir::Log", self.basefs.fname("log")) if self.xml.has('project/noauth'): apt_pkg.config.set("APT::Get::AllowUnauthenticated", "1") apt_pkg.config.set("Acquire::AllowInsecureRepositories", "1") else: apt_pkg.config.set("APT::Get::AllowUnauthenticated", "0") apt_pkg.config.set("Acquire::AllowInsecureRepositories", "0") apt_pkg.init_system() self.source = apt_pkg.SourceList() self.source.read_main_list() self.cache = apt_pkg.Cache() try: self.cache.update(self, self.source) except BaseException as e: print(e) apt_pkg.config.set("APT::Default-Release", suite) self.cache = apt_pkg.Cache() try: self.cache.update(self, self.source) except BaseException as e: print(e) try: self.depcache = apt_pkg.DepCache(self.cache) prefs_name = self.basefs.fname("/etc/apt/preferences") self.depcache.read_pinfile(prefs_name) except BaseException as e: print(e) self.downloads = {} self.acquire = apt_pkg.Acquire(self)
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 fetch_packages(self, packages, download_content=True): """Fetch the files for the given list of package names. The files, and all their dependencies are download, and the metadata and content returned as FetchedPackage objects. If download_content is False then only the metadata is returned (i.e. the FetchedPackages will have None for their content attribute), and only information about the specified packages will be returned, no dependencies. No packages that have been ignored, or are recursive dependencies of ignored packages will be returned. :param packages: a list of package names to install :type packages: an iterable of str :param download_content: whether to download the content of the packages. Default is to do so. :type download_content: bool :return: a list of the packages that were fetched, with relevant metdata and the contents of the files available. :rtype: an iterable of FetchedPackages. :raises KeyError: if any of the package names in the list couldn't be found. """ fetched = {} for package in packages: candidate = self.cache.cache[package].candidate base = os.path.basename(candidate.filename) result_package = FetchedPackage.from_apt(candidate, base) fetched[package] = result_package def check_no_broken_packages(): if self.cache.cache.broken_count: raise DependencyNotSatisfied( "Unable to satisfy dependencies of %s" % ", ".join( [p.name for p in self.cache.cache if p.is_inst_broken])) for package in packages: try: self.cache.cache[package].mark_install(auto_fix=True) except SystemError: # Either we raise a DependencyNotSatisfied error # if some packages are broken, or we raise the original # error if there was another cause check_no_broken_packages() raise # Check that nothing was broken, even if mark_install didn't # raise SystemError, just to make sure. check_no_broken_packages() self._filter_ignored(fetched) if not download_content: self.cache.cache.clear() return fetched.values() acq = apt_pkg.Acquire(DummyProgress()) acqfiles = [] # re to remove the repo private key deb_url_auth_re = re.compile( r"(?P<transport>.*://)(?P<user>.*):.*@(?P<path>.*$)") for package in self.cache.cache.get_changes(): if (package.marked_delete or package.marked_keep): continue logger.debug("Fetching %s ..." % package) candidate = package.candidate base = os.path.basename(candidate.filename) if package.name not in fetched: result_package = FetchedPackage.from_apt(candidate, base) fetched[package.name] = result_package result_package = fetched[package.name] destfile = os.path.join(self.cache.tempdir, base) acqfile = apt_pkg.AcquireFile(acq, candidate.uri, candidate.md5, candidate.size, base, destfile=destfile) acqfiles.append((acqfile, result_package, destfile)) # check if we have a private key in the pkg url deb_url_auth = deb_url_auth_re.match(acqfile.desc_uri) if deb_url_auth: logger.debug(" ... from %s%s:***@%s" % deb_url_auth.groups()) else: logger.debug(" ... from %s" % acqfile.desc_uri) self.cache.cache.clear() acq.run() for acqfile, result_package, destfile in acqfiles: if acqfile.status != acqfile.STAT_DONE: raise FetchError("The item %r could not be fetched: %s" % (acqfile.destfile, acqfile.error_text)) result_package.content = open(destfile) result_package._file_path = destfile return fetched.values()
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