[gnome-software] Add a plugin to set the origin-hostname for packages
- From: Richard Hughes <rhughes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software] Add a plugin to set the origin-hostname for packages
- Date: Fri, 8 Jul 2016 08:29:40 +0000 (UTC)
commit 476d03eccfb9643a394f3a32064aaa37e5bda622
Author: Richard Hughes <richard hughsie com>
Date: Thu Jul 7 09:27:48 2016 +0100
Add a plugin to set the origin-hostname for packages
data/tests/Makefile.am | 3 +-
data/tests/yum.repos.d/utopia.repo | 5 +
src/gs-self-test.c | 29 ++++++
src/plugins/Makefile.am | 6 +
src/plugins/gs-plugin-repos.c | 184 ++++++++++++++++++++++++++++++++++++
5 files changed, 226 insertions(+), 1 deletions(-)
---
diff --git a/data/tests/Makefile.am b/data/tests/Makefile.am
index 019558b..29feb92 100644
--- a/data/tests/Makefile.am
+++ b/data/tests/Makefile.am
@@ -2,6 +2,7 @@ EXTRA_DIST = \
os-release \
chiron-0.2.cab \
chiron-1.1-1.deb \
- chiron-1.1-1.fc24.x86_64.rpm
+ chiron-1.1-1.fc24.x86_64.rpm \
+ yum.repos.d/utopia.repo
-include $(top_srcdir)/git.mk
diff --git a/data/tests/yum.repos.d/utopia.repo b/data/tests/yum.repos.d/utopia.repo
new file mode 100644
index 0000000..e912ec4
--- /dev/null
+++ b/data/tests/yum.repos.d/utopia.repo
@@ -0,0 +1,5 @@
+[utopia]
+name=utopia for Fedora $releasever
+baseurl=http://people.freedesktop.org/~hughsient/fedora/$releasever/x86_64/
+enabled=1
+gpgcheck=0
diff --git a/src/gs-self-test.c b/src/gs-self-test.c
index ccdd89f..30b7fd9 100644
--- a/src/gs-self-test.c
+++ b/src/gs-self-test.c
@@ -644,6 +644,25 @@ gs_plugin_loader_fwupd_func (GsPluginLoader *plugin_loader)
}
static void
+gs_plugin_loader_repos_func (GsPluginLoader *plugin_loader)
+{
+ gboolean ret;
+ g_autoptr(GsApp) app = NULL;
+ g_autoptr(GError) error = NULL;
+
+ /* get the extra bits */
+ app = gs_app_new ("testrepos.desktop");
+ gs_app_set_origin (app, "utopia");
+ ret = gs_plugin_loader_app_refine (plugin_loader, app,
+ GS_PLUGIN_REFINE_FLAGS_REQUIRE_ORIGIN_HOSTNAME,
+ NULL,
+ &error);
+ g_assert_no_error (error);
+ g_assert (ret);
+ g_assert_cmpstr (gs_app_get_origin_hostname (app), ==, "people.freedesktop.org");
+}
+
+static void
gs_plugin_loader_flatpak_func (GsPluginLoader *plugin_loader)
{
GsApp *app;
@@ -967,6 +986,7 @@ main (int argc, char **argv)
gboolean ret;
g_autofree gchar *fn = NULL;
g_autofree gchar *xml = NULL;
+ g_autofree gchar *reposdir = NULL;
g_autoptr(GError) error = NULL;
g_autoptr(GsPluginLoader) plugin_loader = NULL;
const gchar *whitelist[] = {
@@ -984,6 +1004,7 @@ main (int argc, char **argv)
"provenance",
"provenance-license",
"packagekit-local",
+ "repos",
NULL
};
@@ -1006,6 +1027,11 @@ main (int argc, char **argv)
g_assert (!g_file_test (tmp_root, G_FILE_TEST_EXISTS));
}
+ /* dummy data */
+ reposdir = gs_test_get_filename ("tests/yum.repos.d");
+ g_assert (reposdir != NULL);
+ g_setenv ("GS_SELF_TEST_REPOS_DIR", reposdir, TRUE);
+
fn = gs_test_get_filename ("icons/hicolor/48x48/org.gnome.Software.png");
g_assert (fn != NULL);
xml = g_strdup_printf ("<?xml version=\"1.0\"?>\n"
@@ -1113,6 +1139,9 @@ main (int argc, char **argv)
g_test_add_data_func ("/gnome-software/plugin-loader{plugin-cache}",
plugin_loader,
(GTestDataFunc) gs_plugin_loader_plugin_cache_func);
+ g_test_add_data_func ("/gnome-software/plugin-loader{repos}",
+ plugin_loader,
+ (GTestDataFunc) gs_plugin_loader_repos_func);
g_test_add_data_func ("/gnome-software/plugin-loader{flatpak}",
plugin_loader,
(GTestDataFunc) gs_plugin_loader_flatpak_func);
diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
index b1f049d..75abf3d 100644
--- a/src/plugins/Makefile.am
+++ b/src/plugins/Makefile.am
@@ -41,6 +41,7 @@ plugin_LTLIBRARIES = \
libgs_plugin_fedora-distro-upgrades.la \
libgs_plugin_provenance.la \
libgs_plugin_provenance-license.la \
+ libgs_plugin_repos.la \
libgs_plugin_fedora-tagger-usage.la \
libgs_plugin_epiphany.la \
libgs_plugin_icons.la \
@@ -219,6 +220,11 @@ libgs_plugin_steam_la_LDFLAGS = -module -avoid-version
libgs_plugin_steam_la_CFLAGS = $(GS_PLUGIN_CFLAGS) $(WARN_CFLAGS)
endif
+libgs_plugin_repos_la_SOURCES = gs-plugin-repos.c
+libgs_plugin_repos_la_LIBADD = $(GS_PLUGIN_LIBS) $(RPM_LIBS)
+libgs_plugin_repos_la_LDFLAGS = -module -avoid-version
+libgs_plugin_repos_la_CFLAGS = $(GS_PLUGIN_CFLAGS) $(WARN_CFLAGS)
+
libgs_plugin_desktop_categories_la_SOURCES = \
gs-plugin-desktop-categories.c \
gs-desktop-common.c \
diff --git a/src/plugins/gs-plugin-repos.c b/src/plugins/gs-plugin-repos.c
new file mode 100644
index 0000000..d96f315
--- /dev/null
+++ b/src/plugins/gs-plugin-repos.c
@@ -0,0 +1,184 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2016 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 <gnome-software.h>
+
+struct GsPluginData {
+ GHashTable *urls; /* origin : url */
+ GFileMonitor *monitor;
+ gchar *reposdir;
+ gboolean valid;
+};
+
+void
+gs_plugin_initialize (GsPlugin *plugin)
+{
+ GsPluginData *priv = gs_plugin_alloc_data (plugin, sizeof(GsPluginData));
+
+ /* for debugging and the self tests */
+ priv->reposdir = g_strdup (g_getenv ("GS_SELF_TEST_REPOS_DIR"));
+ if (priv->reposdir == NULL)
+ priv->reposdir = g_strdup ("/etc/yum.repos.d");
+
+ /* plugin only makes sense if this exists at startup */
+ if (!g_file_test (priv->reposdir, G_FILE_TEST_EXISTS)) {
+ gs_plugin_set_enabled (plugin, FALSE);
+ return;
+ }
+
+ /* we also watch this for changes */
+ priv->urls = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+
+ /* need application IDs */
+ gs_plugin_add_rule (plugin, GS_PLUGIN_RULE_RUN_AFTER, "packagekit-refine");
+}
+
+void
+gs_plugin_destroy (GsPlugin *plugin)
+{
+ GsPluginData *priv = gs_plugin_get_data (plugin);
+ g_free (priv->reposdir);
+ if (priv->urls != NULL)
+ g_hash_table_unref (priv->urls);
+ if (priv->monitor != NULL)
+ g_object_unref (priv->monitor);
+}
+
+static gboolean
+gs_plugin_repos_setup (GsPlugin *plugin, GCancellable *cancellable, GError **error)
+{
+ GsPluginData *priv = gs_plugin_get_data (plugin);
+ g_autoptr(GDir) dir = NULL;
+ const gchar *fn;
+
+ /* already valid */
+ if (priv->valid)
+ return TRUE;
+
+ /* clear existing */
+ g_hash_table_remove_all (priv->urls);
+
+ /* search all files */
+ dir = g_dir_open (priv->reposdir, 0, error);
+ if (dir == NULL)
+ return FALSE;
+ while ((fn = g_dir_read_name (dir)) != NULL) {
+ g_autofree gchar *filename = NULL;
+ g_auto(GStrv) groups = NULL;
+ g_autoptr(GKeyFile) kf = g_key_file_new ();
+ guint i;
+
+ /* not a repo */
+ if (!g_str_has_suffix (fn, ".repo"))
+ continue;
+
+ /* load file */
+ filename = g_build_filename (priv->reposdir, fn, NULL);
+ if (!g_key_file_load_from_file (kf, filename,
+ G_KEY_FILE_NONE,
+ error))
+ return FALSE;
+
+ /* we can have multiple repos in one file */
+ groups = g_key_file_get_groups (kf, NULL);
+ for (i = 0; groups[i] != NULL; i++) {
+ g_autofree gchar *tmp = NULL;
+ tmp = g_key_file_get_string (kf, groups[i], "baseurl", NULL);
+ if (tmp != NULL) {
+ g_hash_table_insert (priv->urls,
+ g_strdup (groups[i]),
+ g_strdup (tmp));
+ continue;
+ }
+ tmp = g_key_file_get_string (kf, groups[i], "metalink", NULL);
+ if (tmp != NULL) {
+ g_hash_table_insert (priv->urls,
+ g_strdup (groups[i]),
+ g_strdup (tmp));
+ continue;
+ }
+ }
+ }
+
+ /* success */
+ priv->valid = TRUE;
+ return TRUE;
+}
+
+static void
+gs_plugin_repos_changed_cb (GFileMonitor *monitor,
+ GFile *file,
+ GFile *other_file,
+ GFileMonitorEvent event_type,
+ GsPlugin *plugin)
+{
+ GsPluginData *priv = gs_plugin_get_data (plugin);
+ priv->valid = FALSE;
+}
+
+gboolean
+gs_plugin_setup (GsPlugin *plugin, GCancellable *cancellable, GError **error)
+{
+ GsPluginData *priv = gs_plugin_get_data (plugin);
+ g_autoptr(GFile) file = g_file_new_for_path (priv->reposdir);
+
+ /* watch for changes */
+ priv->monitor = g_file_monitor_directory (file, G_FILE_MONITOR_NONE, cancellable, error);
+ if (priv->monitor == NULL)
+ return FALSE;
+ g_signal_connect (priv->monitor, "changed",
+ G_CALLBACK (gs_plugin_repos_changed_cb), plugin);
+
+ /* unconditionally at startup */
+ return gs_plugin_repos_setup (plugin, cancellable, error);
+}
+
+gboolean
+gs_plugin_refine_app (GsPlugin *plugin,
+ GsApp *app,
+ GsPluginRefineFlags flags,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GsPluginData *priv = gs_plugin_get_data (plugin);
+ const gchar *tmp;
+
+ /* not required */
+ if ((flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_ORIGIN_HOSTNAME) == 0)
+ return TRUE;
+ if (gs_app_get_origin_hostname (app) != NULL)
+ return TRUE;
+
+ /* ensure valid */
+ if (!gs_plugin_repos_setup (plugin, cancellable, error))
+ return FALSE;
+
+ /* find hostname */
+ if (gs_app_get_origin (app) == NULL)
+ return TRUE;
+ tmp = g_hash_table_lookup (priv->urls, gs_app_get_origin (app));
+ if (tmp != NULL)
+ gs_app_set_origin_hostname (app, tmp);
+
+ return TRUE;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]