From 3aa9a7f3a12e95e16051e43ba1a28ca837b4c3c5 Mon Sep 17 00:00:00 2001 From: Phaedrus Leeds Date: Tue, 12 Oct 2021 15:07:31 -0700 Subject: app: Fix behavior when installing end-of-life-rebased ref Currently if the user specifies a ref to install that has been renamed via the end-of-life-rebased mechanism, for example "flatpak install com.visualstudio.code.oss", Flatpak erroneously tries to install both the old and new versions of the app. This happens because the code handling end-of-life-rebase conditions is written assuming the rebased app is being updated rather than installed for the first time. Specifically, in FlatpakCliTransaction and FlatpakQuietTransaction, in end_of_lifed_with_rebase(), we treat a failure of flatpak_transaction_add_uninstall() as fatal and return FALSE from the signal handler, which means that the install operation that triggered the signal will not be skipped (see the docs for FlatpakTransaction::end-of-lifed-with-rebase). So, instead check for the FLATPAK_ERROR_NOT_INSTALLED error code and ignore it, so that the installation of the old version of the renamed app will be properly cancelled. Fixes https://github.com/flatpak/flatpak/issues/3754 --- app/flatpak-cli-transaction.c | 20 +++++++++++++++++--- app/flatpak-quiet-transaction.c | 17 +++++++++++++++-- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/app/flatpak-cli-transaction.c b/app/flatpak-cli-transaction.c index 788be097..aa2a23cb 100644 --- a/app/flatpak-cli-transaction.c +++ b/app/flatpak-cli-transaction.c @@ -772,8 +772,7 @@ end_of_lifed_with_rebase (FlatpakTransaction *transaction, { g_autoptr(GError) error = NULL; - if (!flatpak_transaction_add_rebase (transaction, remote, rebased_to_ref, NULL, previous_ids, &error) || - !flatpak_transaction_add_uninstall (transaction, ref_str, &error)) + if (!flatpak_transaction_add_rebase (transaction, remote, rebased_to_ref, NULL, previous_ids, &error)) { g_propagate_prefixed_error (&self->first_operation_error, g_error_copy (error), @@ -782,7 +781,22 @@ end_of_lifed_with_rebase (FlatpakTransaction *transaction, return FALSE; } - return TRUE; /* skip update op, in favour of added uninstall */ + if (!flatpak_transaction_add_uninstall (transaction, ref_str, &error)) + { + /* NOT_INSTALLED error is expected in case the op that triggered this was install not update */ + if (g_error_matches (error, FLATPAK_ERROR, FLATPAK_ERROR_NOT_INSTALLED)) + g_clear_error (&error); + else + { + g_propagate_prefixed_error (&self->first_operation_error, + g_error_copy (error), + _("Failed to uninstall %s for rebase to %s: "), + name, rebased_to_ref); + return FALSE; + } + } + + return TRUE; /* skip install/update op of end-of-life ref */ } else /* IGNORE or NO_REBASE */ return FALSE; diff --git a/app/flatpak-quiet-transaction.c b/app/flatpak-quiet-transaction.c index e0f059ef..a820c082 100644 --- a/app/flatpak-quiet-transaction.c +++ b/app/flatpak-quiet-transaction.c @@ -222,8 +222,7 @@ end_of_lifed_with_rebase (FlatpakTransaction *transaction, g_print (_("Updating to rebased version\n")); - if (!flatpak_transaction_add_rebase (transaction, remote, rebased_to_ref, NULL, previous_ids, &error) || - !flatpak_transaction_add_uninstall (transaction, ref, &error)) + if (!flatpak_transaction_add_rebase (transaction, remote, rebased_to_ref, NULL, previous_ids, &error)) { g_printerr (_("Failed to rebase %s to %s: %s\n"), flatpak_ref_get_name (rref), rebased_to_ref, error->message); @@ -231,6 +230,20 @@ end_of_lifed_with_rebase (FlatpakTransaction *transaction, return FALSE; } + if (!flatpak_transaction_add_uninstall (transaction, ref, &error)) + { + /* NOT_INSTALLED error is expected in case the op that triggered this was install not update */ + if (g_error_matches (error, FLATPAK_ERROR, FLATPAK_ERROR_NOT_INSTALLED)) + g_clear_error (&error); + else + { + g_printerr (_("Failed to uninstall %s for rebase to %s: %s\n"), + flatpak_ref_get_name (rref), rebased_to_ref, error->message); + self->got_error = TRUE; + return FALSE; + } + } + return TRUE; } -- cgit v1.2.1