Commit 1113bf5a authored by Richard Hughes's avatar Richard Hughes

flatpak: Use FlatpakTransaction to install, remove and update

This ensures we will get the same set of extensions and runtimes as the flatpak
CLI tool, and allows us to make the plugin considerably simpler. Rather than
using the plugin cache for the transaction, add each app and runtime being
processed to a per-transaction cache which cleans up the cache model a lot.

This allows us to remove gs_app_{g|s}et_update_runtime(); nobody every properly
understood what this was doing, and it's no longer required.

The counterpart matching also gets cut out; it was a huge layering violation
and didn't work very well when there were two FlatpakInstallations with the
same scope. If the GsApp scope is unknown, ask each GsFlatpak instance to
refine the state until it returns without error.

This also allows the runtime to use a different FlatpakInstallation than the
application itself.
parent 12031b42
image: fedora:27
image: fedora:28
stages:
- build
......@@ -6,7 +6,7 @@ stages:
before_script:
# Update and use base build deps
- dnf update -y && dnf -y install dnf-plugins-core @buildsys-build
- dnf -y builddep gnome-software
- dnf --enablerepo updates-testing -y builddep gnome-software
# Some deps may not be sync'd
- dnf -y install rpm-ostree-devel
......
......@@ -96,7 +96,6 @@ typedef struct
gchar *update_version_ui;
gchar *update_details;
AsUrgencyKind update_urgency;
GsApp *update_runtime;
gchar *management_plugin;
guint match_value;
guint priority;
......@@ -630,10 +629,6 @@ gs_app_to_string_append (GsApp *app, GString *str)
g_string_append (str, "\n\tRuntime:\n\t");
gs_app_to_string_append (priv->runtime, str);
}
if (priv->update_runtime != NULL) {
g_string_append (str, "\n\tUpdate Runtime:\n\t");
gs_app_to_string_append (priv->update_runtime, str);
}
g_string_append_printf (str, "\n");
}
......@@ -1818,9 +1813,7 @@ gs_app_get_runtime (GsApp *app)
{
GsAppPrivate *priv = gs_app_get_instance_private (app);
g_return_val_if_fail (GS_IS_APP (app), NULL);
if (priv->runtime != NULL)
return priv->runtime;
return priv->update_runtime;
return priv->runtime;
}
/**
......@@ -1843,46 +1836,6 @@ gs_app_set_runtime (GsApp *app, GsApp *runtime)
g_set_object (&priv->runtime, runtime);
}
/**
* gs_app_get_update_runtime:
* @app: a #GsApp
*
* Gets the runtime required for the application update.
*
* Returns: (transfer none): a #GsApp, or %NULL for unset
*
* Since: 3.22
**/
GsApp *
gs_app_get_update_runtime (GsApp *app)
{
GsAppPrivate *priv = gs_app_get_instance_private (app);
g_return_val_if_fail (GS_IS_APP (app), NULL);
if (priv->update_runtime != NULL)
return priv->update_runtime;
return priv->runtime;
}
/**
* gs_app_set_update_runtime:
* @app: a #GsApp
* @runtime: a #GsApp
*
* Sets the runtime that the application update requires.
*
* Since: 3.22
**/
void
gs_app_set_update_runtime (GsApp *app, GsApp *runtime)
{
GsAppPrivate *priv = gs_app_get_instance_private (app);
g_autoptr(GMutexLocker) locker = NULL;
g_return_if_fail (GS_IS_APP (app));
g_return_if_fail (app != runtime);
locker = g_mutex_locker_new (&priv->mutex);
g_set_object (&priv->update_runtime, runtime);
}
/**
* gs_app_set_pixbuf:
* @app: a #GsApp
......@@ -3077,10 +3030,7 @@ gs_app_get_size_download (GsApp *app)
sz = priv->size_download;
/* add the runtime if this is not installed */
if (priv->update_runtime != NULL) {
if (gs_app_get_state (priv->update_runtime) == AS_APP_STATE_AVAILABLE)
sz += gs_app_get_size_installed (priv->update_runtime);
} else if (priv->runtime != NULL) {
if (priv->runtime != NULL) {
if (gs_app_get_state (priv->runtime) == AS_APP_STATE_AVAILABLE)
sz += gs_app_get_size_installed (priv->runtime);
}
......@@ -4207,7 +4157,6 @@ gs_app_dispose (GObject *object)
GsAppPrivate *priv = gs_app_get_instance_private (app);
g_clear_object (&priv->runtime);
g_clear_object (&priv->update_runtime);
g_clear_pointer (&priv->addons, g_object_unref);
g_clear_pointer (&priv->history, g_object_unref);
......
......@@ -224,9 +224,6 @@ void gs_app_set_update_details (GsApp *app,
AsUrgencyKind gs_app_get_update_urgency (GsApp *app);
void gs_app_set_update_urgency (GsApp *app,
AsUrgencyKind update_urgency);
GsApp *gs_app_get_update_runtime (GsApp *app);
void gs_app_set_update_runtime (GsApp *app,
GsApp *runtime);
const gchar *gs_app_get_management_plugin (GsApp *app);
void gs_app_set_management_plugin (GsApp *app,
const gchar *management_plugin);
......
......@@ -150,7 +150,7 @@ if get_option('enable-fwupd')
endif
if get_option('enable-flatpak')
flatpak = dependency('flatpak', version : '>= 0.6.12')
flatpak = dependency('flatpak', version : '>= 0.99.3')
endif
if get_option('enable-rpm-ostree')
......
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
* Copyright (C) 2017 Richard Hughes <richard@hughsie.com>
* Copyright (C) 2017-2018 Richard Hughes <richard@hughsie.com>
*
* Licensed under the GNU General Public License Version 2
*
......@@ -58,10 +58,10 @@ gs_flatpak_app_get_file_kind (GsApp *app)
return g_variant_get_uint32 (tmp);
}
GsApp *
gs_flatpak_app_get_runtime_repo (GsApp *app)
const gchar *
gs_flatpak_app_get_runtime_url (GsApp *app)
{
return g_object_get_data (G_OBJECT (app), "flatpak::RuntimeRepo");
return gs_app_get_metadata_item (app, "flatpak::RuntimeUrl");
}
FlatpakRefKind
......@@ -144,12 +144,9 @@ gs_flatpak_app_set_file_kind (GsApp *app, GsFlatpakAppFileKind file_kind)
}
void
gs_flatpak_app_set_runtime_repo (GsApp *app, GsApp *runtime_repo)
gs_flatpak_app_set_runtime_url (GsApp *app, const gchar *val)
{
g_object_set_data_full (G_OBJECT (app),
"flatpak::RuntimeRepo",
g_object_ref (runtime_repo),
(GDestroyNotify) g_object_unref);
gs_app_set_metadata (app, "flatpak::RuntimeUrl", val);
}
void
......
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
* Copyright (C) 2017 Richard Hughes <richard@hughsie.com>
* Copyright (C) 2017-2018 Richard Hughes <richard@hughsie.com>
*
* Licensed under the GNU General Public License Version 2
*
......@@ -49,7 +49,7 @@ const gchar *gs_flatpak_app_get_object_id (GsApp *app);
const gchar *gs_flatpak_app_get_repo_gpgkey (GsApp *app);
const gchar *gs_flatpak_app_get_repo_url (GsApp *app);
GsFlatpakAppFileKind gs_flatpak_app_get_file_kind (GsApp *app);
GsApp *gs_flatpak_app_get_runtime_repo (GsApp *app);
const gchar *gs_flatpak_app_get_runtime_url (GsApp *app);
void gs_flatpak_app_set_ref_name (GsApp *app,
const gchar *val);
......@@ -70,8 +70,8 @@ void gs_flatpak_app_set_repo_url (GsApp *app,
const gchar *val);
void gs_flatpak_app_set_file_kind (GsApp *app,
GsFlatpakAppFileKind file_kind);
void gs_flatpak_app_set_runtime_repo (GsApp *app,
GsApp *runtime_repo);
void gs_flatpak_app_set_runtime_url (GsApp *app,
const gchar *val);
void gs_flatpak_app_set_main_app_ref_name (GsApp *app,
const gchar *main_app_ref);
const gchar *gs_flatpak_app_get_main_app_ref_name (GsApp *app);
......
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
* Copyright (C) 2018 Richard Hughes <richard@hughsie.com>
*
* Licensed under the GNU General Public License Version 2
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <config.h>
#include "gs-flatpak-app.h"
#include "gs-flatpak-transaction.h"
struct _GsFlatpakTransaction {
FlatpakTransaction parent_instance;
FlatpakInstallation *installation;
GHashTable *refhash; /* ref:GsApp */
};
enum {
SIGNAL_REF_TO_APP,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };
G_DEFINE_TYPE (GsFlatpakTransaction, gs_flatpak_transaction, FLATPAK_TYPE_TRANSACTION)
FlatpakInstallation *
gs_flatpak_transaction_get_inst (FlatpakTransaction *transaction)
{
GsFlatpakTransaction *self = GS_FLATPAK_TRANSACTION (transaction);
return self->installation;
}
static void
gs_flatpak_transaction_finalize (GObject *object)
{
GsFlatpakTransaction *self;
g_return_if_fail (GS_IS_FLATPAK_TRANSACTION (object));
self = GS_FLATPAK_TRANSACTION (object);
g_assert (self != NULL);
g_hash_table_unref (self->refhash);
G_OBJECT_CLASS (gs_flatpak_transaction_parent_class)->finalize (object);
}
GsApp *
gs_flatpak_transaction_get_app_by_ref (FlatpakTransaction *transaction, const gchar *ref)
{
GsFlatpakTransaction *self = GS_FLATPAK_TRANSACTION (transaction);
return g_hash_table_lookup (self->refhash, ref);
}
static void
gs_flatpak_transaction_add_app_internal (GsFlatpakTransaction *self, GsApp *app)
{
g_autofree gchar *ref = gs_flatpak_app_get_ref_display (app);
g_hash_table_insert (self->refhash, g_steal_pointer (&ref), g_object_ref (app));
}
void
gs_flatpak_transaction_add_app (FlatpakTransaction *transaction, GsApp *app)
{
GsFlatpakTransaction *self = GS_FLATPAK_TRANSACTION (transaction);
gs_flatpak_transaction_add_app_internal (self, app);
if (gs_app_get_runtime (app) != NULL)
gs_flatpak_transaction_add_app_internal (self, gs_app_get_runtime (app));
}
static GsApp *
_ref_to_app (GsFlatpakTransaction *self, const gchar *ref)
{
GsApp *app = g_hash_table_lookup (self->refhash, ref);
if (app != NULL)
return g_object_ref (app);
g_signal_emit (self, signals[SIGNAL_REF_TO_APP], 0, ref, &app);
return app;
}
static void
_transaction_operation_set_app (FlatpakTransactionOperation *op, GsApp *app)
{
g_object_set_data_full (G_OBJECT (op), "GsApp",
g_object_ref (app), (GDestroyNotify) g_object_unref);
}
static GsApp *
_transaction_operation_get_app (FlatpakTransactionOperation *op)
{
return g_object_get_data (G_OBJECT (op), "GsApp");
}
static gboolean
_transaction_ready (FlatpakTransaction *transaction)
{
GsFlatpakTransaction *self = GS_FLATPAK_TRANSACTION (transaction);
g_autolist(GObject) ops = NULL;
/* nothing to do */
ops = flatpak_transaction_get_operations (transaction);
if (ops == NULL)
return TRUE; // FIXME: error?
for (GList *l = ops; l != NULL; l = l->next) {
FlatpakTransactionOperation *op = l->data;
const gchar *ref = flatpak_transaction_operation_get_ref (op);
g_autoptr(GsApp) app = _ref_to_app (self, ref);
if (app != NULL)
_transaction_operation_set_app (op, app);
}
return TRUE;
}
static void
_transaction_progress_changed_cb (FlatpakTransactionProgress *progress,
gpointer user_data)
{
GsApp *app = GS_APP (user_data);
guint percent = flatpak_transaction_progress_get_progress (progress);
if (flatpak_transaction_progress_get_is_estimating (progress))
return;
gs_app_set_progress (app, percent);
}
static const gchar *
_flatpak_transaction_operation_type_to_string (FlatpakTransactionOperationType ot)
{
if (ot == FLATPAK_TRANSACTION_OPERATION_INSTALL)
return "install";
if (ot == FLATPAK_TRANSACTION_OPERATION_UPDATE)
return "update";
if (ot == FLATPAK_TRANSACTION_OPERATION_INSTALL_BUNDLE)
return "install-bundle";
if (ot == FLATPAK_TRANSACTION_OPERATION_UNINSTALL)
return "uninstall";
return NULL;
}
static void
_transaction_new_operation (FlatpakTransaction *transaction,
FlatpakTransactionOperation *operation,
FlatpakTransactionProgress *progress)
{
GsApp *app;
/* find app */
app = _transaction_operation_get_app (operation);
if (app == NULL) {
FlatpakTransactionOperationType ot;
ot = flatpak_transaction_operation_get_operation_type (operation);
g_warning ("failed to find app for %s during %s",
flatpak_transaction_operation_get_ref (operation),
_flatpak_transaction_operation_type_to_string (ot));
return;
}
/* report progress */
g_signal_connect_object (progress, "changed",
G_CALLBACK (_transaction_progress_changed_cb),
app, 0);
flatpak_transaction_progress_set_update_frequency (progress, 100); /* FIXME? */
/* set app status */
switch (flatpak_transaction_operation_get_operation_type (operation)) {
case FLATPAK_TRANSACTION_OPERATION_INSTALL:
if (gs_app_get_state (app) == AS_APP_STATE_UNKNOWN)
gs_app_set_state (app, AS_APP_STATE_AVAILABLE);
gs_app_set_state (app, AS_APP_STATE_INSTALLING);
break;
case FLATPAK_TRANSACTION_OPERATION_INSTALL_BUNDLE:
if (gs_app_get_state (app) == AS_APP_STATE_UNKNOWN)
gs_app_set_state (app, AS_APP_STATE_AVAILABLE_LOCAL);
gs_app_set_state (app, AS_APP_STATE_INSTALLING);
break;
case FLATPAK_TRANSACTION_OPERATION_UPDATE:
if (gs_app_get_state (app) == AS_APP_STATE_UNKNOWN)
gs_app_set_state (app, AS_APP_STATE_UPDATABLE);
gs_app_set_state (app, AS_APP_STATE_INSTALLING);
break;
case FLATPAK_TRANSACTION_OPERATION_UNINSTALL:
gs_app_set_state (app, AS_APP_STATE_REMOVING);
break;
default:
break;
}
}
static void
_transaction_operation_done (FlatpakTransaction *transaction,
FlatpakTransactionOperation *operation,
FlatpakTransactionResult details)
{
/* invalidate */
GsApp *app = _transaction_operation_get_app (operation);
if (app == NULL) {
g_warning ("failed to find app for %s",
flatpak_transaction_operation_get_ref (operation));
return;
}
switch (flatpak_transaction_operation_get_operation_type (operation)) {
case FLATPAK_TRANSACTION_OPERATION_INSTALL:
case FLATPAK_TRANSACTION_OPERATION_INSTALL_BUNDLE:
gs_app_set_state (app, AS_APP_STATE_INSTALLED);
break;
case FLATPAK_TRANSACTION_OPERATION_UPDATE:
gs_app_set_version (app, gs_app_get_update_version (app));
gs_app_set_update_details (app, NULL);
gs_app_set_update_urgency (app, AS_URGENCY_KIND_UNKNOWN);
gs_app_set_update_version (app, NULL);
/* force getting the new runtime */
gs_app_remove_kudo (app, GS_APP_KUDO_SANDBOXED);
gs_app_set_state (app, AS_APP_STATE_INSTALLED);
break;
case FLATPAK_TRANSACTION_OPERATION_UNINSTALL:
/* we don't actually know if this app is re-installable */
gs_flatpak_app_set_commit (app, NULL);
gs_app_set_state (app, AS_APP_STATE_UNKNOWN);
break;
default:
gs_app_set_state (app, AS_APP_STATE_UNKNOWN);
break;
}
}
static gboolean
_transaction_operation_error (FlatpakTransaction *transaction,
FlatpakTransactionOperation *operation,
const GError *error,
FlatpakTransactionErrorDetails detail)
{
/* invalidate */
GsApp *app = _transaction_operation_get_app (operation);
if (app != NULL)
gs_app_set_state_recover (app);
if (g_error_matches (error, FLATPAK_ERROR, FLATPAK_ERROR_SKIPPED)) {
g_printerr ("%s", error->message);
return TRUE;
}
g_printerr ("%s", error->message);
return FALSE;
}
static int
_transaction_choose_remote_for_ref (FlatpakTransaction *transaction,
const char *for_ref,
const char *runtime_ref,
const char * const *remotes)
{
//FIXME: do something smarter
return 0;
}
static void
_transaction_end_of_lifed (FlatpakTransaction *transaction,
const gchar *ref,
const gchar *reason,
const gchar *rebase)
{
if (rebase) {
g_printerr ("%s is end-of-life, in preference of %s\n", ref, rebase);
} else if (reason) {
g_printerr ("%s is end-of-life, with reason: %s\n", ref, reason);
}
//FIXME: show something in the UI
}
static gboolean
_transaction_add_new_remote (FlatpakTransaction *transaction,
FlatpakTransactionRemoteReason reason,
const char *from_id,
const char *remote_name,
const char *url)
{
/* additional applications */
if (reason == FLATPAK_TRANSACTION_REMOTE_GENERIC_REPO) {
g_debug ("configuring %s as new generic remote", url);
return TRUE; //FIXME?
}
/* runtime deps always make sense */
if (reason == FLATPAK_TRANSACTION_REMOTE_RUNTIME_DEPS) {
g_debug ("configuring %s as new remote for deps", url);
return TRUE;
}
return FALSE;
}
static void
gs_flatpak_transaction_class_init (GsFlatpakTransactionClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
FlatpakTransactionClass *transaction_class = FLATPAK_TRANSACTION_CLASS (klass);
object_class->finalize = gs_flatpak_transaction_finalize;
transaction_class->ready = _transaction_ready;
transaction_class->add_new_remote = _transaction_add_new_remote;
transaction_class->new_operation = _transaction_new_operation;
transaction_class->operation_done = _transaction_operation_done;
transaction_class->operation_error = _transaction_operation_error;
transaction_class->choose_remote_for_ref = _transaction_choose_remote_for_ref;
transaction_class->end_of_lifed = _transaction_end_of_lifed;
signals[SIGNAL_REF_TO_APP] =
g_signal_new ("ref-to-app",
G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
0, NULL, NULL, NULL, G_TYPE_OBJECT, 1, G_TYPE_STRING);
}
static void
gs_flatpak_transaction_init (GsFlatpakTransaction *self)
{
self->refhash = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, (GDestroyNotify) g_object_unref);
}
FlatpakTransaction *
gs_flatpak_transaction_new (FlatpakInstallation *installation,
GCancellable *cancellable,
GError **error)
{
GsFlatpakTransaction *self;
self = g_initable_new (GS_TYPE_FLATPAK_TRANSACTION,
cancellable, error,
"installation", installation,
NULL);
if (self == NULL)
return NULL;
return FLATPAK_TRANSACTION (self);
}
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
* Copyright (C) 2018 Richard Hughes <richard@hughsie.com>
*
* Licensed under the GNU General Public License Version 2
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __GS_FLATPAK_TRANSACTION_H
#define __GS_FLATPAK_TRANSACTION_H
#include <gnome-software.h>
#include <flatpak.h>
G_BEGIN_DECLS
#define GS_TYPE_FLATPAK_TRANSACTION (gs_flatpak_transaction_get_type ())
G_DECLARE_FINAL_TYPE (GsFlatpakTransaction, gs_flatpak_transaction, GS, FLATPAK_TRANSACTION, FlatpakTransaction)
FlatpakTransaction *gs_flatpak_transaction_new (FlatpakInstallation *installation,
GCancellable *cancellable,
GError **error);
FlatpakInstallation *gs_flatpak_transaction_get_inst (FlatpakTransaction *transaction);
GsApp *gs_flatpak_transaction_get_app_by_ref (FlatpakTransaction *transaction,
const gchar *ref);
void gs_flatpak_transaction_add_app (FlatpakTransaction *transaction,
GsApp *app);
G_END_DECLS
#endif /* __GS_FLATPAK_TRANSACTION_H */
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
* Copyright (C) 2017 Richard Hughes <richard@hughsie.com>
* Copyright (C) 2017-2018 Richard Hughes <richard@hughsie.com>
*
* Licensed under the GNU General Public License Version 2
*
......@@ -51,6 +51,8 @@ gs_flatpak_error_convert (GError **perror)
switch (error->code) {
case FLATPAK_ERROR_ALREADY_INSTALLED:
case FLATPAK_ERROR_NOT_INSTALLED:
case FLATPAK_ERROR_REMOTE_NOT_FOUND:
case FLATPAK_ERROR_RUNTIME_NOT_FOUND:
error->code = GS_PLUGIN_ERROR_NOT_SUPPORTED;
break;
default:
......@@ -58,8 +60,9 @@ gs_flatpak_error_convert (GError **perror)
break;
}
} else {
g_warning ("can't reliably fixup error from domain %s",
g_quark_to_string (error->domain));
g_warning ("can't reliably fixup error from domain %s: %s",
g_quark_to_string (error->domain),
error->message);
error->code = GS_PLUGIN_ERROR_FAILED;
}
error->domain = GS_PLUGIN_ERROR;
......@@ -145,14 +148,13 @@ gs_flatpak_app_new_from_repo_file (GFile *file,
/* create source */
repo_title = g_key_file_get_string (kf, "Flatpak Repo", "Title", NULL);
repo_url = g_key_file_get_string (kf, "Flatpak Repo", "Url", NULL);
repo_gpgkey = g_key_file_get_string (kf, "Flatpak Repo", "GPGKey", NULL);
if (repo_title == NULL || repo_url == NULL || repo_gpgkey == NULL ||
repo_title[0] == '\0' || repo_url[0] == '\0' || repo_gpgkey[0] == '\0') {
if (repo_title == NULL || repo_url == NULL ||
repo_title[0] == '\0' || repo_url[0] == '\0') {
g_set_error_literal (error,
GS_PLUGIN_ERROR,
GS_PLUGIN_ERROR_NOT_SUPPORTED,
"not enough data in file, "
"expected Title, Url, GPGKey");
"expected at least Title and Url");
return NULL;
}
......@@ -168,16 +170,6 @@ gs_flatpak_app_new_from_repo_file (GFile *file,
}
}
/* user specified a URL */
if (g_str_has_prefix (repo_gpgkey, "http://") ||
g_str_has_prefix (repo_gpgkey, "https://")) {
g_set_error_literal (error,
GS_PLUGIN_ERROR,
GS_PLUGIN_ERROR_NOT_SUPPORTED,
"Base64 encoded GPGKey required, not URL");
return NULL;
}
/* create source */
app = gs_flatpak_app_new (repo_id);
gs_flatpak_app_set_file_kind (app, GS_FLATPAK_APP_FILE_KIND_REPO);
......@@ -185,10 +177,23 @@ gs_flatpak_app_new_from_repo_file (GFile *file,
gs_app_set_state (app, AS_APP_STATE_AVAILABLE_LOCAL);
gs_app_add_quirk (app, AS_APP_QUIRK_NOT_LAUNCHABLE);
gs_app_set_name (app, GS_APP_QUALITY_NORMAL, repo_title);
gs_flatpak_app_set_repo_gpgkey (app, repo_gpgkey);
gs_flatpak_app_set_repo_url (app, repo_url);
gs_app_set_origin_hostname (app, repo_url);
/* user specified a URL */
repo_gpgkey = g_key_file_get_string (kf, "Flatpak Repo", "GPGKey", NULL);
if (repo_gpgkey != NULL) {
if (g_str_has_prefix (repo_gpgkey, "http://") ||
g_str_has_prefix (repo_gpgkey, "https://")) {
g_set_error_literal (error,
GS_PLUGIN_ERROR,
GS_PLUGIN_ERROR_NOT_SUPPORTED,
"Base64 encoded GPGKey required, not URL");
return NULL;
}
gs_flatpak_app_set_repo_gpgkey (app, repo_gpgkey);
}
/* optional data */
repo_homepage = g_key_file_get_string (kf, "Flatpak Repo", "Homepage", NULL);
if (repo_homepage != NULL)
......
This diff is collapsed.
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
* Copyright (C) 2016 Joaquim Rocha <jrocha@endlessm.com>
* Copyright (C) 2016-2017 Richard Hughes <richard@hughsie.com>
* Copyright (C) 2016-2018 Richard Hughes <richard@hughsie.com>
*
* Licensed under the GNU General Public License Version 2
*
......@@ -42,6 +42,10 @@ typedef enum {
GsFlatpak *gs_flatpak_new (GsPlugin *plugin,
FlatpakInstallation *installation,
GsFlatpakFlags flags);
FlatpakInstallation *gs_flatpak_get_installation (GsFlatpak *self);
GsApp *gs_flatpak_ref_to_app (GsFlatpak *self, const gchar *ref, GCancellable *cancellable, GError **error);
AsAppScope gs_flatpak_get_scope (GsFlatpak *self);
const gchar *gs_flatpak_get_id (GsFlatpak *self);
gboolean gs_flatpak_setup (GsFlatpak *self,
......@@ -73,6 +77,10 @@ gboolean gs_flatpak_refine_app (GsFlatpak *self,
GsPluginRefineFlags flags,
GCancellable *cancellable,
GError **error);
gboolean gs_flatpak_refine_app_state (GsFlatpak *self,
GsApp *app,
GCancellable *cancellable,
GError **error);
gboolean gs_flatpak_refine_wildcard (GsFlatpak *self,
GsApp *app,
GsAppList *list,
......@@ -83,15 +91,11 @@ gboolean gs_flatpak_launch (GsFlatpak *self,
GsApp *app,
GCancellable *cancellable,
GError **error);
gboolean gs_flatpak_app_remove (GsFlatpak *self,
GsApp *app,
GCancellable *cancellable,
GError **error);
gboolean gs_flatpak_app_install (GsFlatpak *self,
gboolean gs_flatpak_app_remove_source (GsFlatpak *self,
GsApp *app,
GCancellable *cancellable,
GError **error);
gboolean gs_flatpak_update_app (GsFlatpak *self,
gboolean gs_flatpak_app_install_source (GsFlatpak *self,
GsApp *app,
GCancellable *cancellable,
GError **error);
......@@ -103,17 +107,8 @@ GsApp *gs_flatpak_file_to_app_bundle (GsFlatpak *self,
GFile *file,
GCancellable *cancellable,
GError **error);
gboolean gs_flatpak_find_source_by_url (GsFlatpak *self,
GsApp *gs_flatpak_find_source_by_url (GsFlatpak *self,
const gchar *name,
GsAppList *list,
GCancellable *cancellable,