237 lines
8.3 KiB
Diff
237 lines
8.3 KiB
Diff
|
From f8ddd2c711cd502c74eb9d45360914fe2e6e1b3f Mon Sep 17 00:00:00 2001
|
||
|
From: Ray Strode <rstrode@redhat.com>
|
||
|
Date: Thu, 20 Aug 2020 13:34:19 -0400
|
||
|
Subject: [PATCH 06/15] subman: Handle subscription-manager giving invalid
|
||
|
status better
|
||
|
|
||
|
subscription-manager potentially returns status messages that the
|
||
|
subman plugin treats as enum values translated in some unknown
|
||
|
other language. It could be tied to system locale, or due to a
|
||
|
caching bug a previous locale used.
|
||
|
|
||
|
This commit tries to work around that bug, by instead relying on
|
||
|
the GetUUID() method and valid attribute. If there's no UUID we
|
||
|
know the system is unregistered. If there's a UUID but the valid
|
||
|
attribute is FALSE we know the system is registered, but hasn't
|
||
|
got proper entitlements.
|
||
|
---
|
||
|
plugins/subman/gsd-subscription-manager.c | 69 ++++++++++++-----------
|
||
|
1 file changed, 36 insertions(+), 33 deletions(-)
|
||
|
|
||
|
diff --git a/plugins/subman/gsd-subscription-manager.c b/plugins/subman/gsd-subscription-manager.c
|
||
|
index 46f051a5..e2c16056 100644
|
||
|
--- a/plugins/subman/gsd-subscription-manager.c
|
||
|
+++ b/plugins/subman/gsd-subscription-manager.c
|
||
|
@@ -104,77 +104,60 @@ typedef struct
|
||
|
gchar *starts;
|
||
|
gchar *ends;
|
||
|
} ProductData;
|
||
|
|
||
|
static void
|
||
|
product_data_free (ProductData *product)
|
||
|
{
|
||
|
g_free (product->product_name);
|
||
|
g_free (product->product_id);
|
||
|
g_free (product->version);
|
||
|
g_free (product->arch);
|
||
|
g_free (product->status);
|
||
|
g_free (product->starts);
|
||
|
g_free (product->ends);
|
||
|
g_free (product);
|
||
|
}
|
||
|
|
||
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ProductData, product_data_free);
|
||
|
|
||
|
static gpointer manager_object = NULL;
|
||
|
|
||
|
GQuark
|
||
|
gsd_subscription_manager_error_quark (void)
|
||
|
{
|
||
|
static GQuark quark = 0;
|
||
|
if (!quark)
|
||
|
quark = g_quark_from_static_string ("gsd_subscription_manager_error");
|
||
|
return quark;
|
||
|
}
|
||
|
|
||
|
-static GsdSubmanSubscriptionStatus
|
||
|
-_client_subscription_status_from_text (const gchar *status_txt)
|
||
|
-{
|
||
|
- if (g_strcmp0 (status_txt, "Unknown") == 0)
|
||
|
- return GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN;
|
||
|
- if (g_strcmp0 (status_txt, "Current") == 0)
|
||
|
- return GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID;
|
||
|
- if (g_strcmp0 (status_txt, "Invalid") == 0)
|
||
|
- return GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID;
|
||
|
- if (g_strcmp0 (status_txt, "Disabled") == 0)
|
||
|
- return GSD_SUBMAN_SUBSCRIPTION_STATUS_DISABLED;
|
||
|
- if (g_strcmp0 (status_txt, "Insufficient") == 0)
|
||
|
- return GSD_SUBMAN_SUBSCRIPTION_STATUS_PARTIALLY_VALID;
|
||
|
- g_warning ("Unknown subscription status: %s", status_txt); // 'Current'?
|
||
|
- return GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN;
|
||
|
-}
|
||
|
-
|
||
|
static GVariant *
|
||
|
_make_installed_products_variant (GPtrArray *installed_products)
|
||
|
{
|
||
|
GVariantBuilder builder;
|
||
|
g_variant_builder_init (&builder, G_VARIANT_TYPE ("aa{sv}"));
|
||
|
|
||
|
for (guint i = 0; i < installed_products->len; i++) {
|
||
|
ProductData *product = g_ptr_array_index (installed_products, i);
|
||
|
g_auto(GVariantDict) dict;
|
||
|
|
||
|
g_variant_dict_init (&dict, NULL);
|
||
|
|
||
|
g_variant_dict_insert (&dict, "product-name", "s", product->product_name);
|
||
|
g_variant_dict_insert (&dict, "product-id", "s", product->product_id);
|
||
|
g_variant_dict_insert (&dict, "version", "s", product->version);
|
||
|
g_variant_dict_insert (&dict, "arch", "s", product->arch);
|
||
|
g_variant_dict_insert (&dict, "status", "s", product->status);
|
||
|
g_variant_dict_insert (&dict, "starts", "s", product->starts);
|
||
|
g_variant_dict_insert (&dict, "ends", "s", product->ends);
|
||
|
|
||
|
g_variant_builder_add_value (&builder, g_variant_dict_end (&dict));
|
||
|
}
|
||
|
|
||
|
return g_variant_builder_end (&builder);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
_emit_property_changed (GsdSubscriptionManager *manager,
|
||
|
const gchar *property_name,
|
||
|
GVariant *property_value)
|
||
|
@@ -248,94 +231,114 @@ _client_installed_products_update (GsdSubscriptionManager *manager, GError **err
|
||
|
|
||
|
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));
|
||
|
product->product_id = g_strdup (json_array_get_string_element (json_product, 1));
|
||
|
product->version = g_strdup (json_array_get_string_element (json_product, 2));
|
||
|
product->arch = g_strdup (json_array_get_string_element (json_product, 3));
|
||
|
product->status = g_strdup (json_array_get_string_element (json_product, 4));
|
||
|
product->starts = g_strdup (json_array_get_string_element (json_product, 6));
|
||
|
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;
|
||
|
+ g_autoptr(GVariant) uuid = NULL;
|
||
|
+ const gchar *uuid_txt = NULL;
|
||
|
JsonNode *json_root;
|
||
|
JsonObject *json_obj;
|
||
|
const gchar *json_txt = NULL;
|
||
|
- const gchar *status_txt = NULL;
|
||
|
- g_autoptr(GVariant) val = NULL;
|
||
|
+ g_autoptr(GVariant) status = 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' */
|
||
|
- "C.UTF-8"),
|
||
|
- G_DBUS_CALL_FLAGS_NONE,
|
||
|
- -1, NULL, error);
|
||
|
- if (val == NULL)
|
||
|
+ uuid = g_dbus_proxy_call_sync (priv->proxies[_RHSM_INTERFACE_CONSUMER],
|
||
|
+ "GetUuid",
|
||
|
+ g_variant_new ("(s)",
|
||
|
+ "C.UTF-8"),
|
||
|
+ G_DBUS_CALL_FLAGS_NONE,
|
||
|
+ -1, NULL, error);
|
||
|
+ if (uuid == NULL)
|
||
|
return FALSE;
|
||
|
- g_variant_get (val, "(&s)", &json_txt);
|
||
|
+
|
||
|
+ g_variant_get (uuid, "(&s)", &uuid_txt);
|
||
|
+
|
||
|
+ status = g_dbus_proxy_call_sync (priv->proxies[_RHSM_INTERFACE_ENTITLEMENT],
|
||
|
+ "GetStatus",
|
||
|
+ g_variant_new ("(ss)",
|
||
|
+ "", /* assumed as 'now' */
|
||
|
+ "C.UTF-8"),
|
||
|
+ G_DBUS_CALL_FLAGS_NONE,
|
||
|
+ -1, NULL, error);
|
||
|
+ if (status == NULL)
|
||
|
+ return FALSE;
|
||
|
+ g_variant_get (status, "(&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")) {
|
||
|
+ if (!json_object_has_member (json_obj, "valid")) {
|
||
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
|
||
|
- "no Entitlement.GetStatus status in %s", json_txt);
|
||
|
+ "no Entitlement.GetStatus valid 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);
|
||
|
+ gboolean is_valid = json_object_get_boolean_member (json_obj, "valid");
|
||
|
+
|
||
|
+ if (uuid_txt[0] != '\0') {
|
||
|
+ if (is_valid) {
|
||
|
+ priv->subscription_status = GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID;
|
||
|
+ } else {
|
||
|
+ priv->subscription_status = GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID;
|
||
|
+ }
|
||
|
+ } else {
|
||
|
+ priv->subscription_status = GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN;
|
||
|
+ }
|
||
|
|
||
|
/* 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)", "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))
|
||
|
--
|
||
|
2.30.0
|
||
|
|