mirror of
https://github.com/flatpak/flatpak.git
synced 2026-05-19 14:22:18 -04:00
transaction: Move the handling of bundle runtime remote from cli code
This allows libflatpak users to also add runtime remotes as needed by bundles. Closes: #1868 Approved by: alexlarsson
This commit is contained in:
committed by
Atomic Bot
parent
c0ebd3a121
commit
98fd052695
@@ -113,147 +113,6 @@ read_gpg_data (GCancellable *cancellable,
|
||||
return flatpak_read_stream (source_stream, FALSE, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
remote_is_already_configured (FlatpakDir *dir,
|
||||
const char *url,
|
||||
const char *collection_id)
|
||||
{
|
||||
g_autofree char *old_remote = NULL;
|
||||
|
||||
old_remote = flatpak_dir_find_remote_by_uri (dir, url, collection_id);
|
||||
if (old_remote == NULL && flatpak_dir_is_user (dir))
|
||||
{
|
||||
g_autoptr(GPtrArray) system_dirs = NULL;
|
||||
int i;
|
||||
|
||||
system_dirs = flatpak_dir_get_system_list (NULL, NULL);
|
||||
if (system_dirs == NULL)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < system_dirs->len; i++)
|
||||
{
|
||||
FlatpakDir *system_dir = g_ptr_array_index (system_dirs, i);
|
||||
old_remote = flatpak_dir_find_remote_by_uri (system_dir, url, collection_id);
|
||||
if (old_remote != NULL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return old_remote != NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
handle_runtime_repo_deps (FlatpakDir *dir, const char *dep_url, GError **error)
|
||||
{
|
||||
g_autoptr(GBytes) dep_data = NULL;
|
||||
g_autofree char *runtime_url = NULL;
|
||||
g_autofree char *new_remote = NULL;
|
||||
g_autofree char *basename = NULL;
|
||||
g_autoptr(SoupURI) uri = NULL;
|
||||
g_auto(GStrv) remotes = NULL;
|
||||
g_autoptr(GKeyFile) config = NULL;
|
||||
g_autoptr(GBytes) gpg_key = NULL;
|
||||
g_autofree char *group = NULL;
|
||||
g_autofree char *runtime_collection_id = NULL;
|
||||
g_autoptr(GKeyFile) dep_keyfile = g_key_file_new ();
|
||||
g_autoptr(GError) local_error = NULL;
|
||||
char *t;
|
||||
int i;
|
||||
|
||||
if (opt_no_deps)
|
||||
return TRUE;
|
||||
|
||||
dep_data = download_uri (dep_url, error);
|
||||
if (dep_data == NULL)
|
||||
{
|
||||
g_prefix_error (error, "Can't load dependent file %s", dep_url);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!g_key_file_load_from_data (dep_keyfile,
|
||||
g_bytes_get_data (dep_data, NULL),
|
||||
g_bytes_get_size (dep_data),
|
||||
0, error))
|
||||
return flatpak_fail (error, "Invalid .flatpakrepo: %s", local_error->message);
|
||||
|
||||
uri = soup_uri_new (dep_url);
|
||||
basename = g_path_get_basename (soup_uri_get_path (uri));
|
||||
/* Strip suffix */
|
||||
t = strchr (basename, '.');
|
||||
if (t != NULL)
|
||||
*t = 0;
|
||||
|
||||
/* Find a free remote name */
|
||||
remotes = flatpak_dir_list_remotes (dir, NULL, NULL);
|
||||
i = 0;
|
||||
do
|
||||
{
|
||||
g_clear_pointer (&new_remote, g_free);
|
||||
|
||||
if (i == 0)
|
||||
new_remote = g_strdup (basename);
|
||||
else
|
||||
new_remote = g_strdup_printf ("%s-%d", basename, i);
|
||||
i++;
|
||||
}
|
||||
while (remotes != NULL && g_strv_contains ((const char * const*)remotes, new_remote));
|
||||
|
||||
config = flatpak_dir_parse_repofile (dir, new_remote, FALSE, dep_keyfile, &gpg_key, NULL, error);
|
||||
if (config == NULL)
|
||||
{
|
||||
g_prefix_error (error, "Can't parse dependent file %s: ", dep_url);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* See if it already exists */
|
||||
group = g_strdup_printf ("remote \"%s\"", new_remote);
|
||||
runtime_url = g_key_file_get_string (config, group, "url", NULL);
|
||||
g_assert (runtime_url != NULL);
|
||||
runtime_collection_id = g_key_file_get_string (config, group, "collection-id", NULL);
|
||||
|
||||
if (remote_is_already_configured (dir, runtime_url, runtime_collection_id))
|
||||
return TRUE;
|
||||
|
||||
if (opt_yes ||
|
||||
flatpak_yes_no_prompt (_("This application depends on runtimes from:\n %s\nConfigure this as new remote '%s'"),
|
||||
runtime_url, new_remote))
|
||||
{
|
||||
if (opt_yes)
|
||||
g_print (_("Configuring %s as new remote '%s'"), runtime_url, new_remote);
|
||||
|
||||
if (!flatpak_dir_modify_remote (dir, new_remote, config, gpg_key, NULL, error))
|
||||
return FALSE;
|
||||
if (!flatpak_dir_recreate_repo (dir, NULL, error))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
handle_runtime_repo_deps_from_bundle (FlatpakDir *dir, GFile *file, GError **error)
|
||||
{
|
||||
g_autofree char *dep_url = NULL;
|
||||
g_autoptr(GVariant) metadata = NULL;
|
||||
|
||||
if (opt_no_deps)
|
||||
return TRUE;
|
||||
|
||||
metadata = flatpak_bundle_load (file, NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&dep_url,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
if (metadata == NULL || dep_url == NULL)
|
||||
return TRUE;
|
||||
|
||||
return handle_runtime_repo_deps (dir, dep_url, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
install_bundle (FlatpakDir *dir,
|
||||
GOptionContext *context,
|
||||
@@ -287,12 +146,6 @@ install_bundle (FlatpakDir *dir,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!handle_runtime_repo_deps_from_bundle (dir, file, error))
|
||||
return FALSE;
|
||||
|
||||
if (!flatpak_dir_ensure_repo (dir, cancellable, error))
|
||||
return FALSE;
|
||||
|
||||
transaction = flatpak_cli_transaction_new (dir, opt_yes, TRUE, error);
|
||||
if (transaction == NULL)
|
||||
return FALSE;
|
||||
|
||||
@@ -78,6 +78,13 @@ struct _FlatpakTransactionOperation {
|
||||
|
||||
typedef struct _FlatpakTransactionPrivate FlatpakTransactionPrivate;
|
||||
|
||||
typedef struct _BundleData BundleData;
|
||||
|
||||
struct _BundleData {
|
||||
GFile *file;
|
||||
GBytes *gpg_data;
|
||||
};
|
||||
|
||||
struct _FlatpakTransactionPrivate {
|
||||
GObject parent;
|
||||
|
||||
@@ -90,6 +97,7 @@ struct _FlatpakTransactionPrivate {
|
||||
GPtrArray *added_origin_remotes;
|
||||
|
||||
GList *flatpakrefs; /* GKeyFiles */
|
||||
GList *bundles; /* BundleData */
|
||||
|
||||
FlatpakTransactionOperation *current_op;
|
||||
|
||||
@@ -136,6 +144,27 @@ enum {
|
||||
LAST_PROGRESS_SIGNAL
|
||||
};
|
||||
|
||||
static BundleData *
|
||||
bundle_data_new (GFile *file,
|
||||
GBytes *gpg_data)
|
||||
{
|
||||
BundleData *data = g_new0 (BundleData, 1);
|
||||
|
||||
data->file = g_object_ref (file);
|
||||
if (gpg_data)
|
||||
data->gpg_data = g_object_ref (gpg_data);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static void
|
||||
bundle_data_free (BundleData *data)
|
||||
{
|
||||
g_clear_object (&data->file);
|
||||
g_clear_object (&data->gpg_data);
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
static guint progress_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
G_DEFINE_TYPE (FlatpakTransactionProgress, flatpak_transaction_progress, G_TYPE_OBJECT)
|
||||
@@ -492,6 +521,7 @@ flatpak_transaction_finalize (GObject *object)
|
||||
g_clear_object (&priv->installation);
|
||||
|
||||
g_list_free_full (priv->flatpakrefs, (GDestroyNotify)g_key_file_unref);
|
||||
g_list_free_full (priv->bundles, (GDestroyNotify)bundle_data_free);
|
||||
g_free (priv->default_arch);
|
||||
g_hash_table_unref (priv->last_op_for_ref);
|
||||
g_hash_table_unref (priv->remote_states);
|
||||
@@ -1342,22 +1372,10 @@ flatpak_transaction_add_install_bundle (FlatpakTransaction *self,
|
||||
GError **error)
|
||||
{
|
||||
FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
|
||||
g_autofree char *remote = NULL;
|
||||
g_autofree char *ref = NULL;
|
||||
g_autofree char *commit = NULL;
|
||||
g_autofree char *metadata = NULL;
|
||||
gboolean created_remote;
|
||||
|
||||
remote = flatpak_dir_ensure_bundle_remote (priv->dir, file, gpg_data,
|
||||
&ref, &commit, &metadata, &created_remote,
|
||||
NULL, error);
|
||||
if (remote == NULL)
|
||||
return FALSE;
|
||||
priv->bundles = g_list_append (priv->flatpakrefs, bundle_data_new (file, gpg_data));
|
||||
|
||||
if (!flatpak_dir_recreate_repo (priv->dir, NULL, error))
|
||||
return FALSE;
|
||||
|
||||
return flatpak_transaction_add_ref (self, remote, ref, NULL, commit, FLATPAK_TRANSACTION_OPERATION_INSTALL_BUNDLE, file, metadata, error);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
@@ -2071,6 +2089,78 @@ flatpak_transaction_resolve_flatpakrefs (FlatpakTransaction *self,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
handle_runtime_repo_deps_from_bundle (FlatpakTransaction *self,
|
||||
GFile *file,
|
||||
GError **error)
|
||||
{
|
||||
FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
|
||||
g_autofree char *dep_url = NULL;
|
||||
g_autofree char *ref = NULL;
|
||||
g_auto(GStrv) ref_parts = NULL;
|
||||
g_autoptr(GVariant) metadata = NULL;
|
||||
|
||||
if (priv->disable_deps)
|
||||
return TRUE;
|
||||
|
||||
metadata = flatpak_bundle_load (file, NULL,
|
||||
NULL,
|
||||
&ref,
|
||||
&dep_url,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
if (metadata == NULL || dep_url == NULL || ref == NULL)
|
||||
return TRUE;
|
||||
|
||||
ref_parts = g_strsplit (ref, "/", -1);
|
||||
|
||||
return handle_runtime_repo_deps (self, ref_parts[1], dep_url, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
flatpak_transaction_resolve_bundles (FlatpakTransaction *self,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
|
||||
GList *l;
|
||||
|
||||
for (l = priv->bundles; l != NULL; l = l->next)
|
||||
{
|
||||
BundleData *data = l->data;
|
||||
g_autofree char *remote = NULL;
|
||||
g_autofree char *ref = NULL;
|
||||
g_autofree char *commit = NULL;
|
||||
g_autofree char *metadata = NULL;
|
||||
gboolean created_remote;
|
||||
|
||||
if (!handle_runtime_repo_deps_from_bundle (self, data->file, error))
|
||||
return FALSE;
|
||||
|
||||
if (!flatpak_dir_ensure_repo (priv->dir, cancellable, error))
|
||||
return FALSE;
|
||||
|
||||
remote = flatpak_dir_ensure_bundle_remote (priv->dir, data->file, data->gpg_data,
|
||||
&ref, &commit, &metadata, &created_remote,
|
||||
NULL, error);
|
||||
if (remote == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (!flatpak_dir_recreate_repo (priv->dir, NULL, error))
|
||||
return FALSE;
|
||||
|
||||
if (!flatpak_transaction_add_ref (self, remote, ref, NULL, commit,
|
||||
FLATPAK_TRANSACTION_OPERATION_INSTALL_BUNDLE, data->file, metadata, error))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
flatpak_transaction_run (FlatpakTransaction *self,
|
||||
GCancellable *cancellable,
|
||||
@@ -2097,6 +2187,9 @@ flatpak_transaction_run (FlatpakTransaction *self,
|
||||
if (!flatpak_transaction_resolve_flatpakrefs (self, cancellable, error))
|
||||
return FALSE;
|
||||
|
||||
if (!flatpak_transaction_resolve_bundles (self, cancellable, error))
|
||||
return FALSE;
|
||||
|
||||
/* Resolve initial ops */
|
||||
if (!resolve_ops (self, cancellable, error))
|
||||
return FALSE;
|
||||
|
||||
Reference in New Issue
Block a user