Blame SOURCES/0012-subman-Add-DBus-API-to-subscribe-for-updates-on-alre.patch

06f198
From 3bb3b2b09d34deafadd3cfe3355137afab20cb23 Mon Sep 17 00:00:00 2001
06f198
From: Ray Strode <rstrode@redhat.com>
06f198
Date: Sun, 24 Jan 2021 11:27:42 -0500
06f198
Subject: [PATCH 12/15] subman: Add DBus API to subscribe for updates on
06f198
 already registered system
06f198
06f198
It's possible an admin may have registered their system without
06f198
attaching any subscriptions to it.
06f198
06f198
At the moment, gnome-settings-daemon only provides a way to register
06f198
and subscribe in one step.
06f198
06f198
This commit adds an API to support doing the last half of the process
06f198
on its own.
06f198
---
06f198
 plugins/subman/gsd-subscription-manager.c | 51 +++++++++++++++++++++++
06f198
 1 file changed, 51 insertions(+)
06f198
06f198
diff --git a/plugins/subman/gsd-subscription-manager.c b/plugins/subman/gsd-subscription-manager.c
06f198
index 1f9ca447..705f8b11 100644
06f198
--- a/plugins/subman/gsd-subscription-manager.c
06f198
+++ b/plugins/subman/gsd-subscription-manager.c
06f198
@@ -19,60 +19,61 @@
06f198
  */
06f198
 
06f198
 #include "config.h"
06f198
 
06f198
 #include <glib/gi18n.h>
06f198
 #include <gio/gunixinputstream.h>
06f198
 #include <gdk/gdk.h>
06f198
 #include <gtk/gtk.h>
06f198
 #include <json-glib/json-glib.h>
06f198
 #include <libnotify/notify.h>
06f198
 
06f198
 #include "gnome-settings-profile.h"
06f198
 #include "gsd-subman-common.h"
06f198
 #include "gsd-subscription-manager.h"
06f198
 
06f198
 #define GSD_DBUS_NAME "org.gnome.SettingsDaemon"
06f198
 #define GSD_DBUS_PATH "/org/gnome/SettingsDaemon"
06f198
 #define GSD_DBUS_BASE_INTERFACE "org.gnome.SettingsDaemon"
06f198
 
06f198
 #define GSD_SUBSCRIPTION_DBUS_NAME		GSD_DBUS_NAME ".Subscription"
06f198
 #define GSD_SUBSCRIPTION_DBUS_PATH		GSD_DBUS_PATH "/Subscription"
06f198
 #define GSD_SUBSCRIPTION_DBUS_INTERFACE		GSD_DBUS_BASE_INTERFACE ".Subscription"
06f198
 
06f198
 static const gchar introspection_xml[] =
06f198
 "<node>"
06f198
 "  <interface name='org.gnome.SettingsDaemon.Subscription'>"
06f198
 "    <method name='Register'>"
06f198
 "      <arg type='a{sv}' name='options' direction='in'/>"
06f198
 "    </method>"
06f198
 "    <method name='Unregister'/>"
06f198
+"    <method name='Attach'/>"
06f198
 "    <property name='InstalledProducts' type='aa{sv}' access='read'/>"
06f198
 "    <property name='SubscriptionStatus' type='u' access='read'/>"
06f198
 "  </interface>"
06f198
 "</node>";
06f198
 
06f198
 #define GSD_SUBSCRIPTION_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_SUBSCRIPTION_MANAGER, GsdSubscriptionManagerPrivate))
06f198
 
06f198
 typedef enum {
06f198
 	_RHSM_INTERFACE_CONFIG,
06f198
 	_RHSM_INTERFACE_REGISTER_SERVER,
06f198
 	_RHSM_INTERFACE_ATTACH,
06f198
 	_RHSM_INTERFACE_ENTITLEMENT,
06f198
 	_RHSM_INTERFACE_PRODUCTS,
06f198
 	_RHSM_INTERFACE_CONSUMER,
06f198
 	_RHSM_INTERFACE_SYSPURPOSE,
06f198
 	_RHSM_INTERFACE_LAST
06f198
 } _RhsmInterface;
06f198
 
06f198
 struct GsdSubscriptionManagerPrivate
06f198
 {
06f198
 	/* D-Bus */
06f198
 	guint		 name_id;
06f198
 	GDBusNodeInfo	*introspection_data;
06f198
 	GDBusConnection	*connection;
06f198
 	GCancellable	*bus_cancellable;
06f198
 
06f198
 	GDBusProxy	*proxies[_RHSM_INTERFACE_LAST];
06f198
 	GHashTable	*config; 	/* str:str */
06f198
 	GPtrArray	*installed_products;
06f198
 	gchar		*address;
06f198
@@ -669,60 +670,104 @@ _client_register (GsdSubscriptionManager *manager,
06f198
 }
06f198
 
06f198
 static gboolean
06f198
 _client_unregister (GsdSubscriptionManager *manager, GError **error)
06f198
 {
06f198
 	g_autoptr(GSubprocess) subprocess = NULL;
06f198
 
06f198
 	/* apparently: "we can't send registration credentials over the regular
06f198
 	 * system or session bus since those aren't really locked down..." */
06f198
 	if (!_client_register_start (manager, error))
06f198
 		return FALSE;
06f198
 	g_debug ("spawning %s", LIBEXECDIR "/gsd-subman-helper");
06f198
 	subprocess = g_subprocess_new (G_SUBPROCESS_FLAGS_STDERR_PIPE, error,
06f198
 				       "pkexec", LIBEXECDIR "/gsd-subman-helper",
06f198
 				       "--kind", "unregister",
06f198
 				       NULL);
06f198
 	if (subprocess == NULL) {
06f198
 		g_prefix_error (error, "failed to find pkexec: ");
06f198
 		return FALSE;
06f198
 	}
06f198
 	if (!_client_subprocess_wait_check (subprocess, error))
06f198
 		return FALSE;
06f198
 	if (!_client_subscription_status_update (manager, error))
06f198
 		return FALSE;
06f198
 	if (!_client_installed_products_update (manager, error))
06f198
 		return FALSE;
06f198
 	_client_maybe__show_notification (manager);
06f198
 	return TRUE;
06f198
 }
06f198
 
06f198
+static gboolean
06f198
+_client_attach (GsdSubscriptionManager *manager,
06f198
+		GError **error)
06f198
+{
06f198
+	g_autoptr(GSubprocess) subprocess = NULL;
06f198
+	g_autoptr(GBytes) stderr_buf = NULL;
06f198
+	gint rc;
06f198
+
06f198
+	g_debug ("spawning %s", LIBEXECDIR "/gsd-subman-helper");
06f198
+	subprocess = g_subprocess_new (G_SUBPROCESS_FLAGS_STDERR_PIPE,
06f198
+				       error,
06f198
+				       "pkexec", LIBEXECDIR "/gsd-subman-helper",
06f198
+				       "--kind", "auto-attach",
06f198
+				       NULL);
06f198
+	if (subprocess == NULL) {
06f198
+		g_prefix_error (error, "failed to find pkexec: ");
06f198
+		return FALSE;
06f198
+	}
06f198
+
06f198
+	if (!g_subprocess_communicate (subprocess, NULL, NULL, NULL, &stderr_buf, error)) {
06f198
+		g_prefix_error (error, "failed to run pkexec: ");
06f198
+		return FALSE;
06f198
+	}
06f198
+
06f198
+	rc = g_subprocess_get_exit_status (subprocess);
06f198
+	if (rc != 0) {
06f198
+		if (g_bytes_get_size (stderr_buf) == 0) {
06f198
+			g_set_error_literal (error, G_IO_ERROR, rc,
06f198
+			                     "Failed to run helper without stderr");
06f198
+			return FALSE;
06f198
+		}
06f198
+
06f198
+		g_set_error (error, G_IO_ERROR, rc,
06f198
+			     "%.*s",
06f198
+			     (int) g_bytes_get_size (stderr_buf),
06f198
+			     (char *) g_bytes_get_data (stderr_buf, NULL));
06f198
+	}
06f198
+
06f198
+	if (!_client_subscription_status_update (manager, error))
06f198
+		return FALSE;
06f198
+	_client_maybe__show_notification (manager);
06f198
+	return TRUE;
06f198
+}
06f198
+
06f198
 static gboolean
06f198
 _client_update_config (GsdSubscriptionManager *manager, GError **error)
06f198
 {
06f198
 	GsdSubscriptionManagerPrivate *priv = manager->priv;
06f198
 	g_autoptr(GVariant) val = NULL;
06f198
 	g_autoptr(GVariant) val_server = NULL;
06f198
 	g_autoptr(GVariantDict) dict = NULL;
06f198
 	GVariantIter iter;
06f198
 	gchar *key;
06f198
 	gchar *value;
06f198
 
06f198
 	val = g_dbus_proxy_call_sync (priv->proxies[_RHSM_INTERFACE_CONFIG],
06f198
 				      "GetAll",
06f198
 				      g_variant_new ("(s)", "C.UTF-8"),
06f198
 				      G_DBUS_CALL_FLAGS_NONE,
06f198
 				      -1, NULL, error);
06f198
 	if (val == NULL)
06f198
 		return FALSE;
06f198
 	dict = g_variant_dict_new (g_variant_get_child_value (val, 0));
06f198
 	val_server = g_variant_dict_lookup_value (dict, "server", G_VARIANT_TYPE("a{ss}"));
06f198
 	if (val_server != NULL) {
06f198
 		g_variant_iter_init (&iter, val_server);
06f198
 		while (g_variant_iter_next (&iter, "{ss}", &key, &value)) {
06f198
 			g_debug ("%s=%s", key, value);
06f198
 			g_hash_table_insert (priv->config,
06f198
 					     g_steal_pointer (&key),
06f198
 					     g_steal_pointer (&value));
06f198
 		}
06f198
 	}
06f198
 	return TRUE;
06f198
@@ -1002,60 +1047,66 @@ handle_method_call (GDBusConnection       *connection,
06f198
 				g_dbus_method_invocation_return_gerror (invocation, error);
06f198
 				return;
06f198
 			}
06f198
 		} else if (g_strcmp0 (kind, "key") == 0) {
06f198
 			const gchar *activation_key = NULL;
06f198
 			g_variant_dict_lookup (dict, "hostname", "&s", &hostname);
06f198
 			g_variant_dict_lookup (dict, "organisation", "&s", &organisation);
06f198
 			g_variant_dict_lookup (dict, "activation-key", "&s", &activation_key);
06f198
 			if (!_client_register_with_keys (manager,
06f198
 							       hostname,
06f198
 							       organisation,
06f198
 							       activation_key,
06f198
 							       &error)) {
06f198
 				g_dbus_method_invocation_return_gerror (invocation, error);
06f198
 				return;
06f198
 			}
06f198
 		} else {
06f198
 			g_dbus_method_invocation_return_error_literal (invocation,
06f198
 								       G_IO_ERROR, G_IO_ERROR_FAILED,
06f198
 								       "Invalid kind specified");
06f198
 
06f198
 			return;
06f198
 		}
06f198
 		g_dbus_method_invocation_return_value (invocation, NULL);
06f198
 	} else if (g_strcmp0 (method_name, "Unregister") == 0) {
06f198
 		if (!_client_unregister (manager, &error)) {
06f198
 			g_dbus_method_invocation_return_gerror (invocation, error);
06f198
 			return;
06f198
 		}
06f198
 		g_dbus_method_invocation_return_value (invocation, NULL);
06f198
+	} else if (g_strcmp0 (method_name, "Attach") == 0) {
06f198
+		if (!_client_attach (manager, &error)) {
06f198
+			g_dbus_method_invocation_return_gerror (invocation, error);
06f198
+			return;
06f198
+		}
06f198
+		g_dbus_method_invocation_return_value (invocation, NULL);
06f198
 	} else {
06f198
 		g_assert_not_reached ();
06f198
 	}
06f198
 }
06f198
 
06f198
 static GVariant *
06f198
 handle_get_property (GDBusConnection *connection,
06f198
 		     const gchar *sender,
06f198
 		     const gchar *object_path,
06f198
 		     const gchar *interface_name,
06f198
 		     const gchar *property_name,
06f198
 		     GError **error, gpointer user_data)
06f198
 {
06f198
 	GsdSubscriptionManager *manager = GSD_SUBSCRIPTION_MANAGER (user_data);
06f198
 	GsdSubscriptionManagerPrivate *priv = manager->priv;
06f198
 
06f198
 	if (g_strcmp0 (interface_name, GSD_SUBSCRIPTION_DBUS_INTERFACE) != 0) {
06f198
 		g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
06f198
 			     "No such interface: %s", interface_name);
06f198
 		return NULL;
06f198
 	}
06f198
 
06f198
 	if (g_strcmp0 (property_name, "SubscriptionStatus") == 0)
06f198
 		return g_variant_new_uint32 (priv->subscription_status);
06f198
 
06f198
 	if (g_strcmp0 (property_name, "InstalledProducts") == 0)
06f198
 		return _make_installed_products_variant (priv->installed_products);
06f198
 
06f198
 	g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
06f198
 		     "Failed to get property: %s", property_name);
06f198
-- 
06f198
2.30.0
06f198