diff --git a/common/flatpak-dir-private.h b/common/flatpak-dir-private.h index a972e851e..2258b84f3 100644 --- a/common/flatpak-dir-private.h +++ b/common/flatpak-dir-private.h @@ -813,6 +813,11 @@ gboolean flatpak_dir_remove_ref (Fla const char *ref, GCancellable *cancellable, GError **error); +gboolean flatpak_dir_remove_undeployed_ref (FlatpakDir *self, + const char *remote_name, + const char *ref, + GCancellable *cancellable, + GError **error); gboolean flatpak_dir_update_exports (FlatpakDir *self, const char *app, GCancellable *cancellable, diff --git a/common/flatpak-dir.c b/common/flatpak-dir.c index 035b85811..67f38a6ac 100644 --- a/common/flatpak-dir.c +++ b/common/flatpak-dir.c @@ -12359,25 +12359,61 @@ flatpak_dir_undeploy_all (FlatpakDir *self, * flatpak_dir_remove_ref: * @self: a #FlatpakDir * @remote_name: the name of the remote - * @ref: the flatpak ref to remove + * @ref: the ref to remove * @cancellable: (nullable) (optional): a #GCancellable * @error: a #GError * - * Remove the flatpak ref given by @remote_name:@ref from the underlying - * OSTree repo. Attempting to remove a ref that is currently deployed - * is an error, you need to uninstall the flatpak first. Note that this does - * not remove the objects bound to @ref from the disk, you will need to - * call flatpak_dir_prune() to do that. + * Remove the ref given by @remote_name:@ref from the underlying + * OSTree repo. Note that this does not remove the objects bound to + * @ref from the disk, you will need to call flatpak_dir_prune() + * to do that. * * Returns: %TRUE if removing the ref succeeded, %FALSE otherwise. */ gboolean flatpak_dir_remove_ref (FlatpakDir *self, const char *remote_name, - const char *ref, /* NOTE: Not necessarily a app/runtime ref */ + const char *ref, GCancellable *cancellable, GError **error) { + if (!ostree_repo_set_ref_immediate (self->repo, + remote_name, + ref, + NULL, + cancellable, + error)) + return FALSE; + + return TRUE; +} + +/** + * flatpak_dir_remove_undeployed_ref: + * @self: a #FlatpakDir + * @remote_name: the name of the remote + * @ref: the flatpak ref to remove + * @cancellable: (nullable) (optional): a #GCancellable + * @error: a #GError + * + * Remove the flatpak ref given by @remote_name:@ref from the underlying + * OSTree repo. The ref must be a valid app or runtime ref, and it must + * not be currently deployed. Note that this does not remove the objects + * bound to @ref from the disk, you will need to call + * flatpak_dir_prune() to do that. + * + * Returns: %TRUE if removing the ref succeeded, %FALSE otherwise. + */ +gboolean +flatpak_dir_remove_undeployed_ref (FlatpakDir *self, + const char *remote_name, + const char *ref, + GCancellable *cancellable, + GError **error) +{ + g_autoptr(FlatpakDecomposed) decomposed = NULL; + g_autoptr(GBytes) deploy_data = NULL; + if (flatpak_dir_use_system_helper (self, NULL)) { const char *installation = flatpak_dir_get_id (self); @@ -12394,15 +12430,21 @@ flatpak_dir_remove_ref (FlatpakDir *self, return TRUE; } - if (!ostree_repo_set_ref_immediate (self->repo, - remote_name, - ref, - NULL, - cancellable, - error)) + decomposed = flatpak_decomposed_new_from_ref (ref, error); + if (decomposed == NULL) return FALSE; - return TRUE; + deploy_data = flatpak_dir_get_deploy_data (self, decomposed, + FLATPAK_DEPLOY_VERSION_ANY, + NULL, NULL); + if (deploy_data != NULL) + { + g_set_error (error, FLATPAK_ERROR, FLATPAK_ERROR_ALREADY_INSTALLED, + _("%s is currently deployed, you need to uninstall it first"), ref); + return FALSE; + } + + return flatpak_dir_remove_ref (self, remote_name, ref, cancellable, error); } gboolean @@ -14946,7 +14988,7 @@ flatpak_dir_cleanup_undeployed_refs (FlatpakDir *self, FlatpakDecomposed *ref = g_ptr_array_index (undeployed_refs, i); g_autofree gchar *remote = flatpak_decomposed_dup_remote (ref); - if (!flatpak_dir_remove_ref (self, remote, flatpak_decomposed_get_ref (ref), cancellable, error)) + if (!flatpak_dir_remove_undeployed_ref (self, remote, flatpak_decomposed_get_ref (ref), cancellable, error)) return FALSE; } diff --git a/common/flatpak-installation.c b/common/flatpak-installation.c index d73da24a0..5dc4eca56 100644 --- a/common/flatpak-installation.c +++ b/common/flatpak-installation.c @@ -2958,8 +2958,10 @@ flatpak_installation_list_remote_related_refs_for_installed_sync (FlatpakInstall * @error: return location for a #GError * * Remove the OSTree ref given by @remote_name:@ref from the local flatpak - * repository. The next time the underlying OSTree repo is pruned, objects - * which were attached to that ref will be removed. This is useful if you + * repository. The ref must not be currently deployed; attempting to remove + * a deployed ref will return an error. Use flatpak_installation_uninstall_full() + * to remove deployed refs. The next time the underlying OSTree repo is pruned, + * objects which were attached to that ref will be removed. This is useful if you * pulled a flatpak ref using flatpak_installation_install_full() and * specified %FLATPAK_INSTALL_FLAGS_NO_DEPLOY but then decided not to * deploy the ref later on and want to remove the local ref to prevent it @@ -2983,7 +2985,7 @@ flatpak_installation_remove_local_ref_sync (FlatpakInstallation *self, if (dir == NULL) return FALSE; - return flatpak_dir_remove_ref (dir, remote_name, ref, cancellable, error); + return flatpak_dir_remove_undeployed_ref (dir, remote_name, ref, cancellable, error); } /** diff --git a/system-helper/flatpak-system-helper.c b/system-helper/flatpak-system-helper.c index 3885a5394..7df34e1e8 100644 --- a/system-helper/flatpak-system-helper.c +++ b/system-helper/flatpak-system-helper.c @@ -1294,7 +1294,7 @@ handle_remove_local_ref (FlatpakSystemHelper *object, return G_DBUS_METHOD_INVOCATION_HANDLED; } - if (!flatpak_dir_remove_ref (system, arg_remote, arg_ref, NULL, &error)) + if (!flatpak_dir_remove_undeployed_ref (system, arg_remote, arg_ref, NULL, &error)) { flatpak_invocation_return_error (invocation, error, "Error removing ref"); return G_DBUS_METHOD_INVOCATION_HANDLED;