def _download_remote_packages(self): @contextmanager def suppress(): """ Suppress stdout within a context. This is necessary in this use case because, unfortunately, the YUM library will do direct printing to stdout in many error conditions. Since we are maintaining a real-time, in-place updating presentation of progress, we must suppress this, as we receive exceptions for our reporting purposes anyways. """ stdout = sys.stdout sys.stdout = open(os.devnull, 'w') yield sys.stdout = stdout try: yb = YumBase() repo = self._set_path(self.package_dir) if self.__yum_callback_obj: repo.setCallback(self.__yum_callback_obj) yb.repos.add(repo) yb.repos.enableRepo(repo.id) with suppress(): # showdups allows us to get multiple versions of the same package. ygh = yb.doPackageLists(showdups=True) # reinstall_available = Available packages which are installed. packages = ygh.available + ygh.reinstall_available # Inform about number of packages total in the repo. self._callback('repo_init', len(packages)) # Check if the packages are already downloaded. This is probably a bit # expensive, but the alternative is simply not knowing, which is # horrible for progress indication. for po in packages: local = po.localPkg() if os.path.exists(local): if yb.verifyPkg(local, po, False): self._callback('pkg_exists', self._get_package_filename(po)) with suppress(): yb.downloadPkgs(packages) self._packages = [self._get_package_filename(pkg) for pkg in packages] self._callback('repo_complete') except (KeyboardInterrupt, SystemExit): pass except Exception as e: self._callback('repo_error', str(e)) raise PackageDownloadError(str(e))