From 919d2922bf72bbbfab096d3b359be99d4ca4dd2d Mon Sep 17 00:00:00 2001 From: Mary Strodl Date: Mon, 2 Oct 2023 17:59:57 -0400 Subject: [PATCH] common: support reinstall option on bundle installations Fixes #2489 Adds and wires up a `reinstall` option to `flatpak_dir_install_bundle`. Previously, bundle install transactions would silently drop the reinstall flag. --- common/flatpak-dir-private.h | 5 +++- common/flatpak-dir.c | 41 ++++++++++++++++++++------- common/flatpak-installation.c | 2 +- common/flatpak-transaction.c | 2 +- system-helper/flatpak-system-helper.c | 4 ++- tests/test-bundle.sh | 5 ++++ 6 files changed, 44 insertions(+), 15 deletions(-) diff --git a/common/flatpak-dir-private.h b/common/flatpak-dir-private.h index 6082ccc5..f09e89d1 100644 --- a/common/flatpak-dir-private.h +++ b/common/flatpak-dir-private.h @@ -243,9 +243,11 @@ typedef enum { typedef enum { FLATPAK_HELPER_INSTALL_BUNDLE_FLAGS_NONE = 0, FLATPAK_HELPER_INSTALL_BUNDLE_FLAGS_NO_INTERACTION = 1 << 0, + FLATPAK_HELPER_INSTALL_BUNDLE_FLAGS_REINSTALL = 1 << 1, } FlatpakHelperInstallBundleFlags; -#define FLATPAK_HELPER_INSTALL_BUNDLE_FLAGS_ALL (FLATPAK_HELPER_INSTALL_BUNDLE_FLAGS_NO_INTERACTION) +#define FLATPAK_HELPER_INSTALL_BUNDLE_FLAGS_ALL (FLATPAK_HELPER_INSTALL_BUNDLE_FLAGS_NO_INTERACTION | \ + FLATPAK_HELPER_INSTALL_BUNDLE_FLAGS_REINSTALL) typedef enum { FLATPAK_HELPER_DEPLOY_APPSTREAM_FLAGS_NONE = 0, @@ -731,6 +733,7 @@ char * flatpak_dir_ensure_bundle_remote (Fla GCancellable *cancellable, GError **error); gboolean flatpak_dir_install_bundle (FlatpakDir *self, + gboolean reinstall, GFile *file, const char *remote, FlatpakDecomposed **out_ref, diff --git a/common/flatpak-dir.c b/common/flatpak-dir.c index 8976c9bf..a4575128 100644 --- a/common/flatpak-dir.c +++ b/common/flatpak-dir.c @@ -10658,6 +10658,7 @@ flatpak_dir_check_add_remotes_config_dir (FlatpakDir *self, gboolean flatpak_dir_install_bundle (FlatpakDir *self, + gboolean reinstall, GFile *file, const char *remote, FlatpakDecomposed **out_ref, @@ -10671,6 +10672,7 @@ flatpak_dir_install_bundle (FlatpakDir *self, g_autofree char *origin = NULL; g_autofree char *to_checksum = NULL; gboolean gpg_verify; + FlatpakHelperInstallBundleFlags install_flags = FLATPAK_HELPER_INSTALL_BUNDLE_FLAGS_NONE; if (!flatpak_dir_check_add_remotes_config_dir (self, error)) return FALSE; @@ -10679,9 +10681,13 @@ flatpak_dir_install_bundle (FlatpakDir *self, { const char *installation = flatpak_dir_get_id (self); + if (reinstall) + install_flags |= FLATPAK_HELPER_INSTALL_BUNDLE_FLAGS_REINSTALL; + if (!flatpak_dir_system_helper_call_install_bundle (self, flatpak_file_get_path_cached (file), - 0, remote, + install_flags, + remote, installation ? installation : "", &ref_str, cancellable, @@ -10716,17 +10722,30 @@ flatpak_dir_install_bundle (FlatpakDir *self, { if (strcmp (flatpak_deploy_data_get_commit (deploy_data), to_checksum) == 0) { - g_autofree char *id = flatpak_decomposed_dup_id (ref); - g_set_error (error, FLATPAK_ERROR, FLATPAK_ERROR_ALREADY_INSTALLED, - _("This version of %s is already installed"), id); - return FALSE; + if (reinstall) + { + g_clear_pointer (&deploy_data, g_bytes_unref); + } + else + { + g_autofree char *id = flatpak_decomposed_dup_id (ref); + g_set_error (error, FLATPAK_ERROR, FLATPAK_ERROR_ALREADY_INSTALLED, + _("This version of %s is already installed"), id); + return FALSE; + } } - - if (strcmp (remote, flatpak_deploy_data_get_origin (deploy_data)) != 0) + else if (strcmp (remote, flatpak_deploy_data_get_origin (deploy_data)) != 0) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - _("Can't change remote during bundle install")); - return FALSE; + if (reinstall) + { + g_clear_pointer (&deploy_data, g_bytes_unref); + } + else + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + _("Can't change remote during bundle install")); + return FALSE; + } } } @@ -10782,7 +10801,7 @@ flatpak_dir_install_bundle (FlatpakDir *self, } else { - if (!flatpak_dir_deploy_install (self, ref, remote, NULL, NULL, FALSE, FALSE, FALSE, cancellable, error)) + if (!flatpak_dir_deploy_install (self, ref, remote, NULL, NULL, reinstall, FALSE, FALSE, cancellable, error)) return FALSE; } diff --git a/common/flatpak-installation.c b/common/flatpak-installation.c index be706174..63b3b15b 100644 --- a/common/flatpak-installation.c +++ b/common/flatpak-installation.c @@ -1775,7 +1775,7 @@ flatpak_installation_install_bundle (FlatpakInstallation *self, if (!flatpak_dir_ensure_repo (dir_clone, cancellable, error)) return NULL; - if (!flatpak_dir_install_bundle (dir_clone, file, remote, NULL, + if (!flatpak_dir_install_bundle (dir_clone, FALSE, file, remote, NULL, cancellable, error)) return NULL; diff --git a/common/flatpak-transaction.c b/common/flatpak-transaction.c index f153a805..5deb52e6 100644 --- a/common/flatpak-transaction.c +++ b/common/flatpak-transaction.c @@ -5158,7 +5158,7 @@ _run_op_kind (FlatpakTransaction *self, op->resolved_metakey, error)) res = FALSE; else - res = flatpak_dir_install_bundle (priv->dir, op->bundle, + res = flatpak_dir_install_bundle (priv->dir, priv->reinstall, op->bundle, op->remote, NULL, cancellable, error); flatpak_transaction_progress_done (progress); diff --git a/system-helper/flatpak-system-helper.c b/system-helper/flatpak-system-helper.c index 623c2fa0..4a1e47de 100644 --- a/system-helper/flatpak-system-helper.c +++ b/system-helper/flatpak-system-helper.c @@ -973,6 +973,7 @@ handle_install_bundle (FlatpakSystemHelper *object, g_autoptr(GFile) bundle_file = g_file_new_for_path (arg_bundle_path); g_autoptr(GError) error = NULL; g_autoptr(FlatpakDecomposed) ref = NULL; + gboolean reinstall; g_info ("InstallBundle %s %u %s %s", arg_bundle_path, arg_flags, arg_remote, arg_installation); @@ -997,7 +998,8 @@ handle_install_bundle (FlatpakSystemHelper *object, return G_DBUS_METHOD_INVOCATION_HANDLED; } - if (!flatpak_dir_install_bundle (system, bundle_file, arg_remote, &ref, NULL, &error)) + reinstall = !!(arg_flags & FLATPAK_HELPER_INSTALL_BUNDLE_FLAGS_NO_INTERACTION); + if (!flatpak_dir_install_bundle (system, reinstall, bundle_file, arg_remote, &ref, NULL, &error)) { flatpak_invocation_return_error (invocation, error, "Error installing bundle"); return G_DBUS_METHOD_INVOCATION_HANDLED; diff --git a/tests/test-bundle.sh b/tests/test-bundle.sh index 63c314a8..157c1536 100755 --- a/tests/test-bundle.sh +++ b/tests/test-bundle.sh @@ -48,6 +48,11 @@ ok "create bundles client-side" ${FLATPAK} uninstall ${U} -y org.test.Hello >&2 ${FLATPAK} install ${U} -y --bundle bundles/hello.flatpak >&2 +# Installing again without reinstall option should fail... +! ${FLATPAK} install ${U} -y --bundle bundles/hello.flatpak >&2 +# Now with reinstall option it should pass... +${FLATPAK} install ${U} -y --bundle bundles/hello.flatpak --reinstall >&2 + # This should have installed the runtime dependency too assert_has_file $FL_DIR/repo/refs/remotes/test-repo/runtime/org.test.Platform/$ARCH/master