]> git.ipfire.org Git - pakfire.git/commitdiff
transaction: Download packages using libpakfire
authorMichael Tremer <michael.tremer@ipfire.org>
Sat, 13 Mar 2021 17:37:52 +0000 (17:37 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sat, 13 Mar 2021 17:37:52 +0000 (17:37 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/_pakfire/transaction.c
src/libpakfire/include/pakfire/package.h
src/libpakfire/include/pakfire/repo.h
src/libpakfire/include/pakfire/transaction.h
src/libpakfire/libpakfire.sym
src/libpakfire/package.c
src/libpakfire/repo.c
src/libpakfire/transaction.c
src/pakfire/builder.py

index 3585ff8c00aef3f9e46566a40d338105fec8ad00..ef7dcd13cead93dc4ee1d027da5f204de786c6a1 100644 (file)
@@ -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",
index 86a82ce5e6e280714eb487a24d4bd40ac0c54e47..6a37b7aefc89d2f3a2802835934d5dc4160251a7 100644 (file)
@@ -158,4 +158,12 @@ enum pakfire_package_dump_flags {
        PAKFIRE_PKG_DUMP_LONG     = 1 << 1,
 };
 
+#ifdef PAKFIRE_PRIVATE
+
+#include <solv/repo.h>
+
+int pakfire_package_is_in_repo(PakfirePackage pkg, Repo* repo);
+
+#endif
+
 #endif /* PAKFIRE_PACKAGE_H */
index c26434b67ec885f1d818154f6b46a0ee377fe21e..7a8efc78f84672a8a2af065506f69139611c56e0 100644 (file)
@@ -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 */
index ae766b2a688849a346045e51d8af6c782aa76bf7..6a182d59182b2f6f41ca13eecaf3b82e8c8681a7 100644 (file)
@@ -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);
index c9781055392086e1c23e843d5d145319ffba8342..200719a2c4718b6ec55610f87b5d54f4cb35a339 100644 (file)
@@ -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;
index 7bc7b8a0e0534d3bd2da2a1a5112d8120c05c6a9..c6300446b84876db2800883d9ab78b6a4825e14a 100644 (file)
@@ -19,6 +19,7 @@
 #############################################################################*/
 
 #include <assert.h>
+#include <linux/limits.h>
 #include <stdlib.h>
 #include <string.h>
 #include <time.h>
@@ -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) {
index b74d50a8f336e72d3162956eb710150a6c98f112..c388972b31aca48685a5b5d6971d9730ba69c40d 100644 (file)
@@ -40,6 +40,7 @@
 #include <pakfire/errno.h>
 #include <pakfire/logging.h>
 #include <pakfire/package.h>
+#include <pakfire/packagelist.h>
 #include <pakfire/pakfire.h>
 #include <pakfire/private.h>
 #include <pakfire/repo.h>
@@ -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;
+}
index 7b37d4d02b8c26b7498a9da084d26770fd9258e4..a3072f350aa0d2317bb9f26cd156f2a4b2a640a5 100644 (file)
@@ -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;
+}
index 35918570f4711b0bffd2b2aeed075e2ed8c85c75..f5b53bcef53835b84acde78f685db6c6be39b7a0 100644 (file)
@@ -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()