From: Michael Tremer Date: Sat, 13 Mar 2021 17:37:52 +0000 (+0000) Subject: transaction: Download packages using libpakfire X-Git-Tag: 0.9.28~1285^2~531 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4a81ff8522d63783a68e8030cc6416e054e691e9;p=pakfire.git transaction: Download packages using libpakfire Signed-off-by: Michael Tremer --- diff --git a/src/_pakfire/transaction.c b/src/_pakfire/transaction.c index 3585ff8c0..ef7dcd13c 100644 --- a/src/_pakfire/transaction.c +++ b/src/_pakfire/transaction.c @@ -120,17 +120,32 @@ static PyObject* Transaction_run(TransactionObject* self) { Py_RETURN_NONE; } +static PyObject* Transaction_download(TransactionObject* self) { + int r = pakfire_transaction_download(self->transaction); + if (r) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + + Py_RETURN_NONE; +} static Py_ssize_t Transaction_len(TransactionObject* self) { return pakfire_transaction_count(self->transaction); } static struct PyMethodDef Transaction_methods[] = { + { + "download", + (PyCFunction)Transaction_download, + METH_NOARGS, + NULL, + }, { "dump", (PyCFunction)Transaction_dump, METH_NOARGS, - NULL + NULL, }, { "run", diff --git a/src/libpakfire/include/pakfire/package.h b/src/libpakfire/include/pakfire/package.h index 86a82ce5e..6a37b7aef 100644 --- a/src/libpakfire/include/pakfire/package.h +++ b/src/libpakfire/include/pakfire/package.h @@ -158,4 +158,12 @@ enum pakfire_package_dump_flags { PAKFIRE_PKG_DUMP_LONG = 1 << 1, }; +#ifdef PAKFIRE_PRIVATE + +#include + +int pakfire_package_is_in_repo(PakfirePackage pkg, Repo* repo); + +#endif + #endif /* PAKFIRE_PACKAGE_H */ diff --git a/src/libpakfire/include/pakfire/repo.h b/src/libpakfire/include/pakfire/repo.h index c26434b67..7a8efc78f 100644 --- a/src/libpakfire/include/pakfire/repo.h +++ b/src/libpakfire/include/pakfire/repo.h @@ -99,6 +99,8 @@ void pakfire_repo_free_all(Pakfire pakfire); Repo* pakfire_repo_get_repo(PakfireRepo repo); Repodata* pakfire_repo_get_repodata(PakfireRepo repo); +int pakfire_repo_download_packages(PakfireRepo repo, PakfirePackageList packages); + #endif #endif /* PAKFIRE_REPO_H */ diff --git a/src/libpakfire/include/pakfire/transaction.h b/src/libpakfire/include/pakfire/transaction.h index ae766b2a6..6a182d591 100644 --- a/src/libpakfire/include/pakfire/transaction.h +++ b/src/libpakfire/include/pakfire/transaction.h @@ -41,6 +41,8 @@ char* pakfire_transaction_dump(PakfireTransaction transaction, size_t width); int pakfire_transaction_run(PakfireTransaction transaction); +int pakfire_transaction_download(PakfireTransaction transaction); + #ifdef PAKFIRE_PRIVATE Transaction* pakfire_transaction_get_transaction(PakfireTransaction transaction); diff --git a/src/libpakfire/libpakfire.sym b/src/libpakfire/libpakfire.sym index c97810553..200719a2c 100644 --- a/src/libpakfire/libpakfire.sym +++ b/src/libpakfire/libpakfire.sym @@ -400,6 +400,7 @@ global: # transaction pakfire_transaction_count; pakfire_transaction_create; + pakfire_transaction_download; pakfire_transaction_dump; pakfire_transaction_get_packages; pakfire_transaction_get_step; diff --git a/src/libpakfire/package.c b/src/libpakfire/package.c index 7bc7b8a0e..c6300446b 100644 --- a/src/libpakfire/package.c +++ b/src/libpakfire/package.c @@ -19,6 +19,7 @@ #############################################################################*/ #include +#include #include #include #include @@ -668,6 +669,15 @@ PAKFIRE_EXPORT void pakfire_package_set_enhances(PakfirePackage pkg, PakfireRela pakfire_package_set_relationlist(pkg, SOLVABLE_ENHANCES, relationlist, 0); } +/* + Fast-path function to check if a package is in a certain repository +*/ +int pakfire_package_is_in_repo(PakfirePackage pkg, Repo* repo) { + Solvable* s = get_solvable(pkg); + + return s->repo == repo; +} + PAKFIRE_EXPORT PakfireRepo pakfire_package_get_repo(PakfirePackage pkg) { if (!pkg->repo) { Solvable* s = get_solvable(pkg); @@ -914,7 +924,7 @@ PAKFIRE_EXPORT int pakfire_package_is_cached(PakfirePackage pkg) { } PAKFIRE_EXPORT char* pakfire_package_get_cache_path(PakfirePackage pkg) { - char buffer[STRING_SIZE] = ""; + char path[PATH_MAX]; const char* filename = pakfire_package_get_filename(pkg); const char* checksum = pakfire_package_get_checksum(pkg); @@ -922,10 +932,10 @@ PAKFIRE_EXPORT char* pakfire_package_get_cache_path(PakfirePackage pkg) { if (strlen(checksum) < 3) return NULL; - snprintf(buffer, sizeof(buffer), "%c%c/%s/%s", checksum[0], checksum[1], + snprintf(path, sizeof(path) - 1, "%c%c/%s/%s", checksum[0], checksum[1], checksum + 2, filename); - return pakfire_make_cache_path(pkg->pakfire, buffer); + return pakfire_make_cache_path(pkg->pakfire, path); } PAKFIRE_EXPORT PakfireArchive pakfire_package_get_archive(PakfirePackage pkg) { diff --git a/src/libpakfire/repo.c b/src/libpakfire/repo.c index b74d50a8f..c388972b3 100644 --- a/src/libpakfire/repo.c +++ b/src/libpakfire/repo.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -979,3 +980,42 @@ PAKFIRE_EXPORT int pakfire_repo_refresh(PakfireRepo repo, const int force) { // Refresh metadata return pakfire_repo_refresh_metadata(repo, force); } + +int pakfire_repo_download_packages(PakfireRepo repo, PakfirePackageList packages) { + int r; + + struct pakfire_downloader* downloader = pakfire_repo_downloader(repo); + if (!downloader) + return 1; + + const size_t num_packages = pakfire_packagelist_count(packages); + + for (unsigned int i = 0; i < num_packages; i++) { + PakfirePackage pkg = pakfire_packagelist_get(packages, i); + + // Skip packages that are not in this repository + if (!pakfire_package_is_in_repo(pkg, repo->repo)) { + pakfire_package_unref(pkg); + continue; + } + + char* cache_path = pakfire_package_get_cache_path(pkg); + + // Add transfer to downloader + r = pakfire_downloader_add_transfer(downloader, + pakfire_package_get_filename(pkg), cache_path); + if (r) { + pakfire_package_unref(pkg); + free(cache_path); + goto ERROR; + } + } + + // Run the download + r = pakfire_downloader_run(downloader); + +ERROR: + pakfire_downloader_unref(downloader); + + return r; +} diff --git a/src/libpakfire/transaction.c b/src/libpakfire/transaction.c index 7b37d4d02..a3072f350 100644 --- a/src/libpakfire/transaction.c +++ b/src/libpakfire/transaction.c @@ -430,3 +430,62 @@ ERROR: return r; } + +PAKFIRE_EXPORT int pakfire_transaction_download(PakfireTransaction transaction) { + /* + XXX TODO + This is not a very pretty solution, because we have to run a downloader + for each repository. It would be better to add all downloads to one downloader. + */ + int r; + + PakfirePackageList packages = pakfire_packagelist_create(transaction->pakfire); + if (!packages) + return 1; + + // Add all packages that need to be downloaded + for (unsigned int i = 0; i < transaction->num_steps; i++) { + PakfireStep step = transaction->steps[i]; + + // Skip all steps that do not require a download + if (!pakfire_step_needs_download(step)) + continue; + + // Fetch the package + PakfirePackage pkg = pakfire_step_get_package(step); + + // Add it to the list + pakfire_packagelist_push(packages, pkg); + + pakfire_package_unref(pkg); + } + + // If the list is empty, we do not need to continue + if (pakfire_packagelist_count(packages) == 0) { + r = 0; + goto ERROR; + } + + Pool* pool = pakfire_get_solv_pool(transaction->pakfire); + Repo* repo; + int i; + + FOR_REPOS(i, repo) { + PakfireRepo _repo = pakfire_repo_create_from_repo(transaction->pakfire, repo); + + r = pakfire_repo_download_packages(_repo, packages); + pakfire_repo_unref(_repo); + + if (r) + goto ERROR; + } + + // Success + r = 0; + +ERROR: + if (packages) + pakfire_packagelist_unref(packages); + + return r; +} diff --git a/src/pakfire/builder.py b/src/pakfire/builder.py index 35918570f..f5b53bcef 100644 --- a/src/pakfire/builder.py +++ b/src/pakfire/builder.py @@ -34,7 +34,6 @@ from . import _pakfire from . import base from . import cgroups from . import config -from . import downloaders from . import logger from . import packages from . import repository @@ -324,8 +323,7 @@ class BuilderContext(object): self.log.info(t) # Download transaction - d = downloaders.TransactionDownloader(self.pakfire, transaction) - d.download() + transaction.download() # Run the transaction transaction.run()