Blob Blame History Raw
From bc561b63748bc6d62841a392903974703f59cea7 Mon Sep 17 00:00:00 2001
From: Kalev Lember <klember@redhat.com>
Date: Fri, 19 Apr 2019 07:14:02 +0200
Subject: [PATCH 1/8] GsApp: Add recently added quirks to
 gs_app_quirk_to_string

---
 lib/gs-app.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/lib/gs-app.c b/lib/gs-app.c
index 17a546731..d5a30927a 100644
--- a/lib/gs-app.c
+++ b/lib/gs-app.c
@@ -235,6 +235,14 @@ _as_app_quirk_flag_to_string (GsAppQuirk quirk)
 		return "is-proxy";
 	if (quirk == GS_APP_QUIRK_REMOVABLE_HARDWARE)
 		return "removable-hardware";
+	if (quirk == GS_APP_QUIRK_DEVELOPER_VERIFIED)
+		return "developer-verified";
+	if (quirk == GS_APP_QUIRK_PARENTAL_FILTER)
+		return "parental-filter";
+	if (quirk == GS_APP_QUIRK_NEW_PERMISSIONS)
+		return "new-permissions";
+	if (quirk == GS_APP_QUIRK_PARENTAL_NOT_LAUNCHABLE)
+		return "parental-not-launchable";
 	return NULL;
 }
 
-- 
2.21.0


From c21b68f47169e01f0c053b18d44aaef5fe948602 Mon Sep 17 00:00:00 2001
From: Kalev Lember <klember@redhat.com>
Date: Wed, 24 Apr 2019 09:48:11 +0200
Subject: [PATCH 2/8] rpm-ostree: Implement provides search

---
 plugins/rpm-ostree/gs-plugin-rpm-ostree.c | 64 +++++++++++++++++++++++
 1 file changed, 64 insertions(+)

diff --git a/plugins/rpm-ostree/gs-plugin-rpm-ostree.c b/plugins/rpm-ostree/gs-plugin-rpm-ostree.c
index b6b7fbd3f..b47a66a39 100644
--- a/plugins/rpm-ostree/gs-plugin-rpm-ostree.c
+++ b/plugins/rpm-ostree/gs-plugin-rpm-ostree.c
@@ -1099,6 +1099,21 @@ find_package_by_name (DnfSack     *sack,
 	return g_object_ref (pkgs->pdata[pkgs->len-1]);
 }
 
+static GPtrArray *
+find_packages_by_provides (DnfSack *sack,
+                           gchar **search)
+{
+	g_autoptr(GPtrArray) pkgs = NULL;
+	hy_autoquery HyQuery query = hy_query_create (sack);
+
+	hy_query_filter_provides_in (query, search);
+	hy_query_filter_latest_per_arch (query, TRUE);
+
+	pkgs = hy_query_run (query);
+
+	return g_steal_pointer (&pkgs);
+}
+
 static gboolean
 resolve_installed_packages_app (GsPlugin *plugin,
                                 GPtrArray *pkglist,
@@ -1148,6 +1163,10 @@ resolve_available_packages_app (GsPlugin *plugin,
 			gs_app_set_origin (app, reponame);
 		}
 
+		/* set more metadata for packages that don't have appstream data */
+		gs_app_set_name (app, GS_APP_QUALITY_LOWEST, dnf_package_get_name (pkg));
+		gs_app_set_summary (app, GS_APP_QUALITY_LOWEST, dnf_package_get_summary (pkg));
+
 		return TRUE /* found */;
 	}
 
@@ -1496,3 +1515,48 @@ out:
 		(void) Fclose (rpmfd);
 	return ret;
 }
+
+gboolean
+gs_plugin_add_search_what_provides (GsPlugin *plugin,
+                                    gchar **search,
+                                    GsAppList *list,
+                                    GCancellable *cancellable,
+                                    GError **error)
+{
+	GsPluginData *priv = gs_plugin_get_data (plugin);
+	g_autoptr(GMutexLocker) locker = NULL;
+	g_autoptr(GPtrArray) pkglist = NULL;
+
+	locker = g_mutex_locker_new (&priv->mutex);
+
+	if (priv->dnf_context == NULL)
+		return TRUE;
+
+	pkglist = find_packages_by_provides (dnf_context_get_sack (priv->dnf_context), search);
+	for (guint i = 0; i < pkglist->len; i++) {
+		DnfPackage *pkg = g_ptr_array_index (pkglist, i);
+		g_autoptr(GsApp) app = NULL;
+
+		app = gs_plugin_cache_lookup (plugin, dnf_package_get_nevra (pkg));
+		if (app != NULL) {
+			gs_app_list_add (list, app);
+			continue;
+		}
+
+		/* create new app */
+		app = gs_app_new (NULL);
+		gs_app_set_metadata (app, "GnomeSoftware::Creator", gs_plugin_get_name (plugin));
+		gs_app_set_management_plugin (app, gs_plugin_get_name (plugin));
+		gs_app_add_quirk (app, GS_APP_QUIRK_NEEDS_REBOOT);
+		app_set_rpm_ostree_packaging_format (app);
+		gs_app_set_kind (app, AS_APP_KIND_GENERIC);
+		gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_PACKAGE);
+		gs_app_set_scope (app, AS_APP_SCOPE_SYSTEM);
+		gs_app_add_source (app, dnf_package_get_name (pkg));
+
+		gs_plugin_cache_add (plugin, dnf_package_get_nevra (pkg), app);
+		gs_app_list_add (list, app);
+	}
+
+	return TRUE;
+}
-- 
2.21.0


From 03feb124bed19417796642d45aa883b14d21f145 Mon Sep 17 00:00:00 2001
From: Kalev Lember <klember@redhat.com>
Date: Tue, 30 Apr 2019 14:02:21 +0200
Subject: [PATCH 3/8] plugin event: trivial: Try harder to avoid returning NULL
 unique ID

---
 lib/gs-plugin-event.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/lib/gs-plugin-event.c b/lib/gs-plugin-event.c
index 2e292c0a8..cf122561d 100644
--- a/lib/gs-plugin-event.c
+++ b/lib/gs-plugin-event.c
@@ -157,10 +157,14 @@ const gchar *
 gs_plugin_event_get_unique_id (GsPluginEvent *event)
 {
 	/* just proxy */
-	if (event->origin != NULL)
+	if (event->origin != NULL &&
+	    gs_app_get_unique_id (event->origin) != NULL) {
 		return gs_app_get_unique_id (event->origin);
-	if (event->app != NULL)
+	}
+	if (event->app != NULL &&
+	    gs_app_get_unique_id (event->app) != NULL) {
 		return gs_app_get_unique_id (event->app);
+	}
 
 	/* generate from error */
 	if (event->error != NULL) {
-- 
2.21.0


From 8915ad5da1a2a7661c211561250a56dc23f6b8ff Mon Sep 17 00:00:00 2001
From: Kalev Lember <klember@redhat.com>
Date: Tue, 30 Apr 2019 15:02:05 +0200
Subject: [PATCH 4/8] rpm-ostree: trivial: Update rpmostree1 dbus interface
 description

---
 plugins/rpm-ostree/org.projectatomic.rpmostree1.xml | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/plugins/rpm-ostree/org.projectatomic.rpmostree1.xml b/plugins/rpm-ostree/org.projectatomic.rpmostree1.xml
index 077002e38..6ae04a459 100644
--- a/plugins/rpm-ostree/org.projectatomic.rpmostree1.xml
+++ b/plugins/rpm-ostree/org.projectatomic.rpmostree1.xml
@@ -281,6 +281,13 @@
       <arg type="s" name="transaction_address" direction="out"/>
     </method>
 
+    <!-- Set options in yum .repo files -->
+    <method name="ModifyYumRepo">
+      <arg type="s" name="repo_id" direction="in"/>
+      <arg type="a{ss}" name="settings" direction="in"/>
+      <arg type="s" name="transaction_address" direction="out"/>
+    </method>
+
     <!-- Available modifiers:
          "set-refspec" (type 's')
          "set-revision" (type 's')
@@ -430,7 +437,7 @@
 
       <!--
          transfer data, format is:
-         (bytes transferred, bytes/s)
+         (bytes transfered, bytes/s)
       -->
     	<arg name="transfer" type="(tt)" direction="out"/>
     </signal>
-- 
2.21.0


From 3541297e9f69c1bee0e7ed416fbe9d55e918d0e0 Mon Sep 17 00:00:00 2001
From: Kalev Lember <klember@redhat.com>
Date: Tue, 30 Apr 2019 15:11:24 +0200
Subject: [PATCH 5/8] rpm-ostree: Implement getting the repo list, and enabling
 and disabling repos

This also bumps the required rpm-ostree version to 2019.3 for the
required rpm-ostree DBus API.
---
 meson.build                               |   2 +-
 plugins/rpm-ostree/gs-plugin-rpm-ostree.c | 110 ++++++++++++++++++++++
 2 files changed, 111 insertions(+), 1 deletion(-)

diff --git a/meson.build b/meson.build
index c08bf4901..f71ad139b 100644
--- a/meson.build
+++ b/meson.build
@@ -161,7 +161,7 @@ if get_option('rpm_ostree')
   libdnf = dependency('libdnf')
   ostree = dependency('ostree-1')
   rpm = dependency('rpm')
-  rpm_ostree = dependency('rpm-ostree-1', version : '>= 2018.4')
+  rpm_ostree = dependency('rpm-ostree-1', version : '>= 2019.3')
 endif
 
 if get_option('gudev')
diff --git a/plugins/rpm-ostree/gs-plugin-rpm-ostree.c b/plugins/rpm-ostree/gs-plugin-rpm-ostree.c
index b47a66a39..ae2f2435f 100644
--- a/plugins/rpm-ostree/gs-plugin-rpm-ostree.c
+++ b/plugins/rpm-ostree/gs-plugin-rpm-ostree.c
@@ -928,6 +928,60 @@ gs_plugin_update_app (GsPlugin *plugin,
 	return TRUE;
 }
 
+static gboolean
+gs_plugin_repo_enable (GsPlugin *plugin,
+                       GsApp *app,
+                       gboolean enable,
+                       GCancellable *cancellable,
+                       GError **error)
+{
+	GsPluginData *priv = gs_plugin_get_data (plugin);
+	g_autofree gchar *transaction_address = NULL;
+	g_autoptr(GVariantBuilder) options_builder = NULL;
+	g_autoptr(TransactionProgress) tp = NULL;
+
+	if (enable)
+		gs_app_set_state (app, AS_APP_STATE_INSTALLING);
+	else
+		gs_app_set_state (app, AS_APP_STATE_REMOVING);
+
+	options_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{ss}"));
+	g_variant_builder_add (options_builder, "{ss}", "enabled", enable ? "1" : "0");
+	if (!gs_rpmostree_os_call_modify_yum_repo_sync (priv->os_proxy,
+	                                                gs_app_get_id (app),
+	                                                g_variant_builder_end (options_builder),
+	                                                &transaction_address,
+	                                                cancellable,
+	                                                error)) {
+		gs_rpmostree_error_convert (error);
+		gs_app_set_state_recover (app);
+		gs_utils_error_add_origin_id (error, app);
+		return FALSE;
+	}
+
+	tp = transaction_progress_new ();
+	tp->app = g_object_ref (app);
+	if (!gs_rpmostree_transaction_get_response_sync (priv->sysroot_proxy,
+	                                                 transaction_address,
+	                                                 tp,
+	                                                 cancellable,
+	                                                 error)) {
+		gs_rpmostree_error_convert (error);
+		gs_app_set_state_recover (app);
+		gs_utils_error_add_origin_id (error, app);
+		return FALSE;
+	}
+
+
+	/* state is known */
+	if (enable)
+		gs_app_set_state (app, AS_APP_STATE_INSTALLED);
+	else
+		gs_app_set_state (app, AS_APP_STATE_AVAILABLE);
+
+	return TRUE;
+}
+
 gboolean
 gs_plugin_app_install (GsPlugin *plugin,
                        GsApp *app,
@@ -945,6 +999,10 @@ gs_plugin_app_install (GsPlugin *plugin,
 	if (g_strcmp0 (gs_app_get_management_plugin (app), gs_plugin_get_name (plugin)) != 0)
 		return TRUE;
 
+	/* enable repo */
+	if (gs_app_get_kind (app) == AS_APP_KIND_SOURCE)
+		return gs_plugin_repo_enable (plugin, app, TRUE, cancellable, error);
+
 	switch (gs_app_get_state (app)) {
 	case AS_APP_STATE_AVAILABLE:
 		if (gs_app_get_source_default (app) == NULL) {
@@ -1041,6 +1099,10 @@ gs_plugin_app_remove (GsPlugin *plugin,
 	if (g_strcmp0 (gs_app_get_management_plugin (app), gs_plugin_get_name (plugin)) != 0)
 		return TRUE;
 
+	/* disable repo */
+	if (gs_app_get_kind (app) == AS_APP_KIND_SOURCE)
+		return gs_plugin_repo_enable (plugin, app, FALSE, cancellable, error);
+
 	gs_app_set_state (app, AS_APP_STATE_REMOVING);
 	tp->app = g_object_ref (app);
 
@@ -1560,3 +1622,51 @@ gs_plugin_add_search_what_provides (GsPlugin *plugin,
 
 	return TRUE;
 }
+
+gboolean
+gs_plugin_add_sources (GsPlugin *plugin,
+		       GsAppList *list,
+		       GCancellable *cancellable,
+		       GError **error)
+{
+	GsPluginData *priv = gs_plugin_get_data (plugin);
+	g_autoptr(GMutexLocker) locker = NULL;
+	GPtrArray *repos;
+
+	locker = g_mutex_locker_new (&priv->mutex);
+
+	if (priv->dnf_context == NULL)
+		return TRUE;
+
+	repos = dnf_context_get_repos (priv->dnf_context);
+	if (repos == NULL)
+		return TRUE;
+
+	for (guint i = 0; i < repos->len; i++) {
+		DnfRepo *repo = g_ptr_array_index (repos, i);
+		g_autofree gchar *description = NULL;
+		g_autoptr(GsApp) app = NULL;
+		gboolean enabled;
+
+		/* hide these from the user */
+		if (dnf_repo_is_devel (repo) || dnf_repo_is_source (repo))
+			continue;
+
+		app = gs_app_new (dnf_repo_get_id (repo));
+		gs_app_set_management_plugin (app, gs_plugin_get_name (plugin));
+		gs_app_set_kind (app, AS_APP_KIND_SOURCE);
+		gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_PACKAGE);
+		gs_app_add_quirk (app, GS_APP_QUIRK_NOT_LAUNCHABLE);
+
+		enabled = (dnf_repo_get_enabled (repo) & DNF_REPO_ENABLED_PACKAGES) > 0;
+		gs_app_set_state (app, enabled ? AS_APP_STATE_INSTALLED : AS_APP_STATE_AVAILABLE);
+
+		description = dnf_repo_get_description (repo);
+		gs_app_set_name (app, GS_APP_QUALITY_LOWEST, description);
+		gs_app_set_summary (app, GS_APP_QUALITY_LOWEST, description);
+
+		gs_app_list_add (list, app);
+	}
+
+	return TRUE;
+}
-- 
2.21.0


From 8e661a5d4a6d390be8eaff57acae649918c6bf81 Mon Sep 17 00:00:00 2001
From: Kalev Lember <klember@redhat.com>
Date: Tue, 30 Apr 2019 15:18:37 +0200
Subject: [PATCH 6/8] repos dialog: trivial: Special-case rpm-ostree repos the
 same as packagekit

---
 src/gs-repo-row.c     | 1 +
 src/gs-repos-dialog.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/src/gs-repo-row.c b/src/gs-repo-row.c
index f3d091183..7ce7e618a 100644
--- a/src/gs-repo-row.c
+++ b/src/gs-repo-row.c
@@ -68,6 +68,7 @@ repo_supports_removal (GsApp *repo)
 	/* can't remove a repo, only enable/disable existing ones */
 	if (g_strcmp0 (management_plugin, "fwupd") == 0 ||
 	    g_strcmp0 (management_plugin, "packagekit") == 0 ||
+	    g_strcmp0 (management_plugin, "rpm-ostree") == 0 ||
 	    g_strcmp0 (management_plugin, "shell-extensions") == 0)
 		return FALSE;
 
diff --git a/src/gs-repos-dialog.c b/src/gs-repos-dialog.c
index 3d9f7f578..478acb7d2 100644
--- a/src/gs-repos-dialog.c
+++ b/src/gs-repos-dialog.c
@@ -135,6 +135,7 @@ repo_supports_removal (GsApp *repo)
 	/* can't remove a repo, only enable/disable existing ones */
 	if (g_strcmp0 (management_plugin, "fwupd") == 0 ||
 	    g_strcmp0 (management_plugin, "packagekit") == 0 ||
+	    g_strcmp0 (management_plugin, "rpm-ostree") == 0 ||
 	    g_strcmp0 (management_plugin, "shell-extensions") == 0)
 		return FALSE;
 
-- 
2.21.0


From d8ebbe420d5d0642987c6c6b799f108c7b4ce709 Mon Sep 17 00:00:00 2001
From: Kalev Lember <klember@redhat.com>
Date: Fri, 19 Apr 2019 07:17:00 +0200
Subject: [PATCH 7/8] Add HIDE_FROM_SEARCH quirk

This allows plugins to control if apps are discoverable or not.

Discoverable here means that they get hidden from search results and
category views, unless they are already installed. This makes it
possible to launch and remove and update already installed apps, but
hides them otherwise.

This is going to be used in the rpm-ostree plugin to hide package-based
desktop apps on Fedora Silverblue and only show flatpak apps by default.
---
 lib/gs-app.c           | 2 ++
 lib/gs-app.h           | 2 ++
 lib/gs-plugin-loader.c | 8 ++++++++
 3 files changed, 12 insertions(+)

diff --git a/lib/gs-app.c b/lib/gs-app.c
index d5a30927a..186ceb549 100644
--- a/lib/gs-app.c
+++ b/lib/gs-app.c
@@ -243,6 +243,8 @@ _as_app_quirk_flag_to_string (GsAppQuirk quirk)
 		return "new-permissions";
 	if (quirk == GS_APP_QUIRK_PARENTAL_NOT_LAUNCHABLE)
 		return "parental-not-launchable";
+	if (quirk == GS_APP_QUIRK_HIDE_FROM_SEARCH)
+		return "hide-from-search";
 	return NULL;
 }
 
diff --git a/lib/gs-app.h b/lib/gs-app.h
index f6421f0b4..cd185154e 100644
--- a/lib/gs-app.h
+++ b/lib/gs-app.h
@@ -85,6 +85,7 @@ typedef enum {
  * @GS_APP_QUIRK_PARENTAL_FILTER:	The app has been filtered by parental controls, and should be hidden
  * @GS_APP_QUIRK_NEW_PERMISSIONS:	The update requires new permissions
  * @GS_APP_QUIRK_PARENTAL_NOT_LAUNCHABLE:	The app cannot be run by the current user due to parental controls, and should not be launchable
+ * @GS_APP_QUIRK_HIDE_FROM_SEARCH:	The app should not be shown in search results
  *
  * The application attributes.
  **/
@@ -105,6 +106,7 @@ typedef enum {
 	GS_APP_QUIRK_PARENTAL_FILTER	= 1 << 12,	/* Since: 3.32 */
 	GS_APP_QUIRK_NEW_PERMISSIONS	= 1 << 13,	/* Since: 3.32 */
 	GS_APP_QUIRK_PARENTAL_NOT_LAUNCHABLE	= 1 << 14,	/* Since: 3.32 */
+	GS_APP_QUIRK_HIDE_FROM_SEARCH	= 1 << 15,	/* Since: 3.32 */
 	/*< private >*/
 	GS_APP_QUIRK_LAST
 } GsAppQuirk;
diff --git a/lib/gs-plugin-loader.c b/lib/gs-plugin-loader.c
index ca0504a34..aa775e9ef 100644
--- a/lib/gs-plugin-loader.c
+++ b/lib/gs-plugin-loader.c
@@ -1226,6 +1226,14 @@ gs_plugin_loader_app_is_valid (GsApp *app, gpointer user_data)
 		return FALSE;
 	}
 
+	/* don't show apps with hide-from-search quirk, unless they are already installed */
+	if (!gs_app_is_installed (app) &&
+	    gs_app_has_quirk (app, GS_APP_QUIRK_HIDE_FROM_SEARCH)) {
+		g_debug ("app invalid as hide-from-search quirk set %s",
+		         gs_plugin_loader_get_app_str (app));
+		return FALSE;
+	}
+
 	/* don't show sources */
 	if (gs_app_get_kind (app) == AS_APP_KIND_SOURCE) {
 		g_debug ("app invalid as source %s",
-- 
2.21.0


From 8ff12e84acc6f2e0723d908b9c0968cfc6d57b03 Mon Sep 17 00:00:00 2001
From: Kalev Lember <klember@redhat.com>
Date: Fri, 19 Apr 2019 07:31:56 +0200
Subject: [PATCH 8/8] rpm-ostree: Set HIDE_FROM_SEARCH quirk for apps we don't
 want to show

The plan for Fedora Silverblue is to use rpm-ostree layering for things
that are non-apps (e.g. hardware support, codecs, fonts etc that
supplement the base system), and only offer apps through flatpak.

This commit makes it so that available apps don't show up in search, but
anything already installed still gets correctly shown (so that they are
removable / launchable /updatable etc).
---
 plugins/rpm-ostree/gs-plugin-rpm-ostree.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/plugins/rpm-ostree/gs-plugin-rpm-ostree.c b/plugins/rpm-ostree/gs-plugin-rpm-ostree.c
index ae2f2435f..a05099265 100644
--- a/plugins/rpm-ostree/gs-plugin-rpm-ostree.c
+++ b/plugins/rpm-ostree/gs-plugin-rpm-ostree.c
@@ -1229,6 +1229,19 @@ resolve_available_packages_app (GsPlugin *plugin,
 		gs_app_set_name (app, GS_APP_QUALITY_LOWEST, dnf_package_get_name (pkg));
 		gs_app_set_summary (app, GS_APP_QUALITY_LOWEST, dnf_package_get_summary (pkg));
 
+		/* set hide-from-search quirk for available apps we don't want to show */
+		if (!gs_app_is_installed (app)) {
+			switch (gs_app_get_kind (app)) {
+			case AS_APP_KIND_DESKTOP:
+			case AS_APP_KIND_WEB_APP:
+			case AS_APP_KIND_CONSOLE:
+				gs_app_add_quirk (app, GS_APP_QUIRK_HIDE_FROM_SEARCH);
+				break;
+			default:
+				break;
+			}
+		}
+
 		return TRUE /* found */;
 	}
 
-- 
2.21.0