[gnome-software] fwupd: Support updating metadata from multiple remotes
- From: Richard Hughes <rhughes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software] fwupd: Support updating metadata from multiple remotes
- Date: Fri, 9 Jun 2017 09:14:50 +0000 (UTC)
commit 6b3462416b635318684423711487d83b9fdd21ed
Author: Richard Hughes <richard hughsie com>
Date: Fri Jun 2 11:53:31 2017 +0100
fwupd: Support updating metadata from multiple remotes
meson.build | 2 +-
plugins/fwupd/gs-plugin-fwupd.c | 239 ++++++++++++++++++++++----------------
2 files changed, 139 insertions(+), 102 deletions(-)
---
diff --git a/meson.build b/meson.build
index 54f5b26..18dbbd0 100644
--- a/meson.build
+++ b/meson.build
@@ -133,7 +133,7 @@ if get_option('enable-packagekit')
endif
if get_option('enable-firmware')
- fwupd = dependency('fwupd', version : '>= 0.8.0')
+ fwupd = dependency('fwupd', version : '>= 0.9.3')
endif
if get_option('enable-flatpak')
diff --git a/plugins/fwupd/gs-plugin-fwupd.c b/plugins/fwupd/gs-plugin-fwupd.c
index 6531d88..f2804ea 100644
--- a/plugins/fwupd/gs-plugin-fwupd.c
+++ b/plugins/fwupd/gs-plugin-fwupd.c
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
- * Copyright (C) 2013-2016 Richard Hughes <richard hughsie com>
+ * Copyright (C) 2013-2017 Richard Hughes <richard hughsie com>
*
* Licensed under the GNU General Public License Version 2
*
@@ -44,10 +44,8 @@ struct GsPluginData {
GPtrArray *to_ignore;
GsApp *app_current;
GsApp *cached_origin;
- gchar *lvfs_sig_fn;
- gchar *lvfs_sig_hash;
+ GHashTable *remote_asc_hash;
gchar *config_fn;
- gchar *download_uri;
};
static void
@@ -103,6 +101,8 @@ gs_plugin_initialize (GsPlugin *plugin)
priv->client = fwupd_client_new ();
priv->to_download = g_ptr_array_new_with_free_func (g_free);
priv->to_ignore = g_ptr_array_new_with_free_func (g_free);
+ priv->remote_asc_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, g_free);
priv->config_fn = g_build_filename (SYSCONFDIR, "fwupd.conf", NULL);
if (!g_file_test (priv->config_fn, G_FILE_TEST_EXISTS)) {
g_free (priv->config_fn);
@@ -124,10 +124,8 @@ gs_plugin_destroy (GsPlugin *plugin)
GsPluginData *priv = gs_plugin_get_data (plugin);
if (priv->cached_origin != NULL)
g_object_unref (priv->cached_origin);
- g_free (priv->lvfs_sig_fn);
- g_free (priv->lvfs_sig_hash);
+ g_hash_table_unref (priv->remote_asc_hash);
g_free (priv->config_fn);
- g_free (priv->download_uri);
g_object_unref (priv->client);
g_ptr_array_unref (priv->to_download);
g_ptr_array_unref (priv->to_ignore);
@@ -217,33 +215,80 @@ gs_plugin_fwupd_notify_status_cb (GObject *object,
}
}
-gboolean
-gs_plugin_setup (GsPlugin *plugin, GCancellable *cancellable, GError **error)
+static gchar *
+gs_plugin_fwupd_get_file_checksum (const gchar *filename,
+ GChecksumType checksum_type,
+ GError **error)
{
- GsPluginData *priv = gs_plugin_get_data (plugin);
gsize len;
g_autofree gchar *data = NULL;
- g_autoptr(GKeyFile) config = NULL;
- /* read config file */
- config = g_key_file_new ();
- if (!g_key_file_load_from_file (config, priv->config_fn,
- G_KEY_FILE_NONE, error)) {
+ if (!g_file_get_contents (filename, &data, &len, error)) {
gs_utils_error_convert_gio (error);
+ return NULL;
+ }
+ return g_compute_checksum_for_data (checksum_type, (const guchar *)data, len);
+}
+
+static gboolean
+gs_plugin_fwupd_setup_remote (GsPlugin *plugin, FwupdRemote *remote, GError **error)
+{
+ GsPluginData *priv = gs_plugin_get_data (plugin);
+ g_autofree gchar *filename_asc = NULL;
+
+ /* find the name of the signature file in the cache */
+ filename_asc = gs_utils_get_cache_filename ("firmware",
+ fwupd_remote_get_filename_asc (remote),
+ GS_UTILS_CACHE_FLAG_WRITEABLE,
+ error);
+ if (filename_asc == NULL)
return FALSE;
+
+ /* if it exists, add the hash */
+ if (g_file_test (filename_asc, G_FILE_TEST_EXISTS)) {
+ g_autofree gchar *hash = NULL;
+ hash = gs_plugin_fwupd_get_file_checksum (filename_asc,
+ G_CHECKSUM_SHA1,
+ error);
+ if (hash == NULL)
+ return FALSE;
+ g_hash_table_insert (priv->remote_asc_hash,
+ g_steal_pointer (&filename_asc),
+ g_steal_pointer (&hash));
}
- /* get the download URI */
- priv->download_uri = g_key_file_get_string (config, "fwupd",
- "DownloadURI", error);
- if (priv->download_uri == NULL)
+ return TRUE;
+}
+
+static gboolean
+gs_plugin_fwupd_setup_remotes (GsPlugin *plugin, GCancellable *cancellable, GError **error)
+{
+ GsPluginData *priv = gs_plugin_get_data (plugin);
+ g_autoptr(GPtrArray) remotes = NULL;
+
+ /* find all enabled remotes */
+ remotes = fwupd_client_get_remotes (priv->client, cancellable, error);
+ if (remotes == NULL)
return FALSE;
+ for (guint i = 0; i < remotes->len; i++) {
+ FwupdRemote *remote = g_ptr_array_index (remotes, i);
+ if (!fwupd_remote_get_enabled (remote))
+ continue;
+ if (!gs_plugin_fwupd_setup_remote (plugin, remote, error))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+gboolean
+gs_plugin_setup (GsPlugin *plugin, GCancellable *cancellable, GError **error)
+{
+ GsPluginData *priv = gs_plugin_get_data (plugin);
/* add source */
priv->cached_origin = gs_app_new (gs_plugin_get_name (plugin));
gs_app_set_kind (priv->cached_origin, AS_APP_KIND_SOURCE);
gs_app_set_bundle_kind (priv->cached_origin, AS_BUNDLE_KIND_CABINET);
- gs_app_set_origin_hostname (priv->cached_origin, priv->download_uri);
/* add the source to the plugin cache which allows us to match the
* unique ID to a GsApp when creating an event */
@@ -266,26 +311,8 @@ gs_plugin_setup (GsPlugin *plugin, GCancellable *cancellable, GError **error)
g_signal_connect (priv->client, "notify::status",
G_CALLBACK (gs_plugin_fwupd_notify_status_cb), plugin);
- /* get the hash of the previously downloaded file */
- priv->lvfs_sig_fn = gs_utils_get_cache_filename ("firmware",
- "firmware.xml.gz.asc",
- GS_UTILS_CACHE_FLAG_WRITEABLE,
- error);
- if (priv->lvfs_sig_fn == NULL) {
- gs_utils_error_convert_gio (error);
- return FALSE;
- }
- if (g_file_test (priv->lvfs_sig_fn, G_FILE_TEST_EXISTS)) {
- if (!g_file_get_contents (priv->lvfs_sig_fn,
- &data, &len, error)) {
- gs_utils_error_convert_gio (error);
- return FALSE;
- }
- priv->lvfs_sig_hash =
- g_compute_checksum_for_data (G_CHECKSUM_SHA1, (guchar *) data, len);
- }
-
- return TRUE;
+ /* get the hashes of the previously downloaded asc files */
+ return gs_plugin_fwupd_setup_remotes (plugin, cancellable, error);
}
static void
@@ -307,21 +334,6 @@ gs_plugin_fwupd_add_required_location (GsPlugin *plugin, const gchar *location)
g_ptr_array_add (priv->to_download, g_strdup (location));
}
-static gchar *
-gs_plugin_fwupd_get_file_checksum (const gchar *filename,
- GChecksumType checksum_type,
- GError **error)
-{
- gsize len;
- g_autofree gchar *data = NULL;
-
- if (!g_file_get_contents (filename, &data, &len, error)) {
- gs_utils_error_convert_gio (error);
- return NULL;
- }
- return g_compute_checksum_for_data (checksum_type, (const guchar *)data, len);
-}
-
static GsApp *
gs_plugin_fwupd_new_app_from_results (GsPlugin *plugin, FwupdResult *res)
{
@@ -665,43 +677,44 @@ gs_plugin_add_updates_pending (GsPlugin *plugin,
}
static gboolean
-gs_plugin_fwupd_check_lvfs_metadata (GsPlugin *plugin,
- guint cache_age,
- GCancellable *cancellable,
- GError **error)
+gs_plugin_fwupd_refresh_remote (GsPlugin *plugin,
+ FwupdRemote *remote,
+ guint cache_age,
+ GCancellable *cancellable,
+ GError **error)
{
GsPluginData *priv = gs_plugin_get_data (plugin);
+ const gchar *checksum_old;
g_autoptr(GError) error_local = NULL;
- g_autofree gchar *basename_data = NULL;
- g_autofree gchar *cache_fn_data = NULL;
+ g_autofree gchar *filename = NULL;
+ g_autofree gchar *filename_asc = NULL;
g_autofree gchar *checksum = NULL;
- g_autofree gchar *url_sig = NULL;
+ g_autofree gchar *url = NULL;
+ g_autofree gchar *url_asc = NULL;
g_autoptr(GBytes) data = NULL;
g_autoptr(GsApp) app_dl = gs_app_new (gs_plugin_get_name (plugin));
/* check cache age */
+ filename_asc = gs_utils_get_cache_filename ("firmware",
+ fwupd_remote_get_filename_asc (remote),
+ GS_UTILS_CACHE_FLAG_WRITEABLE,
+ error);
if (cache_age > 0) {
- guint tmp;
- g_autoptr(GFile) file = NULL;
- file = g_file_new_for_path (priv->lvfs_sig_fn);
- tmp = gs_utils_get_file_age (file);
+ g_autoptr(GFile) file = g_file_new_for_path (filename_asc);
+ guint tmp = gs_utils_get_file_age (file);
if (tmp < cache_age) {
g_debug ("%s is only %u seconds old, so ignoring refresh",
- priv->lvfs_sig_fn, tmp);
+ filename_asc, tmp);
return TRUE;
}
}
/* download the signature first, it's smaller */
- url_sig = g_strdup_printf ("%s.asc", priv->download_uri);
+ url_asc = soup_uri_to_string (fwupd_remote_get_uri_asc (remote), FALSE);
gs_app_set_summary_missing (app_dl,
/* TRANSLATORS: status text when downloading */
_("Downloading firmware update signature…"));
- data = gs_plugin_download_data (plugin,
- app_dl,
- url_sig,
- cancellable,
- error);
+ data = gs_plugin_download_data (plugin, app_dl, url_asc, cancellable, error);
if (data == NULL) {
gs_utils_error_add_unique_id (error, priv->cached_origin);
return FALSE;
@@ -711,62 +724,86 @@ gs_plugin_fwupd_check_lvfs_metadata (GsPlugin *plugin,
checksum = g_compute_checksum_for_data (G_CHECKSUM_SHA1,
(const guchar *) g_bytes_get_data (data, NULL),
g_bytes_get_size (data));
- if (g_strcmp0 (checksum, priv->lvfs_sig_hash) == 0) {
- g_debug ("signature of %s is unchanged", url_sig);
+ checksum_old = g_hash_table_lookup (priv->remote_asc_hash, filename_asc);
+ if (g_strcmp0 (checksum, checksum_old) == 0) {
+ g_debug ("signature of %s is unchanged", url_asc);
return TRUE;
}
/* save to a file */
- g_debug ("saving new LVFS signature to %s:", priv->lvfs_sig_fn);
- if (!g_file_set_contents (priv->lvfs_sig_fn,
+ g_debug ("saving new remote signature to %s:", filename_asc);
+ if (!g_file_set_contents (filename_asc,
g_bytes_get_data (data, NULL),
(guint) g_bytes_get_size (data),
&error_local)) {
g_set_error (error,
GS_PLUGIN_ERROR,
GS_PLUGIN_ERROR_WRITE_FAILED,
- "Failed to save firmware: %s",
+ "Failed to save firmware signature: %s",
error_local->message);
return FALSE;
}
/* save the new checksum so we don't downoad the payload unless it's changed */
- g_free (priv->lvfs_sig_hash);
- priv->lvfs_sig_hash = g_strdup (checksum);
+ g_hash_table_insert (priv->remote_asc_hash,
+ g_strdup (filename_asc),
+ g_steal_pointer (&checksum));
/* download the payload and save to file */
- basename_data = g_path_get_basename (priv->download_uri);
- cache_fn_data = gs_utils_get_cache_filename ("firmware",
- basename_data,
- GS_UTILS_CACHE_FLAG_WRITEABLE,
- error);
- if (cache_fn_data == NULL)
+ filename = gs_utils_get_cache_filename ("firmware",
+ fwupd_remote_get_filename (remote),
+ GS_UTILS_CACHE_FLAG_WRITEABLE,
+ error);
+ if (filename == NULL)
return FALSE;
- g_debug ("saving new LVFS data to %s:", cache_fn_data);
+ g_debug ("saving new firmware metadata to %s:", filename);
gs_app_set_summary_missing (app_dl,
/* TRANSLATORS: status text when downloading */
_("Downloading firmware update metadata…"));
- if (!gs_plugin_download_file (plugin, app_dl,
- priv->download_uri,
- cache_fn_data,
- cancellable,
- error)) {
+ url = soup_uri_to_string (fwupd_remote_get_uri (remote), FALSE);
+ if (!gs_plugin_download_file (plugin, app_dl, url, filename,
+ cancellable, error)) {
gs_utils_error_add_unique_id (error, priv->cached_origin);
return FALSE;
}
/* phew, lets send all this to fwupd */
- if (!fwupd_client_update_metadata (priv->client,
- cache_fn_data,
- priv->lvfs_sig_fn,
- cancellable,
- error)) {
+ if (!fwupd_client_update_metadata_with_id (priv->client,
+ fwupd_remote_get_id (remote),
+ filename,
+ filename_asc,
+ cancellable,
+ error)) {
gs_plugin_fwupd_error_convert (error);
return FALSE;
}
return TRUE;
}
+static gboolean
+gs_plugin_fwupd_refresh_remotes (GsPlugin *plugin,
+ guint cache_age,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GsPluginData *priv = gs_plugin_get_data (plugin);
+ g_autoptr(GPtrArray) remotes = NULL;
+
+ /* get the list of enabled remotes */
+ remotes = fwupd_client_get_remotes (priv->client, cancellable, error);
+ if (remotes == NULL)
+ return FALSE;
+ for (guint i = 0; i < remotes->len; i++) {
+ FwupdRemote *remote = g_ptr_array_index (remotes, i);
+ if (!fwupd_remote_get_enabled (remote))
+ continue;
+ if (!gs_plugin_fwupd_refresh_remote (plugin, remote, cache_age,
+ cancellable, error))
+ return FALSE;
+ }
+ return TRUE;
+}
+
gboolean
gs_plugin_refresh (GsPlugin *plugin,
guint cache_age,
@@ -780,10 +817,10 @@ gs_plugin_refresh (GsPlugin *plugin,
/* get the metadata and signature file */
if (flags & GS_PLUGIN_REFRESH_FLAGS_METADATA) {
- if (!gs_plugin_fwupd_check_lvfs_metadata (plugin,
- cache_age,
- cancellable,
- error))
+ if (!gs_plugin_fwupd_refresh_remotes (plugin,
+ cache_age,
+ cancellable,
+ error))
return FALSE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]