]> git.ipfire.org Git - pakfire.git/commitdiff
transactions: Major rewrite of step generation
authorMichael Tremer <michael.tremer@ipfire.org>
Thu, 21 Sep 2023 10:40:09 +0000 (10:40 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Thu, 21 Sep 2023 10:40:09 +0000 (10:40 +0000)
When we extract from libsolv what steps we need to perform in order to
apply the changes to our system, there was a problem that when updating
packages, the previous version was not properly removed from the
database.

This has now been fixed by adding additional steps which are passive and
will remove the left-over metadata.

This should hopefully make the entire process more robust and easier to
handle in the code as each step has one simple job to do.

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

index ae09b79390e8910e59c6a8051b3d4640f2f094bb..7d88d4de3e7c1c5dadd5adf344d06ab7660f48f5 100644 (file)
@@ -22,6 +22,7 @@
 #include <stdlib.h>
 
 #include <solv/transaction.h>
+#include <solv/solverdebug.h>
 
 #include <pakfire/archive.h>
 #include <pakfire/db.h>
@@ -70,48 +71,56 @@ enum pakfire_actions {
 };
 
 enum pakfire_steps {
-       PAKFIRE_STEP_IGNORE = 0,
+       PAKFIRE_STEP_UNKNOWN = 0,
        PAKFIRE_STEP_INSTALL,
        PAKFIRE_STEP_REINSTALL,
+       PAKFIRE_STEP_REINSTALLED,
        PAKFIRE_STEP_ERASE,
        PAKFIRE_STEP_UPGRADE,
+       PAKFIRE_STEP_UPGRADED,
        PAKFIRE_STEP_DOWNGRADE,
-       PAKFIRE_STEP_OBSOLETE,
+       PAKFIRE_STEP_DOWNGRADED,
 };
 
 static enum pakfire_steps pakfire_transaction_get_step_type(
                struct pakfire_transaction* transaction, struct pakfire_package* pkg) {
-       int type = transaction_type(transaction->transaction, pakfire_package_id(pkg),
-               SOLVER_TRANSACTION_SHOW_ACTIVE|SOLVER_TRANSACTION_CHANGE_IS_REINSTALL);
+       const Id id = pakfire_package_id(pkg);
+
+       int type = transaction_type(transaction->transaction, id, SOLVER_TRANSACTION_SHOW_ACTIVE);
+
+       // If this step is being ignored in active mode, we try passive mode
+       if (type == SOLVER_TRANSACTION_IGNORE)
+               type = transaction_type(transaction->transaction, id, 0);
 
        // Translate solver types into our own types
        switch (type) {
                case SOLVER_TRANSACTION_INSTALL:
-               case SOLVER_TRANSACTION_MULTIINSTALL:
                        return PAKFIRE_STEP_INSTALL;
 
                case SOLVER_TRANSACTION_REINSTALL:
-               case SOLVER_TRANSACTION_MULTIREINSTALL:
                        return PAKFIRE_STEP_REINSTALL;
 
+               case SOLVER_TRANSACTION_REINSTALLED:
+                       return PAKFIRE_STEP_REINSTALLED;
+
                case SOLVER_TRANSACTION_ERASE:
                        return PAKFIRE_STEP_ERASE;
 
-               case SOLVER_TRANSACTION_DOWNGRADE:
-                       return PAKFIRE_STEP_DOWNGRADE;
-
                case SOLVER_TRANSACTION_UPGRADE:
                        return PAKFIRE_STEP_UPGRADE;
 
-               case SOLVER_TRANSACTION_OBSOLETES:
-                       return PAKFIRE_STEP_OBSOLETE;
+               case SOLVER_TRANSACTION_UPGRADED:
+                       return PAKFIRE_STEP_UPGRADED;
+
+               case SOLVER_TRANSACTION_DOWNGRADE:
+                       return PAKFIRE_STEP_DOWNGRADE;
 
-               // Anything we don't care about
-               case SOLVER_TRANSACTION_IGNORE:
-               case SOLVER_TRANSACTION_REINSTALLED:
                case SOLVER_TRANSACTION_DOWNGRADED:
+                       return PAKFIRE_STEP_DOWNGRADED;
+
                default:
-                               return PAKFIRE_STEP_IGNORE;
+                       ERROR(transaction->pakfire, "Unhandled step type 0x%x. Ignoring.\n", type);
+                       return PAKFIRE_STEP_UNKNOWN;
        }
 }
 
@@ -164,6 +173,9 @@ static int pakfire_transaction_import_transaction(
        // Order the transaction
        transaction_order(t, 0);
 
+       // Log the transaction
+       transaction_print(t);
+
        // Free any previous content
        pakfire_transaction_free_archives_and_packages(transaction);
 
@@ -818,6 +830,39 @@ static const char* pakfire_action_type_string(enum pakfire_actions type) {
        return NULL;
 }
 
+static const char* pakfire_step_type_string(enum pakfire_steps type) {
+       switch (type) {
+               case PAKFIRE_STEP_UNKNOWN:
+                       return "UNKNOWN";
+
+               case PAKFIRE_STEP_INSTALL:
+                       return "INSTALL";
+
+               case PAKFIRE_STEP_REINSTALL:
+                       return "REINSTALL";
+
+               case PAKFIRE_STEP_REINSTALLED:
+                       return "REINSTALLED";
+
+               case PAKFIRE_STEP_ERASE:
+                       return "ERASE";
+
+               case PAKFIRE_STEP_UPGRADE:
+                       return "UPGRADE";
+
+               case PAKFIRE_STEP_UPGRADED:
+                       return "UPGRADED";
+
+               case PAKFIRE_STEP_DOWNGRADE:
+                       return "DOWNGRADE";
+
+               case PAKFIRE_STEP_DOWNGRADED:
+                       return "DOWNGRADED";
+       }
+
+       return NULL;
+}
+
 static int pakfire_transaction_package_is_userinstalled(
                struct pakfire_transaction* transaction, struct pakfire_package* pkg) {
        // No packages on the list
@@ -864,7 +909,8 @@ static int pakfire_transaction_run_step(struct pakfire_transaction* transaction,
        const char* nevra = pakfire_package_get_string(pkg, PAKFIRE_PKG_NEVRA);
        const enum pakfire_steps type = pakfire_transaction_get_step_type(transaction, pkg);
 
-       DEBUG(transaction->pakfire, "Running %s for %s\n", pakfire_action_type_string(action), nevra);
+       ERROR(transaction->pakfire, "Running %s (%s) for %s\n",
+               pakfire_action_type_string(action), pakfire_step_type_string(type), nevra);
 
        int r = 0;
        switch (action) {
@@ -889,12 +935,14 @@ static int pakfire_transaction_run_step(struct pakfire_transaction* transaction,
                                        break;
 
                                case PAKFIRE_STEP_ERASE:
-                               case PAKFIRE_STEP_OBSOLETE:
                                        r = pakfire_transaction_run_script(transaction, db,
                                                "pretransun", pkg, archive);
                                        break;
 
-                               case PAKFIRE_STEP_IGNORE:
+                               case PAKFIRE_STEP_REINSTALLED:
+                               case PAKFIRE_STEP_UPGRADED:
+                               case PAKFIRE_STEP_DOWNGRADED:
+                               case PAKFIRE_STEP_UNKNOWN:
                                        break;
                        }
                        break;
@@ -915,12 +963,14 @@ static int pakfire_transaction_run_step(struct pakfire_transaction* transaction,
                                        break;
 
                                case PAKFIRE_STEP_ERASE:
-                               case PAKFIRE_STEP_OBSOLETE:
                                        r = pakfire_transaction_run_script(transaction, db,
                                                "posttransun", pkg, archive);
                                        break;
 
-                               case PAKFIRE_STEP_IGNORE:
+                               case PAKFIRE_STEP_REINSTALLED:
+                               case PAKFIRE_STEP_UPGRADED:
+                               case PAKFIRE_STEP_DOWNGRADED:
+                               case PAKFIRE_STEP_UNKNOWN:
                                        break;
                        }
                        break;
@@ -1002,7 +1052,6 @@ static int pakfire_transaction_run_step(struct pakfire_transaction* transaction,
                                        break;
 
                                case PAKFIRE_STEP_ERASE:
-                               case PAKFIRE_STEP_OBSOLETE:
                                        r = pakfire_transaction_run_script(transaction, db,
                                                "preun", pkg, archive);
                                        if (r)
@@ -1020,7 +1069,20 @@ static int pakfire_transaction_run_step(struct pakfire_transaction* transaction,
                                                "postun", pkg, archive);
                                        break;
 
-                               case PAKFIRE_STEP_IGNORE:
+                               // Erase the package data without running any scripts
+                               case PAKFIRE_STEP_UPGRADED:
+                               case PAKFIRE_STEP_DOWNGRADED:
+                                       r = pakfire_transaction_erase(transaction, db, pkg);
+                                       if (r)
+                                               break;
+
+                                       r = pakfire_db_remove_package(db, pkg);
+                                       if (r)
+                                               break;
+                                       break;
+
+                               case PAKFIRE_STEP_REINSTALLED:
+                               case PAKFIRE_STEP_UNKNOWN:
                                        break;
                        }
                        break;
@@ -1087,11 +1149,13 @@ static int pakfire_transaction_open_archives(struct pakfire_transaction* transac
                        case PAKFIRE_STEP_REINSTALL:
                        case PAKFIRE_STEP_UPGRADE:
                        case PAKFIRE_STEP_DOWNGRADE:
-                       case PAKFIRE_STEP_OBSOLETE:
                                break;
 
+                       case PAKFIRE_STEP_REINSTALLED:
                        case PAKFIRE_STEP_ERASE:
-                       case PAKFIRE_STEP_IGNORE:
+                       case PAKFIRE_STEP_UPGRADED:
+                       case PAKFIRE_STEP_DOWNGRADED:
+                       case PAKFIRE_STEP_UNKNOWN:
                                continue;
                }