455 lines
15 KiB
Diff
455 lines
15 KiB
Diff
From df08a65d86626ff135a12d96cff6f48f3f1864ae Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Thu, 20 Aug 2020 11:20:47 -0400
|
|
Subject: [PATCH 04/15] subman: Drop userlang field
|
|
|
|
It's currently always erroneously set to empty string.
|
|
|
|
This commit drops it, and just uses "C.UTF-8" everywhere,
|
|
which is what we actually want.
|
|
---
|
|
plugins/subman/gsd-subscription-manager.c | 14 ++++++--------
|
|
1 file changed, 6 insertions(+), 8 deletions(-)
|
|
|
|
diff --git a/plugins/subman/gsd-subscription-manager.c b/plugins/subman/gsd-subscription-manager.c
|
|
index a8c18a26..46f051a5 100644
|
|
--- a/plugins/subman/gsd-subscription-manager.c
|
|
+++ b/plugins/subman/gsd-subscription-manager.c
|
|
@@ -45,61 +45,60 @@ static const gchar introspection_xml[] =
|
|
" <arg type='a{sv}' name='options' direction='in'/>"
|
|
" </method>"
|
|
" <method name='Unregister'/>"
|
|
" <property name='InstalledProducts' type='aa{sv}' access='read'/>"
|
|
" <property name='SubscriptionStatus' type='u' access='read'/>"
|
|
" </interface>"
|
|
"</node>";
|
|
|
|
#define GSD_SUBSCRIPTION_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_SUBSCRIPTION_MANAGER, GsdSubscriptionManagerPrivate))
|
|
|
|
typedef enum {
|
|
_RHSM_INTERFACE_CONFIG,
|
|
_RHSM_INTERFACE_REGISTER_SERVER,
|
|
_RHSM_INTERFACE_ATTACH,
|
|
_RHSM_INTERFACE_ENTITLEMENT,
|
|
_RHSM_INTERFACE_PRODUCTS,
|
|
_RHSM_INTERFACE_CONSUMER,
|
|
_RHSM_INTERFACE_SYSPURPOSE,
|
|
_RHSM_INTERFACE_LAST
|
|
} _RhsmInterface;
|
|
|
|
struct GsdSubscriptionManagerPrivate
|
|
{
|
|
/* D-Bus */
|
|
guint name_id;
|
|
GDBusNodeInfo *introspection_data;
|
|
GDBusConnection *connection;
|
|
GCancellable *bus_cancellable;
|
|
|
|
GDBusProxy *proxies[_RHSM_INTERFACE_LAST];
|
|
- const gchar *userlang; /* owned by GLib internally */
|
|
GHashTable *config; /* str:str */
|
|
GPtrArray *installed_products;
|
|
gchar *address;
|
|
|
|
GTimer *timer_last_notified;
|
|
NotifyNotification *notification_expired;
|
|
NotifyNotification *notification_registered;
|
|
NotifyNotification *notification_registration_required;
|
|
GsdSubmanSubscriptionStatus subscription_status;
|
|
GsdSubmanSubscriptionStatus subscription_status_last;
|
|
};
|
|
|
|
enum {
|
|
PROP_0,
|
|
};
|
|
|
|
static void gsd_subscription_manager_class_init (GsdSubscriptionManagerClass *klass);
|
|
static void gsd_subscription_manager_init (GsdSubscriptionManager *subscription_manager);
|
|
static void gsd_subscription_manager_finalize (GObject *object);
|
|
|
|
G_DEFINE_TYPE (GsdSubscriptionManager, gsd_subscription_manager, G_TYPE_OBJECT)
|
|
|
|
typedef struct
|
|
{
|
|
gchar *product_name;
|
|
gchar *product_id;
|
|
gchar *version;
|
|
gchar *arch;
|
|
gchar *status;
|
|
gchar *starts;
|
|
@@ -197,61 +196,61 @@ _emit_property_changed (GsdSubscriptionManager *manager,
|
|
property_value);
|
|
g_dbus_connection_emit_signal (priv->connection,
|
|
NULL,
|
|
GSD_SUBSCRIPTION_DBUS_PATH,
|
|
"org.freedesktop.DBus.Properties",
|
|
"PropertiesChanged",
|
|
g_variant_new ("(sa{sv}as)",
|
|
GSD_SUBSCRIPTION_DBUS_INTERFACE,
|
|
&builder,
|
|
&invalidated_builder),
|
|
NULL);
|
|
g_variant_builder_clear (&builder);
|
|
g_variant_builder_clear (&invalidated_builder);
|
|
}
|
|
|
|
static gboolean
|
|
_client_installed_products_update (GsdSubscriptionManager *manager, GError **error)
|
|
{
|
|
GsdSubscriptionManagerPrivate *priv = manager->priv;
|
|
JsonNode *json_root;
|
|
JsonArray *json_products_array;
|
|
const gchar *json_txt = NULL;
|
|
g_autoptr(GVariant) val = NULL;
|
|
g_autoptr(JsonParser) json_parser = json_parser_new ();
|
|
|
|
val = g_dbus_proxy_call_sync (priv->proxies[_RHSM_INTERFACE_PRODUCTS],
|
|
"ListInstalledProducts",
|
|
g_variant_new ("(sa{sv}s)",
|
|
"" /* filter_string */,
|
|
NULL /* proxy_options */,
|
|
- priv->userlang),
|
|
+ "C.UTF-8"),
|
|
G_DBUS_CALL_FLAGS_NONE,
|
|
-1, NULL, error);
|
|
if (val == NULL)
|
|
return FALSE;
|
|
g_variant_get (val, "(&s)", &json_txt);
|
|
g_debug ("Products.ListInstalledProducts JSON: %s", json_txt);
|
|
if (!json_parser_load_from_data (json_parser, json_txt, -1, error))
|
|
return FALSE;
|
|
json_root = json_parser_get_root (json_parser);
|
|
json_products_array = json_node_get_array (json_root);
|
|
if (json_products_array == NULL) {
|
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
|
|
"no InstalledProducts array in %s", json_txt);
|
|
return FALSE;
|
|
}
|
|
|
|
g_ptr_array_set_size (priv->installed_products, 0);
|
|
|
|
for (guint i = 0; i < json_array_get_length (json_products_array); i++) {
|
|
JsonArray *json_product = json_array_get_array_element (json_products_array, i);
|
|
g_autoptr(ProductData) product = g_new0 (ProductData, 1);
|
|
|
|
if (json_product == NULL)
|
|
continue;
|
|
if (json_array_get_length (json_product) < 8) {
|
|
g_debug ("Unexpected number of array elements in InstalledProducts JSON");
|
|
continue;
|
|
}
|
|
|
|
product->product_name = g_strdup (json_array_get_string_element (json_product, 0));
|
|
@@ -263,179 +262,179 @@ _client_installed_products_update (GsdSubscriptionManager *manager, GError **err
|
|
product->ends = g_strdup (json_array_get_string_element (json_product, 7));
|
|
|
|
g_ptr_array_add (priv->installed_products, g_steal_pointer (&product));
|
|
}
|
|
|
|
/* emit notification for g-c-c */
|
|
_emit_property_changed (manager, "InstalledProducts",
|
|
_make_installed_products_variant (priv->installed_products));
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static gboolean
|
|
_client_subscription_status_update (GsdSubscriptionManager *manager, GError **error)
|
|
{
|
|
GsdSubscriptionManagerPrivate *priv = manager->priv;
|
|
JsonNode *json_root;
|
|
JsonObject *json_obj;
|
|
const gchar *json_txt = NULL;
|
|
const gchar *status_txt = NULL;
|
|
g_autoptr(GVariant) val = NULL;
|
|
g_autoptr(JsonParser) json_parser = json_parser_new ();
|
|
|
|
/* save old value */
|
|
priv->subscription_status_last = priv->subscription_status;
|
|
|
|
val = g_dbus_proxy_call_sync (priv->proxies[_RHSM_INTERFACE_ENTITLEMENT],
|
|
"GetStatus",
|
|
g_variant_new ("(ss)",
|
|
"", /* assumed as 'now' */
|
|
- priv->userlang),
|
|
+ "C.UTF-8"),
|
|
G_DBUS_CALL_FLAGS_NONE,
|
|
-1, NULL, error);
|
|
if (val == NULL)
|
|
return FALSE;
|
|
g_variant_get (val, "(&s)", &json_txt);
|
|
g_debug ("Entitlement.GetStatus JSON: %s", json_txt);
|
|
if (!json_parser_load_from_data (json_parser, json_txt, -1, error))
|
|
return FALSE;
|
|
json_root = json_parser_get_root (json_parser);
|
|
json_obj = json_node_get_object (json_root);
|
|
if (!json_object_has_member (json_obj, "status")) {
|
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
|
|
"no Entitlement.GetStatus status in %s", json_txt);
|
|
return FALSE;
|
|
}
|
|
|
|
status_txt = json_object_get_string_member (json_obj, "status");
|
|
g_debug ("Entitlement.GetStatus: %s", status_txt);
|
|
priv->subscription_status = _client_subscription_status_from_text (status_txt);
|
|
|
|
/* emit notification for g-c-c */
|
|
if (priv->subscription_status != priv->subscription_status_last) {
|
|
_emit_property_changed (manager, "SubscriptionStatus",
|
|
g_variant_new_uint32 (priv->subscription_status));
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static gboolean
|
|
_client_syspurpose_update (GsdSubscriptionManager *manager, GError **error)
|
|
{
|
|
GsdSubscriptionManagerPrivate *priv = manager->priv;
|
|
JsonNode *json_root;
|
|
JsonObject *json_obj;
|
|
const gchar *json_txt = NULL;
|
|
g_autoptr(GVariant) val = NULL;
|
|
g_autoptr(JsonParser) json_parser = json_parser_new ();
|
|
|
|
val = g_dbus_proxy_call_sync (priv->proxies[_RHSM_INTERFACE_SYSPURPOSE],
|
|
"GetSyspurpose",
|
|
- g_variant_new ("(s)", priv->userlang),
|
|
+ g_variant_new ("(s)", "C.UTF-8"),
|
|
G_DBUS_CALL_FLAGS_NONE,
|
|
-1, NULL, error);
|
|
if (val == NULL)
|
|
return FALSE;
|
|
g_variant_get (val, "(&s)", &json_txt);
|
|
g_debug ("Syspurpose.GetSyspurpose JSON: %s", json_txt);
|
|
if (!json_parser_load_from_data (json_parser, json_txt, -1, error))
|
|
return FALSE;
|
|
json_root = json_parser_get_root (json_parser);
|
|
json_obj = json_node_get_object (json_root);
|
|
if (!json_object_has_member (json_obj, "status")) {
|
|
g_debug ("Syspurpose.GetSyspurpose: Unknown");
|
|
return TRUE;
|
|
}
|
|
g_debug ("Syspurpose.GetSyspurpose: '%s", json_object_get_string_member (json_obj, "status"));
|
|
return TRUE;
|
|
}
|
|
|
|
static gboolean
|
|
_client_register_start (GsdSubscriptionManager *manager, GError **error)
|
|
{
|
|
GsdSubscriptionManagerPrivate *priv = manager->priv;
|
|
const gchar *address = NULL;
|
|
g_autoptr(GDBusProxy) proxy = NULL;
|
|
g_autoptr(GVariant) val = NULL;
|
|
|
|
/* already started */
|
|
if (priv->address != NULL)
|
|
return TRUE;
|
|
|
|
/* apparently: "we can't send registration credentials over the regular
|
|
* system or session bus since those aren't really locked down..." */
|
|
proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
|
|
G_DBUS_PROXY_FLAGS_NONE,
|
|
NULL,
|
|
"com.redhat.RHSM1",
|
|
"/com/redhat/RHSM1/RegisterServer",
|
|
"com.redhat.RHSM1.RegisterServer",
|
|
NULL, error);
|
|
if (proxy == NULL)
|
|
return FALSE;
|
|
val = g_dbus_proxy_call_sync (proxy, "Start",
|
|
- g_variant_new ("(s)", priv->userlang),
|
|
+ g_variant_new ("(s)", "C.UTF-8"),
|
|
G_DBUS_CALL_FLAGS_NONE,
|
|
-1, NULL, error);
|
|
if (val == NULL)
|
|
return FALSE;
|
|
g_variant_get (val, "(&s)", &address);
|
|
g_debug ("RegisterServer.Start: %s", address);
|
|
priv->address = g_strdup (address);
|
|
return TRUE;
|
|
}
|
|
|
|
static gboolean
|
|
_client_register_stop (GsdSubscriptionManager *manager, GError **error)
|
|
{
|
|
GsdSubscriptionManagerPrivate *priv = manager->priv;
|
|
g_autoptr(GDBusProxy) proxy = NULL;
|
|
g_autoptr(GVariant) val = NULL;
|
|
|
|
/* already started */
|
|
if (priv->address == NULL)
|
|
return TRUE;
|
|
|
|
/* stop registration server */
|
|
proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
|
|
G_DBUS_PROXY_FLAGS_NONE,
|
|
NULL,
|
|
"com.redhat.RHSM1",
|
|
"/com/redhat/RHSM1/RegisterServer",
|
|
"com.redhat.RHSM1.RegisterServer",
|
|
NULL, error);
|
|
if (proxy == NULL)
|
|
return FALSE;
|
|
val = g_dbus_proxy_call_sync (proxy, "Stop",
|
|
- g_variant_new ("(s)", priv->userlang),
|
|
+ g_variant_new ("(s)", "C.UTF-8"),
|
|
G_DBUS_CALL_FLAGS_NONE,
|
|
-1, NULL, error);
|
|
if (val == NULL)
|
|
return FALSE;
|
|
g_clear_pointer (&priv->address, g_free);
|
|
return TRUE;
|
|
}
|
|
|
|
static gboolean
|
|
_client_subprocess_wait_check (GSubprocess *subprocess, GError **error)
|
|
{
|
|
gint rc;
|
|
if (!g_subprocess_wait (subprocess, NULL, error)) {
|
|
g_prefix_error (error, "failed to run pkexec: ");
|
|
return FALSE;
|
|
}
|
|
rc = g_subprocess_get_exit_status (subprocess);
|
|
if (rc != 0) {
|
|
GInputStream *istream = g_subprocess_get_stderr_pipe (subprocess);
|
|
gchar buf[1024] = { 0x0 };
|
|
gsize sz = 0;
|
|
g_input_stream_read_all (istream, buf, sizeof(buf) - 1, &sz, NULL, NULL);
|
|
if (sz == 0) {
|
|
g_set_error_literal (error, G_IO_ERROR, rc,
|
|
"Failed to run helper without stderr");
|
|
return FALSE;
|
|
}
|
|
g_set_error_literal (error, G_IO_ERROR, rc, buf);
|
|
return FALSE;
|
|
}
|
|
@@ -637,61 +636,61 @@ _client_unregister (GsdSubscriptionManager *manager, GError **error)
|
|
"pkexec", LIBEXECDIR "/gsd-subman-helper",
|
|
"--kind", "unregister",
|
|
NULL);
|
|
if (subprocess == NULL) {
|
|
g_prefix_error (error, "failed to find pkexec: ");
|
|
return FALSE;
|
|
}
|
|
if (!_client_subprocess_wait_check (subprocess, error))
|
|
return FALSE;
|
|
if (!_client_subscription_status_update (manager, error))
|
|
return FALSE;
|
|
if (!_client_installed_products_update (manager, error))
|
|
return FALSE;
|
|
_client_maybe__show_notification (manager);
|
|
return TRUE;
|
|
}
|
|
|
|
static gboolean
|
|
_client_update_config (GsdSubscriptionManager *manager, GError **error)
|
|
{
|
|
GsdSubscriptionManagerPrivate *priv = manager->priv;
|
|
g_autoptr(GVariant) val = NULL;
|
|
g_autoptr(GVariant) val_server = NULL;
|
|
g_autoptr(GVariantDict) dict = NULL;
|
|
GVariantIter iter;
|
|
gchar *key;
|
|
gchar *value;
|
|
|
|
val = g_dbus_proxy_call_sync (priv->proxies[_RHSM_INTERFACE_CONFIG],
|
|
"GetAll",
|
|
- g_variant_new ("(s)", priv->userlang),
|
|
+ g_variant_new ("(s)", "C.UTF-8"),
|
|
G_DBUS_CALL_FLAGS_NONE,
|
|
-1, NULL, error);
|
|
if (val == NULL)
|
|
return FALSE;
|
|
dict = g_variant_dict_new (g_variant_get_child_value (val, 0));
|
|
val_server = g_variant_dict_lookup_value (dict, "server", G_VARIANT_TYPE("a{ss}"));
|
|
if (val_server != NULL) {
|
|
g_variant_iter_init (&iter, val_server);
|
|
while (g_variant_iter_next (&iter, "{ss}", &key, &value)) {
|
|
g_debug ("%s=%s", key, value);
|
|
g_hash_table_insert (priv->config,
|
|
g_steal_pointer (&key),
|
|
g_steal_pointer (&value));
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
static void
|
|
_subman_proxy_signal_cb (GDBusProxy *proxy,
|
|
const gchar *sender_name,
|
|
const gchar *signal_name,
|
|
GVariant *parameters,
|
|
GsdSubscriptionManager *manager)
|
|
{
|
|
g_autoptr(GError) error = NULL;
|
|
if (!_client_syspurpose_update (manager, &error)) {
|
|
g_warning ("failed to update syspurpose: %s", error->message);
|
|
g_clear_error (&error);
|
|
}
|
|
@@ -736,61 +735,60 @@ _rhsm_interface_to_string (_RhsmInterface kind)
|
|
}
|
|
|
|
static gboolean
|
|
_client_load (GsdSubscriptionManager *manager, GError **error)
|
|
{
|
|
GsdSubscriptionManagerPrivate *priv = manager->priv;
|
|
|
|
priv->config = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
|
|
|
|
/* connect to all the interfaces on the *different* objects :| */
|
|
for (guint i = 0; i < _RHSM_INTERFACE_LAST; i++) {
|
|
const gchar *kind = _rhsm_interface_to_string (i);
|
|
g_autofree gchar *opath = g_strdup_printf ("/com/redhat/RHSM1/%s", kind);
|
|
g_autofree gchar *iface = g_strdup_printf ("com.redhat.RHSM1.%s", kind);
|
|
priv->proxies[i] =
|
|
g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
|
|
G_DBUS_PROXY_FLAGS_NONE,
|
|
NULL,
|
|
"com.redhat.RHSM1",
|
|
opath, iface,
|
|
NULL,
|
|
error);
|
|
if (priv->proxies[i] == NULL)
|
|
return FALSE;
|
|
/* we want to get notified if the status of the system changes */
|
|
g_signal_connect (priv->proxies[i], "g-signal",
|
|
G_CALLBACK (_subman_proxy_signal_cb), manager);
|
|
}
|
|
|
|
/* get initial status */
|
|
- priv->userlang = "";
|
|
if (!_client_update_config (manager, error))
|
|
return FALSE;
|
|
if (!_client_subscription_status_update (manager, error))
|
|
return FALSE;
|
|
if (!_client_installed_products_update (manager, error))
|
|
return FALSE;
|
|
if (!_client_syspurpose_update (manager, error))
|
|
return FALSE;
|
|
|
|
/* success */
|
|
return TRUE;
|
|
}
|
|
|
|
gboolean
|
|
gsd_subscription_manager_start (GsdSubscriptionManager *manager, GError **error)
|
|
{
|
|
gboolean ret;
|
|
g_debug ("Starting subscription manager");
|
|
gnome_settings_profile_start (NULL);
|
|
ret = _client_load (manager, error);
|
|
_client_maybe__show_notification (manager);
|
|
gnome_settings_profile_end (NULL);
|
|
return ret;
|
|
}
|
|
|
|
void
|
|
gsd_subscription_manager_stop (GsdSubscriptionManager *manager)
|
|
{
|
|
g_debug ("Stopping subscription manager");
|
|
_client_unload (manager);
|
|
--
|
|
2.30.0
|
|
|