import gnome-settings-daemon-3.32.0-14.el8
This commit is contained in:
parent
3f821160de
commit
55c8c8631a
@ -0,0 +1,125 @@
|
||||
From a8115378fd876bfd4c3871428cdc16134ed484b1 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
||||
Date: Tue, 5 Jan 2021 11:11:18 +0100
|
||||
Subject: [PATCH] media-keys: Mark screen cast as stopped if it was signalled
|
||||
as such
|
||||
|
||||
gnome-shell now sends a 'Stopped' signal if it was stopped without
|
||||
gsd-media-keys itself being the stopper.
|
||||
---
|
||||
plugins/media-keys/gsd-media-keys-manager.c | 52 +++++++++++++++++++--
|
||||
1 file changed, 49 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/plugins/media-keys/gsd-media-keys-manager.c b/plugins/media-keys/gsd-media-keys-manager.c
|
||||
index 4d251f08..a526d5cf 100644
|
||||
--- a/plugins/media-keys/gsd-media-keys-manager.c
|
||||
+++ b/plugins/media-keys/gsd-media-keys-manager.c
|
||||
@@ -210,6 +210,7 @@ struct GsdMediaKeysManagerPrivate
|
||||
guint screencast_timeout_id;
|
||||
gboolean screencast_recording;
|
||||
GCancellable *screencast_cancellable;
|
||||
+ guint screencast_stopped_signal_id;
|
||||
|
||||
/* Rotation */
|
||||
guint iio_sensor_watch_id;
|
||||
@@ -2346,20 +2347,26 @@ do_rfkill_action (GsdMediaKeysManager *manager,
|
||||
}
|
||||
|
||||
static void
|
||||
-screencast_stop (GsdMediaKeysManager *manager)
|
||||
+screencast_stopped (GsdMediaKeysManager *manager)
|
||||
{
|
||||
if (manager->priv->screencast_timeout_id > 0) {
|
||||
g_source_remove (manager->priv->screencast_timeout_id);
|
||||
manager->priv->screencast_timeout_id = 0;
|
||||
}
|
||||
|
||||
+ manager->priv->screencast_recording = FALSE;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+screencast_stop (GsdMediaKeysManager *manager)
|
||||
+{
|
||||
+ screencast_stopped (manager);
|
||||
+
|
||||
g_dbus_proxy_call (manager->priv->screencast_proxy,
|
||||
"StopScreencast", NULL,
|
||||
G_DBUS_CALL_FLAGS_NONE, -1,
|
||||
manager->priv->screencast_cancellable,
|
||||
NULL, NULL);
|
||||
-
|
||||
- manager->priv->screencast_recording = FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -2835,6 +2842,21 @@ initialize_volume_handler (GsdMediaKeysManager *manager)
|
||||
gnome_settings_profile_end ("gvc_mixer_control_new");
|
||||
}
|
||||
|
||||
+
|
||||
+static void
|
||||
+on_screencast_stopped (GDBusConnection *connection,
|
||||
+ const gchar *sender_name,
|
||||
+ const gchar *object_path,
|
||||
+ const gchar *interface_name,
|
||||
+ const gchar *signal_name,
|
||||
+ GVariant *parameters,
|
||||
+ gpointer data)
|
||||
+{
|
||||
+ GsdMediaKeysManager *manager = data;
|
||||
+
|
||||
+ screencast_stopped (manager);
|
||||
+}
|
||||
+
|
||||
static void
|
||||
on_screencast_proxy_ready (GObject *source,
|
||||
GAsyncResult *result,
|
||||
@@ -2850,7 +2872,20 @@ on_screencast_proxy_ready (GObject *source,
|
||||
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
g_warning ("Failed to create proxy for screencast: %s", error->message);
|
||||
g_error_free (error);
|
||||
+ return;
|
||||
}
|
||||
+
|
||||
+ manager->priv->screencast_stopped_signal_id =
|
||||
+ g_dbus_connection_signal_subscribe (manager->priv->connection,
|
||||
+ SHELL_DBUS_NAME ".Screencast",
|
||||
+ SHELL_DBUS_NAME ".Screencast",
|
||||
+ "Stopped",
|
||||
+ SHELL_DBUS_PATH "/Screencast",
|
||||
+ NULL,
|
||||
+ G_DBUS_SIGNAL_FLAGS_NONE,
|
||||
+ on_screencast_stopped,
|
||||
+ manager,
|
||||
+ NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2901,6 +2936,11 @@ shell_presence_changed (GsdMediaKeysManager *manager)
|
||||
on_screencast_proxy_ready, manager);
|
||||
g_free (name_owner);
|
||||
} else {
|
||||
+ if (manager->priv->screencast_stopped_signal_id)
|
||||
+ g_dbus_connection_signal_unsubscribe (manager->priv->connection,
|
||||
+ manager->priv->screencast_stopped_signal_id);
|
||||
+ manager->priv->screencast_stopped_signal_id = 0;
|
||||
+
|
||||
g_ptr_array_set_size (manager->priv->keys, 0);
|
||||
g_clear_object (&manager->priv->key_grabber);
|
||||
g_clear_object (&manager->priv->screencast_proxy);
|
||||
@@ -3091,6 +3131,12 @@ gsd_media_keys_manager_stop (GsdMediaKeysManager *manager)
|
||||
priv->reenable_power_button_timer_id = 0;
|
||||
}
|
||||
|
||||
+ if (priv->screencast_stopped_signal_id) {
|
||||
+ g_dbus_connection_signal_unsubscribe (priv->connection,
|
||||
+ priv->screencast_stopped_signal_id);
|
||||
+ priv->screencast_stopped_signal_id = 0;
|
||||
+ }
|
||||
+
|
||||
g_clear_pointer (&manager->priv->ca, ca_context_destroy);
|
||||
|
||||
#if HAVE_GUDEV
|
||||
--
|
||||
2.27.0
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,768 @@
|
||||
From f723ed1078e050c4d966d40b2aea74970c74279c Mon Sep 17 00:00:00 2001
|
||||
From: Kalev Lember <klember@redhat.com>
|
||||
Date: Thu, 27 Jun 2019 16:12:00 +0200
|
||||
Subject: [PATCH 02/15] subman: Add InstalledProducts dbus property for g-c-c
|
||||
|
||||
---
|
||||
plugins/subman/gsd-subscription-manager.c | 135 ++++++++++++++++++++++
|
||||
1 file changed, 135 insertions(+)
|
||||
|
||||
diff --git a/plugins/subman/gsd-subscription-manager.c b/plugins/subman/gsd-subscription-manager.c
|
||||
index 08b13fa6..a8c18a26 100644
|
||||
--- a/plugins/subman/gsd-subscription-manager.c
|
||||
+++ b/plugins/subman/gsd-subscription-manager.c
|
||||
@@ -1,186 +1,304 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||
*
|
||||
* Copyright (C) 2019 Richard Hughes <richard@hughsie.com>
|
||||
+ * Copyright (C) 2019 Kalev Lember <klember@redhat.com>
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <gdk/gdk.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <json-glib/json-glib.h>
|
||||
#include <libnotify/notify.h>
|
||||
|
||||
#include "gnome-settings-profile.h"
|
||||
#include "gsd-subman-common.h"
|
||||
#include "gsd-subscription-manager.h"
|
||||
|
||||
#define GSD_DBUS_NAME "org.gnome.SettingsDaemon"
|
||||
#define GSD_DBUS_PATH "/org/gnome/SettingsDaemon"
|
||||
#define GSD_DBUS_BASE_INTERFACE "org.gnome.SettingsDaemon"
|
||||
|
||||
#define GSD_SUBSCRIPTION_DBUS_NAME GSD_DBUS_NAME ".Subscription"
|
||||
#define GSD_SUBSCRIPTION_DBUS_PATH GSD_DBUS_PATH "/Subscription"
|
||||
#define GSD_SUBSCRIPTION_DBUS_INTERFACE GSD_DBUS_BASE_INTERFACE ".Subscription"
|
||||
|
||||
static const gchar introspection_xml[] =
|
||||
"<node>"
|
||||
" <interface name='org.gnome.SettingsDaemon.Subscription'>"
|
||||
" <method name='Register'>"
|
||||
" <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;
|
||||
+ 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)
|
||||
{
|
||||
GsdSubscriptionManagerPrivate *priv = manager->priv;
|
||||
GVariantBuilder builder;
|
||||
GVariantBuilder invalidated_builder;
|
||||
|
||||
/* not yet connected */
|
||||
if (priv->connection == NULL)
|
||||
return;
|
||||
|
||||
/* build the dict */
|
||||
g_variant_builder_init (&invalidated_builder, G_VARIANT_TYPE ("as"));
|
||||
g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
|
||||
g_variant_builder_add (&builder,
|
||||
"{sv}",
|
||||
property_name,
|
||||
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),
|
||||
+ 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));
|
||||
+ 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;
|
||||
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),
|
||||
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")) {
|
||||
@@ -423,185 +541,195 @@ _client_register_with_keys (GsdSubscriptionManager *manager,
|
||||
GError **error)
|
||||
{
|
||||
GsdSubscriptionManagerPrivate *priv = manager->priv;
|
||||
g_autoptr(GSubprocess) subprocess = NULL;
|
||||
|
||||
/* apparently: "we can't send registration credentials over the regular
|
||||
* system or session bus since those aren't really locked down..." */
|
||||
if (!_client_register_start (manager, error))
|
||||
return FALSE;
|
||||
g_debug ("spawning %s", LIBEXECDIR "/gsd-subman-helper");
|
||||
subprocess = g_subprocess_new (G_SUBPROCESS_FLAGS_STDERR_PIPE, error,
|
||||
"pkexec", LIBEXECDIR "/gsd-subman-helper",
|
||||
"--kind", "register-with-key",
|
||||
"--address", priv->address,
|
||||
"--hostname", hostname,
|
||||
"--organisation", organisation,
|
||||
"--activation-key", activation_key,
|
||||
NULL);
|
||||
if (subprocess == NULL) {
|
||||
g_prefix_error (error, "failed to find pkexec: ");
|
||||
return FALSE;
|
||||
}
|
||||
if (!_client_subprocess_wait_check (subprocess, error))
|
||||
return FALSE;
|
||||
|
||||
/* FIXME: also do on error? */
|
||||
if (!_client_register_stop (manager, 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);
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_client_register (GsdSubscriptionManager *manager,
|
||||
const gchar *hostname,
|
||||
const gchar *organisation,
|
||||
const gchar *username,
|
||||
const gchar *password,
|
||||
GError **error)
|
||||
{
|
||||
GsdSubscriptionManagerPrivate *priv = manager->priv;
|
||||
g_autoptr(GSubprocess) subprocess = NULL;
|
||||
|
||||
/* fallback */
|
||||
if (organisation == NULL)
|
||||
organisation = "";
|
||||
|
||||
/* apparently: "we can't send registration credentials over the regular
|
||||
* system or session bus since those aren't really locked down..." */
|
||||
if (!_client_register_start (manager, error))
|
||||
return FALSE;
|
||||
g_debug ("spawning %s", LIBEXECDIR "/gsd-subman-helper");
|
||||
subprocess = g_subprocess_new (G_SUBPROCESS_FLAGS_STDERR_PIPE, error,
|
||||
"pkexec", LIBEXECDIR "/gsd-subman-helper",
|
||||
"--kind", "register-with-username",
|
||||
"--address", priv->address,
|
||||
"--hostname", hostname,
|
||||
"--organisation", organisation,
|
||||
"--username", username,
|
||||
"--password", password,
|
||||
NULL);
|
||||
if (subprocess == NULL) {
|
||||
g_prefix_error (error, "failed to find pkexec: ");
|
||||
return FALSE;
|
||||
}
|
||||
if (!_client_subprocess_wait_check (subprocess, error))
|
||||
return FALSE;
|
||||
|
||||
/* FIXME: also do on error? */
|
||||
if (!_client_register_stop (manager, 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_unregister (GsdSubscriptionManager *manager, GError **error)
|
||||
{
|
||||
g_autoptr(GSubprocess) subprocess = NULL;
|
||||
|
||||
/* apparently: "we can't send registration credentials over the regular
|
||||
* system or session bus since those aren't really locked down..." */
|
||||
if (!_client_register_start (manager, error))
|
||||
return FALSE;
|
||||
g_debug ("spawning %s", LIBEXECDIR "/gsd-subman-helper");
|
||||
subprocess = g_subprocess_new (G_SUBPROCESS_FLAGS_STDERR_PIPE, 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_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);
|
||||
}
|
||||
if (!_client_subscription_status_update (manager, &error)) {
|
||||
g_warning ("failed to update subscription status: %s", error->message);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
+ if (!_client_installed_products_update (manager, &error)) {
|
||||
+ g_warning ("failed to update installed products: %s", error->message);
|
||||
+ g_clear_error (&error);
|
||||
+ }
|
||||
_client_maybe__show_notification (manager);
|
||||
}
|
||||
|
||||
static void
|
||||
_client_unload (GsdSubscriptionManager *manager)
|
||||
{
|
||||
GsdSubscriptionManagerPrivate *priv = manager->priv;
|
||||
for (guint i = 0; i < _RHSM_INTERFACE_LAST; i++)
|
||||
g_clear_object (&priv->proxies[i]);
|
||||
g_hash_table_unref (priv->config);
|
||||
}
|
||||
|
||||
static const gchar *
|
||||
_rhsm_interface_to_string (_RhsmInterface kind)
|
||||
{
|
||||
if (kind == _RHSM_INTERFACE_CONFIG)
|
||||
return "Config";
|
||||
if (kind == _RHSM_INTERFACE_REGISTER_SERVER)
|
||||
return "RegisterServer";
|
||||
if (kind == _RHSM_INTERFACE_ATTACH)
|
||||
return "Attach";
|
||||
if (kind == _RHSM_INTERFACE_ENTITLEMENT)
|
||||
return "Entitlement";
|
||||
if (kind == _RHSM_INTERFACE_PRODUCTS)
|
||||
return "Products";
|
||||
if (kind == _RHSM_INTERFACE_CONSUMER)
|
||||
return "Consumer";
|
||||
if (kind == _RHSM_INTERFACE_SYSPURPOSE)
|
||||
return "Syspurpose";
|
||||
return NULL;
|
||||
@@ -613,60 +741,62 @@ _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);
|
||||
}
|
||||
|
||||
static void
|
||||
gsd_subscription_manager_class_init (GsdSubscriptionManagerClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
@@ -676,60 +806,61 @@ gsd_subscription_manager_class_init (GsdSubscriptionManagerClass *klass)
|
||||
}
|
||||
|
||||
static void
|
||||
_launch_info_overview (void)
|
||||
{
|
||||
const gchar *argv[] = { "gnome-control-center", "info-overview", NULL };
|
||||
g_debug ("Running gnome-control-center info-overview");
|
||||
g_spawn_async (NULL, (gchar **) argv, NULL, G_SPAWN_SEARCH_PATH,
|
||||
NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
_notify_closed_cb (NotifyNotification *notification, gpointer user_data)
|
||||
{
|
||||
/* FIXME: only launch when clicking on the main body, not the window close */
|
||||
if (notify_notification_get_closed_reason (notification) == 0x400)
|
||||
_launch_info_overview ();
|
||||
}
|
||||
|
||||
static void
|
||||
_notify_clicked_cb (NotifyNotification *notification, char *action, gpointer user_data)
|
||||
{
|
||||
_launch_info_overview ();
|
||||
}
|
||||
|
||||
static void
|
||||
gsd_subscription_manager_init (GsdSubscriptionManager *manager)
|
||||
{
|
||||
GsdSubscriptionManagerPrivate *priv = manager->priv = GSD_SUBSCRIPTION_MANAGER_GET_PRIVATE (manager);
|
||||
|
||||
+ priv->installed_products = g_ptr_array_new_with_free_func ((GDestroyNotify) product_data_free);
|
||||
priv->timer_last_notified = g_timer_new ();
|
||||
|
||||
/* expired */
|
||||
priv->notification_expired =
|
||||
notify_notification_new (_("Subscription Has Expired"),
|
||||
_("Add or renew a subscription to continue receiving software updates."),
|
||||
NULL);
|
||||
notify_notification_set_app_name (priv->notification_expired, _("Subscription"));
|
||||
notify_notification_set_hint_string (priv->notification_expired, "desktop-entry", "subman-panel");
|
||||
notify_notification_set_hint_string (priv->notification_expired, "x-gnome-privacy-scope", "system");
|
||||
notify_notification_set_urgency (priv->notification_expired, NOTIFY_URGENCY_CRITICAL);
|
||||
notify_notification_add_action (priv->notification_expired,
|
||||
"info-overview", _("Subscribe System…"),
|
||||
_notify_clicked_cb,
|
||||
manager, NULL);
|
||||
g_signal_connect (priv->notification_expired, "closed",
|
||||
G_CALLBACK (_notify_closed_cb), manager);
|
||||
|
||||
/* registered */
|
||||
priv->notification_registered =
|
||||
notify_notification_new (_("Registration Successful"),
|
||||
_("The system has been registered and software updates have been enabled."),
|
||||
NULL);
|
||||
notify_notification_set_app_name (priv->notification_registered, _("Subscription"));
|
||||
notify_notification_set_hint_string (priv->notification_registered, "desktop-entry", "subman-panel");
|
||||
notify_notification_set_hint_string (priv->notification_registered, "x-gnome-privacy-scope", "system");
|
||||
notify_notification_set_urgency (priv->notification_registered, NOTIFY_URGENCY_CRITICAL);
|
||||
g_signal_connect (priv->notification_registered, "closed",
|
||||
G_CALLBACK (_notify_closed_cb), manager);
|
||||
|
||||
@@ -740,60 +871,61 @@ gsd_subscription_manager_init (GsdSubscriptionManager *manager)
|
||||
NULL);
|
||||
notify_notification_set_app_name (priv->notification_registration_required, _("Subscription"));
|
||||
notify_notification_set_hint_string (priv->notification_registration_required, "desktop-entry", "subman-panel");
|
||||
notify_notification_set_hint_string (priv->notification_registration_required, "x-gnome-privacy-scope", "system");
|
||||
notify_notification_set_urgency (priv->notification_registration_required, NOTIFY_URGENCY_CRITICAL);
|
||||
notify_notification_add_action (priv->notification_registration_required,
|
||||
"info-overview", _("Register System…"),
|
||||
_notify_clicked_cb,
|
||||
manager, NULL);
|
||||
g_signal_connect (priv->notification_registration_required, "closed",
|
||||
G_CALLBACK (_notify_closed_cb), manager);
|
||||
}
|
||||
|
||||
static void
|
||||
gsd_subscription_manager_finalize (GObject *object)
|
||||
{
|
||||
GsdSubscriptionManager *manager;
|
||||
|
||||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (GSD_IS_SUBSCRIPTION_MANAGER (object));
|
||||
|
||||
manager = GSD_SUBSCRIPTION_MANAGER (object);
|
||||
|
||||
gsd_subscription_manager_stop (manager);
|
||||
|
||||
if (manager->priv->bus_cancellable != NULL) {
|
||||
g_cancellable_cancel (manager->priv->bus_cancellable);
|
||||
g_clear_object (&manager->priv->bus_cancellable);
|
||||
}
|
||||
|
||||
+ g_clear_pointer (&manager->priv->installed_products, g_ptr_array_unref);
|
||||
g_clear_pointer (&manager->priv->introspection_data, g_dbus_node_info_unref);
|
||||
g_clear_object (&manager->priv->connection);
|
||||
g_clear_object (&manager->priv->notification_expired);
|
||||
g_clear_object (&manager->priv->notification_registered);
|
||||
g_timer_destroy (manager->priv->timer_last_notified);
|
||||
|
||||
if (manager->priv->name_id != 0) {
|
||||
g_bus_unown_name (manager->priv->name_id);
|
||||
manager->priv->name_id = 0;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (gsd_subscription_manager_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_method_call (GDBusConnection *connection,
|
||||
const gchar *sender,
|
||||
const gchar *object_path,
|
||||
const gchar *interface_name,
|
||||
const gchar *method_name,
|
||||
GVariant *parameters,
|
||||
GDBusMethodInvocation *invocation,
|
||||
gpointer user_data)
|
||||
{
|
||||
GsdSubscriptionManager *manager = GSD_SUBSCRIPTION_MANAGER (user_data);
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
if (g_strcmp0 (method_name, "Register") == 0) {
|
||||
const gchar *organisation = NULL;
|
||||
const gchar *hostname = NULL;
|
||||
@@ -857,60 +989,63 @@ handle_method_call (GDBusConnection *connection,
|
||||
if (!_client_unregister (manager, &error)) {
|
||||
g_dbus_method_invocation_return_gerror (invocation, error);
|
||||
return;
|
||||
}
|
||||
g_dbus_method_invocation_return_value (invocation, NULL);
|
||||
} else {
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static GVariant *
|
||||
handle_get_property (GDBusConnection *connection,
|
||||
const gchar *sender,
|
||||
const gchar *object_path,
|
||||
const gchar *interface_name,
|
||||
const gchar *property_name,
|
||||
GError **error, gpointer user_data)
|
||||
{
|
||||
GsdSubscriptionManager *manager = GSD_SUBSCRIPTION_MANAGER (user_data);
|
||||
GsdSubscriptionManagerPrivate *priv = manager->priv;
|
||||
|
||||
if (g_strcmp0 (interface_name, GSD_SUBSCRIPTION_DBUS_INTERFACE) != 0) {
|
||||
g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
|
||||
"No such interface: %s", interface_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (g_strcmp0 (property_name, "SubscriptionStatus") == 0)
|
||||
return g_variant_new_uint32 (priv->subscription_status);
|
||||
|
||||
+ if (g_strcmp0 (property_name, "InstalledProducts") == 0)
|
||||
+ return _make_installed_products_variant (priv->installed_products);
|
||||
+
|
||||
g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
|
||||
"Failed to get property: %s", property_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
handle_set_property (GDBusConnection *connection,
|
||||
const gchar *sender,
|
||||
const gchar *object_path,
|
||||
const gchar *interface_name,
|
||||
const gchar *property_name,
|
||||
GVariant *value,
|
||||
GError **error, gpointer user_data)
|
||||
{
|
||||
if (g_strcmp0 (interface_name, GSD_SUBSCRIPTION_DBUS_INTERFACE) != 0) {
|
||||
g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
|
||||
"No such interface: %s", interface_name);
|
||||
return FALSE;
|
||||
}
|
||||
g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
|
||||
"No such property: %s", property_name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static const GDBusInterfaceVTable interface_vtable =
|
||||
{
|
||||
handle_method_call,
|
||||
handle_get_property,
|
||||
handle_set_property
|
||||
};
|
||||
--
|
||||
2.30.0
|
||||
|
313
SOURCES/0003-subman-Increase-RHSM-dbus-call-timeouts.patch
Normal file
313
SOURCES/0003-subman-Increase-RHSM-dbus-call-timeouts.patch
Normal file
@ -0,0 +1,313 @@
|
||||
From 0d88b2133b20957e00b0eeb0c0f48932485cc73d Mon Sep 17 00:00:00 2001
|
||||
From: Kalev Lember <klember@redhat.com>
|
||||
Date: Fri, 28 Jun 2019 18:10:36 +0200
|
||||
Subject: [PATCH 03/15] subman: Increase RHSM dbus call timeouts
|
||||
|
||||
Increase the dbus timeouts to 5 minutes as the register/unregister calls
|
||||
seem to routinely take more than a minute.
|
||||
---
|
||||
plugins/subman/gsd-subman-helper.c | 17 ++++++++++++-----
|
||||
1 file changed, 12 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/plugins/subman/gsd-subman-helper.c b/plugins/subman/gsd-subman-helper.c
|
||||
index 182f7190..af7a82e9 100644
|
||||
--- a/plugins/subman/gsd-subman-helper.c
|
||||
+++ b/plugins/subman/gsd-subman-helper.c
|
||||
@@ -1,60 +1,62 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
|
||||
*
|
||||
* Copyright (C) 2019 Richard Hughes <rhughes@redhat.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 <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <gio/gio.h>
|
||||
#include <json-glib/json-glib.h>
|
||||
|
||||
+#define DBUS_TIMEOUT 300000 /* 5 minutes */
|
||||
+
|
||||
static void
|
||||
_helper_convert_error (const gchar *json_txt, GError **error)
|
||||
{
|
||||
JsonNode *json_root;
|
||||
JsonObject *json_obj;
|
||||
const gchar *message;
|
||||
g_autoptr(JsonParser) json_parser = json_parser_new ();
|
||||
|
||||
/* this may be plain text or JSON :| */
|
||||
if (!json_parser_load_from_data (json_parser, json_txt, -1, NULL)) {
|
||||
g_set_error_literal (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_SUPPORTED,
|
||||
json_txt);
|
||||
return;
|
||||
}
|
||||
json_root = json_parser_get_root (json_parser);
|
||||
json_obj = json_node_get_object (json_root);
|
||||
if (!json_object_has_member (json_obj, "message")) {
|
||||
g_set_error (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_INVALID_DATA,
|
||||
"no message' in %s", json_txt);
|
||||
return;
|
||||
}
|
||||
message = json_object_get_string_member (json_obj, "message");
|
||||
if (g_strstr_len (message, -1, "Invalid user credentials") != NULL) {
|
||||
g_set_error_literal (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_PERMISSION_DENIED,
|
||||
@@ -67,125 +69,128 @@ _helper_convert_error (const gchar *json_txt, GError **error)
|
||||
message);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_helper_unregister (GError **error)
|
||||
{
|
||||
g_autoptr(GDBusProxy) proxy = NULL;
|
||||
g_autoptr(GVariantBuilder) proxy_options = NULL;
|
||||
g_autoptr(GVariant) res = NULL;
|
||||
|
||||
g_debug ("unregistering");
|
||||
proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
|
||||
NULL,
|
||||
"com.redhat.RHSM1",
|
||||
"/com/redhat/RHSM1/Unregister",
|
||||
"com.redhat.RHSM1.Unregister",
|
||||
NULL, error);
|
||||
if (proxy == NULL) {
|
||||
g_prefix_error (error, "Failed to get proxy: ");
|
||||
return FALSE;
|
||||
}
|
||||
proxy_options = g_variant_builder_new (G_VARIANT_TYPE_VARDICT);
|
||||
res = g_dbus_proxy_call_sync (proxy,
|
||||
"Unregister",
|
||||
g_variant_new ("(a{sv}s)",
|
||||
proxy_options,
|
||||
""), /* lang */
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
- -1, NULL, error);
|
||||
+ DBUS_TIMEOUT,
|
||||
+ NULL, error);
|
||||
return res != NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_helper_auto_attach (GError **error)
|
||||
{
|
||||
const gchar *str = NULL;
|
||||
g_autoptr(GDBusProxy) proxy = NULL;
|
||||
g_autoptr(GVariantBuilder) proxy_options = NULL;
|
||||
g_autoptr(GVariant) res = NULL;
|
||||
|
||||
g_debug ("auto-attaching subscriptions");
|
||||
proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
|
||||
NULL,
|
||||
"com.redhat.RHSM1",
|
||||
"/com/redhat/RHSM1/Attach",
|
||||
"com.redhat.RHSM1.Attach",
|
||||
NULL, error);
|
||||
if (proxy == NULL) {
|
||||
g_prefix_error (error, "Failed to get proxy: ");
|
||||
return FALSE;
|
||||
}
|
||||
proxy_options = g_variant_builder_new (G_VARIANT_TYPE_VARDICT);
|
||||
res = g_dbus_proxy_call_sync (proxy,
|
||||
"AutoAttach",
|
||||
g_variant_new ("(sa{sv}s)",
|
||||
"", /* now? */
|
||||
proxy_options,
|
||||
""), /* lang */
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
- -1, NULL, error);
|
||||
+ DBUS_TIMEOUT,
|
||||
+ NULL, error);
|
||||
if (res == NULL)
|
||||
return FALSE;
|
||||
g_variant_get (res, "(&s)", &str);
|
||||
g_debug ("Attach.AutoAttach: %s", str);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_helper_save_config (const gchar *key, const gchar *value, GError **error)
|
||||
{
|
||||
g_autoptr(GDBusProxy) proxy = NULL;
|
||||
g_autoptr(GVariant) res = NULL;
|
||||
proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
|
||||
NULL,
|
||||
"com.redhat.RHSM1",
|
||||
"/com/redhat/RHSM1/Config",
|
||||
"com.redhat.RHSM1.Config",
|
||||
NULL, error);
|
||||
if (proxy == NULL) {
|
||||
g_prefix_error (error, "Failed to get proxy: ");
|
||||
return FALSE;
|
||||
}
|
||||
res = g_dbus_proxy_call_sync (proxy, "Set",
|
||||
g_variant_new ("(svs)",
|
||||
key,
|
||||
g_variant_new_string (value),
|
||||
""), /* lang */
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
- -1, NULL, error);
|
||||
+ DBUS_TIMEOUT,
|
||||
+ NULL, error);
|
||||
return res != NULL;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
const gchar *userlang = ""; /* as root, so no translations */
|
||||
g_autofree gchar *activation_key = NULL;
|
||||
g_autofree gchar *address = NULL;
|
||||
g_autofree gchar *hostname = NULL;
|
||||
g_autofree gchar *kind = NULL;
|
||||
g_autofree gchar *organisation = NULL;
|
||||
g_autofree gchar *password = NULL;
|
||||
g_autofree gchar *port = NULL;
|
||||
g_autofree gchar *prefix = NULL;
|
||||
g_autofree gchar *proxy_server = NULL;
|
||||
g_autofree gchar *username = NULL;
|
||||
g_autoptr(GDBusConnection) conn_private = NULL;
|
||||
g_autoptr(GDBusProxy) proxy = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(GOptionContext) context = g_option_context_new (NULL);
|
||||
g_autoptr(GVariantBuilder) proxy_options = NULL;
|
||||
g_autoptr(GVariantBuilder) subman_conopts = NULL;
|
||||
g_autoptr(GVariantBuilder) subman_options = NULL;
|
||||
|
||||
const GOptionEntry options[] = {
|
||||
{ "kind", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING,
|
||||
&kind, "Kind, e.g. 'username' or 'key'", NULL },
|
||||
{ "address", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING,
|
||||
&address, "UNIX address", NULL },
|
||||
@@ -278,95 +283,97 @@ main (int argc, char *argv[])
|
||||
g_variant_builder_add (subman_conopts, "{ss}", "host", hostname);
|
||||
g_variant_builder_add (subman_conopts, "{ss}", "handler", prefix);
|
||||
g_variant_builder_add (subman_conopts, "{ss}", "port", port);
|
||||
|
||||
/* call into RHSM */
|
||||
if (g_strcmp0 (kind, "register-with-key") == 0) {
|
||||
g_auto(GStrv) activation_keys = NULL;
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
g_autoptr(GVariant) res = NULL;
|
||||
|
||||
if (activation_key == NULL) {
|
||||
g_printerr ("Required --activation-key\n");
|
||||
return G_IO_ERROR_INVALID_DATA;
|
||||
}
|
||||
if (organisation == NULL) {
|
||||
g_printerr ("Required --organisation\n");
|
||||
return G_IO_ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
g_debug ("registering using activation key");
|
||||
activation_keys = g_strsplit (activation_key, ",", -1);
|
||||
res = g_dbus_proxy_call_sync (proxy,
|
||||
"RegisterWithActivationKeys",
|
||||
g_variant_new ("(s^asa{ss}a{ss}s)",
|
||||
organisation,
|
||||
activation_keys,
|
||||
subman_options,
|
||||
subman_conopts,
|
||||
userlang),
|
||||
G_DBUS_CALL_FLAGS_NO_AUTO_START,
|
||||
- -1, NULL, &error_local);
|
||||
+ DBUS_TIMEOUT,
|
||||
+ NULL, &error_local);
|
||||
if (res == NULL) {
|
||||
g_dbus_error_strip_remote_error (error_local);
|
||||
_helper_convert_error (error_local->message, &error);
|
||||
g_printerr ("Failed to RegisterWithActivationKeys: %s\n", error->message);
|
||||
return error->code;
|
||||
}
|
||||
} else if (g_strcmp0 (kind, "register-with-username") == 0) {
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
g_autoptr(GVariant) res = NULL;
|
||||
|
||||
g_debug ("registering using username and password");
|
||||
if (username == NULL) {
|
||||
g_printerr ("Required --username\n");
|
||||
return G_IO_ERROR_INVALID_DATA;
|
||||
}
|
||||
if (password == NULL) {
|
||||
g_printerr ("Required --password\n");
|
||||
return G_IO_ERROR_INVALID_DATA;
|
||||
}
|
||||
if (organisation == NULL) {
|
||||
g_printerr ("Required --organisation\n");
|
||||
return G_IO_ERROR_INVALID_DATA;
|
||||
}
|
||||
res = g_dbus_proxy_call_sync (proxy,
|
||||
"Register",
|
||||
g_variant_new ("(sssa{ss}a{ss}s)",
|
||||
organisation,
|
||||
username,
|
||||
password,
|
||||
subman_options,
|
||||
subman_conopts,
|
||||
userlang),
|
||||
G_DBUS_CALL_FLAGS_NO_AUTO_START,
|
||||
- -1, NULL, &error_local);
|
||||
+ DBUS_TIMEOUT,
|
||||
+ NULL, &error_local);
|
||||
if (res == NULL) {
|
||||
g_dbus_error_strip_remote_error (error_local);
|
||||
_helper_convert_error (error_local->message, &error);
|
||||
g_printerr ("Failed to Register: %s\n", error->message);
|
||||
return error->code;
|
||||
}
|
||||
} else {
|
||||
g_printerr ("Invalid --kind specified: %s\n", kind);
|
||||
return G_IO_ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
/* set the new hostname */
|
||||
if (!_helper_save_config ("server.hostname", hostname, &error)) {
|
||||
g_printerr ("Failed to save hostname: %s\n", error->message);
|
||||
return G_IO_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
if (!_helper_save_config ("server.prefix", prefix, &error)) {
|
||||
g_printerr ("Failed to save prefix: %s\n", error->message);
|
||||
return G_IO_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
if (!_helper_save_config ("server.port", port, &error)) {
|
||||
g_printerr ("Failed to save port: %s\n", error->message);
|
||||
return G_IO_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
/* wait for rhsmd to notice the new config */
|
||||
g_usleep (G_USEC_PER_SEC * 5);
|
||||
|
||||
/* auto-attach */
|
||||
if (!_helper_auto_attach (&error)) {
|
||||
--
|
||||
2.30.0
|
||||
|
454
SOURCES/0004-subman-Drop-userlang-field.patch
Normal file
454
SOURCES/0004-subman-Drop-userlang-field.patch
Normal file
@ -0,0 +1,454 @@
|
||||
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
|
||||
|
@ -0,0 +1,373 @@
|
||||
From db73e2211ecc746434d78d23d801c92581fa8824 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Sun, 24 Jan 2021 15:04:17 -0500
|
||||
Subject: [PATCH 05/15] subman: Use user locale for registration/subscription
|
||||
operations
|
||||
|
||||
This makes sure that error messages are in the correct locale.
|
||||
---
|
||||
plugins/subman/gsd-subman-helper.c | 17 +++++++++++------
|
||||
1 file changed, 11 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/plugins/subman/gsd-subman-helper.c b/plugins/subman/gsd-subman-helper.c
|
||||
index af7a82e9..f84e91bf 100644
|
||||
--- a/plugins/subman/gsd-subman-helper.c
|
||||
+++ b/plugins/subman/gsd-subman-helper.c
|
||||
@@ -1,61 +1,63 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
|
||||
*
|
||||
* Copyright (C) 2019 Richard Hughes <rhughes@redhat.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 <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
+#include <locale.h>
|
||||
|
||||
#include <gio/gio.h>
|
||||
#include <json-glib/json-glib.h>
|
||||
|
||||
#define DBUS_TIMEOUT 300000 /* 5 minutes */
|
||||
+static const char *locale;
|
||||
|
||||
static void
|
||||
_helper_convert_error (const gchar *json_txt, GError **error)
|
||||
{
|
||||
JsonNode *json_root;
|
||||
JsonObject *json_obj;
|
||||
const gchar *message;
|
||||
g_autoptr(JsonParser) json_parser = json_parser_new ();
|
||||
|
||||
/* this may be plain text or JSON :| */
|
||||
if (!json_parser_load_from_data (json_parser, json_txt, -1, NULL)) {
|
||||
g_set_error_literal (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_SUPPORTED,
|
||||
json_txt);
|
||||
return;
|
||||
}
|
||||
json_root = json_parser_get_root (json_parser);
|
||||
json_obj = json_node_get_object (json_root);
|
||||
if (!json_object_has_member (json_obj, "message")) {
|
||||
g_set_error (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_INVALID_DATA,
|
||||
"no message' in %s", json_txt);
|
||||
return;
|
||||
}
|
||||
message = json_object_get_string_member (json_obj, "message");
|
||||
if (g_strstr_len (message, -1, "Invalid user credentials") != NULL) {
|
||||
g_set_error_literal (error,
|
||||
G_IO_ERROR,
|
||||
@@ -67,184 +69,187 @@ _helper_convert_error (const gchar *json_txt, GError **error)
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_SUPPORTED,
|
||||
message);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_helper_unregister (GError **error)
|
||||
{
|
||||
g_autoptr(GDBusProxy) proxy = NULL;
|
||||
g_autoptr(GVariantBuilder) proxy_options = NULL;
|
||||
g_autoptr(GVariant) res = NULL;
|
||||
|
||||
g_debug ("unregistering");
|
||||
proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
|
||||
NULL,
|
||||
"com.redhat.RHSM1",
|
||||
"/com/redhat/RHSM1/Unregister",
|
||||
"com.redhat.RHSM1.Unregister",
|
||||
NULL, error);
|
||||
if (proxy == NULL) {
|
||||
g_prefix_error (error, "Failed to get proxy: ");
|
||||
return FALSE;
|
||||
}
|
||||
proxy_options = g_variant_builder_new (G_VARIANT_TYPE_VARDICT);
|
||||
res = g_dbus_proxy_call_sync (proxy,
|
||||
"Unregister",
|
||||
g_variant_new ("(a{sv}s)",
|
||||
proxy_options,
|
||||
- ""), /* lang */
|
||||
+ locale),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
DBUS_TIMEOUT,
|
||||
NULL, error);
|
||||
return res != NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_helper_auto_attach (GError **error)
|
||||
{
|
||||
const gchar *str = NULL;
|
||||
g_autoptr(GDBusProxy) proxy = NULL;
|
||||
g_autoptr(GVariantBuilder) proxy_options = NULL;
|
||||
g_autoptr(GVariant) res = NULL;
|
||||
|
||||
g_debug ("auto-attaching subscriptions");
|
||||
proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
|
||||
NULL,
|
||||
"com.redhat.RHSM1",
|
||||
"/com/redhat/RHSM1/Attach",
|
||||
"com.redhat.RHSM1.Attach",
|
||||
NULL, error);
|
||||
if (proxy == NULL) {
|
||||
g_prefix_error (error, "Failed to get proxy: ");
|
||||
return FALSE;
|
||||
}
|
||||
proxy_options = g_variant_builder_new (G_VARIANT_TYPE_VARDICT);
|
||||
res = g_dbus_proxy_call_sync (proxy,
|
||||
"AutoAttach",
|
||||
g_variant_new ("(sa{sv}s)",
|
||||
"", /* now? */
|
||||
proxy_options,
|
||||
- ""), /* lang */
|
||||
+ locale),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
DBUS_TIMEOUT,
|
||||
NULL, error);
|
||||
if (res == NULL)
|
||||
return FALSE;
|
||||
g_variant_get (res, "(&s)", &str);
|
||||
g_debug ("Attach.AutoAttach: %s", str);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_helper_save_config (const gchar *key, const gchar *value, GError **error)
|
||||
{
|
||||
g_autoptr(GDBusProxy) proxy = NULL;
|
||||
g_autoptr(GVariant) res = NULL;
|
||||
proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
|
||||
NULL,
|
||||
"com.redhat.RHSM1",
|
||||
"/com/redhat/RHSM1/Config",
|
||||
"com.redhat.RHSM1.Config",
|
||||
NULL, error);
|
||||
if (proxy == NULL) {
|
||||
g_prefix_error (error, "Failed to get proxy: ");
|
||||
return FALSE;
|
||||
}
|
||||
res = g_dbus_proxy_call_sync (proxy, "Set",
|
||||
g_variant_new ("(svs)",
|
||||
key,
|
||||
g_variant_new_string (value),
|
||||
- ""), /* lang */
|
||||
+ locale),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
DBUS_TIMEOUT,
|
||||
NULL, error);
|
||||
return res != NULL;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
- const gchar *userlang = ""; /* as root, so no translations */
|
||||
g_autofree gchar *activation_key = NULL;
|
||||
g_autofree gchar *address = NULL;
|
||||
g_autofree gchar *hostname = NULL;
|
||||
g_autofree gchar *kind = NULL;
|
||||
g_autofree gchar *organisation = NULL;
|
||||
g_autofree gchar *password = NULL;
|
||||
g_autofree gchar *port = NULL;
|
||||
g_autofree gchar *prefix = NULL;
|
||||
g_autofree gchar *proxy_server = NULL;
|
||||
g_autofree gchar *username = NULL;
|
||||
g_autoptr(GDBusConnection) conn_private = NULL;
|
||||
g_autoptr(GDBusProxy) proxy = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(GOptionContext) context = g_option_context_new (NULL);
|
||||
g_autoptr(GVariantBuilder) proxy_options = NULL;
|
||||
g_autoptr(GVariantBuilder) subman_conopts = NULL;
|
||||
g_autoptr(GVariantBuilder) subman_options = NULL;
|
||||
|
||||
const GOptionEntry options[] = {
|
||||
{ "kind", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING,
|
||||
&kind, "Kind, e.g. 'username' or 'key'", NULL },
|
||||
{ "address", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING,
|
||||
&address, "UNIX address", NULL },
|
||||
{ "username", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING,
|
||||
&username, "Username", NULL },
|
||||
{ "password", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING,
|
||||
&password, "Password", NULL },
|
||||
{ "organisation", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING,
|
||||
&organisation, "Organisation", NULL },
|
||||
{ "activation-key", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING,
|
||||
&activation_key, "Activation keys", NULL },
|
||||
{ "hostname", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING,
|
||||
&hostname, "Registration server hostname", NULL },
|
||||
{ "prefix", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING,
|
||||
&prefix, "Registration server prefix", NULL },
|
||||
{ "port", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING,
|
||||
&port, "Registration server port", NULL },
|
||||
{ "proxy", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING,
|
||||
&proxy_server, "Proxy settings", NULL },
|
||||
{ NULL}
|
||||
};
|
||||
|
||||
/* check calling UID */
|
||||
if (getuid () != 0 || geteuid () != 0) {
|
||||
g_printerr ("This program can only be used by the root user\n");
|
||||
return G_IO_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
+
|
||||
+ setlocale (LC_ALL, "");
|
||||
+ locale = setlocale (LC_MESSAGES, NULL);
|
||||
+
|
||||
g_option_context_add_main_entries (context, options, NULL);
|
||||
if (!g_option_context_parse (context, &argc, &argv, &error)) {
|
||||
g_printerr ("Failed to parse arguments: %s\n", error->message);
|
||||
return G_IO_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/* uncommon actions */
|
||||
if (kind == NULL) {
|
||||
g_printerr ("No --kind specified\n");
|
||||
return G_IO_ERROR_INVALID_DATA;
|
||||
}
|
||||
if (g_strcmp0 (kind, "unregister") == 0) {
|
||||
if (!_helper_unregister (&error)) {
|
||||
g_printerr ("Failed to Unregister: %s\n", error->message);
|
||||
return G_IO_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
if (g_strcmp0 (kind, "auto-attach") == 0) {
|
||||
if (!_helper_auto_attach (&error)) {
|
||||
g_printerr ("Failed to AutoAttach: %s\n", error->message);
|
||||
return G_IO_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
/* connect to abstract socket for reasons */
|
||||
if (address == NULL) {
|
||||
g_printerr ("No --address specified\n");
|
||||
return G_IO_ERROR_INVALID_DATA;
|
||||
@@ -281,96 +286,96 @@ main (int argc, char *argv[])
|
||||
port = g_strdup ("443");
|
||||
subman_conopts = g_variant_builder_new (G_VARIANT_TYPE("a{ss}"));
|
||||
g_variant_builder_add (subman_conopts, "{ss}", "host", hostname);
|
||||
g_variant_builder_add (subman_conopts, "{ss}", "handler", prefix);
|
||||
g_variant_builder_add (subman_conopts, "{ss}", "port", port);
|
||||
|
||||
/* call into RHSM */
|
||||
if (g_strcmp0 (kind, "register-with-key") == 0) {
|
||||
g_auto(GStrv) activation_keys = NULL;
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
g_autoptr(GVariant) res = NULL;
|
||||
|
||||
if (activation_key == NULL) {
|
||||
g_printerr ("Required --activation-key\n");
|
||||
return G_IO_ERROR_INVALID_DATA;
|
||||
}
|
||||
if (organisation == NULL) {
|
||||
g_printerr ("Required --organisation\n");
|
||||
return G_IO_ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
g_debug ("registering using activation key");
|
||||
activation_keys = g_strsplit (activation_key, ",", -1);
|
||||
res = g_dbus_proxy_call_sync (proxy,
|
||||
"RegisterWithActivationKeys",
|
||||
g_variant_new ("(s^asa{ss}a{ss}s)",
|
||||
organisation,
|
||||
activation_keys,
|
||||
subman_options,
|
||||
subman_conopts,
|
||||
- userlang),
|
||||
+ locale),
|
||||
G_DBUS_CALL_FLAGS_NO_AUTO_START,
|
||||
DBUS_TIMEOUT,
|
||||
NULL, &error_local);
|
||||
if (res == NULL) {
|
||||
g_dbus_error_strip_remote_error (error_local);
|
||||
_helper_convert_error (error_local->message, &error);
|
||||
g_printerr ("Failed to RegisterWithActivationKeys: %s\n", error->message);
|
||||
return error->code;
|
||||
}
|
||||
} else if (g_strcmp0 (kind, "register-with-username") == 0) {
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
g_autoptr(GVariant) res = NULL;
|
||||
|
||||
g_debug ("registering using username and password");
|
||||
if (username == NULL) {
|
||||
g_printerr ("Required --username\n");
|
||||
return G_IO_ERROR_INVALID_DATA;
|
||||
}
|
||||
if (password == NULL) {
|
||||
g_printerr ("Required --password\n");
|
||||
return G_IO_ERROR_INVALID_DATA;
|
||||
}
|
||||
if (organisation == NULL) {
|
||||
g_printerr ("Required --organisation\n");
|
||||
return G_IO_ERROR_INVALID_DATA;
|
||||
}
|
||||
res = g_dbus_proxy_call_sync (proxy,
|
||||
"Register",
|
||||
g_variant_new ("(sssa{ss}a{ss}s)",
|
||||
organisation,
|
||||
username,
|
||||
password,
|
||||
subman_options,
|
||||
subman_conopts,
|
||||
- userlang),
|
||||
+ locale),
|
||||
G_DBUS_CALL_FLAGS_NO_AUTO_START,
|
||||
DBUS_TIMEOUT,
|
||||
NULL, &error_local);
|
||||
if (res == NULL) {
|
||||
g_dbus_error_strip_remote_error (error_local);
|
||||
_helper_convert_error (error_local->message, &error);
|
||||
g_printerr ("Failed to Register: %s\n", error->message);
|
||||
return error->code;
|
||||
}
|
||||
} else {
|
||||
g_printerr ("Invalid --kind specified: %s\n", kind);
|
||||
return G_IO_ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
/* set the new hostname */
|
||||
if (!_helper_save_config ("server.hostname", hostname, &error)) {
|
||||
g_printerr ("Failed to save hostname: %s\n", error->message);
|
||||
return G_IO_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
if (!_helper_save_config ("server.prefix", prefix, &error)) {
|
||||
g_printerr ("Failed to save prefix: %s\n", error->message);
|
||||
return G_IO_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
if (!_helper_save_config ("server.port", port, &error)) {
|
||||
g_printerr ("Failed to save port: %s\n", error->message);
|
||||
return G_IO_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
/* wait for rhsmd to notice the new config */
|
||||
g_usleep (G_USEC_PER_SEC * 5);
|
||||
--
|
||||
2.30.0
|
||||
|
@ -0,0 +1,236 @@
|
||||
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
|
||||
|
@ -0,0 +1,260 @@
|
||||
From 477dc8accccab568002bd19caa3fbf898bc05aad Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Tue, 25 Aug 2020 10:34:03 -0400
|
||||
Subject: [PATCH 07/15] subman: Force re-subscribe if the admin already
|
||||
subscribed
|
||||
|
||||
It's possible for an admin to to half-enroll the system with RHN,
|
||||
using the CLI tools.
|
||||
|
||||
Meaning, it's possible for them to register the system with the
|
||||
service, but not attach to a purchased license for the machine,
|
||||
the, so called, entitlements.
|
||||
|
||||
The subman module always does both halves of the registration process
|
||||
in lock step. This means, if an admin tries to register using GNOME
|
||||
while in a half-registered state, subman will fail because the first
|
||||
step, the registration step, is already finished.
|
||||
|
||||
This commit addresses that problem by trying to unregister up front
|
||||
before registering.
|
||||
---
|
||||
plugins/subman/gsd-subman-helper.c | 11 +++++++++--
|
||||
1 file changed, 9 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/plugins/subman/gsd-subman-helper.c b/plugins/subman/gsd-subman-helper.c
|
||||
index f84e91bf..3931ef2e 100644
|
||||
--- a/plugins/subman/gsd-subman-helper.c
|
||||
+++ b/plugins/subman/gsd-subman-helper.c
|
||||
@@ -51,61 +51,60 @@ _helper_convert_error (const gchar *json_txt, GError **error)
|
||||
json_root = json_parser_get_root (json_parser);
|
||||
json_obj = json_node_get_object (json_root);
|
||||
if (!json_object_has_member (json_obj, "message")) {
|
||||
g_set_error (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_INVALID_DATA,
|
||||
"no message' in %s", json_txt);
|
||||
return;
|
||||
}
|
||||
message = json_object_get_string_member (json_obj, "message");
|
||||
if (g_strstr_len (message, -1, "Invalid user credentials") != NULL) {
|
||||
g_set_error_literal (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_PERMISSION_DENIED,
|
||||
message);
|
||||
return;
|
||||
}
|
||||
g_set_error_literal (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_SUPPORTED,
|
||||
message);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_helper_unregister (GError **error)
|
||||
{
|
||||
g_autoptr(GDBusProxy) proxy = NULL;
|
||||
g_autoptr(GVariantBuilder) proxy_options = NULL;
|
||||
g_autoptr(GVariant) res = NULL;
|
||||
|
||||
- g_debug ("unregistering");
|
||||
proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
|
||||
NULL,
|
||||
"com.redhat.RHSM1",
|
||||
"/com/redhat/RHSM1/Unregister",
|
||||
"com.redhat.RHSM1.Unregister",
|
||||
NULL, error);
|
||||
if (proxy == NULL) {
|
||||
g_prefix_error (error, "Failed to get proxy: ");
|
||||
return FALSE;
|
||||
}
|
||||
proxy_options = g_variant_builder_new (G_VARIANT_TYPE_VARDICT);
|
||||
res = g_dbus_proxy_call_sync (proxy,
|
||||
"Unregister",
|
||||
g_variant_new ("(a{sv}s)",
|
||||
proxy_options,
|
||||
locale),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
DBUS_TIMEOUT,
|
||||
NULL, error);
|
||||
return res != NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_helper_auto_attach (GError **error)
|
||||
{
|
||||
const gchar *str = NULL;
|
||||
g_autoptr(GDBusProxy) proxy = NULL;
|
||||
g_autoptr(GVariantBuilder) proxy_options = NULL;
|
||||
@@ -208,60 +207,61 @@ main (int argc, char *argv[])
|
||||
{ "prefix", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING,
|
||||
&prefix, "Registration server prefix", NULL },
|
||||
{ "port", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING,
|
||||
&port, "Registration server port", NULL },
|
||||
{ "proxy", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING,
|
||||
&proxy_server, "Proxy settings", NULL },
|
||||
{ NULL}
|
||||
};
|
||||
|
||||
/* check calling UID */
|
||||
if (getuid () != 0 || geteuid () != 0) {
|
||||
g_printerr ("This program can only be used by the root user\n");
|
||||
return G_IO_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
setlocale (LC_ALL, "");
|
||||
locale = setlocale (LC_MESSAGES, NULL);
|
||||
|
||||
g_option_context_add_main_entries (context, options, NULL);
|
||||
if (!g_option_context_parse (context, &argc, &argv, &error)) {
|
||||
g_printerr ("Failed to parse arguments: %s\n", error->message);
|
||||
return G_IO_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/* uncommon actions */
|
||||
if (kind == NULL) {
|
||||
g_printerr ("No --kind specified\n");
|
||||
return G_IO_ERROR_INVALID_DATA;
|
||||
}
|
||||
if (g_strcmp0 (kind, "unregister") == 0) {
|
||||
+ g_debug ("unregistering");
|
||||
if (!_helper_unregister (&error)) {
|
||||
g_printerr ("Failed to Unregister: %s\n", error->message);
|
||||
return G_IO_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
if (g_strcmp0 (kind, "auto-attach") == 0) {
|
||||
if (!_helper_auto_attach (&error)) {
|
||||
g_printerr ("Failed to AutoAttach: %s\n", error->message);
|
||||
return G_IO_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
/* connect to abstract socket for reasons */
|
||||
if (address == NULL) {
|
||||
g_printerr ("No --address specified\n");
|
||||
return G_IO_ERROR_INVALID_DATA;
|
||||
}
|
||||
conn_private = g_dbus_connection_new_for_address_sync (address,
|
||||
G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
|
||||
NULL, NULL,
|
||||
&error);
|
||||
if (conn_private == NULL) {
|
||||
g_printerr ("Invalid --address specified: %s\n", error->message);
|
||||
return G_IO_ERROR_INVALID_DATA;
|
||||
}
|
||||
proxy = g_dbus_proxy_new_sync (conn_private,
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
|
||||
NULL, /* GDBusInterfaceInfo */
|
||||
@@ -277,96 +277,103 @@ main (int argc, char *argv[])
|
||||
/* no options */
|
||||
subman_options = g_variant_builder_new (G_VARIANT_TYPE("a{ss}"));
|
||||
|
||||
/* set registration server */
|
||||
if (hostname == NULL || hostname[0] == '\0')
|
||||
hostname = g_strdup ("subscription.rhsm.redhat.com");
|
||||
if (prefix == NULL || prefix[0] == '\0')
|
||||
prefix = g_strdup ("/subscription");
|
||||
if (port == NULL || port[0] == '\0')
|
||||
port = g_strdup ("443");
|
||||
subman_conopts = g_variant_builder_new (G_VARIANT_TYPE("a{ss}"));
|
||||
g_variant_builder_add (subman_conopts, "{ss}", "host", hostname);
|
||||
g_variant_builder_add (subman_conopts, "{ss}", "handler", prefix);
|
||||
g_variant_builder_add (subman_conopts, "{ss}", "port", port);
|
||||
|
||||
/* call into RHSM */
|
||||
if (g_strcmp0 (kind, "register-with-key") == 0) {
|
||||
g_auto(GStrv) activation_keys = NULL;
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
g_autoptr(GVariant) res = NULL;
|
||||
|
||||
if (activation_key == NULL) {
|
||||
g_printerr ("Required --activation-key\n");
|
||||
return G_IO_ERROR_INVALID_DATA;
|
||||
}
|
||||
if (organisation == NULL) {
|
||||
g_printerr ("Required --organisation\n");
|
||||
return G_IO_ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
+ g_debug ("trying to unregister in case machine is already registered");
|
||||
+ _helper_unregister (NULL);
|
||||
+
|
||||
g_debug ("registering using activation key");
|
||||
activation_keys = g_strsplit (activation_key, ",", -1);
|
||||
res = g_dbus_proxy_call_sync (proxy,
|
||||
"RegisterWithActivationKeys",
|
||||
g_variant_new ("(s^asa{ss}a{ss}s)",
|
||||
organisation,
|
||||
activation_keys,
|
||||
subman_options,
|
||||
subman_conopts,
|
||||
locale),
|
||||
G_DBUS_CALL_FLAGS_NO_AUTO_START,
|
||||
DBUS_TIMEOUT,
|
||||
NULL, &error_local);
|
||||
if (res == NULL) {
|
||||
g_dbus_error_strip_remote_error (error_local);
|
||||
_helper_convert_error (error_local->message, &error);
|
||||
g_printerr ("Failed to RegisterWithActivationKeys: %s\n", error->message);
|
||||
return error->code;
|
||||
}
|
||||
} else if (g_strcmp0 (kind, "register-with-username") == 0) {
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
g_autoptr(GVariant) res = NULL;
|
||||
|
||||
- g_debug ("registering using username and password");
|
||||
if (username == NULL) {
|
||||
g_printerr ("Required --username\n");
|
||||
return G_IO_ERROR_INVALID_DATA;
|
||||
}
|
||||
if (password == NULL) {
|
||||
g_printerr ("Required --password\n");
|
||||
return G_IO_ERROR_INVALID_DATA;
|
||||
}
|
||||
if (organisation == NULL) {
|
||||
g_printerr ("Required --organisation\n");
|
||||
return G_IO_ERROR_INVALID_DATA;
|
||||
}
|
||||
+
|
||||
+ g_debug ("trying to unregister in case machine is already registered");
|
||||
+ _helper_unregister (NULL);
|
||||
+
|
||||
+ g_debug ("registering using username and password");
|
||||
res = g_dbus_proxy_call_sync (proxy,
|
||||
"Register",
|
||||
g_variant_new ("(sssa{ss}a{ss}s)",
|
||||
organisation,
|
||||
username,
|
||||
password,
|
||||
subman_options,
|
||||
subman_conopts,
|
||||
locale),
|
||||
G_DBUS_CALL_FLAGS_NO_AUTO_START,
|
||||
DBUS_TIMEOUT,
|
||||
NULL, &error_local);
|
||||
if (res == NULL) {
|
||||
g_dbus_error_strip_remote_error (error_local);
|
||||
_helper_convert_error (error_local->message, &error);
|
||||
g_printerr ("Failed to Register: %s\n", error->message);
|
||||
return error->code;
|
||||
}
|
||||
} else {
|
||||
g_printerr ("Invalid --kind specified: %s\n", kind);
|
||||
return G_IO_ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
/* set the new hostname */
|
||||
if (!_helper_save_config ("server.hostname", hostname, &error)) {
|
||||
g_printerr ("Failed to save hostname: %s\n", error->message);
|
||||
return G_IO_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
if (!_helper_save_config ("server.prefix", prefix, &error)) {
|
||||
g_printerr ("Failed to save prefix: %s\n", error->message);
|
||||
--
|
||||
2.30.0
|
||||
|
@ -0,0 +1,576 @@
|
||||
From b73800da7f384eea66b6eb67f5f40129f3dfc372 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Tue, 25 Aug 2020 16:20:42 -0400
|
||||
Subject: [PATCH 08/15] subman: Don't send secrets through command line
|
||||
|
||||
The command line is introspectable with "ps", and it even gets logged
|
||||
to syslog, so it's not suitable for passing secrets.
|
||||
|
||||
Unfortunately, the user's password is currently passed.
|
||||
|
||||
This commit addresses that problem by passing the password through
|
||||
stdin, instead.
|
||||
---
|
||||
plugins/subman/gsd-subman-helper.c | 32 ++++++++------
|
||||
plugins/subman/gsd-subscription-manager.c | 52 ++++++++++++++++++++---
|
||||
plugins/subman/meson.build | 2 +-
|
||||
3 files changed, 66 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/plugins/subman/gsd-subman-helper.c b/plugins/subman/gsd-subman-helper.c
|
||||
index 3931ef2e..edf1e41f 100644
|
||||
--- a/plugins/subman/gsd-subman-helper.c
|
||||
+++ b/plugins/subman/gsd-subman-helper.c
|
||||
@@ -1,59 +1,61 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
|
||||
*
|
||||
* Copyright (C) 2019 Richard Hughes <rhughes@redhat.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 <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <locale.h>
|
||||
|
||||
#include <gio/gio.h>
|
||||
+#include <gio/gunixinputstream.h>
|
||||
#include <json-glib/json-glib.h>
|
||||
|
||||
#define DBUS_TIMEOUT 300000 /* 5 minutes */
|
||||
static const char *locale;
|
||||
|
||||
static void
|
||||
_helper_convert_error (const gchar *json_txt, GError **error)
|
||||
{
|
||||
JsonNode *json_root;
|
||||
JsonObject *json_obj;
|
||||
const gchar *message;
|
||||
g_autoptr(JsonParser) json_parser = json_parser_new ();
|
||||
|
||||
/* this may be plain text or JSON :| */
|
||||
if (!json_parser_load_from_data (json_parser, json_txt, -1, NULL)) {
|
||||
g_set_error_literal (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_SUPPORTED,
|
||||
json_txt);
|
||||
return;
|
||||
}
|
||||
json_root = json_parser_get_root (json_parser);
|
||||
json_obj = json_node_get_object (json_root);
|
||||
if (!json_object_has_member (json_obj, "message")) {
|
||||
g_set_error (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_INVALID_DATA,
|
||||
"no message' in %s", json_txt);
|
||||
return;
|
||||
}
|
||||
@@ -149,86 +151,82 @@ _helper_save_config (const gchar *key, const gchar *value, GError **error)
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
|
||||
NULL,
|
||||
"com.redhat.RHSM1",
|
||||
"/com/redhat/RHSM1/Config",
|
||||
"com.redhat.RHSM1.Config",
|
||||
NULL, error);
|
||||
if (proxy == NULL) {
|
||||
g_prefix_error (error, "Failed to get proxy: ");
|
||||
return FALSE;
|
||||
}
|
||||
res = g_dbus_proxy_call_sync (proxy, "Set",
|
||||
g_variant_new ("(svs)",
|
||||
key,
|
||||
g_variant_new_string (value),
|
||||
locale),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
DBUS_TIMEOUT,
|
||||
NULL, error);
|
||||
return res != NULL;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
g_autofree gchar *activation_key = NULL;
|
||||
g_autofree gchar *address = NULL;
|
||||
g_autofree gchar *hostname = NULL;
|
||||
g_autofree gchar *kind = NULL;
|
||||
g_autofree gchar *organisation = NULL;
|
||||
- g_autofree gchar *password = NULL;
|
||||
g_autofree gchar *port = NULL;
|
||||
g_autofree gchar *prefix = NULL;
|
||||
g_autofree gchar *proxy_server = NULL;
|
||||
g_autofree gchar *username = NULL;
|
||||
g_autoptr(GDBusConnection) conn_private = NULL;
|
||||
g_autoptr(GDBusProxy) proxy = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(GOptionContext) context = g_option_context_new (NULL);
|
||||
g_autoptr(GVariantBuilder) proxy_options = NULL;
|
||||
g_autoptr(GVariantBuilder) subman_conopts = NULL;
|
||||
g_autoptr(GVariantBuilder) subman_options = NULL;
|
||||
+ g_autoptr(GInputStream) standard_input_stream = g_unix_input_stream_new (STDIN_FILENO, FALSE);
|
||||
|
||||
const GOptionEntry options[] = {
|
||||
{ "kind", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING,
|
||||
&kind, "Kind, e.g. 'username' or 'key'", NULL },
|
||||
{ "address", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING,
|
||||
&address, "UNIX address", NULL },
|
||||
{ "username", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING,
|
||||
&username, "Username", NULL },
|
||||
- { "password", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING,
|
||||
- &password, "Password", NULL },
|
||||
{ "organisation", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING,
|
||||
&organisation, "Organisation", NULL },
|
||||
- { "activation-key", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING,
|
||||
- &activation_key, "Activation keys", NULL },
|
||||
{ "hostname", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING,
|
||||
&hostname, "Registration server hostname", NULL },
|
||||
{ "prefix", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING,
|
||||
&prefix, "Registration server prefix", NULL },
|
||||
{ "port", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING,
|
||||
&port, "Registration server port", NULL },
|
||||
{ "proxy", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING,
|
||||
&proxy_server, "Proxy settings", NULL },
|
||||
{ NULL}
|
||||
};
|
||||
|
||||
/* check calling UID */
|
||||
if (getuid () != 0 || geteuid () != 0) {
|
||||
g_printerr ("This program can only be used by the root user\n");
|
||||
return G_IO_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
setlocale (LC_ALL, "");
|
||||
locale = setlocale (LC_MESSAGES, NULL);
|
||||
|
||||
g_option_context_add_main_entries (context, options, NULL);
|
||||
if (!g_option_context_parse (context, &argc, &argv, &error)) {
|
||||
g_printerr ("Failed to parse arguments: %s\n", error->message);
|
||||
return G_IO_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/* uncommon actions */
|
||||
if (kind == NULL) {
|
||||
g_printerr ("No --kind specified\n");
|
||||
return G_IO_ERROR_INVALID_DATA;
|
||||
@@ -267,109 +265,117 @@ main (int argc, char *argv[])
|
||||
NULL, /* GDBusInterfaceInfo */
|
||||
NULL, /* name */
|
||||
"/com/redhat/RHSM1/Register",
|
||||
"com.redhat.RHSM1.Register",
|
||||
NULL, &error);
|
||||
if (proxy == NULL) {
|
||||
g_printerr ("Count not contact RHSM: %s\n", error->message);
|
||||
return G_IO_ERROR_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* no options */
|
||||
subman_options = g_variant_builder_new (G_VARIANT_TYPE("a{ss}"));
|
||||
|
||||
/* set registration server */
|
||||
if (hostname == NULL || hostname[0] == '\0')
|
||||
hostname = g_strdup ("subscription.rhsm.redhat.com");
|
||||
if (prefix == NULL || prefix[0] == '\0')
|
||||
prefix = g_strdup ("/subscription");
|
||||
if (port == NULL || port[0] == '\0')
|
||||
port = g_strdup ("443");
|
||||
subman_conopts = g_variant_builder_new (G_VARIANT_TYPE("a{ss}"));
|
||||
g_variant_builder_add (subman_conopts, "{ss}", "host", hostname);
|
||||
g_variant_builder_add (subman_conopts, "{ss}", "handler", prefix);
|
||||
g_variant_builder_add (subman_conopts, "{ss}", "port", port);
|
||||
|
||||
/* call into RHSM */
|
||||
if (g_strcmp0 (kind, "register-with-key") == 0) {
|
||||
g_auto(GStrv) activation_keys = NULL;
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
g_autoptr(GVariant) res = NULL;
|
||||
+ gchar activation_key[PIPE_BUF + 1] = "";
|
||||
|
||||
- if (activation_key == NULL) {
|
||||
- g_printerr ("Required --activation-key\n");
|
||||
- return G_IO_ERROR_INVALID_DATA;
|
||||
- }
|
||||
if (organisation == NULL) {
|
||||
g_printerr ("Required --organisation\n");
|
||||
return G_IO_ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
+ g_input_stream_read (standard_input_stream, activation_key, sizeof (activation_key) - 1, NULL, &error_local);
|
||||
+
|
||||
+ if (error_local != NULL) {
|
||||
+ g_printerr ("Could not read activation key: %s\n", error_local->message);
|
||||
+ return G_IO_ERROR_INVALID_DATA;
|
||||
+ }
|
||||
+
|
||||
g_debug ("trying to unregister in case machine is already registered");
|
||||
_helper_unregister (NULL);
|
||||
|
||||
g_debug ("registering using activation key");
|
||||
activation_keys = g_strsplit (activation_key, ",", -1);
|
||||
res = g_dbus_proxy_call_sync (proxy,
|
||||
"RegisterWithActivationKeys",
|
||||
g_variant_new ("(s^asa{ss}a{ss}s)",
|
||||
organisation,
|
||||
activation_keys,
|
||||
subman_options,
|
||||
subman_conopts,
|
||||
locale),
|
||||
G_DBUS_CALL_FLAGS_NO_AUTO_START,
|
||||
DBUS_TIMEOUT,
|
||||
NULL, &error_local);
|
||||
if (res == NULL) {
|
||||
g_dbus_error_strip_remote_error (error_local);
|
||||
_helper_convert_error (error_local->message, &error);
|
||||
g_printerr ("Failed to RegisterWithActivationKeys: %s\n", error->message);
|
||||
return error->code;
|
||||
}
|
||||
} else if (g_strcmp0 (kind, "register-with-username") == 0) {
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
g_autoptr(GVariant) res = NULL;
|
||||
+ gchar password[PIPE_BUF + 1] = "";
|
||||
|
||||
if (username == NULL) {
|
||||
g_printerr ("Required --username\n");
|
||||
return G_IO_ERROR_INVALID_DATA;
|
||||
}
|
||||
- if (password == NULL) {
|
||||
- g_printerr ("Required --password\n");
|
||||
- return G_IO_ERROR_INVALID_DATA;
|
||||
- }
|
||||
if (organisation == NULL) {
|
||||
g_printerr ("Required --organisation\n");
|
||||
return G_IO_ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
+ g_input_stream_read (standard_input_stream, password, sizeof (password) - 1, NULL, &error_local);
|
||||
+
|
||||
+ if (error_local != NULL) {
|
||||
+ g_printerr ("Could not read password: %s\n", error_local->message);
|
||||
+ return G_IO_ERROR_INVALID_DATA;
|
||||
+ }
|
||||
+
|
||||
g_debug ("trying to unregister in case machine is already registered");
|
||||
_helper_unregister (NULL);
|
||||
|
||||
g_debug ("registering using username and password");
|
||||
res = g_dbus_proxy_call_sync (proxy,
|
||||
"Register",
|
||||
g_variant_new ("(sssa{ss}a{ss}s)",
|
||||
organisation,
|
||||
username,
|
||||
password,
|
||||
subman_options,
|
||||
subman_conopts,
|
||||
locale),
|
||||
G_DBUS_CALL_FLAGS_NO_AUTO_START,
|
||||
DBUS_TIMEOUT,
|
||||
NULL, &error_local);
|
||||
if (res == NULL) {
|
||||
g_dbus_error_strip_remote_error (error_local);
|
||||
_helper_convert_error (error_local->message, &error);
|
||||
g_printerr ("Failed to Register: %s\n", error->message);
|
||||
return error->code;
|
||||
}
|
||||
} else {
|
||||
g_printerr ("Invalid --kind specified: %s\n", kind);
|
||||
return G_IO_ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
/* set the new hostname */
|
||||
if (!_helper_save_config ("server.hostname", hostname, &error)) {
|
||||
g_printerr ("Failed to save hostname: %s\n", error->message);
|
||||
diff --git a/plugins/subman/gsd-subscription-manager.c b/plugins/subman/gsd-subscription-manager.c
|
||||
index e2c16056..0838d490 100644
|
||||
--- a/plugins/subman/gsd-subscription-manager.c
|
||||
+++ b/plugins/subman/gsd-subscription-manager.c
|
||||
@@ -1,53 +1,54 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||
*
|
||||
* Copyright (C) 2019 Richard Hughes <richard@hughsie.com>
|
||||
* Copyright (C) 2019 Kalev Lember <klember@redhat.com>
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
+#include <gio/gunixinputstream.h>
|
||||
#include <gdk/gdk.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <json-glib/json-glib.h>
|
||||
#include <libnotify/notify.h>
|
||||
|
||||
#include "gnome-settings-profile.h"
|
||||
#include "gsd-subman-common.h"
|
||||
#include "gsd-subscription-manager.h"
|
||||
|
||||
#define GSD_DBUS_NAME "org.gnome.SettingsDaemon"
|
||||
#define GSD_DBUS_PATH "/org/gnome/SettingsDaemon"
|
||||
#define GSD_DBUS_BASE_INTERFACE "org.gnome.SettingsDaemon"
|
||||
|
||||
#define GSD_SUBSCRIPTION_DBUS_NAME GSD_DBUS_NAME ".Subscription"
|
||||
#define GSD_SUBSCRIPTION_DBUS_PATH GSD_DBUS_PATH "/Subscription"
|
||||
#define GSD_SUBSCRIPTION_DBUS_INTERFACE GSD_DBUS_BASE_INTERFACE ".Subscription"
|
||||
|
||||
static const gchar introspection_xml[] =
|
||||
"<node>"
|
||||
" <interface name='org.gnome.SettingsDaemon.Subscription'>"
|
||||
" <method name='Register'>"
|
||||
" <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))
|
||||
@@ -517,129 +518,168 @@ _client_maybe__show_notification (GsdSubscriptionManager *manager)
|
||||
}
|
||||
}
|
||||
|
||||
/* nag again */
|
||||
if (priv->subscription_status == GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN &&
|
||||
g_timer_elapsed (priv->timer_last_notified, NULL) > 60 * 60 * 24) {
|
||||
_show_notification (manager, _NOTIFY_REGISTRATION_REQUIRED);
|
||||
return;
|
||||
}
|
||||
if (priv->subscription_status == GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID &&
|
||||
g_timer_elapsed (priv->timer_last_notified, NULL) > 60 * 60 * 24) {
|
||||
_show_notification (manager, _NOTIFY_EXPIRED);
|
||||
return;
|
||||
}
|
||||
if (priv->subscription_status == GSD_SUBMAN_SUBSCRIPTION_STATUS_PARTIALLY_VALID &&
|
||||
g_timer_elapsed (priv->timer_last_notified, NULL) > 60 * 60 * 24) {
|
||||
_show_notification (manager, _NOTIFY_EXPIRED);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_client_register_with_keys (GsdSubscriptionManager *manager,
|
||||
const gchar *hostname,
|
||||
const gchar *organisation,
|
||||
const gchar *activation_key,
|
||||
GError **error)
|
||||
{
|
||||
GsdSubscriptionManagerPrivate *priv = manager->priv;
|
||||
g_autoptr(GSubprocess) subprocess = NULL;
|
||||
+ g_autoptr(GBytes) stdin_buf = g_bytes_new (activation_key, strlen (activation_key) + 1);
|
||||
+ g_autoptr(GBytes) stderr_buf = NULL;
|
||||
+ gint rc;
|
||||
|
||||
/* apparently: "we can't send registration credentials over the regular
|
||||
* system or session bus since those aren't really locked down..." */
|
||||
if (!_client_register_start (manager, error))
|
||||
return FALSE;
|
||||
g_debug ("spawning %s", LIBEXECDIR "/gsd-subman-helper");
|
||||
- subprocess = g_subprocess_new (G_SUBPROCESS_FLAGS_STDERR_PIPE, error,
|
||||
+ subprocess = g_subprocess_new (G_SUBPROCESS_FLAGS_STDIN_PIPE | G_SUBPROCESS_FLAGS_STDERR_PIPE, error,
|
||||
"pkexec", LIBEXECDIR "/gsd-subman-helper",
|
||||
"--kind", "register-with-key",
|
||||
"--address", priv->address,
|
||||
"--hostname", hostname,
|
||||
"--organisation", organisation,
|
||||
- "--activation-key", activation_key,
|
||||
NULL);
|
||||
if (subprocess == NULL) {
|
||||
g_prefix_error (error, "failed to find pkexec: ");
|
||||
return FALSE;
|
||||
}
|
||||
- if (!_client_subprocess_wait_check (subprocess, error))
|
||||
+
|
||||
+ if (!g_subprocess_communicate (subprocess, stdin_buf, NULL, NULL, &stderr_buf, error)) {
|
||||
+ g_prefix_error (error, "failed to run pkexec: ");
|
||||
return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ rc = g_subprocess_get_exit_status (subprocess);
|
||||
+ if (rc != 0) {
|
||||
+ if (g_bytes_get_size (stderr_buf) == 0) {
|
||||
+ g_set_error_literal (error, G_IO_ERROR, rc,
|
||||
+ "Failed to run helper without stderr");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ g_set_error (error, G_IO_ERROR, rc,
|
||||
+ "%.*s",
|
||||
+ g_bytes_get_size (stderr_buf),
|
||||
+ g_bytes_get_data (stderr_buf, NULL));
|
||||
+ }
|
||||
|
||||
/* FIXME: also do on error? */
|
||||
if (!_client_register_stop (manager, 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);
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_client_register (GsdSubscriptionManager *manager,
|
||||
const gchar *hostname,
|
||||
const gchar *organisation,
|
||||
const gchar *username,
|
||||
const gchar *password,
|
||||
GError **error)
|
||||
{
|
||||
GsdSubscriptionManagerPrivate *priv = manager->priv;
|
||||
g_autoptr(GSubprocess) subprocess = NULL;
|
||||
+ g_autoptr(GBytes) stdin_buf = g_bytes_new (password, strlen (password) + 1);
|
||||
+ g_autoptr(GBytes) stderr_buf = NULL;
|
||||
+ gint rc;
|
||||
|
||||
/* fallback */
|
||||
if (organisation == NULL)
|
||||
organisation = "";
|
||||
|
||||
/* apparently: "we can't send registration credentials over the regular
|
||||
* system or session bus since those aren't really locked down..." */
|
||||
if (!_client_register_start (manager, error))
|
||||
return FALSE;
|
||||
g_debug ("spawning %s", LIBEXECDIR "/gsd-subman-helper");
|
||||
- subprocess = g_subprocess_new (G_SUBPROCESS_FLAGS_STDERR_PIPE, error,
|
||||
+ subprocess = g_subprocess_new (G_SUBPROCESS_FLAGS_STDIN_PIPE | G_SUBPROCESS_FLAGS_STDERR_PIPE,
|
||||
+ error,
|
||||
"pkexec", LIBEXECDIR "/gsd-subman-helper",
|
||||
"--kind", "register-with-username",
|
||||
"--address", priv->address,
|
||||
"--hostname", hostname,
|
||||
"--organisation", organisation,
|
||||
"--username", username,
|
||||
- "--password", password,
|
||||
NULL);
|
||||
if (subprocess == NULL) {
|
||||
g_prefix_error (error, "failed to find pkexec: ");
|
||||
return FALSE;
|
||||
}
|
||||
- if (!_client_subprocess_wait_check (subprocess, error))
|
||||
+
|
||||
+ if (!g_subprocess_communicate (subprocess, stdin_buf, NULL, NULL, &stderr_buf, error)) {
|
||||
+ g_prefix_error (error, "failed to run pkexec: ");
|
||||
return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ rc = g_subprocess_get_exit_status (subprocess);
|
||||
+ if (rc != 0) {
|
||||
+ if (g_bytes_get_size (stderr_buf) == 0) {
|
||||
+ g_set_error_literal (error, G_IO_ERROR, rc,
|
||||
+ "Failed to run helper without stderr");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ g_set_error (error, G_IO_ERROR, rc,
|
||||
+ "%.*s",
|
||||
+ g_bytes_get_size (stderr_buf),
|
||||
+ g_bytes_get_data (stderr_buf, NULL));
|
||||
+ }
|
||||
|
||||
/* FIXME: also do on error? */
|
||||
if (!_client_register_stop (manager, 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_unregister (GsdSubscriptionManager *manager, GError **error)
|
||||
{
|
||||
g_autoptr(GSubprocess) subprocess = NULL;
|
||||
|
||||
/* apparently: "we can't send registration credentials over the regular
|
||||
* system or session bus since those aren't really locked down..." */
|
||||
if (!_client_register_start (manager, error))
|
||||
return FALSE;
|
||||
g_debug ("spawning %s", LIBEXECDIR "/gsd-subman-helper");
|
||||
subprocess = g_subprocess_new (G_SUBPROCESS_FLAGS_STDERR_PIPE, error,
|
||||
"pkexec", LIBEXECDIR "/gsd-subman-helper",
|
||||
"--kind", "unregister",
|
||||
NULL);
|
||||
if (subprocess == NULL) {
|
||||
g_prefix_error (error, "failed to find pkexec: ");
|
||||
return FALSE;
|
||||
}
|
||||
diff --git a/plugins/subman/meson.build b/plugins/subman/meson.build
|
||||
index bfd073b6..e4b4589d 100644
|
||||
--- a/plugins/subman/meson.build
|
||||
+++ b/plugins/subman/meson.build
|
||||
@@ -22,35 +22,35 @@ executable(
|
||||
c_args: cflags,
|
||||
install: true,
|
||||
install_rpath: gsd_pkglibdir,
|
||||
install_dir: gsd_libexecdir
|
||||
)
|
||||
|
||||
# .Register needs to be called from root as subman can't do PolicyKit...
|
||||
policy = 'org.gnome.settings-daemon.plugins.subman.policy'
|
||||
policy_in = configure_file(
|
||||
input: policy + '.in.in',
|
||||
output: policy + '.in',
|
||||
configuration: plugins_conf
|
||||
)
|
||||
|
||||
i18n.merge_file(
|
||||
policy,
|
||||
input: policy_in,
|
||||
output: policy,
|
||||
po_dir: po_dir,
|
||||
install: true,
|
||||
install_dir: join_paths(gsd_datadir, 'polkit-1', 'actions')
|
||||
)
|
||||
|
||||
install_data('org.gnome.settings-daemon.plugins.subman.rules',
|
||||
install_dir : join_paths(gsd_datadir, 'polkit-1', 'rules.d'))
|
||||
|
||||
executable(
|
||||
'gsd-subman-helper',
|
||||
'gsd-subman-helper.c',
|
||||
include_directories: top_inc,
|
||||
- dependencies: [gio_dep, jsonglib_dep],
|
||||
+ dependencies: [gio_dep, gio_unix_dep, jsonglib_dep],
|
||||
install: true,
|
||||
install_rpath: gsd_pkglibdir,
|
||||
install_dir: gsd_libexecdir
|
||||
)
|
||||
--
|
||||
2.30.0
|
||||
|
310
SOURCES/0009-subman-Don-t-treat-failure-to-attach-as-fatal.patch
Normal file
310
SOURCES/0009-subman-Don-t-treat-failure-to-attach-as-fatal.patch
Normal file
@ -0,0 +1,310 @@
|
||||
From 1255b2b83284d262f6b8c3ceb23d499ddbf77d48 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Thu, 21 Jan 2021 09:52:19 -0500
|
||||
Subject: [PATCH 09/15] subman: Don't treat failure to attach as fatal
|
||||
|
||||
Many organizations don't require specific subscriptions to get
|
||||
updates (called "simple content access"). At the moment,
|
||||
those systems get an error when registering.
|
||||
|
||||
This commit quiets the error.
|
||||
---
|
||||
plugins/subman/gsd-subman-helper.c | 46 ++++++++++++++++++++++++------
|
||||
1 file changed, 37 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/plugins/subman/gsd-subman-helper.c b/plugins/subman/gsd-subman-helper.c
|
||||
index edf1e41f..53a4d56b 100644
|
||||
--- a/plugins/subman/gsd-subman-helper.c
|
||||
+++ b/plugins/subman/gsd-subman-helper.c
|
||||
@@ -25,145 +25,169 @@
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <locale.h>
|
||||
|
||||
#include <gio/gio.h>
|
||||
#include <gio/gunixinputstream.h>
|
||||
#include <json-glib/json-glib.h>
|
||||
|
||||
#define DBUS_TIMEOUT 300000 /* 5 minutes */
|
||||
static const char *locale;
|
||||
|
||||
static void
|
||||
_helper_convert_error (const gchar *json_txt, GError **error)
|
||||
{
|
||||
JsonNode *json_root;
|
||||
JsonObject *json_obj;
|
||||
const gchar *message;
|
||||
g_autoptr(JsonParser) json_parser = json_parser_new ();
|
||||
|
||||
/* this may be plain text or JSON :| */
|
||||
if (!json_parser_load_from_data (json_parser, json_txt, -1, NULL)) {
|
||||
g_set_error_literal (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_SUPPORTED,
|
||||
json_txt);
|
||||
return;
|
||||
}
|
||||
json_root = json_parser_get_root (json_parser);
|
||||
json_obj = json_node_get_object (json_root);
|
||||
+ if (json_object_has_member (json_obj, "severity")) {
|
||||
+ const gchar *severity;
|
||||
+
|
||||
+ /* warnings are non-fatal so we ignore them
|
||||
+ */
|
||||
+ severity = json_object_get_string_member (json_obj, "severity");
|
||||
+ if (g_strstr_len (severity, -1, "warning") != NULL) {
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (!json_object_has_member (json_obj, "message")) {
|
||||
g_set_error (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_INVALID_DATA,
|
||||
"no message' in %s", json_txt);
|
||||
return;
|
||||
}
|
||||
message = json_object_get_string_member (json_obj, "message");
|
||||
if (g_strstr_len (message, -1, "Invalid user credentials") != NULL) {
|
||||
g_set_error_literal (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_PERMISSION_DENIED,
|
||||
message);
|
||||
return;
|
||||
}
|
||||
g_set_error_literal (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_SUPPORTED,
|
||||
message);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_helper_unregister (GError **error)
|
||||
{
|
||||
g_autoptr(GDBusProxy) proxy = NULL;
|
||||
g_autoptr(GVariantBuilder) proxy_options = NULL;
|
||||
g_autoptr(GVariant) res = NULL;
|
||||
|
||||
proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
|
||||
NULL,
|
||||
"com.redhat.RHSM1",
|
||||
"/com/redhat/RHSM1/Unregister",
|
||||
"com.redhat.RHSM1.Unregister",
|
||||
NULL, error);
|
||||
if (proxy == NULL) {
|
||||
g_prefix_error (error, "Failed to get proxy: ");
|
||||
return FALSE;
|
||||
}
|
||||
proxy_options = g_variant_builder_new (G_VARIANT_TYPE_VARDICT);
|
||||
res = g_dbus_proxy_call_sync (proxy,
|
||||
"Unregister",
|
||||
g_variant_new ("(a{sv}s)",
|
||||
proxy_options,
|
||||
locale),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
DBUS_TIMEOUT,
|
||||
NULL, error);
|
||||
return res != NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_helper_auto_attach (GError **error)
|
||||
{
|
||||
const gchar *str = NULL;
|
||||
+ g_autoptr(GError) error_local = NULL;
|
||||
g_autoptr(GDBusProxy) proxy = NULL;
|
||||
g_autoptr(GVariantBuilder) proxy_options = NULL;
|
||||
g_autoptr(GVariant) res = NULL;
|
||||
|
||||
g_debug ("auto-attaching subscriptions");
|
||||
proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
|
||||
NULL,
|
||||
"com.redhat.RHSM1",
|
||||
"/com/redhat/RHSM1/Attach",
|
||||
"com.redhat.RHSM1.Attach",
|
||||
- NULL, error);
|
||||
+ NULL, &error_local);
|
||||
if (proxy == NULL) {
|
||||
- g_prefix_error (error, "Failed to get proxy: ");
|
||||
+ g_dbus_error_strip_remote_error (error_local);
|
||||
+ g_propagate_prefixed_error (error,
|
||||
+ g_steal_pointer (&error_local),
|
||||
+ "Failed to get proxy: ");
|
||||
return FALSE;
|
||||
}
|
||||
proxy_options = g_variant_builder_new (G_VARIANT_TYPE_VARDICT);
|
||||
res = g_dbus_proxy_call_sync (proxy,
|
||||
"AutoAttach",
|
||||
g_variant_new ("(sa{sv}s)",
|
||||
"", /* now? */
|
||||
proxy_options,
|
||||
locale),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
DBUS_TIMEOUT,
|
||||
- NULL, error);
|
||||
- if (res == NULL)
|
||||
- return FALSE;
|
||||
+ NULL, &error_local);
|
||||
+ if (res == NULL) {
|
||||
+ g_dbus_error_strip_remote_error (error_local);
|
||||
+ _helper_convert_error (error_local->message, error);
|
||||
+
|
||||
+ if (*error != NULL) {
|
||||
+ g_prefix_error (error, "Failed to get proxy: ");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ return TRUE;
|
||||
+ }
|
||||
g_variant_get (res, "(&s)", &str);
|
||||
g_debug ("Attach.AutoAttach: %s", str);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_helper_save_config (const gchar *key, const gchar *value, GError **error)
|
||||
{
|
||||
g_autoptr(GDBusProxy) proxy = NULL;
|
||||
g_autoptr(GVariant) res = NULL;
|
||||
proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
|
||||
NULL,
|
||||
"com.redhat.RHSM1",
|
||||
"/com/redhat/RHSM1/Config",
|
||||
"com.redhat.RHSM1.Config",
|
||||
NULL, error);
|
||||
if (proxy == NULL) {
|
||||
g_prefix_error (error, "Failed to get proxy: ");
|
||||
return FALSE;
|
||||
}
|
||||
res = g_dbus_proxy_call_sync (proxy, "Set",
|
||||
g_variant_new ("(svs)",
|
||||
key,
|
||||
g_variant_new_string (value),
|
||||
locale),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
DBUS_TIMEOUT,
|
||||
NULL, error);
|
||||
@@ -298,105 +322,109 @@ main (int argc, char *argv[])
|
||||
g_printerr ("Required --organisation\n");
|
||||
return G_IO_ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
g_input_stream_read (standard_input_stream, activation_key, sizeof (activation_key) - 1, NULL, &error_local);
|
||||
|
||||
if (error_local != NULL) {
|
||||
g_printerr ("Could not read activation key: %s\n", error_local->message);
|
||||
return G_IO_ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
g_debug ("trying to unregister in case machine is already registered");
|
||||
_helper_unregister (NULL);
|
||||
|
||||
g_debug ("registering using activation key");
|
||||
activation_keys = g_strsplit (activation_key, ",", -1);
|
||||
res = g_dbus_proxy_call_sync (proxy,
|
||||
"RegisterWithActivationKeys",
|
||||
g_variant_new ("(s^asa{ss}a{ss}s)",
|
||||
organisation,
|
||||
activation_keys,
|
||||
subman_options,
|
||||
subman_conopts,
|
||||
locale),
|
||||
G_DBUS_CALL_FLAGS_NO_AUTO_START,
|
||||
DBUS_TIMEOUT,
|
||||
NULL, &error_local);
|
||||
if (res == NULL) {
|
||||
g_dbus_error_strip_remote_error (error_local);
|
||||
_helper_convert_error (error_local->message, &error);
|
||||
- g_printerr ("Failed to RegisterWithActivationKeys: %s\n", error->message);
|
||||
- return error->code;
|
||||
+ if (error != NULL) {
|
||||
+ g_printerr ("Failed to RegisterWithActivationKeys: %s\n", error->message);
|
||||
+ return error->code;
|
||||
+ }
|
||||
}
|
||||
} else if (g_strcmp0 (kind, "register-with-username") == 0) {
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
g_autoptr(GVariant) res = NULL;
|
||||
gchar password[PIPE_BUF + 1] = "";
|
||||
|
||||
if (username == NULL) {
|
||||
g_printerr ("Required --username\n");
|
||||
return G_IO_ERROR_INVALID_DATA;
|
||||
}
|
||||
if (organisation == NULL) {
|
||||
g_printerr ("Required --organisation\n");
|
||||
return G_IO_ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
g_input_stream_read (standard_input_stream, password, sizeof (password) - 1, NULL, &error_local);
|
||||
|
||||
if (error_local != NULL) {
|
||||
g_printerr ("Could not read password: %s\n", error_local->message);
|
||||
return G_IO_ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
g_debug ("trying to unregister in case machine is already registered");
|
||||
_helper_unregister (NULL);
|
||||
|
||||
g_debug ("registering using username and password");
|
||||
res = g_dbus_proxy_call_sync (proxy,
|
||||
"Register",
|
||||
g_variant_new ("(sssa{ss}a{ss}s)",
|
||||
organisation,
|
||||
username,
|
||||
password,
|
||||
subman_options,
|
||||
subman_conopts,
|
||||
locale),
|
||||
G_DBUS_CALL_FLAGS_NO_AUTO_START,
|
||||
DBUS_TIMEOUT,
|
||||
NULL, &error_local);
|
||||
if (res == NULL) {
|
||||
g_dbus_error_strip_remote_error (error_local);
|
||||
_helper_convert_error (error_local->message, &error);
|
||||
- g_printerr ("Failed to Register: %s\n", error->message);
|
||||
- return error->code;
|
||||
+ if (error != NULL) {
|
||||
+ g_printerr ("Failed to Register: %s\n", error->message);
|
||||
+ return error->code;
|
||||
+ }
|
||||
}
|
||||
} else {
|
||||
g_printerr ("Invalid --kind specified: %s\n", kind);
|
||||
return G_IO_ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
/* set the new hostname */
|
||||
if (!_helper_save_config ("server.hostname", hostname, &error)) {
|
||||
g_printerr ("Failed to save hostname: %s\n", error->message);
|
||||
return G_IO_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
if (!_helper_save_config ("server.prefix", prefix, &error)) {
|
||||
g_printerr ("Failed to save prefix: %s\n", error->message);
|
||||
return G_IO_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
if (!_helper_save_config ("server.port", port, &error)) {
|
||||
g_printerr ("Failed to save port: %s\n", error->message);
|
||||
return G_IO_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
/* wait for rhsmd to notice the new config */
|
||||
g_usleep (G_USEC_PER_SEC * 5);
|
||||
|
||||
/* auto-attach */
|
||||
if (!_helper_auto_attach (&error)) {
|
||||
g_printerr ("Failed to AutoAttach: %s\n", error->message);
|
||||
return G_IO_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
--
|
||||
2.30.0
|
||||
|
427
SOURCES/0010-subman-Add-new-no-installed-products-state.patch
Normal file
427
SOURCES/0010-subman-Add-new-no-installed-products-state.patch
Normal file
@ -0,0 +1,427 @@
|
||||
From d53c27802c69773d63d108f57912035fd3caabf9 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Sun, 24 Jan 2021 11:24:36 -0500
|
||||
Subject: [PATCH 10/15] subman: Add new no-installed-products state
|
||||
|
||||
It's possible, though unlikley, the system has
|
||||
no packages installed from Red Hat supported package sets.
|
||||
|
||||
This commit adds a new state to track that situation.
|
||||
---
|
||||
plugins/subman/gsd-subman-common.c | 2 ++
|
||||
plugins/subman/gsd-subman-common.h | 1 +
|
||||
plugins/subman/gsd-subscription-manager.c | 17 +++++++----------
|
||||
3 files changed, 10 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/plugins/subman/gsd-subman-common.c b/plugins/subman/gsd-subman-common.c
|
||||
index e515131e..eef5175d 100644
|
||||
--- a/plugins/subman/gsd-subman-common.c
|
||||
+++ b/plugins/subman/gsd-subman-common.c
|
||||
@@ -5,32 +5,34 @@
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gsd-subman-common.h"
|
||||
|
||||
const gchar *
|
||||
gsd_subman_subscription_status_to_string (GsdSubmanSubscriptionStatus status)
|
||||
{
|
||||
if (status == GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID)
|
||||
return "valid";
|
||||
if (status == GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID)
|
||||
return "invalid";
|
||||
if (status == GSD_SUBMAN_SUBSCRIPTION_STATUS_DISABLED)
|
||||
return "disabled";
|
||||
if (status == GSD_SUBMAN_SUBSCRIPTION_STATUS_PARTIALLY_VALID)
|
||||
return "partially-valid";
|
||||
+ if (status == GSD_SUBMAN_SUBSCRIPTION_STATUS_NO_INSTALLED_PRODUCTS)
|
||||
+ return "no-installed-products";
|
||||
return "unknown";
|
||||
}
|
||||
diff --git a/plugins/subman/gsd-subman-common.h b/plugins/subman/gsd-subman-common.h
|
||||
index fccf9f6a..f8a3d9f4 100644
|
||||
--- a/plugins/subman/gsd-subman-common.h
|
||||
+++ b/plugins/subman/gsd-subman-common.h
|
||||
@@ -3,38 +3,39 @@
|
||||
* Copyright (C) 2019 Richard Hughes <rhughes@redhat.com>
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __GSD_SUBMAN_COMMON_H
|
||||
#define __GSD_SUBMAN_COMMON_H
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef enum {
|
||||
GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN,
|
||||
GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID,
|
||||
GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID,
|
||||
GSD_SUBMAN_SUBSCRIPTION_STATUS_DISABLED,
|
||||
GSD_SUBMAN_SUBSCRIPTION_STATUS_PARTIALLY_VALID,
|
||||
+ GSD_SUBMAN_SUBSCRIPTION_STATUS_NO_INSTALLED_PRODUCTS,
|
||||
GSD_SUBMAN_SUBSCRIPTION_STATUS_LAST
|
||||
} GsdSubmanSubscriptionStatus;
|
||||
|
||||
const gchar *gsd_subman_subscription_status_to_string (GsdSubmanSubscriptionStatus status);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSD_SUBMAN_COMMON_H */
|
||||
diff --git a/plugins/subman/gsd-subscription-manager.c b/plugins/subman/gsd-subscription-manager.c
|
||||
index 0838d490..46f8d35c 100644
|
||||
--- a/plugins/subman/gsd-subscription-manager.c
|
||||
+++ b/plugins/subman/gsd-subscription-manager.c
|
||||
@@ -242,60 +242,67 @@ _client_installed_products_update (GsdSubscriptionManager *manager, GError **err
|
||||
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;
|
||||
g_autoptr(GVariant) status = NULL;
|
||||
g_autoptr(JsonParser) json_parser = json_parser_new ();
|
||||
|
||||
/* save old value */
|
||||
priv->subscription_status_last = priv->subscription_status;
|
||||
+ if (!_client_installed_products_update (manager, error))
|
||||
+ goto out;
|
||||
+
|
||||
+ if (priv->installed_products->len == 0) {
|
||||
+ priv->subscription_status = GSD_SUBMAN_SUBSCRIPTION_STATUS_NO_INSTALLED_PRODUCTS;
|
||||
+ goto out;
|
||||
+ }
|
||||
|
||||
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 (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, "valid")) {
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
|
||||
"no Entitlement.GetStatus valid in %s", json_txt);
|
||||
@@ -563,62 +570,60 @@ _client_register_with_keys (GsdSubscriptionManager *manager,
|
||||
NULL);
|
||||
if (subprocess == NULL) {
|
||||
g_prefix_error (error, "failed to find pkexec: ");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!g_subprocess_communicate (subprocess, stdin_buf, NULL, NULL, &stderr_buf, error)) {
|
||||
g_prefix_error (error, "failed to run pkexec: ");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
rc = g_subprocess_get_exit_status (subprocess);
|
||||
if (rc != 0) {
|
||||
if (g_bytes_get_size (stderr_buf) == 0) {
|
||||
g_set_error_literal (error, G_IO_ERROR, rc,
|
||||
"Failed to run helper without stderr");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_set_error (error, G_IO_ERROR, rc,
|
||||
"%.*s",
|
||||
g_bytes_get_size (stderr_buf),
|
||||
g_bytes_get_data (stderr_buf, NULL));
|
||||
}
|
||||
|
||||
/* FIXME: also do on error? */
|
||||
if (!_client_register_stop (manager, 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);
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_client_register (GsdSubscriptionManager *manager,
|
||||
const gchar *hostname,
|
||||
const gchar *organisation,
|
||||
const gchar *username,
|
||||
const gchar *password,
|
||||
GError **error)
|
||||
{
|
||||
GsdSubscriptionManagerPrivate *priv = manager->priv;
|
||||
g_autoptr(GSubprocess) subprocess = NULL;
|
||||
g_autoptr(GBytes) stdin_buf = g_bytes_new (password, strlen (password) + 1);
|
||||
g_autoptr(GBytes) stderr_buf = NULL;
|
||||
gint rc;
|
||||
|
||||
/* fallback */
|
||||
if (organisation == NULL)
|
||||
organisation = "";
|
||||
|
||||
/* apparently: "we can't send registration credentials over the regular
|
||||
* system or session bus since those aren't really locked down..." */
|
||||
if (!_client_register_start (manager, error))
|
||||
return FALSE;
|
||||
g_debug ("spawning %s", LIBEXECDIR "/gsd-subman-helper");
|
||||
subprocess = g_subprocess_new (G_SUBPROCESS_FLAGS_STDIN_PIPE | G_SUBPROCESS_FLAGS_STDERR_PIPE,
|
||||
@@ -632,62 +637,60 @@ _client_register (GsdSubscriptionManager *manager,
|
||||
NULL);
|
||||
if (subprocess == NULL) {
|
||||
g_prefix_error (error, "failed to find pkexec: ");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!g_subprocess_communicate (subprocess, stdin_buf, NULL, NULL, &stderr_buf, error)) {
|
||||
g_prefix_error (error, "failed to run pkexec: ");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
rc = g_subprocess_get_exit_status (subprocess);
|
||||
if (rc != 0) {
|
||||
if (g_bytes_get_size (stderr_buf) == 0) {
|
||||
g_set_error_literal (error, G_IO_ERROR, rc,
|
||||
"Failed to run helper without stderr");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_set_error (error, G_IO_ERROR, rc,
|
||||
"%.*s",
|
||||
g_bytes_get_size (stderr_buf),
|
||||
g_bytes_get_data (stderr_buf, NULL));
|
||||
}
|
||||
|
||||
/* FIXME: also do on error? */
|
||||
if (!_client_register_stop (manager, 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_unregister (GsdSubscriptionManager *manager, GError **error)
|
||||
{
|
||||
g_autoptr(GSubprocess) subprocess = NULL;
|
||||
|
||||
/* apparently: "we can't send registration credentials over the regular
|
||||
* system or session bus since those aren't really locked down..." */
|
||||
if (!_client_register_start (manager, error))
|
||||
return FALSE;
|
||||
g_debug ("spawning %s", LIBEXECDIR "/gsd-subman-helper");
|
||||
subprocess = g_subprocess_new (G_SUBPROCESS_FLAGS_STDERR_PIPE, 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;
|
||||
@@ -714,64 +717,60 @@ _client_update_config (GsdSubscriptionManager *manager, GError **error)
|
||||
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);
|
||||
}
|
||||
if (!_client_subscription_status_update (manager, &error)) {
|
||||
g_warning ("failed to update subscription status: %s", error->message);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
- if (!_client_installed_products_update (manager, &error)) {
|
||||
- g_warning ("failed to update installed products: %s", error->message);
|
||||
- g_clear_error (&error);
|
||||
- }
|
||||
_client_maybe__show_notification (manager);
|
||||
}
|
||||
|
||||
static void
|
||||
_client_unload (GsdSubscriptionManager *manager)
|
||||
{
|
||||
GsdSubscriptionManagerPrivate *priv = manager->priv;
|
||||
for (guint i = 0; i < _RHSM_INTERFACE_LAST; i++)
|
||||
g_clear_object (&priv->proxies[i]);
|
||||
g_hash_table_unref (priv->config);
|
||||
}
|
||||
|
||||
static const gchar *
|
||||
_rhsm_interface_to_string (_RhsmInterface kind)
|
||||
{
|
||||
if (kind == _RHSM_INTERFACE_CONFIG)
|
||||
return "Config";
|
||||
if (kind == _RHSM_INTERFACE_REGISTER_SERVER)
|
||||
return "RegisterServer";
|
||||
if (kind == _RHSM_INTERFACE_ATTACH)
|
||||
return "Attach";
|
||||
if (kind == _RHSM_INTERFACE_ENTITLEMENT)
|
||||
return "Entitlement";
|
||||
if (kind == _RHSM_INTERFACE_PRODUCTS)
|
||||
return "Products";
|
||||
if (kind == _RHSM_INTERFACE_CONSUMER)
|
||||
return "Consumer";
|
||||
if (kind == _RHSM_INTERFACE_SYSPURPOSE)
|
||||
return "Syspurpose";
|
||||
return NULL;
|
||||
@@ -782,62 +781,60 @@ _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 */
|
||||
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);
|
||||
}
|
||||
|
||||
static void
|
||||
gsd_subscription_manager_class_init (GsdSubscriptionManagerClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
--
|
||||
2.30.0
|
||||
|
146
SOURCES/0011-subman-Fix-some-build-warnings.patch
Normal file
146
SOURCES/0011-subman-Fix-some-build-warnings.patch
Normal file
@ -0,0 +1,146 @@
|
||||
From 432850e943d72daedb1d352a0332d3fdee6078e2 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Sun, 24 Jan 2021 11:26:40 -0500
|
||||
Subject: [PATCH 11/15] subman: Fix some build warnings
|
||||
|
||||
---
|
||||
plugins/subman/gsd-subscription-manager.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/plugins/subman/gsd-subscription-manager.c b/plugins/subman/gsd-subscription-manager.c
|
||||
index 46f8d35c..1f9ca447 100644
|
||||
--- a/plugins/subman/gsd-subscription-manager.c
|
||||
+++ b/plugins/subman/gsd-subscription-manager.c
|
||||
@@ -561,62 +561,62 @@ _client_register_with_keys (GsdSubscriptionManager *manager,
|
||||
if (!_client_register_start (manager, error))
|
||||
return FALSE;
|
||||
g_debug ("spawning %s", LIBEXECDIR "/gsd-subman-helper");
|
||||
subprocess = g_subprocess_new (G_SUBPROCESS_FLAGS_STDIN_PIPE | G_SUBPROCESS_FLAGS_STDERR_PIPE, error,
|
||||
"pkexec", LIBEXECDIR "/gsd-subman-helper",
|
||||
"--kind", "register-with-key",
|
||||
"--address", priv->address,
|
||||
"--hostname", hostname,
|
||||
"--organisation", organisation,
|
||||
NULL);
|
||||
if (subprocess == NULL) {
|
||||
g_prefix_error (error, "failed to find pkexec: ");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!g_subprocess_communicate (subprocess, stdin_buf, NULL, NULL, &stderr_buf, error)) {
|
||||
g_prefix_error (error, "failed to run pkexec: ");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
rc = g_subprocess_get_exit_status (subprocess);
|
||||
if (rc != 0) {
|
||||
if (g_bytes_get_size (stderr_buf) == 0) {
|
||||
g_set_error_literal (error, G_IO_ERROR, rc,
|
||||
"Failed to run helper without stderr");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_set_error (error, G_IO_ERROR, rc,
|
||||
"%.*s",
|
||||
- g_bytes_get_size (stderr_buf),
|
||||
- g_bytes_get_data (stderr_buf, NULL));
|
||||
+ (int) g_bytes_get_size (stderr_buf),
|
||||
+ (char *) g_bytes_get_data (stderr_buf, NULL));
|
||||
}
|
||||
|
||||
/* FIXME: also do on error? */
|
||||
if (!_client_register_stop (manager, error))
|
||||
return FALSE;
|
||||
if (!_client_subscription_status_update (manager, error))
|
||||
return FALSE;
|
||||
_client_maybe__show_notification (manager);
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_client_register (GsdSubscriptionManager *manager,
|
||||
const gchar *hostname,
|
||||
const gchar *organisation,
|
||||
const gchar *username,
|
||||
const gchar *password,
|
||||
GError **error)
|
||||
{
|
||||
GsdSubscriptionManagerPrivate *priv = manager->priv;
|
||||
g_autoptr(GSubprocess) subprocess = NULL;
|
||||
g_autoptr(GBytes) stdin_buf = g_bytes_new (password, strlen (password) + 1);
|
||||
g_autoptr(GBytes) stderr_buf = NULL;
|
||||
gint rc;
|
||||
|
||||
/* fallback */
|
||||
if (organisation == NULL)
|
||||
organisation = "";
|
||||
@@ -628,62 +628,62 @@ _client_register (GsdSubscriptionManager *manager,
|
||||
g_debug ("spawning %s", LIBEXECDIR "/gsd-subman-helper");
|
||||
subprocess = g_subprocess_new (G_SUBPROCESS_FLAGS_STDIN_PIPE | G_SUBPROCESS_FLAGS_STDERR_PIPE,
|
||||
error,
|
||||
"pkexec", LIBEXECDIR "/gsd-subman-helper",
|
||||
"--kind", "register-with-username",
|
||||
"--address", priv->address,
|
||||
"--hostname", hostname,
|
||||
"--organisation", organisation,
|
||||
"--username", username,
|
||||
NULL);
|
||||
if (subprocess == NULL) {
|
||||
g_prefix_error (error, "failed to find pkexec: ");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!g_subprocess_communicate (subprocess, stdin_buf, NULL, NULL, &stderr_buf, error)) {
|
||||
g_prefix_error (error, "failed to run pkexec: ");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
rc = g_subprocess_get_exit_status (subprocess);
|
||||
if (rc != 0) {
|
||||
if (g_bytes_get_size (stderr_buf) == 0) {
|
||||
g_set_error_literal (error, G_IO_ERROR, rc,
|
||||
"Failed to run helper without stderr");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_set_error (error, G_IO_ERROR, rc,
|
||||
"%.*s",
|
||||
- g_bytes_get_size (stderr_buf),
|
||||
- g_bytes_get_data (stderr_buf, NULL));
|
||||
+ (int) g_bytes_get_size (stderr_buf),
|
||||
+ (char *) g_bytes_get_data (stderr_buf, NULL));
|
||||
}
|
||||
|
||||
/* FIXME: also do on error? */
|
||||
if (!_client_register_stop (manager, error))
|
||||
return FALSE;
|
||||
if (!_client_subscription_status_update (manager, error))
|
||||
return FALSE;
|
||||
_client_maybe__show_notification (manager);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_client_unregister (GsdSubscriptionManager *manager, GError **error)
|
||||
{
|
||||
g_autoptr(GSubprocess) subprocess = NULL;
|
||||
|
||||
/* apparently: "we can't send registration credentials over the regular
|
||||
* system or session bus since those aren't really locked down..." */
|
||||
if (!_client_register_start (manager, error))
|
||||
return FALSE;
|
||||
g_debug ("spawning %s", LIBEXECDIR "/gsd-subman-helper");
|
||||
subprocess = g_subprocess_new (G_SUBPROCESS_FLAGS_STDERR_PIPE, 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))
|
||||
--
|
||||
2.30.0
|
||||
|
@ -0,0 +1,259 @@
|
||||
From 3bb3b2b09d34deafadd3cfe3355137afab20cb23 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Sun, 24 Jan 2021 11:27:42 -0500
|
||||
Subject: [PATCH 12/15] subman: Add DBus API to subscribe for updates on
|
||||
already registered system
|
||||
|
||||
It's possible an admin may have registered their system without
|
||||
attaching any subscriptions to it.
|
||||
|
||||
At the moment, gnome-settings-daemon only provides a way to register
|
||||
and subscribe in one step.
|
||||
|
||||
This commit adds an API to support doing the last half of the process
|
||||
on its own.
|
||||
---
|
||||
plugins/subman/gsd-subscription-manager.c | 51 +++++++++++++++++++++++
|
||||
1 file changed, 51 insertions(+)
|
||||
|
||||
diff --git a/plugins/subman/gsd-subscription-manager.c b/plugins/subman/gsd-subscription-manager.c
|
||||
index 1f9ca447..705f8b11 100644
|
||||
--- a/plugins/subman/gsd-subscription-manager.c
|
||||
+++ b/plugins/subman/gsd-subscription-manager.c
|
||||
@@ -19,60 +19,61 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <gio/gunixinputstream.h>
|
||||
#include <gdk/gdk.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <json-glib/json-glib.h>
|
||||
#include <libnotify/notify.h>
|
||||
|
||||
#include "gnome-settings-profile.h"
|
||||
#include "gsd-subman-common.h"
|
||||
#include "gsd-subscription-manager.h"
|
||||
|
||||
#define GSD_DBUS_NAME "org.gnome.SettingsDaemon"
|
||||
#define GSD_DBUS_PATH "/org/gnome/SettingsDaemon"
|
||||
#define GSD_DBUS_BASE_INTERFACE "org.gnome.SettingsDaemon"
|
||||
|
||||
#define GSD_SUBSCRIPTION_DBUS_NAME GSD_DBUS_NAME ".Subscription"
|
||||
#define GSD_SUBSCRIPTION_DBUS_PATH GSD_DBUS_PATH "/Subscription"
|
||||
#define GSD_SUBSCRIPTION_DBUS_INTERFACE GSD_DBUS_BASE_INTERFACE ".Subscription"
|
||||
|
||||
static const gchar introspection_xml[] =
|
||||
"<node>"
|
||||
" <interface name='org.gnome.SettingsDaemon.Subscription'>"
|
||||
" <method name='Register'>"
|
||||
" <arg type='a{sv}' name='options' direction='in'/>"
|
||||
" </method>"
|
||||
" <method name='Unregister'/>"
|
||||
+" <method name='Attach'/>"
|
||||
" <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];
|
||||
GHashTable *config; /* str:str */
|
||||
GPtrArray *installed_products;
|
||||
gchar *address;
|
||||
@@ -669,60 +670,104 @@ _client_register (GsdSubscriptionManager *manager,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_client_unregister (GsdSubscriptionManager *manager, GError **error)
|
||||
{
|
||||
g_autoptr(GSubprocess) subprocess = NULL;
|
||||
|
||||
/* apparently: "we can't send registration credentials over the regular
|
||||
* system or session bus since those aren't really locked down..." */
|
||||
if (!_client_register_start (manager, error))
|
||||
return FALSE;
|
||||
g_debug ("spawning %s", LIBEXECDIR "/gsd-subman-helper");
|
||||
subprocess = g_subprocess_new (G_SUBPROCESS_FLAGS_STDERR_PIPE, 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_attach (GsdSubscriptionManager *manager,
|
||||
+ GError **error)
|
||||
+{
|
||||
+ g_autoptr(GSubprocess) subprocess = NULL;
|
||||
+ g_autoptr(GBytes) stderr_buf = NULL;
|
||||
+ gint rc;
|
||||
+
|
||||
+ g_debug ("spawning %s", LIBEXECDIR "/gsd-subman-helper");
|
||||
+ subprocess = g_subprocess_new (G_SUBPROCESS_FLAGS_STDERR_PIPE,
|
||||
+ error,
|
||||
+ "pkexec", LIBEXECDIR "/gsd-subman-helper",
|
||||
+ "--kind", "auto-attach",
|
||||
+ NULL);
|
||||
+ if (subprocess == NULL) {
|
||||
+ g_prefix_error (error, "failed to find pkexec: ");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ if (!g_subprocess_communicate (subprocess, NULL, NULL, NULL, &stderr_buf, error)) {
|
||||
+ g_prefix_error (error, "failed to run pkexec: ");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ rc = g_subprocess_get_exit_status (subprocess);
|
||||
+ if (rc != 0) {
|
||||
+ if (g_bytes_get_size (stderr_buf) == 0) {
|
||||
+ g_set_error_literal (error, G_IO_ERROR, rc,
|
||||
+ "Failed to run helper without stderr");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ g_set_error (error, G_IO_ERROR, rc,
|
||||
+ "%.*s",
|
||||
+ (int) g_bytes_get_size (stderr_buf),
|
||||
+ (char *) g_bytes_get_data (stderr_buf, NULL));
|
||||
+ }
|
||||
+
|
||||
+ if (!_client_subscription_status_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)", "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;
|
||||
@@ -1002,60 +1047,66 @@ handle_method_call (GDBusConnection *connection,
|
||||
g_dbus_method_invocation_return_gerror (invocation, error);
|
||||
return;
|
||||
}
|
||||
} else if (g_strcmp0 (kind, "key") == 0) {
|
||||
const gchar *activation_key = NULL;
|
||||
g_variant_dict_lookup (dict, "hostname", "&s", &hostname);
|
||||
g_variant_dict_lookup (dict, "organisation", "&s", &organisation);
|
||||
g_variant_dict_lookup (dict, "activation-key", "&s", &activation_key);
|
||||
if (!_client_register_with_keys (manager,
|
||||
hostname,
|
||||
organisation,
|
||||
activation_key,
|
||||
&error)) {
|
||||
g_dbus_method_invocation_return_gerror (invocation, error);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
g_dbus_method_invocation_return_error_literal (invocation,
|
||||
G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Invalid kind specified");
|
||||
|
||||
return;
|
||||
}
|
||||
g_dbus_method_invocation_return_value (invocation, NULL);
|
||||
} else if (g_strcmp0 (method_name, "Unregister") == 0) {
|
||||
if (!_client_unregister (manager, &error)) {
|
||||
g_dbus_method_invocation_return_gerror (invocation, error);
|
||||
return;
|
||||
}
|
||||
g_dbus_method_invocation_return_value (invocation, NULL);
|
||||
+ } else if (g_strcmp0 (method_name, "Attach") == 0) {
|
||||
+ if (!_client_attach (manager, &error)) {
|
||||
+ g_dbus_method_invocation_return_gerror (invocation, error);
|
||||
+ return;
|
||||
+ }
|
||||
+ g_dbus_method_invocation_return_value (invocation, NULL);
|
||||
} else {
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static GVariant *
|
||||
handle_get_property (GDBusConnection *connection,
|
||||
const gchar *sender,
|
||||
const gchar *object_path,
|
||||
const gchar *interface_name,
|
||||
const gchar *property_name,
|
||||
GError **error, gpointer user_data)
|
||||
{
|
||||
GsdSubscriptionManager *manager = GSD_SUBSCRIPTION_MANAGER (user_data);
|
||||
GsdSubscriptionManagerPrivate *priv = manager->priv;
|
||||
|
||||
if (g_strcmp0 (interface_name, GSD_SUBSCRIPTION_DBUS_INTERFACE) != 0) {
|
||||
g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
|
||||
"No such interface: %s", interface_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (g_strcmp0 (property_name, "SubscriptionStatus") == 0)
|
||||
return g_variant_new_uint32 (priv->subscription_status);
|
||||
|
||||
if (g_strcmp0 (property_name, "InstalledProducts") == 0)
|
||||
return _make_installed_products_variant (priv->installed_products);
|
||||
|
||||
g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
|
||||
"Failed to get property: %s", property_name);
|
||||
--
|
||||
2.30.0
|
||||
|
141
SOURCES/0013-subman-Improve-subscription-status-handling.patch
Normal file
141
SOURCES/0013-subman-Improve-subscription-status-handling.patch
Normal file
@ -0,0 +1,141 @@
|
||||
From d9eb6331efa92cd28a8ba3ccc1665c3744296465 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Sun, 24 Jan 2021 11:34:03 -0500
|
||||
Subject: [PATCH 13/15] subman: Improve subscription status handling
|
||||
|
||||
This commit improves how subscription-manager status is
|
||||
parsed to give more detailed information about subscription
|
||||
state.
|
||||
---
|
||||
plugins/subman/gsd-subscription-manager.c | 33 +++++++++++++++++++----
|
||||
1 file changed, 28 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/plugins/subman/gsd-subscription-manager.c b/plugins/subman/gsd-subscription-manager.c
|
||||
index 705f8b11..6d80bfa9 100644
|
||||
--- a/plugins/subman/gsd-subscription-manager.c
|
||||
+++ b/plugins/subman/gsd-subscription-manager.c
|
||||
@@ -262,93 +262,116 @@ _client_subscription_status_update (GsdSubscriptionManager *manager, GError **er
|
||||
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;
|
||||
g_autoptr(GVariant) status = NULL;
|
||||
g_autoptr(JsonParser) json_parser = json_parser_new ();
|
||||
|
||||
/* save old value */
|
||||
priv->subscription_status_last = priv->subscription_status;
|
||||
if (!_client_installed_products_update (manager, error))
|
||||
goto out;
|
||||
|
||||
if (priv->installed_products->len == 0) {
|
||||
priv->subscription_status = GSD_SUBMAN_SUBSCRIPTION_STATUS_NO_INSTALLED_PRODUCTS;
|
||||
goto out;
|
||||
}
|
||||
|
||||
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 (uuid, "(&s)", &uuid_txt);
|
||||
|
||||
+ if (uuid_txt[0] == '\0') {
|
||||
+ priv->subscription_status = GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
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);
|
||||
+
|
||||
+ const gchar *status_id = NULL;
|
||||
+
|
||||
+ if (json_object_has_member (json_obj, "status_id")) {
|
||||
+ status_id = json_object_get_string_member (json_obj, "status_id");
|
||||
+ }
|
||||
+
|
||||
if (!json_object_has_member (json_obj, "valid")) {
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
|
||||
"no Entitlement.GetStatus valid in %s", json_txt);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean is_valid = json_object_get_boolean_member (json_obj, "valid");
|
||||
|
||||
- if (uuid_txt[0] != '\0') {
|
||||
- if (is_valid) {
|
||||
+ if (is_valid) {
|
||||
+ if (g_strcmp0 (status_id, "disabled") != 0) {
|
||||
priv->subscription_status = GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID;
|
||||
} else {
|
||||
- priv->subscription_status = GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID;
|
||||
+ priv->subscription_status = GSD_SUBMAN_SUBSCRIPTION_STATUS_DISABLED;
|
||||
+ }
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ for (guint i = 0; i < priv->installed_products->len; i++) {
|
||||
+ ProductData *product = g_ptr_array_index (priv->installed_products, i);
|
||||
+
|
||||
+ if (g_strcmp0 (product->status, "subscribed") == 0) {
|
||||
+ priv->subscription_status = GSD_SUBMAN_SUBSCRIPTION_STATUS_PARTIALLY_VALID;
|
||||
+ goto out;
|
||||
}
|
||||
- } else {
|
||||
- priv->subscription_status = GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN;
|
||||
}
|
||||
|
||||
+ priv->subscription_status = GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID;
|
||||
+
|
||||
+out:
|
||||
/* 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))
|
||||
return FALSE;
|
||||
--
|
||||
2.30.0
|
||||
|
56
SOURCES/0014-subman-Drop-LAST-from-status-enum.patch
Normal file
56
SOURCES/0014-subman-Drop-LAST-from-status-enum.patch
Normal file
@ -0,0 +1,56 @@
|
||||
From a78b25b9507edb958a46779f2bb808bf678fa4a7 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Sun, 24 Jan 2021 11:55:19 -0500
|
||||
Subject: [PATCH 14/15] subman: Drop "LAST" from status enum
|
||||
|
||||
It's unused, so get rid of it.
|
||||
---
|
||||
plugins/subman/gsd-subman-common.h | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/plugins/subman/gsd-subman-common.h b/plugins/subman/gsd-subman-common.h
|
||||
index f8a3d9f4..88226564 100644
|
||||
--- a/plugins/subman/gsd-subman-common.h
|
||||
+++ b/plugins/subman/gsd-subman-common.h
|
||||
@@ -4,38 +4,37 @@
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __GSD_SUBMAN_COMMON_H
|
||||
#define __GSD_SUBMAN_COMMON_H
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef enum {
|
||||
GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN,
|
||||
GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID,
|
||||
GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID,
|
||||
GSD_SUBMAN_SUBSCRIPTION_STATUS_DISABLED,
|
||||
GSD_SUBMAN_SUBSCRIPTION_STATUS_PARTIALLY_VALID,
|
||||
GSD_SUBMAN_SUBSCRIPTION_STATUS_NO_INSTALLED_PRODUCTS,
|
||||
- GSD_SUBMAN_SUBSCRIPTION_STATUS_LAST
|
||||
} GsdSubmanSubscriptionStatus;
|
||||
|
||||
const gchar *gsd_subman_subscription_status_to_string (GsdSubmanSubscriptionStatus status);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSD_SUBMAN_COMMON_H */
|
||||
--
|
||||
2.30.0
|
||||
|
419
SOURCES/0015-subman-Clean-up-notification-behavior.patch
Normal file
419
SOURCES/0015-subman-Clean-up-notification-behavior.patch
Normal file
@ -0,0 +1,419 @@
|
||||
From 3412be1f63df2a5967ef92c27028368df1646b5c Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Sun, 24 Jan 2021 12:41:20 -0500
|
||||
Subject: [PATCH 15/15] subman: Clean up notification behavior
|
||||
|
||||
Notifications were only displayed for some status transitions.
|
||||
|
||||
This commit introduces some booleans based on the old and new
|
||||
statuses to make the code clearer and to make it easier to hit
|
||||
all the cases.
|
||||
---
|
||||
plugins/subman/gsd-subman-common.h | 1 +
|
||||
plugins/subman/gsd-subscription-manager.c | 141 ++++++++++++++++++----
|
||||
2 files changed, 120 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/plugins/subman/gsd-subman-common.h b/plugins/subman/gsd-subman-common.h
|
||||
index 88226564..9397dbe4 100644
|
||||
--- a/plugins/subman/gsd-subman-common.h
|
||||
+++ b/plugins/subman/gsd-subman-common.h
|
||||
@@ -1,40 +1,41 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||
*
|
||||
* Copyright (C) 2019 Richard Hughes <rhughes@redhat.com>
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __GSD_SUBMAN_COMMON_H
|
||||
#define __GSD_SUBMAN_COMMON_H
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef enum {
|
||||
+ GSD_SUBMAN_SUBSCRIPTION_STATUS_NOT_READ = -1,
|
||||
GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN,
|
||||
GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID,
|
||||
GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID,
|
||||
GSD_SUBMAN_SUBSCRIPTION_STATUS_DISABLED,
|
||||
GSD_SUBMAN_SUBSCRIPTION_STATUS_PARTIALLY_VALID,
|
||||
GSD_SUBMAN_SUBSCRIPTION_STATUS_NO_INSTALLED_PRODUCTS,
|
||||
} GsdSubmanSubscriptionStatus;
|
||||
|
||||
const gchar *gsd_subman_subscription_status_to_string (GsdSubmanSubscriptionStatus status);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSD_SUBMAN_COMMON_H */
|
||||
diff --git a/plugins/subman/gsd-subscription-manager.c b/plugins/subman/gsd-subscription-manager.c
|
||||
index 6d80bfa9..aaccbbc6 100644
|
||||
--- a/plugins/subman/gsd-subscription-manager.c
|
||||
+++ b/plugins/subman/gsd-subscription-manager.c
|
||||
@@ -243,60 +243,61 @@ _client_installed_products_update (GsdSubscriptionManager *manager, GError **err
|
||||
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;
|
||||
g_autoptr(GVariant) status = NULL;
|
||||
g_autoptr(JsonParser) json_parser = json_parser_new ();
|
||||
|
||||
/* save old value */
|
||||
priv->subscription_status_last = priv->subscription_status;
|
||||
+
|
||||
if (!_client_installed_products_update (manager, error))
|
||||
goto out;
|
||||
|
||||
if (priv->installed_products->len == 0) {
|
||||
priv->subscription_status = GSD_SUBMAN_SUBSCRIPTION_STATUS_NO_INSTALLED_PRODUCTS;
|
||||
goto out;
|
||||
}
|
||||
|
||||
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 (uuid, "(&s)", &uuid_txt);
|
||||
|
||||
if (uuid_txt[0] == '\0') {
|
||||
priv->subscription_status = GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN;
|
||||
goto out;
|
||||
}
|
||||
|
||||
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,
|
||||
@@ -485,109 +486,203 @@ typedef enum {
|
||||
static void
|
||||
_show_notification (GsdSubscriptionManager *manager, _NotifyKind notify_kind)
|
||||
{
|
||||
GsdSubscriptionManagerPrivate *priv = manager->priv;
|
||||
switch (notify_kind) {
|
||||
case _NOTIFY_EXPIRED:
|
||||
notify_notification_close (priv->notification_registered, NULL);
|
||||
notify_notification_close (priv->notification_registration_required, NULL);
|
||||
notify_notification_show (priv->notification_expired, NULL);
|
||||
break;
|
||||
case _NOTIFY_REGISTRATION_REQUIRED:
|
||||
notify_notification_close (priv->notification_registered, NULL);
|
||||
notify_notification_close (priv->notification_expired, NULL);
|
||||
notify_notification_show (priv->notification_registration_required, NULL);
|
||||
break;
|
||||
case _NOTIFY_REGISTERED:
|
||||
notify_notification_close (priv->notification_expired, NULL);
|
||||
notify_notification_close (priv->notification_registration_required, NULL);
|
||||
notify_notification_show (priv->notification_registered, NULL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
g_timer_reset (priv->timer_last_notified);
|
||||
}
|
||||
|
||||
static void
|
||||
_client_maybe__show_notification (GsdSubscriptionManager *manager)
|
||||
{
|
||||
GsdSubscriptionManagerPrivate *priv = manager->priv;
|
||||
+ gboolean was_read, was_registered, had_subscriptions, needed_subscriptions;
|
||||
+ gboolean is_read, is_registered, has_subscriptions, needs_subscriptions;
|
||||
+
|
||||
+ switch (priv->subscription_status_last) {
|
||||
+ case GSD_SUBMAN_SUBSCRIPTION_STATUS_NOT_READ:
|
||||
+ was_read = FALSE;
|
||||
+ was_registered = FALSE;
|
||||
+ needed_subscriptions = TRUE;
|
||||
+ had_subscriptions = FALSE;
|
||||
+ break;
|
||||
+ case GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN:
|
||||
+ was_read = TRUE;
|
||||
+ was_registered = FALSE;
|
||||
+ needed_subscriptions = TRUE;
|
||||
+ had_subscriptions = FALSE;
|
||||
+ break;
|
||||
+ case GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID:
|
||||
+ was_read = TRUE;
|
||||
+ was_registered = TRUE;
|
||||
+ needed_subscriptions = TRUE;
|
||||
+ had_subscriptions = TRUE;
|
||||
+ break;
|
||||
+ case GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID:
|
||||
+ was_read = TRUE;
|
||||
+ was_registered = TRUE;
|
||||
+ needed_subscriptions = TRUE;
|
||||
+ had_subscriptions = FALSE;
|
||||
+ break;
|
||||
+ case GSD_SUBMAN_SUBSCRIPTION_STATUS_DISABLED:
|
||||
+ was_read = TRUE;
|
||||
+ was_registered = TRUE;
|
||||
+ needed_subscriptions = FALSE;
|
||||
+ had_subscriptions = FALSE;
|
||||
+ break;
|
||||
+ case GSD_SUBMAN_SUBSCRIPTION_STATUS_PARTIALLY_VALID:
|
||||
+ was_read = TRUE;
|
||||
+ was_registered = TRUE;
|
||||
+ needed_subscriptions = TRUE;
|
||||
+ had_subscriptions = FALSE;
|
||||
+ case GSD_SUBMAN_SUBSCRIPTION_STATUS_NO_INSTALLED_PRODUCTS:
|
||||
+ was_read = TRUE;
|
||||
+ was_registered = FALSE;
|
||||
+ needed_subscriptions = FALSE;
|
||||
+ had_subscriptions = FALSE;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ switch (priv->subscription_status) {
|
||||
+ case GSD_SUBMAN_SUBSCRIPTION_STATUS_NOT_READ:
|
||||
+ is_read = FALSE;
|
||||
+ is_registered = FALSE;
|
||||
+ needs_subscriptions = TRUE;
|
||||
+ has_subscriptions = FALSE;
|
||||
+ break;
|
||||
+ case GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN:
|
||||
+ is_read = TRUE;
|
||||
+ is_registered = FALSE;
|
||||
+ needs_subscriptions = TRUE;
|
||||
+ has_subscriptions = FALSE;
|
||||
+ break;
|
||||
+ case GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID:
|
||||
+ is_read = TRUE;
|
||||
+ is_registered = TRUE;
|
||||
+ needs_subscriptions = TRUE;
|
||||
+ has_subscriptions = TRUE;
|
||||
+ break;
|
||||
+ case GSD_SUBMAN_SUBSCRIPTION_STATUS_PARTIALLY_VALID:
|
||||
+ case GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID:
|
||||
+ is_read = TRUE;
|
||||
+ is_registered = TRUE;
|
||||
+ needs_subscriptions = TRUE;
|
||||
+ has_subscriptions = FALSE;
|
||||
+ break;
|
||||
+ case GSD_SUBMAN_SUBSCRIPTION_STATUS_DISABLED:
|
||||
+ is_read = TRUE;
|
||||
+ is_registered = TRUE;
|
||||
+ needs_subscriptions = FALSE;
|
||||
+ has_subscriptions = FALSE;
|
||||
+ break;
|
||||
+ case GSD_SUBMAN_SUBSCRIPTION_STATUS_NO_INSTALLED_PRODUCTS:
|
||||
+ is_read = TRUE;
|
||||
+ is_registered = FALSE;
|
||||
+ needs_subscriptions = FALSE;
|
||||
+ has_subscriptions = FALSE;
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
/* startup */
|
||||
- if (priv->subscription_status_last == GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN &&
|
||||
- priv->subscription_status == GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN) {
|
||||
+ if (!was_read && is_read && priv->subscription_status == GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN) {
|
||||
_show_notification (manager, _NOTIFY_REGISTRATION_REQUIRED);
|
||||
return;
|
||||
}
|
||||
|
||||
/* something changed */
|
||||
- if (priv->subscription_status_last != priv->subscription_status) {
|
||||
+ if (was_read && is_read && priv->subscription_status_last != priv->subscription_status) {
|
||||
g_debug ("transisition from subscription status '%s' to '%s'",
|
||||
gsd_subman_subscription_status_to_string (priv->subscription_status_last),
|
||||
gsd_subman_subscription_status_to_string (priv->subscription_status));
|
||||
|
||||
- /* needs registration */
|
||||
- if (priv->subscription_status_last == GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID &&
|
||||
- priv->subscription_status == GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID) {
|
||||
- _show_notification (manager, _NOTIFY_REGISTRATION_REQUIRED);
|
||||
+ /* needs subscription */
|
||||
+ if (is_registered && needs_subscriptions && !has_subscriptions) {
|
||||
+ _show_notification (manager, _NOTIFY_EXPIRED);
|
||||
return;
|
||||
}
|
||||
|
||||
/* was unregistered */
|
||||
- if (priv->subscription_status_last == GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID &&
|
||||
- priv->subscription_status == GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN) {
|
||||
+ if (was_registered && !is_registered) {
|
||||
_show_notification (manager, _NOTIFY_REGISTRATION_REQUIRED);
|
||||
return;
|
||||
}
|
||||
|
||||
- /* registered */
|
||||
- if (priv->subscription_status_last == GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN &&
|
||||
- priv->subscription_status == GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID &&
|
||||
- g_timer_elapsed (priv->timer_last_notified, NULL) > 60) {
|
||||
- _show_notification (manager, _NOTIFY_REGISTERED);
|
||||
- return;
|
||||
+ /* just registered */
|
||||
+ if (!was_registered && is_registered) {
|
||||
+ if (!needs_subscriptions || has_subscriptions) {
|
||||
+ _show_notification (manager, _NOTIFY_REGISTERED);
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* subscriptions changed */
|
||||
+ if (was_registered && is_registered) {
|
||||
+ /* subscribed */
|
||||
+ if (!had_subscriptions &&
|
||||
+ needs_subscriptions && has_subscriptions) {
|
||||
+ _show_notification (manager, _NOTIFY_REGISTERED);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* simple content access enabled */
|
||||
+ if (needed_subscriptions && !had_subscriptions && !needs_subscriptions) {
|
||||
+ _show_notification (manager, _NOTIFY_REGISTERED);
|
||||
+ return;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
/* nag again */
|
||||
- if (priv->subscription_status == GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN &&
|
||||
+ if (!is_registered &&
|
||||
g_timer_elapsed (priv->timer_last_notified, NULL) > 60 * 60 * 24) {
|
||||
_show_notification (manager, _NOTIFY_REGISTRATION_REQUIRED);
|
||||
return;
|
||||
}
|
||||
- if (priv->subscription_status == GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID &&
|
||||
- g_timer_elapsed (priv->timer_last_notified, NULL) > 60 * 60 * 24) {
|
||||
- _show_notification (manager, _NOTIFY_EXPIRED);
|
||||
- return;
|
||||
- }
|
||||
- if (priv->subscription_status == GSD_SUBMAN_SUBSCRIPTION_STATUS_PARTIALLY_VALID &&
|
||||
+ if (is_registered && !has_subscriptions && needs_subscriptions &&
|
||||
g_timer_elapsed (priv->timer_last_notified, NULL) > 60 * 60 * 24) {
|
||||
_show_notification (manager, _NOTIFY_EXPIRED);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_client_register_with_keys (GsdSubscriptionManager *manager,
|
||||
const gchar *hostname,
|
||||
const gchar *organisation,
|
||||
const gchar *activation_key,
|
||||
GError **error)
|
||||
{
|
||||
GsdSubscriptionManagerPrivate *priv = manager->priv;
|
||||
g_autoptr(GSubprocess) subprocess = NULL;
|
||||
g_autoptr(GBytes) stdin_buf = g_bytes_new (activation_key, strlen (activation_key) + 1);
|
||||
g_autoptr(GBytes) stderr_buf = NULL;
|
||||
gint rc;
|
||||
|
||||
/* apparently: "we can't send registration credentials over the regular
|
||||
* system or session bus since those aren't really locked down..." */
|
||||
if (!_client_register_start (manager, error))
|
||||
return FALSE;
|
||||
g_debug ("spawning %s", LIBEXECDIR "/gsd-subman-helper");
|
||||
subprocess = g_subprocess_new (G_SUBPROCESS_FLAGS_STDIN_PIPE | G_SUBPROCESS_FLAGS_STDERR_PIPE, error,
|
||||
"pkexec", LIBEXECDIR "/gsd-subman-helper",
|
||||
"--kind", "register-with-key",
|
||||
"--address", priv->address,
|
||||
"--hostname", hostname,
|
||||
"--organisation", organisation,
|
||||
@@ -914,60 +1009,62 @@ gsd_subscription_manager_class_init (GsdSubscriptionManagerClass *klass)
|
||||
static void
|
||||
_launch_info_overview (void)
|
||||
{
|
||||
const gchar *argv[] = { "gnome-control-center", "info-overview", NULL };
|
||||
g_debug ("Running gnome-control-center info-overview");
|
||||
g_spawn_async (NULL, (gchar **) argv, NULL, G_SPAWN_SEARCH_PATH,
|
||||
NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
_notify_closed_cb (NotifyNotification *notification, gpointer user_data)
|
||||
{
|
||||
/* FIXME: only launch when clicking on the main body, not the window close */
|
||||
if (notify_notification_get_closed_reason (notification) == 0x400)
|
||||
_launch_info_overview ();
|
||||
}
|
||||
|
||||
static void
|
||||
_notify_clicked_cb (NotifyNotification *notification, char *action, gpointer user_data)
|
||||
{
|
||||
_launch_info_overview ();
|
||||
}
|
||||
|
||||
static void
|
||||
gsd_subscription_manager_init (GsdSubscriptionManager *manager)
|
||||
{
|
||||
GsdSubscriptionManagerPrivate *priv = manager->priv = GSD_SUBSCRIPTION_MANAGER_GET_PRIVATE (manager);
|
||||
|
||||
priv->installed_products = g_ptr_array_new_with_free_func ((GDestroyNotify) product_data_free);
|
||||
priv->timer_last_notified = g_timer_new ();
|
||||
+ priv->subscription_status = GSD_SUBMAN_SUBSCRIPTION_STATUS_NOT_READ;
|
||||
+ priv->subscription_status_last = GSD_SUBMAN_SUBSCRIPTION_STATUS_NOT_READ;
|
||||
|
||||
/* expired */
|
||||
priv->notification_expired =
|
||||
notify_notification_new (_("Subscription Has Expired"),
|
||||
_("Add or renew a subscription to continue receiving software updates."),
|
||||
NULL);
|
||||
notify_notification_set_app_name (priv->notification_expired, _("Subscription"));
|
||||
notify_notification_set_hint_string (priv->notification_expired, "desktop-entry", "subman-panel");
|
||||
notify_notification_set_hint_string (priv->notification_expired, "x-gnome-privacy-scope", "system");
|
||||
notify_notification_set_urgency (priv->notification_expired, NOTIFY_URGENCY_CRITICAL);
|
||||
notify_notification_add_action (priv->notification_expired,
|
||||
"info-overview", _("Subscribe System…"),
|
||||
_notify_clicked_cb,
|
||||
manager, NULL);
|
||||
g_signal_connect (priv->notification_expired, "closed",
|
||||
G_CALLBACK (_notify_closed_cb), manager);
|
||||
|
||||
/* registered */
|
||||
priv->notification_registered =
|
||||
notify_notification_new (_("Registration Successful"),
|
||||
_("The system has been registered and software updates have been enabled."),
|
||||
NULL);
|
||||
notify_notification_set_app_name (priv->notification_registered, _("Subscription"));
|
||||
notify_notification_set_hint_string (priv->notification_registered, "desktop-entry", "subman-panel");
|
||||
notify_notification_set_hint_string (priv->notification_registered, "x-gnome-privacy-scope", "system");
|
||||
notify_notification_set_urgency (priv->notification_registered, NOTIFY_URGENCY_CRITICAL);
|
||||
g_signal_connect (priv->notification_registered, "closed",
|
||||
G_CALLBACK (_notify_closed_cb), manager);
|
||||
|
||||
/* registration required */
|
||||
--
|
||||
2.30.0
|
||||
|
25
SOURCES/0016-subman-Update-POTFILES.in.patch
Normal file
25
SOURCES/0016-subman-Update-POTFILES.in.patch
Normal file
@ -0,0 +1,25 @@
|
||||
From ff1278ecdebb5b23c80589a65f053d535a4d4f6a Mon Sep 17 00:00:00 2001
|
||||
From: Kalev Lember <klember@redhat.com>
|
||||
Date: Fri, 12 Feb 2021 14:51:29 +0100
|
||||
Subject: [PATCH 16/16] subman: Update POTFILES.in
|
||||
|
||||
---
|
||||
po/POTFILES.in | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/po/POTFILES.in b/po/POTFILES.in
|
||||
index 7f17d5b5..9b94dc0f 100644
|
||||
--- a/po/POTFILES.in
|
||||
+++ b/po/POTFILES.in
|
||||
@@ -25,6 +25,8 @@ plugins/print-notifications/gsd-printer.c
|
||||
plugins/print-notifications/gsd-print-notifications-manager.c
|
||||
plugins/smartcard/gsd-smartcard-manager.c
|
||||
plugins/smartcard/gsd-smartcard-service.c
|
||||
+plugins/subman/gsd-subscription-manager.c
|
||||
+plugins/subman/org.gnome.settings-daemon.plugins.subman.policy.in.in
|
||||
plugins/wacom/gsd-wacom-manager.c
|
||||
plugins/wacom/org.gnome.settings-daemon.plugins.wacom.policy.in.in
|
||||
plugins/xsettings/gsd-xsettings-manager.c
|
||||
--
|
||||
2.29.2
|
||||
|
9212
SOURCES/0017-Update-translations.patch
Normal file
9212
SOURCES/0017-Update-translations.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -6,9 +6,13 @@
|
||||
%global libgweather_version 3.9.5
|
||||
%global geoclue_version 2.3.1
|
||||
|
||||
%if %{undefined centos}
|
||||
%bcond_without subman
|
||||
%endif
|
||||
|
||||
Name: gnome-settings-daemon
|
||||
Version: 3.32.0
|
||||
Release: 11%{?dist}
|
||||
Release: 14%{?dist}
|
||||
Summary: The daemon sharing settings from GNOME to GTK+/KDE applications
|
||||
|
||||
License: GPLv2+
|
||||
@ -21,6 +25,7 @@ BuildRequires: gcc
|
||||
BuildRequires: cups-devel
|
||||
BuildRequires: gettext
|
||||
BuildRequires: perl-interpreter
|
||||
BuildRequires: git
|
||||
BuildRequires: pkgconfig(alsa)
|
||||
BuildRequires: pkgconfig(colord) >= 1.0.2
|
||||
BuildRequires: pkgconfig(fontconfig)
|
||||
@ -32,6 +37,9 @@ BuildRequires: pkgconfig(gsettings-desktop-schemas) >= %{gsettings_desktop_sche
|
||||
BuildRequires: pkgconfig(gtk+-3.0) >= %{gtk3_version}
|
||||
BuildRequires: pkgconfig(gudev-1.0)
|
||||
BuildRequires: pkgconfig(gweather-3.0) >= %{libgweather_version}
|
||||
%if %{with subman}
|
||||
BuildRequires: pkgconfig(json-glib-1.0)
|
||||
%endif
|
||||
BuildRequires: pkgconfig(lcms2) >= 2.2
|
||||
BuildRequires: pkgconfig(libcanberra-gtk3)
|
||||
BuildRequires: pkgconfig(libgeoclue-2.0)
|
||||
@ -75,14 +83,40 @@ Conflicts: gnome-session < 3.27.90
|
||||
# older gdm, gnome-session and gnome-shell releases that expect the functionality
|
||||
Conflicts: gnome-shell < 3.25.4
|
||||
|
||||
# account plugin
|
||||
Patch00001: 0001-account-first-cut-at-account-plugin.patch
|
||||
Patch00002: 0002-account-reshow-the-notification-when-screen-unlocks.patch
|
||||
Patch00003: 0003-account-display-nag-screen-periodically.patch
|
||||
Patch00004: 0004-account-don-t-poll-more-frequently-than-notification.patch
|
||||
Patch00005: 0001-smartcard-Cancel-cancellable-when-stopping.patch
|
||||
Patch00006: 0001-xsettings-Add-an-entry-for-the-overlay-scrolling-set.patch
|
||||
|
||||
Patch10001: 0001-housekeeping-Add-a-GPU-memory-usage-notification.patch
|
||||
Patch10001: 0001-smartcard-Cancel-cancellable-when-stopping.patch
|
||||
|
||||
Patch20001: 0001-xsettings-Add-an-entry-for-the-overlay-scrolling-set.patch
|
||||
|
||||
# Handle org.gnome.Shell.Screencast Stopped signal (#1705392)
|
||||
Patch30001: 0001-media-keys-Mark-screen-cast-as-stopped-if-it-was-sig.patch
|
||||
|
||||
Patch40001: 0001-housekeeping-Add-a-GPU-memory-usage-notification.patch
|
||||
|
||||
# subscription manager integration
|
||||
Patch50001: 0001-subman-Add-a-new-plugin-to-provide-system-subscripti.patch
|
||||
Patch50002: 0002-subman-Add-InstalledProducts-dbus-property-for-g-c-c.patch
|
||||
Patch50003: 0003-subman-Increase-RHSM-dbus-call-timeouts.patch
|
||||
Patch50004: 0004-subman-Drop-userlang-field.patch
|
||||
Patch50005: 0005-subman-Use-user-locale-for-registration-subscription.patch
|
||||
Patch50006: 0006-subman-Handle-subscription-manager-giving-invalid-st.patch
|
||||
Patch50007: 0007-subman-Force-re-subscribe-if-the-admin-already-subsc.patch
|
||||
Patch50008: 0008-subman-Don-t-send-secrets-through-command-line.patch
|
||||
Patch50009: 0009-subman-Don-t-treat-failure-to-attach-as-fatal.patch
|
||||
Patch50010: 0010-subman-Add-new-no-installed-products-state.patch
|
||||
Patch50011: 0011-subman-Fix-some-build-warnings.patch
|
||||
Patch50012: 0012-subman-Add-DBus-API-to-subscribe-for-updates-on-alre.patch
|
||||
Patch50013: 0013-subman-Improve-subscription-status-handling.patch
|
||||
Patch50014: 0014-subman-Drop-LAST-from-status-enum.patch
|
||||
Patch50015: 0015-subman-Clean-up-notification-behavior.patch
|
||||
Patch50016: 0016-subman-Update-POTFILES.in.patch
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=1876291
|
||||
Patch50017: 0017-Update-translations.patch
|
||||
|
||||
%description
|
||||
A daemon to share settings from GNOME to other applications. It also
|
||||
@ -97,17 +131,7 @@ The %{name}-devel package contains libraries and header files for
|
||||
developing applications that use %{name}.
|
||||
|
||||
%prep
|
||||
%setup -q
|
||||
|
||||
%patch00001 -p 1
|
||||
%patch00002 -p 1
|
||||
%patch00003 -p 1
|
||||
%patch00004 -p 1
|
||||
%patch00005 -p 1
|
||||
%patch00006 -p 1
|
||||
|
||||
%patch10001 -p 1
|
||||
|
||||
%autosetup -S git
|
||||
|
||||
%build
|
||||
%meson
|
||||
@ -204,6 +228,12 @@ mkdir $RPM_BUILD_ROOT%{_libdir}/gnome-settings-daemon-3.0/gtk-modules
|
||||
%{_sysconfdir}/xdg/autostart/org.gnome.SettingsDaemon.Sharing.desktop
|
||||
%{_datadir}/glib-2.0/schemas/org.gnome.settings-daemon.plugins.sharing.gschema.xml
|
||||
|
||||
%{_sysconfdir}/xdg/autostart/org.gnome.SettingsDaemon.Subscription.desktop
|
||||
%{_libexecdir}/gsd-subman
|
||||
%{_libexecdir}/gsd-subman-helper
|
||||
%{_datadir}/polkit-1/actions/org.gnome.settings-daemon.plugins.subman.policy
|
||||
%{_datadir}/polkit-1/rules.d/org.gnome.settings-daemon.plugins.subman.rules
|
||||
|
||||
%{_libdir}/gnome-settings-daemon-3.0/libgsd.so
|
||||
|
||||
/usr/lib/udev/rules.d/*.rules
|
||||
@ -218,6 +248,18 @@ mkdir $RPM_BUILD_ROOT%{_libdir}/gnome-settings-daemon-3.0/gtk-modules
|
||||
%{_libdir}/pkgconfig/gnome-settings-daemon.pc
|
||||
|
||||
%changelog
|
||||
* Mon Mar 01 2021 Kalev Lember <klember@redhat.com> - 3.32.0-14
|
||||
- Update fr, ja, zh_CN translations
|
||||
- Resolves: #1876291
|
||||
|
||||
* Thu Jan 21 2021 Ray Strode <rstrode@redhat.com> - 3.32.0-13
|
||||
- Add back subscription-manager plugin
|
||||
Related: #1870837
|
||||
|
||||
* Tue Jan 05 2021 Jonas Ådahl <jadahl@redhat.com> - 3.32.0-12
|
||||
- Handle org.gnome.Shell.Screencast Stopped signal
|
||||
Related: #1705392
|
||||
|
||||
* Wed Sep 02 2020 Ray Strode <rstrode@redhat.com> - 3.32.0-11
|
||||
- Remove subman plugin for now
|
||||
Resolves: #1872457
|
||||
|
Loading…
Reference in New Issue
Block a user