From a5d86b8acb08f5bac014c8fa205f436700b31827 Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Wed, 7 Oct 2020 18:59:28 +0200 Subject: [PATCH] transaction: inject eol status to flatpak_dir_list_unused_refs() This way we can get the proper eol status for the new to-be-installed refs, rather than whatever was previously installed. This allows us to detect when a runtime is updated and the new one is eol, and nothing uses it, so it can be auto-uninstalled. --- app/flatpak-builtins-uninstall.c | 2 +- common/flatpak-dir-private.h | 1 + common/flatpak-dir.c | 25 ++++++++++++++++++------- common/flatpak-installation.c | 2 +- common/flatpak-transaction.c | 11 +++++++++-- tests/list-unused.c | 2 +- 6 files changed, 31 insertions(+), 12 deletions(-) diff --git a/app/flatpak-builtins-uninstall.c b/app/flatpak-builtins-uninstall.c index 1bfe7a5c..e171d49e 100644 --- a/app/flatpak-builtins-uninstall.c +++ b/app/flatpak-builtins-uninstall.c @@ -245,7 +245,7 @@ flatpak_builtin_uninstall (int argc, char **argv, GCancellable *cancellable, GEr udir = uninstall_dir_ensure (uninstall_dirs, dir); - unused = flatpak_dir_list_unused_refs (dir, opt_arch, NULL, NULL, FALSE, cancellable, error); + unused = flatpak_dir_list_unused_refs (dir, opt_arch, NULL, NULL, NULL, FALSE, cancellable, error); if (unused == NULL) return FALSE; diff --git a/common/flatpak-dir-private.h b/common/flatpak-dir-private.h index 89a8c4f1..86265291 100644 --- a/common/flatpak-dir-private.h +++ b/common/flatpak-dir-private.h @@ -1022,6 +1022,7 @@ gboolean flatpak_dir_delete_mirror_refs (FlatpakDir *self, char ** flatpak_dir_list_unused_refs (FlatpakDir *self, const char *arch, GHashTable *metadata_injection, + GHashTable *eol_injection, const char * const *refs_to_exclude, gboolean filter_by_eol, GCancellable *cancellable, diff --git a/common/flatpak-dir.c b/common/flatpak-dir.c index 44b6c01e..ee06c9e7 100644 --- a/common/flatpak-dir.c +++ b/common/flatpak-dir.c @@ -14909,6 +14909,7 @@ char ** flatpak_dir_list_unused_refs (FlatpakDir *self, const char *arch, GHashTable *metadata_injection, + GHashTable *eol_injection, const char * const *refs_to_exclude, gboolean filter_by_eol, GCancellable *cancellable, @@ -14970,14 +14971,24 @@ flatpak_dir_list_unused_refs (FlatpakDir *self, if (filter_by_eol) { - g_autoptr(GBytes) deploy_data = NULL; - deploy_data = flatpak_dir_get_deploy_data (self, ref, FLATPAK_DEPLOY_VERSION_ANY, - cancellable, error); - if (deploy_data == NULL) - return NULL; + gboolean is_eol = FALSE; - if (flatpak_deploy_data_get_eol (deploy_data) == NULL && - flatpak_deploy_data_get_eol_rebase (deploy_data) == NULL) + if (eol_injection && g_hash_table_contains (eol_injection, ref)) + { + is_eol = GPOINTER_TO_INT (g_hash_table_lookup (eol_injection, ref)); + } + else + { + g_autoptr(GBytes) deploy_data = NULL; + + deploy_data = flatpak_dir_get_deploy_data (self, ref, FLATPAK_DEPLOY_VERSION_ANY, + cancellable, NULL); + is_eol = deploy_data != NULL && + (flatpak_deploy_data_get_eol (deploy_data) != NULL || + flatpak_deploy_data_get_eol_rebase (deploy_data)); + } + + if (!is_eol) { g_debug ("Ref %s is not EOL, considering as used", ref); continue; diff --git a/common/flatpak-installation.c b/common/flatpak-installation.c index 9c72f76f..fc4acb87 100644 --- a/common/flatpak-installation.c +++ b/common/flatpak-installation.c @@ -2961,7 +2961,7 @@ flatpak_installation_list_unused_refs_with_options (FlatpakInstallation *self, if (dir == NULL) return NULL; - refs_strv = flatpak_dir_list_unused_refs (dir, arch, metadata_injection, + refs_strv = flatpak_dir_list_unused_refs (dir, arch, metadata_injection, NULL, (const char * const *)refs_to_exclude, filter_by_eol, cancellable, error); if (refs_strv == NULL) diff --git a/common/flatpak-transaction.c b/common/flatpak-transaction.c index d1d6e1c5..9ce5692b 100644 --- a/common/flatpak-transaction.c +++ b/common/flatpak-transaction.c @@ -4203,6 +4203,7 @@ add_uninstall_unused_ops (FlatpakTransaction *self, g_autoptr(GHashTable) maybe_unused_runtimes = NULL; g_autoptr(GHashTable) newly_used_runtimes = NULL; g_autoptr(GHashTable) metadata_injection = NULL; + g_autoptr(GHashTable) eol_injection = NULL; g_autoptr(GPtrArray) to_be_excluded = NULL; g_autoptr(GPtrArray) run_after_ops = NULL; g_auto(GStrv) old_unused_refs = NULL; @@ -4219,6 +4220,7 @@ add_uninstall_unused_ops (FlatpakTransaction *self, old_unused_refs = flatpak_dir_list_unused_refs (priv->dir, NULL, /* arch */ NULL, /* metadata_injection */ + NULL, /* eol_injection */ NULL, /* exclude_refs */ TRUE, /* filter_by_eol */ cancellable, error); @@ -4233,6 +4235,8 @@ add_uninstall_unused_ops (FlatpakTransaction *self, * thereby make an installed extension become unused. */ metadata_injection = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL); + eol_injection = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL); + /* This is the set of runtimes and apps scheduled for uninstallation and * which are therefore excluded when calculating used refs. */ to_be_excluded = g_ptr_array_new (); @@ -4258,6 +4262,8 @@ add_uninstall_unused_ops (FlatpakTransaction *self, { if (op->resolved_metakey) g_hash_table_insert (metadata_injection, op->ref, op->resolved_metakey); + g_hash_table_insert (eol_injection, op->ref, + GINT_TO_POINTER (op->eol != NULL || op->eol_rebase != NULL)); } } @@ -4270,8 +4276,9 @@ add_uninstall_unused_ops (FlatpakTransaction *self, /* These are the refs that will be unused & eol after the transaction */ unused_refs = flatpak_dir_list_unused_refs (priv->dir, NULL, /* arch */ - metadata_injection, /* metadata_injection */ - to_be_excluded_strv, /* exclude_refs */ + metadata_injection, + eol_injection, + to_be_excluded_strv, TRUE, /* filter_by_eol */ cancellable, error); if (unused_refs == NULL) diff --git a/tests/list-unused.c b/tests/list-unused.c index 5e858a20..7e2636e8 100644 --- a/tests/list-unused.c +++ b/tests/list-unused.c @@ -35,7 +35,7 @@ main (int argc, char *argv[]) else dir = flatpak_dir_get_system_default (); - refs = flatpak_dir_list_unused_refs (dir, NULL, NULL, (const char * const *)opt_exclude_refs, FALSE, NULL, &error); + refs = flatpak_dir_list_unused_refs (dir, NULL, NULL, NULL, (const char * const *)opt_exclude_refs, FALSE, NULL, &error); g_assert_nonnull (refs); g_assert_no_error (error);