]> git.ipfire.org Git - pakfire.git/commitdiff
transactions: Add dry-run mode
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 15 Jul 2022 11:45:06 +0000 (11:45 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 15 Jul 2022 11:45:06 +0000 (11:45 +0000)
This is useful when we want to check whether a package can be
installed/erased/etc.

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/_pakfire/pakfire.c
src/libpakfire/build.c
src/libpakfire/include/pakfire/pakfire.h
src/libpakfire/include/pakfire/transaction.h
src/libpakfire/pakfire.c
src/libpakfire/transaction.c

index 6f31889c6b64180cf7509b83c35ca8c45ab29b9f..8b438635767dbbada04289e5f8e5ca2ee0f8764d 100644 (file)
@@ -368,6 +368,7 @@ ERROR:
 static PyObject* Pakfire_install(PakfireObject* self, PyObject* args, PyObject* kwargs) {
        char* kwlist[] = {
                "packages",
+               "dryrun",
                "without_recommended",
                "allow_uninstall",
                "allow_downgrade",
@@ -375,14 +376,16 @@ static PyObject* Pakfire_install(PakfireObject* self, PyObject* args, PyObject*
                NULL
        };
        char** packages = NULL;
+       int dryrun = 0;
        int without_recommended = 0;
        int allow_uninstall = 0;
        int allow_downgrade = 0;
        int solver_flags = 0;
+       int transaction_flags = 0;
        PyObject* status_callback = NULL;
 
-       if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$pppO", kwlist,
-                       convert_packages, &packages, &without_recommended, &allow_uninstall,
+       if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$ppppO", kwlist,
+                       convert_packages, &packages, &dryrun, &without_recommended, &allow_uninstall,
                        &allow_downgrade, &status_callback))
                return NULL;
 
@@ -392,6 +395,10 @@ static PyObject* Pakfire_install(PakfireObject* self, PyObject* args, PyObject*
                return NULL;
        }
 
+       // Enable dry-run mode
+       if (dryrun)
+               transaction_flags |= PAKFIRE_TRANSACTION_DRY_RUN;
+
        // Do not install recommended packages
        if (without_recommended)
                solver_flags |= PAKFIRE_REQUEST_WITHOUT_RECOMMENDED;
@@ -405,8 +412,8 @@ static PyObject* Pakfire_install(PakfireObject* self, PyObject* args, PyObject*
                solver_flags |= PAKFIRE_REQUEST_ALLOW_DOWNGRADE;
 
        // Run pakfire_install
-       int r = pakfire_install(self->pakfire, solver_flags, (const char**)packages,
-               NULL, 0, NULL, Pakfire_status_callback, status_callback);
+       int r = pakfire_install(self->pakfire, transaction_flags, solver_flags,
+               (const char**)packages, NULL, 0, NULL, Pakfire_status_callback, status_callback);
        if (r)
                PyErr_SetFromErrno(PyExc_OSError);
 
@@ -425,17 +432,20 @@ static PyObject* Pakfire_install(PakfireObject* self, PyObject* args, PyObject*
 static PyObject* Pakfire_erase(PakfireObject* self, PyObject* args, PyObject* kwargs) {
        char* kwlist[] = {
                "packages",
+               "dryrun",
                "keep_dependencies",
                "status_callback",
                NULL
        };
        char** packages = NULL;
+       int dryrun = 0;
        int keep_dependencies = 0;
+       int transaction_flags = 0;
        int flags = 0;
        PyObject* status_callback = NULL;
 
-       if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$pO", kwlist,
-                       convert_packages, &packages, &keep_dependencies, &status_callback))
+       if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$ppO", kwlist,
+                       convert_packages, &packages, &dryrun, &keep_dependencies, &status_callback))
                return NULL;
 
        // Check if callback is callable
@@ -444,12 +454,15 @@ static PyObject* Pakfire_erase(PakfireObject* self, PyObject* args, PyObject* kw
                return NULL;
        }
 
+       if (dryrun)
+               transaction_flags |= PAKFIRE_TRANSACTION_DRY_RUN;
+
        if (keep_dependencies)
                flags |= PAKFIRE_REQUEST_KEEP_DEPS;
 
        // Run pakfire_erase
-       int r = pakfire_erase(self->pakfire, 0, (const char**)packages, NULL, flags, NULL,
-               Pakfire_status_callback, status_callback);
+       int r = pakfire_erase(self->pakfire, transaction_flags, 0, (const char**)packages,
+               NULL, flags, NULL, Pakfire_status_callback, status_callback);
        if (r)
                PyErr_SetFromErrno(PyExc_OSError);
 
@@ -468,6 +481,7 @@ static PyObject* Pakfire_erase(PakfireObject* self, PyObject* args, PyObject* kw
 static PyObject* Pakfire_update(PakfireObject* self, PyObject* args, PyObject* kwargs) {
        char* kwlist[] = {
                "packages",
+               "dryrun",
                "excludes",
                "allow_uninstall",
                "allow_downgrade",
@@ -476,9 +490,11 @@ static PyObject* Pakfire_update(PakfireObject* self, PyObject* args, PyObject* k
        };
        char** packages = NULL;
        char** excludes = NULL;
+       int dryrun = 0;
        int allow_uninstall = 0;
        int allow_downgrade = 0;
        int solver_flags = 0;
+       int transaction_flags = 0;
        PyObject* status_callback = NULL;
 
        if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&ppO", kwlist,
@@ -492,6 +508,9 @@ static PyObject* Pakfire_update(PakfireObject* self, PyObject* args, PyObject* k
                return NULL;
        }
 
+       if (dryrun)
+               transaction_flags = PAKFIRE_TRANSACTION_DRY_RUN;
+
        // Can the solver uninstall packages?
        if (allow_uninstall)
                solver_flags |= PAKFIRE_REQUEST_ALLOW_UNINSTALL;
@@ -501,8 +520,9 @@ static PyObject* Pakfire_update(PakfireObject* self, PyObject* args, PyObject* k
                solver_flags |= PAKFIRE_REQUEST_ALLOW_DOWNGRADE;
 
        // Run pakfire_update
-       int r = pakfire_update(self->pakfire, solver_flags, (const char**)packages,
-               (const char**)excludes, 0, NULL, Pakfire_status_callback, status_callback);
+       int r = pakfire_update(self->pakfire, transaction_flags, solver_flags,
+               (const char**)packages, (const char**)excludes, 0, NULL,
+               Pakfire_status_callback, status_callback);
        if (r)
                PyErr_SetFromErrno(PyExc_OSError);
 
index d536346f17145c4b7b4a9aa057060bc19a4180d3..66a21fb5deeac073bee354d07c271053f29290cf 100644 (file)
@@ -776,7 +776,7 @@ PAKFIRE_EXPORT int pakfire_build(struct pakfire* pakfire, const char* path,
        };
 
        // Install the package into the build environment
-       r = pakfire_install(pakfire, 0, packages, NULL, PAKFIRE_REQUEST_ESSENTIAL,
+       r = pakfire_install(pakfire, 0, 0, packages, NULL, PAKFIRE_REQUEST_ESSENTIAL,
                NULL, NULL, NULL);
        if (r) {
                ERROR(pakfire, "Could not install %s\n", path);
@@ -895,7 +895,7 @@ PAKFIRE_EXPORT int pakfire_shell(struct pakfire* pakfire, const char** packages)
 
        // Install any additional packages
        if (packages) {
-               r = pakfire_install(pakfire, 0, packages, NULL, 0, NULL, NULL, NULL);
+               r = pakfire_install(pakfire, 0, 0, packages, NULL, 0, NULL, NULL, NULL);
                if (r)
                        return r;
        }
index ec731a8d2677e52ff502b59097df5b90d5064940..b901b8d502037e3fecdc79ee234f7b57fb1a2b29 100644 (file)
@@ -109,14 +109,14 @@ void pakfire_log_set_priority(struct pakfire* pakfire, int priority);
 
 // Install/Erase/Update
 
-int pakfire_install(struct pakfire* pakfire, int solver_flags, const char** packages,
-       const char** locks, int job_flags, int* changed,
+int pakfire_install(struct pakfire* pakfire, int transaction_flags, int solver_flags,
+       const char** packages, const char** locks, int job_flags, int* changed,
        pakfire_status_callback status_callback, void* status_callback_data);
-int pakfire_erase(struct pakfire* pakfire, int solver_flags, const char** packages,
-       const char** locks, int job_flags, int* changed,
+int pakfire_erase(struct pakfire* pakfire, int transaction_flags, int solver_flags,
+       const char** packages, const char** locks, int job_flags, int* changed,
        pakfire_status_callback status_callback, void* status_callback_data);
-int pakfire_update(struct pakfire* pakfire, int solver_flags, const char** packages,
-       const char** locks, int jobs_flags, int* changed,
+int pakfire_update(struct pakfire* pakfire, int transaction_flags, int solver_flags,
+       const char** packages, const char** locks, int jobs_flags, int* changed,
        pakfire_status_callback status_callback, void* status_callback_data);
 
 // Check
index 0cabaa81c50a8da8ed4ac6f154e329ec5b876357..8b8ec0405a00fcd5433e70e3298c96a3ea15179d 100644 (file)
 
 struct pakfire_transaction;
 
+enum pakfire_transaction_flags {
+       PAKFIRE_TRANSACTION_DRY_RUN = (1 << 0),
+};
+
 struct pakfire_transaction* pakfire_transaction_ref(struct pakfire_transaction* transaction);
 struct pakfire_transaction* pakfire_transaction_unref(struct pakfire_transaction* transaction);
 
@@ -32,7 +36,7 @@ char* pakfire_transaction_dump(struct pakfire_transaction* transaction, size_t w
 void pakfire_transaction_set_status_callback(
        struct pakfire_transaction* transaction, pakfire_status_callback callback, void* data);
 
-int pakfire_transaction_run(struct pakfire_transaction* transaction);
+int pakfire_transaction_run(struct pakfire_transaction* transaction, int flags);
 
 int pakfire_transaction_download(struct pakfire_transaction* transaction);
 
index 378ab095f525c05ddb394678033859472481fdbf..08fb8f20ec3624a0c3c0035ad524734b804aa1cb 100644 (file)
@@ -1670,10 +1670,17 @@ struct archive* pakfire_make_archive_disk_writer(struct pakfire* pakfire) {
 
 // Convenience functions to install/erase/update packages
 
-static int pakfire_perform_transaction(struct pakfire* pakfire, int solver_flags,
+static int pakfire_perform_transaction(
+               struct pakfire* pakfire,
+               int transaction_flags,
+               int solver_flags,
                int (*action)(struct pakfire_request* request, const char* what, int flags),
-               const char** packages, const char** locks, int job_flags, int* changed,
-               pakfire_status_callback status_callback, void* status_callback_data) {
+               const char** packages,
+               const char** locks,
+               int job_flags,
+               int* changed,
+               pakfire_status_callback status_callback,
+               void* status_callback_data) {
        struct pakfire_request* request = NULL;
        struct pakfire_transaction* transaction = NULL;
        struct pakfire_problem** problems = NULL;
@@ -1757,7 +1764,7 @@ static int pakfire_perform_transaction(struct pakfire* pakfire, int solver_flags
                        transaction, status_callback, status_callback_data);
 
        // Run the transaction
-       r = pakfire_transaction_run(transaction);
+       r = pakfire_transaction_run(transaction, transaction_flags);
        if (r)
                goto ERROR;
 
@@ -1782,18 +1789,50 @@ ERROR:
        return r;
 }
 
-PAKFIRE_EXPORT int pakfire_install(struct pakfire* pakfire, int solver_flags,
-               const char** packages, const char** locks, int flags, int* changed,
-               pakfire_status_callback status_callback, void* status_callback_data) {
-       return pakfire_perform_transaction(pakfire, solver_flags, pakfire_request_install,
-               packages, locks, flags, changed, status_callback, status_callback_data);
-}
-
-PAKFIRE_EXPORT int pakfire_erase(struct pakfire* pakfire, int solver_flags,
-               const char** packages, const char** locks, int flags, int* changed,
-               pakfire_status_callback status_callback, void* status_callback_data) {
-       return pakfire_perform_transaction(pakfire, solver_flags, pakfire_request_erase,
-               packages, locks, flags, changed, status_callback, status_callback_data);
+PAKFIRE_EXPORT int pakfire_install(
+               struct pakfire* pakfire,
+               int transaction_flags,
+               int solver_flags,
+               const char** packages,
+               const char** locks,
+               int flags,
+               int* changed,
+               pakfire_status_callback status_callback,
+               void* status_callback_data) {
+       return pakfire_perform_transaction(
+               pakfire,
+               transaction_flags,
+               solver_flags,
+               pakfire_request_install,
+               packages,
+               locks,
+               flags,
+               changed,
+               status_callback,
+               status_callback_data);
+}
+
+PAKFIRE_EXPORT int pakfire_erase(
+               struct pakfire* pakfire,
+               int transaction_flags,
+               int solver_flags,
+               const char** packages,
+               const char** locks,
+               int flags,
+               int* changed,
+               pakfire_status_callback status_callback,
+               void* status_callback_data) {
+       return pakfire_perform_transaction(
+               pakfire,
+               transaction_flags,
+               solver_flags,
+               pakfire_request_erase,
+               packages,
+               locks,
+               flags,
+               changed,
+               status_callback,
+               status_callback_data);
 }
 
 static int pakfire_perform_transaction_simple(struct pakfire* pakfire, int solver_flags,
@@ -1862,7 +1901,7 @@ static int pakfire_perform_transaction_simple(struct pakfire* pakfire, int solve
                        transaction, status_callback, status_callback_data);
 
        // Run the transaction
-       r = pakfire_transaction_run(transaction);
+       r = pakfire_transaction_run(transaction, 0);
        if (r)
                goto ERROR;
 
@@ -1886,9 +1925,16 @@ ERROR:
        return r;
 }
 
-PAKFIRE_EXPORT int pakfire_update(struct pakfire* pakfire, int solver_flags,
-               const char** packages, const char** locks, int flags, int* changed,
-               pakfire_status_callback status_callback, void* status_callback_data) {
+PAKFIRE_EXPORT int pakfire_update(
+               struct pakfire* pakfire,
+               int transaction_flags,
+               int solver_flags,
+               const char** packages,
+               const char** locks,
+               int flags,
+               int* changed,
+               pakfire_status_callback status_callback,
+               void* status_callback_data) {
        // If no packages are being passed, we will try to update everything
        // XXX add locks
        if (!packages)
@@ -1896,8 +1942,9 @@ PAKFIRE_EXPORT int pakfire_update(struct pakfire* pakfire, int solver_flags,
                        pakfire, solver_flags, pakfire_request_update_all, flags, changed,
                        status_callback, status_callback_data);
 
-       return pakfire_perform_transaction(pakfire, solver_flags, pakfire_request_update,
-               packages, locks, flags, changed, status_callback, status_callback_data);
+       return pakfire_perform_transaction(pakfire, transaction_flags, solver_flags,
+               pakfire_request_update, packages, locks, flags, changed,
+               status_callback, status_callback_data);
 }
 
 static int pakfire_verify(struct pakfire* pakfire, int *changed) {
@@ -1958,7 +2005,7 @@ static int pakfire_build_install_packages(struct pakfire* pakfire, int* snapshot
        int changed = 0;
 
        // Install everything
-       r = pakfire_install(pakfire, 0, (const char**)packages, NULL, 0, &changed, NULL, NULL);
+       r = pakfire_install(pakfire, 0, 0, (const char**)packages, NULL, 0, &changed, NULL, NULL);
        if (r) {
                ERROR(pakfire, "Could not install build dependencies: %m\n");
                goto ERROR;
index e7f92b6a9f77e4cfb150f315f9b93110751bd586..6e853207483611de6b1c34b19c3bd3be6058c44c 100644 (file)
@@ -1254,7 +1254,8 @@ ERROR:
        return r;
 }
 
-PAKFIRE_EXPORT int pakfire_transaction_run(struct pakfire_transaction* transaction) {
+PAKFIRE_EXPORT int pakfire_transaction_run(
+               struct pakfire_transaction* transaction, int flags) {
        int r;
 
        // Skip running an empty transaction
@@ -1283,6 +1284,10 @@ PAKFIRE_EXPORT int pakfire_transaction_run(struct pakfire_transaction* transacti
        if (r)
                goto ERROR;
 
+       // End here for a dry run
+       if (flags & PAKFIRE_TRANSACTION_DRY_RUN)
+               goto ERROR;
+
        // Download what we need
        r = pakfire_transaction_download(transaction);
        if (r)