diff --git a/common/flatpak-dir-private.h b/common/flatpak-dir-private.h index 0a5f4c4d..a4daf913 100644 --- a/common/flatpak-dir-private.h +++ b/common/flatpak-dir-private.h @@ -948,6 +948,8 @@ gboolean flatpak_dir_find_latest_rev (FlatpakDir *self, OstreeRepoFinderResult ***out_results, GCancellable *cancellable, GError **error); +GPtrArray * flatpak_dir_find_remote_auto_install_refs (FlatpakDir *self, + const char *remote_name); typedef struct { diff --git a/common/flatpak-dir.c b/common/flatpak-dir.c index 607deb49..b156be62 100644 --- a/common/flatpak-dir.c +++ b/common/flatpak-dir.c @@ -12562,6 +12562,20 @@ flatpak_dir_get_remote_disabled (FlatpakDir *self, return FALSE; } +static char * +flatpak_dir_get_remote_install_authenticator_name (FlatpakDir *self, + const char *remote_name) +{ + GKeyFile *config = flatpak_dir_get_repo_config (self); + g_autofree char *group = get_group (remote_name); + + if (config == NULL || + !g_key_file_get_boolean (config, group, "xa.authenticator-install", NULL)) + return NULL; + + return g_key_file_get_string (config, group, "xa.authenticator-name", NULL); +} + gboolean flatpak_dir_remote_has_deploys (FlatpakDir *self, const char *remote) @@ -14663,6 +14677,25 @@ flatpak_dir_find_local_related (FlatpakDir *self, return g_steal_pointer (&related); } +GPtrArray * +flatpak_dir_find_remote_auto_install_refs (FlatpakDir *self, + const char *remote_name) +{ + GPtrArray *auto_install_refs = g_ptr_array_new_with_free_func ((GDestroyNotify) g_free); + g_autofree char *authenticator_name = NULL; + g_autofree char *authenticator_ref = NULL; + + authenticator_name = flatpak_dir_get_remote_install_authenticator_name (self, remote_name); + if (authenticator_name != NULL) + authenticator_ref = g_strdup_printf ("app/%s/%s/autoinstall", authenticator_name, flatpak_get_arch ()); + + if (authenticator_ref) + g_ptr_array_add (auto_install_refs, g_steal_pointer (&authenticator_ref)); + + return auto_install_refs; +} + + static GDBusProxy * get_localed_dbus_proxy (void) { diff --git a/common/flatpak-transaction.c b/common/flatpak-transaction.c index d9b4996f..527b93e4 100644 --- a/common/flatpak-transaction.c +++ b/common/flatpak-transaction.c @@ -2246,12 +2246,15 @@ flatpak_transaction_update_metadata (FlatpakTransaction *self, g_autoptr(GError) my_error = NULL; g_autoptr(FlatpakRemoteState) state = flatpak_transaction_ensure_remote_state (self, FLATPAK_TRANSACTION_OPERATION_UPDATE, remote, NULL); - g_debug ("Updating remote metadata for %s", remote); + g_debug ("Looking for remote metadata updates for %s", remote); if (!flatpak_dir_update_remote_configuration (priv->dir, remote, state, &updated, cancellable, &my_error)) - g_message (_("Error updating remote metadata for '%s': %s"), remote, my_error->message); + g_debug (_("Error updating remote metadata for '%s': %s"), remote, my_error->message); if (updated) - some_updated = TRUE; + { + g_debug ("Got updatedo metadata for %s", remote); + some_updated = TRUE; + } } if (some_updated) @@ -2269,6 +2272,59 @@ flatpak_transaction_update_metadata (FlatpakTransaction *self, return TRUE; } +static gboolean +flatpak_transaction_add_auto_install (FlatpakTransaction *self, + GCancellable *cancellable, + GError **error) +{ + FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self); + g_auto(GStrv) remotes = NULL; + + remotes = flatpak_dir_list_remotes (priv->dir, cancellable, error); + if (remotes == NULL) + return FALSE; + + /* Auto-add auto-download apps that are not already installed. + * Try to avoid doing network i/o until we know its needed, as this + * iterates over all configured remotes. + */ + for (int i = 0; remotes[i] != NULL; i++) + { + char *remote = remotes[i]; + g_autoptr(GPtrArray) auto_install_refs = NULL; + + if (flatpak_dir_get_remote_disabled (priv->dir, remote)) + continue; + + auto_install_refs = flatpak_dir_find_remote_auto_install_refs (priv->dir, remote); + for (int i = 0; i < auto_install_refs->len; i++) + { + const char *ref = g_ptr_array_index (auto_install_refs, i); + g_autoptr(GError) local_error = NULL; + g_autoptr(GFile) deploy = NULL; + + deploy = flatpak_dir_get_if_deployed (priv->dir, ref, NULL, cancellable); + if (deploy == NULL) + { + g_autoptr(FlatpakRemoteState) state = flatpak_transaction_ensure_remote_state (self, FLATPAK_TRANSACTION_OPERATION_UPDATE, remote, NULL); + + if (state != NULL && + flatpak_remote_state_lookup_ref (state, ref, NULL, NULL, NULL)) + { + g_debug ("Auto adding install of %s from remote %s", ref, remote); + if (!flatpak_transaction_add_ref (self, remote, ref, NULL, NULL, NULL, + FLATPAK_TRANSACTION_OPERATION_INSTALL_OR_UPDATE, + NULL, NULL, + &local_error)) + g_debug ("Failed to add auto-install ref %s: %s", ref, local_error->message); + } + } + } + } + + return TRUE; +} + static void emit_new_op (FlatpakTransaction *self, FlatpakTransactionOperation *op, FlatpakTransactionProgress *progress) { @@ -3880,6 +3936,9 @@ flatpak_transaction_real_run (FlatpakTransaction *self, /* Work around ostree-pull spinning the default main context for the sync calls */ main_context = flatpak_main_context_new_default (); + if (!flatpak_transaction_add_auto_install (self, cancellable, error)) + return FALSE; + if (!flatpak_transaction_resolve_flatpakrefs (self, cancellable, error)) return FALSE;