transaction: Automatically install authenticator if needed

If the local config for the remote specifies an authenticator name
and that is should in installed, automatically add it to updates
in a transaction.

The local config can either be manually configured, or automatically
from a flatpakrepo file or the summary metadata.
This commit is contained in:
Alexander Larsson
2019-12-18 12:25:29 +01:00
committed by Alexander Larsson
parent 7480bd8f07
commit 1291663a5a
3 changed files with 97 additions and 3 deletions

View File

@@ -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
{

View File

@@ -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)
{

View File

@@ -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;