Compare commits
No commits in common. "c9" and "c8" have entirely different histories.
2
.gitignore
vendored
2
.gitignore
vendored
@ -1 +1 @@
|
||||
SOURCES/gnome-settings-daemon-40.0.1.tar.xz
|
||||
SOURCES/gnome-settings-daemon-3.32.0.tar.xz
|
||||
|
@ -1 +1 @@
|
||||
5c9249cc5e89627bd548d7cfc9f839c7524ad85f SOURCES/gnome-settings-daemon-40.0.1.tar.xz
|
||||
92145a7a5714ebf3aeb90baaacb7e6955335731b SOURCES/gnome-settings-daemon-3.32.0.tar.xz
|
||||
|
@ -0,0 +1,47 @@
|
||||
From bd0488fe501bae74fae1fbb21566aa35f38aa6fc Mon Sep 17 00:00:00 2001
|
||||
From: Felipe Borges <felipeborges@gnome.org>
|
||||
Date: Wed, 15 Feb 2023 15:27:59 +0100
|
||||
Subject: [PATCH] Make power-button-action always power off when chassis=server
|
||||
|
||||
Servers often don't support hibernation/suspend.
|
||||
---
|
||||
...rg.gnome.settings-daemon.plugins.power.gschema.xml.in | 2 +-
|
||||
plugins/media-keys/gsd-media-keys-manager.c | 9 ++++++---
|
||||
2 files changed, 7 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/data/org.gnome.settings-daemon.plugins.power.gschema.xml.in b/data/org.gnome.settings-daemon.plugins.power.gschema.xml.in
|
||||
index fc61d133..952104ed 100644
|
||||
--- a/data/org.gnome.settings-daemon.plugins.power.gschema.xml.in
|
||||
+++ b/data/org.gnome.settings-daemon.plugins.power.gschema.xml.in
|
||||
@@ -39,7 +39,7 @@
|
||||
<key name="power-button-action" enum="org.gnome.settings-daemon.GsdPowerButtonActionType">
|
||||
<default>'suspend'</default>
|
||||
<summary>Power button action</summary>
|
||||
- <description>The action to take when the system power button is pressed. Virtual machines only honor the 'nothing' action, and will shutdown otherwise. Tablets always suspend, ignoring all the other action options.</description>
|
||||
+ <description>The action to take when the system power button is pressed. Virtual machines and servers only honor the 'nothing' action, and will shutdown otherwise. Tablets always suspend, ignoring all the other action options.</description>
|
||||
</key>
|
||||
</schema>
|
||||
</schemalist>
|
||||
diff --git a/plugins/media-keys/gsd-media-keys-manager.c b/plugins/media-keys/gsd-media-keys-manager.c
|
||||
index ac6f7ab4..46bdade6 100644
|
||||
--- a/plugins/media-keys/gsd-media-keys-manager.c
|
||||
+++ b/plugins/media-keys/gsd-media-keys-manager.c
|
||||
@@ -2083,9 +2083,12 @@ do_config_power_button_action (GsdMediaKeysManager *manager,
|
||||
if (manager->priv->power_button_disabled)
|
||||
return;
|
||||
|
||||
- action_type = g_settings_get_enum (manager->priv->power_settings, "power-button-action");
|
||||
- /* Always power off VMs, except when power-button-action is "nothing" */
|
||||
- if (g_strcmp0 (manager->priv->chassis_type, "vm") == 0) {
|
||||
+ action_type = g_settings_get_enum (manager->priv->power_settings, "power-button-action");
|
||||
+ /* Always power off VMs and servers, except when power-button-action is "nothing" */
|
||||
+ if (g_strcmp0 (manager->priv->chassis_type, "vm") == 0 ||
|
||||
+ g_strcmp0 (manager->priv->chassis_type, "server")) {
|
||||
+ g_warning ("Virtual machines and servers only honor the 'nothing' power-button-action, and will shutdown otherwise");
|
||||
+
|
||||
if (action_type != GSD_POWER_BUTTON_ACTION_NOTHING)
|
||||
power_action (manager, "PowerOff", !in_lock_screen);
|
||||
|
||||
--
|
||||
2.37.1
|
||||
|
12157
SOURCES/0001-account-first-cut-at-account-plugin.patch
Normal file
12157
SOURCES/0001-account-first-cut-at-account-plugin.patch
Normal file
File diff suppressed because it is too large
Load Diff
5101
SOURCES/0001-housekeeping-Add-a-GPU-memory-usage-notification.patch
Normal file
5101
SOURCES/0001-housekeeping-Add-a-GPU-memory-usage-notification.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
@ -0,0 +1,34 @@
|
||||
From 77b52a04c9154a7e7b2434f6c70ba6b4fd84c9f1 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Berg <bberg@redhat.com>
|
||||
Date: Thu, 15 Oct 2020 15:18:35 +0200
|
||||
Subject: [PATCH] power: Avoid automatic logout in GDM/greeter
|
||||
|
||||
In GDM sessions (greeter, initial-setup), it does not make sense to
|
||||
automatically logout. This can happen if the system wide default is
|
||||
changed to default to the "logout" action.
|
||||
|
||||
Note that we already use the RUNNING_UNDER_GDM environment variable in
|
||||
the keyboard plugin currently. So doing this is likely sane, even if we
|
||||
probably want a more elegant strategy to detect whether we are in a
|
||||
"login" session.
|
||||
---
|
||||
plugins/power/gsd-power-manager.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/plugins/power/gsd-power-manager.c b/plugins/power/gsd-power-manager.c
|
||||
index e103a8a7..b100ff9e 100644
|
||||
--- a/plugins/power/gsd-power-manager.c
|
||||
+++ b/plugins/power/gsd-power-manager.c
|
||||
@@ -872,6 +872,9 @@ static void
|
||||
gnome_session_logout (GsdPowerManager *manager,
|
||||
guint logout_mode)
|
||||
{
|
||||
+ if (g_getenv("RUNNING_UNDER_GDM"))
|
||||
+ return;
|
||||
+
|
||||
g_dbus_proxy_call (G_DBUS_PROXY (manager->priv->session),
|
||||
"Logout",
|
||||
g_variant_new ("(u)", logout_mode),
|
||||
--
|
||||
2.26.2
|
||||
|
@ -1,458 +0,0 @@
|
||||
From 8dd4c164f6ce166a5767588bd6fb8e4c3e8e1a09 Mon Sep 17 00:00:00 2001
|
||||
From: Bastien Nocera <hadess@hadess.net>
|
||||
Date: Fri, 16 Jul 2021 13:40:10 +0200
|
||||
Subject: [PATCH 1/4] power: Enable power-saver profile when low on battery
|
||||
|
||||
When low on battery, and if the feature is enabled, hold the power
|
||||
profile to "power-saver" until the battery is sufficiently recharged.
|
||||
---
|
||||
...ttings-daemon.plugins.power.gschema.xml.in | 5 +
|
||||
plugins/power/gsd-power-manager.c | 128 ++++++++++++++++++
|
||||
plugins/power/test.py | 32 +++++
|
||||
3 files changed, 165 insertions(+)
|
||||
|
||||
diff --git a/data/org.gnome.settings-daemon.plugins.power.gschema.xml.in b/data/org.gnome.settings-daemon.plugins.power.gschema.xml.in
|
||||
index 93c704e9..04b287bd 100644
|
||||
--- a/data/org.gnome.settings-daemon.plugins.power.gschema.xml.in
|
||||
+++ b/data/org.gnome.settings-daemon.plugins.power.gschema.xml.in
|
||||
@@ -41,5 +41,10 @@
|
||||
<summary>Power button action</summary>
|
||||
<description>The action to take when the system power button is pressed. This action is hard-coded (and the setting ignored) on virtual machines (power off) and tablets (suspend).</description>
|
||||
</key>
|
||||
+ <key name="power-saver-profile-on-low-battery" type="b">
|
||||
+ <default>true</default>
|
||||
+ <summary>Enable power-saver profile when battery is low</summary>
|
||||
+ <description>Automatically enable the "power-saver" profile using power-profiles-daemon if the battery is low.</description>
|
||||
+ </key>
|
||||
</schema>
|
||||
</schemalist>
|
||||
diff --git a/plugins/power/gsd-power-manager.c b/plugins/power/gsd-power-manager.c
|
||||
index 95cec9c3..1f125a6f 100644
|
||||
--- a/plugins/power/gsd-power-manager.c
|
||||
+++ b/plugins/power/gsd-power-manager.c
|
||||
@@ -59,6 +59,10 @@
|
||||
#define UPOWER_DBUS_INTERFACE "org.freedesktop.UPower"
|
||||
#define UPOWER_DBUS_INTERFACE_KBDBACKLIGHT "org.freedesktop.UPower.KbdBacklight"
|
||||
|
||||
+#define PPD_DBUS_NAME "net.hadess.PowerProfiles"
|
||||
+#define PPD_DBUS_PATH "/net/hadess/PowerProfiles"
|
||||
+#define PPD_DBUS_INTERFACE "net.hadess.PowerProfiles"
|
||||
+
|
||||
#define GSD_POWER_SETTINGS_SCHEMA "org.gnome.settings-daemon.plugins.power"
|
||||
|
||||
#define GSD_POWER_DBUS_NAME GSD_DBUS_NAME ".Power"
|
||||
@@ -185,6 +189,10 @@ struct _GsdPowerManager
|
||||
gdouble ambient_last_absolute;
|
||||
gint64 ambient_last_time;
|
||||
|
||||
+ /* Power Profiles */
|
||||
+ GDBusProxy *power_profiles_proxy;
|
||||
+ guint32 power_saver_cookie;
|
||||
+
|
||||
/* Sound */
|
||||
guint32 critical_alert_timeout_id;
|
||||
|
||||
@@ -1927,6 +1935,67 @@ idle_configure (GsdPowerManager *manager)
|
||||
}
|
||||
}
|
||||
|
||||
+static void
|
||||
+hold_profile_cb (GObject *source_object,
|
||||
+ GAsyncResult *res,
|
||||
+ gpointer user_data)
|
||||
+{
|
||||
+ GsdPowerManager *manager = user_data;
|
||||
+ g_autoptr(GError) error = NULL;
|
||||
+ g_autoptr(GVariant) result = NULL;
|
||||
+
|
||||
+ result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object),
|
||||
+ res,
|
||||
+ &error);
|
||||
+ if (result == NULL) {
|
||||
+ g_warning ("Couldn't hold power-saver profile: %s", error->message);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (g_variant_is_of_type (result, G_VARIANT_TYPE ("(u)"))) {
|
||||
+ g_variant_get (result, "(u)", &manager->power_saver_cookie);
|
||||
+ g_debug ("Holding power-saver profile with cookie %u", manager->power_saver_cookie);
|
||||
+ } else {
|
||||
+ g_warning ("Calling HoldProfile() did not return a uint32");
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+enable_power_saver (GsdPowerManager *manager)
|
||||
+{
|
||||
+ if (!manager->power_profiles_proxy)
|
||||
+ return;
|
||||
+ if (!g_settings_get_boolean (manager->settings, "power-saver-profile-on-low-battery"))
|
||||
+ return;
|
||||
+
|
||||
+ g_debug ("Starting hold of power-saver profile");
|
||||
+
|
||||
+ g_dbus_proxy_call (manager->power_profiles_proxy,
|
||||
+ "HoldProfile",
|
||||
+ g_variant_new("(sss)",
|
||||
+ "power-saver",
|
||||
+ "Power saver profile when low on battery",
|
||||
+ GSD_POWER_DBUS_NAME),
|
||||
+ G_DBUS_CALL_FLAGS_NONE,
|
||||
+ -1, manager->cancellable, hold_profile_cb, manager);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+disable_power_saver (GsdPowerManager *manager)
|
||||
+{
|
||||
+ if (!manager->power_profiles_proxy || manager->power_saver_cookie == 0)
|
||||
+ return;
|
||||
+
|
||||
+ g_debug ("Releasing power-saver profile");
|
||||
+
|
||||
+ g_dbus_proxy_call (manager->power_profiles_proxy,
|
||||
+ "ReleaseProfile",
|
||||
+ g_variant_new ("(u)", manager->power_saver_cookie),
|
||||
+ G_DBUS_CALL_FLAGS_NONE,
|
||||
+ -1, NULL, dbus_call_log_error, "ReleaseProfile failed");
|
||||
+ manager->power_saver_cookie = 0;
|
||||
+}
|
||||
+
|
||||
static void
|
||||
main_battery_or_ups_low_changed (GsdPowerManager *manager,
|
||||
gboolean is_low)
|
||||
@@ -1935,6 +2004,10 @@ main_battery_or_ups_low_changed (GsdPowerManager *manager,
|
||||
return;
|
||||
manager->battery_is_low = is_low;
|
||||
idle_configure (manager);
|
||||
+ if (is_low)
|
||||
+ enable_power_saver (manager);
|
||||
+ else
|
||||
+ disable_power_saver (manager);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -2078,6 +2151,39 @@ screensaver_signal_cb (GDBusProxy *proxy,
|
||||
handle_wake_up_screen (GSD_POWER_MANAGER (user_data));
|
||||
}
|
||||
|
||||
+static void
|
||||
+power_profiles_proxy_signal_cb (GDBusProxy *proxy,
|
||||
+ const gchar *sender_name,
|
||||
+ const gchar *signal_name,
|
||||
+ GVariant *parameters,
|
||||
+ gpointer user_data)
|
||||
+{
|
||||
+ GsdPowerManager *manager = GSD_POWER_MANAGER (user_data);
|
||||
+
|
||||
+ if (g_strcmp0 (signal_name, "ProfileReleased") != 0)
|
||||
+ return;
|
||||
+ manager->power_saver_cookie = 0;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+power_profiles_proxy_ready_cb (GObject *source_object,
|
||||
+ GAsyncResult *res,
|
||||
+ gpointer user_data)
|
||||
+{
|
||||
+ g_autoptr(GError) error = NULL;
|
||||
+ GsdPowerManager *manager = GSD_POWER_MANAGER (user_data);
|
||||
+
|
||||
+ manager->power_profiles_proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
|
||||
+ if (manager->power_profiles_proxy == NULL) {
|
||||
+ g_debug ("Could not connect to power-profiles-daemon: %s", error->message);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ g_signal_connect (manager->power_profiles_proxy, "g-signal",
|
||||
+ G_CALLBACK (power_profiles_proxy_signal_cb),
|
||||
+ manager);
|
||||
+}
|
||||
+
|
||||
static void
|
||||
power_keyboard_proxy_ready_cb (GObject *source_object,
|
||||
GAsyncResult *res,
|
||||
@@ -2289,6 +2395,14 @@ engine_settings_key_changed_cb (GSettings *settings,
|
||||
idle_configure (manager);
|
||||
return;
|
||||
}
|
||||
+ if (g_str_equal (key, "power-saver-profile-on-low-battery")) {
|
||||
+ if (manager->battery_is_low &&
|
||||
+ g_settings_get_boolean (settings, key))
|
||||
+ enable_power_saver (manager);
|
||||
+ else
|
||||
+ disable_power_saver (manager);
|
||||
+ return;
|
||||
+ }
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2599,6 +2713,17 @@ on_rr_screen_acquired (GObject *object,
|
||||
g_signal_connect (manager->up_client, "notify::on-battery",
|
||||
G_CALLBACK (up_client_on_battery_cb), manager);
|
||||
|
||||
+ /* connect to power-profiles-daemon */
|
||||
+ g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM,
|
||||
+ G_DBUS_PROXY_FLAGS_NONE,
|
||||
+ NULL,
|
||||
+ PPD_DBUS_NAME,
|
||||
+ PPD_DBUS_PATH,
|
||||
+ PPD_DBUS_INTERFACE,
|
||||
+ manager->cancellable,
|
||||
+ power_profiles_proxy_ready_cb,
|
||||
+ manager);
|
||||
+
|
||||
/* connect to UPower for keyboard backlight control */
|
||||
manager->kbd_brightness_now = -1;
|
||||
g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM,
|
||||
@@ -2862,6 +2987,9 @@ gsd_power_manager_stop (GsdPowerManager *manager)
|
||||
|
||||
g_clear_object (&manager->screensaver_proxy);
|
||||
|
||||
+ disable_power_saver (manager);
|
||||
+ g_clear_object (&manager->power_profiles_proxy);
|
||||
+
|
||||
play_loop_stop (&manager->critical_alert_timeout_id);
|
||||
|
||||
g_clear_object (&manager->idle_monitor);
|
||||
diff --git a/plugins/power/test.py b/plugins/power/test.py
|
||||
index bb5861a4..f554400e 100755
|
||||
--- a/plugins/power/test.py
|
||||
+++ b/plugins/power/test.py
|
||||
@@ -76,6 +76,13 @@ class PowerPluginBase(gsdtestcase.GSDTestCase):
|
||||
'gnome_screensaver', stdout=subprocess.PIPE)
|
||||
gsdtestcase.set_nonblock(self.screensaver.stdout)
|
||||
|
||||
+ # start mock power-profiles-daemon
|
||||
+ try:
|
||||
+ (self.ppd, self.obj_ppd) = self.spawn_server_template('power_profiles_daemon')
|
||||
+ self.addCleanup(self.stop_process, self.ppd)
|
||||
+ except ModuleNotFoundError:
|
||||
+ self.ppd = None
|
||||
+
|
||||
self.session_log = OutputChecker()
|
||||
self.session = subprocess.Popen(['gnome-session', '-f',
|
||||
'-a', os.path.join(self.workdir, 'autostart'),
|
||||
@@ -1302,5 +1309,30 @@ class PowerPluginTest8(PowerPluginBase):
|
||||
|
||||
self.assertEqual(exc.exception.get_dbus_message(), 'No usable backlight could be found!')
|
||||
|
||||
+ def test_power_saver_on_low_battery(self):
|
||||
+ '''Check that the power-saver profile gets held when low on battery'''
|
||||
+
|
||||
+ if not self.ppd:
|
||||
+ self.skipTest("power-profiles-daemon dbusmock support is not available")
|
||||
+
|
||||
+ obj_props = dbus.Interface(self.obj_ppd, dbus.PROPERTIES_IFACE)
|
||||
+
|
||||
+ self.set_composite_battery_discharging()
|
||||
+ time.sleep(0.5)
|
||||
+ holds = obj_props.Get('net.hadess.PowerProfiles', 'ActiveProfileHolds')
|
||||
+ self.assertEqual(len(holds), 0)
|
||||
+
|
||||
+ self.set_composite_battery_critical()
|
||||
+ time.sleep(0.5)
|
||||
+ holds = obj_props.Get('net.hadess.PowerProfiles', 'ActiveProfileHolds')
|
||||
+ self.assertEqual(len(holds), 1)
|
||||
+ self.assertEqual(holds[0]['Profile'], 'power-saver')
|
||||
+ self.assertEqual(holds[0]['ApplicationId'], 'org.gnome.SettingsDaemon.Power')
|
||||
+
|
||||
+ self.set_composite_battery_discharging()
|
||||
+ time.sleep(0.5)
|
||||
+ holds = obj_props.Get('net.hadess.PowerProfiles', 'ActiveProfileHolds')
|
||||
+ self.assertEqual(len(holds), 0)
|
||||
+
|
||||
# avoid writing to stderr
|
||||
unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout, verbosity=2))
|
||||
--
|
||||
2.31.1
|
||||
|
||||
|
||||
From 74ed476d1a37a43eeba8c8bee8f5be5d499b0805 Mon Sep 17 00:00:00 2001
|
||||
From: Bastien Nocera <hadess@hadess.net>
|
||||
Date: Wed, 28 Jul 2021 16:40:24 +0200
|
||||
Subject: [PATCH 2/4] power: Dim screen faster if power saver mode is on
|
||||
|
||||
As done on other platforms, aggressively dim the screen after a
|
||||
short period when the user has selected to enter power saver mode.
|
||||
|
||||
The same aggressive screen dim will be used if the battery is low and
|
||||
power-profiles-daemon is not available. If it is available, then it
|
||||
fixes a screen dim happening when the battery was low which might
|
||||
have been unwanted.
|
||||
|
||||
See https://gitlab.gnome.org/GNOME/gnome-control-center/-/issues/232
|
||||
|
||||
Prior art:
|
||||
https://support.apple.com/en-us/HT205234
|
||||
---
|
||||
plugins/power/gsd-power-manager.c | 46 +++++++++++++++++++++++++++++--
|
||||
1 file changed, 44 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/plugins/power/gsd-power-manager.c b/plugins/power/gsd-power-manager.c
|
||||
index 1f125a6f..cfef9718 100644
|
||||
--- a/plugins/power/gsd-power-manager.c
|
||||
+++ b/plugins/power/gsd-power-manager.c
|
||||
@@ -192,6 +192,7 @@ struct _GsdPowerManager
|
||||
/* Power Profiles */
|
||||
GDBusProxy *power_profiles_proxy;
|
||||
guint32 power_saver_cookie;
|
||||
+ gboolean power_saver_enabled;
|
||||
|
||||
/* Sound */
|
||||
guint32 critical_alert_timeout_id;
|
||||
@@ -1780,6 +1781,20 @@ clear_idle_watch (GnomeIdleMonitor *monitor,
|
||||
*id = 0;
|
||||
}
|
||||
|
||||
+static gboolean
|
||||
+is_power_save_active (GsdPowerManager *manager)
|
||||
+{
|
||||
+ /*
|
||||
+ * If we have power-profiles-daemon, then we follow its setting,
|
||||
+ * otherwise we go into power-save mode when the battery is low.
|
||||
+ */
|
||||
+ if (manager->power_profiles_proxy &&
|
||||
+ g_dbus_proxy_get_name_owner (manager->power_profiles_proxy))
|
||||
+ return manager->power_saver_enabled;
|
||||
+ else
|
||||
+ return manager->battery_is_low;
|
||||
+}
|
||||
+
|
||||
static void
|
||||
idle_configure (GsdPowerManager *manager)
|
||||
{
|
||||
@@ -1903,8 +1918,8 @@ idle_configure (GsdPowerManager *manager)
|
||||
/* Don't dim when the screen lock is active */
|
||||
} else if (!on_battery) {
|
||||
/* Don't dim when charging */
|
||||
- } else if (manager->battery_is_low) {
|
||||
- /* Aggressively blank when battery is low */
|
||||
+ } else if (is_power_save_active (manager)) {
|
||||
+ /* Try to save power by dimming agressively */
|
||||
timeout_dim = SCREENSAVER_TIMEOUT_BLANK;
|
||||
} else {
|
||||
if (g_settings_get_boolean (manager->settings, "idle-dim")) {
|
||||
@@ -2165,6 +2180,27 @@ power_profiles_proxy_signal_cb (GDBusProxy *proxy,
|
||||
manager->power_saver_cookie = 0;
|
||||
}
|
||||
|
||||
+static void
|
||||
+update_active_power_profile (GsdPowerManager *manager)
|
||||
+{
|
||||
+ g_autoptr(GVariant) v = NULL;
|
||||
+ const char *active_profile;
|
||||
+ gboolean power_saver_enabled;
|
||||
+
|
||||
+ v = g_dbus_proxy_get_cached_property (manager->power_profiles_proxy, "ActiveProfile");
|
||||
+ if (v) {
|
||||
+ active_profile = g_variant_get_string (v, NULL);
|
||||
+ power_saver_enabled = g_strcmp0 (active_profile, "power-saver") == 0;
|
||||
+ if (power_saver_enabled != manager->power_saver_enabled) {
|
||||
+ manager->power_saver_enabled = power_saver_enabled;
|
||||
+ idle_configure (manager);
|
||||
+ }
|
||||
+ } else {
|
||||
+ /* p-p-d might have disappeared from the bus */
|
||||
+ idle_configure (manager);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void
|
||||
power_profiles_proxy_ready_cb (GObject *source_object,
|
||||
GAsyncResult *res,
|
||||
@@ -2179,9 +2215,15 @@ power_profiles_proxy_ready_cb (GObject *source_object,
|
||||
return;
|
||||
}
|
||||
|
||||
+ g_signal_connect_swapped (manager->power_profiles_proxy,
|
||||
+ "g-properties-changed",
|
||||
+ G_CALLBACK (update_active_power_profile),
|
||||
+ manager);
|
||||
g_signal_connect (manager->power_profiles_proxy, "g-signal",
|
||||
G_CALLBACK (power_profiles_proxy_signal_cb),
|
||||
manager);
|
||||
+
|
||||
+ update_active_power_profile (manager);
|
||||
}
|
||||
|
||||
static void
|
||||
--
|
||||
2.31.1
|
||||
|
||||
|
||||
From 89e25ed7871258aa6df7f824e226a7b8a28f23f3 Mon Sep 17 00:00:00 2001
|
||||
From: Bastien Nocera <hadess@hadess.net>
|
||||
Date: Thu, 29 Jul 2021 12:05:40 +0200
|
||||
Subject: [PATCH 3/4] power: Respect dim screen settings when not on battery
|
||||
|
||||
The dim screen settings in the UI was not well respected as it only
|
||||
worked on discharging laptops.
|
||||
|
||||
Closes: https://gitlab.gnome.org/GNOME/gnome-control-center/-/issues/837
|
||||
---
|
||||
plugins/power/gsd-power-manager.c | 2 --
|
||||
1 file changed, 2 deletions(-)
|
||||
|
||||
diff --git a/plugins/power/gsd-power-manager.c b/plugins/power/gsd-power-manager.c
|
||||
index cfef9718..e7b9752f 100644
|
||||
--- a/plugins/power/gsd-power-manager.c
|
||||
+++ b/plugins/power/gsd-power-manager.c
|
||||
@@ -1916,8 +1916,6 @@ idle_configure (GsdPowerManager *manager)
|
||||
timeout_dim = 0;
|
||||
if (manager->screensaver_active) {
|
||||
/* Don't dim when the screen lock is active */
|
||||
- } else if (!on_battery) {
|
||||
- /* Don't dim when charging */
|
||||
} else if (is_power_save_active (manager)) {
|
||||
/* Try to save power by dimming agressively */
|
||||
timeout_dim = SCREENSAVER_TIMEOUT_BLANK;
|
||||
--
|
||||
2.31.1
|
||||
|
||||
|
||||
From f91abc0033b9cf17fd0e171cb7d652f88edac294 Mon Sep 17 00:00:00 2001
|
||||
From: Bastien Nocera <hadess@hadess.net>
|
||||
Date: Mon, 9 Aug 2021 17:57:11 +0200
|
||||
Subject: [PATCH 4/4] power: When dimming the screen, dim it quicker by default
|
||||
|
||||
Now that we respect the "dim when idle" setting[1], dim quicker to try
|
||||
and save more power. 4/5 of the timeout to the screensaver was always a
|
||||
bit too undecided as a fraction, even when using the dimming as a
|
||||
warning that the screen was going to go to the screensaver (see commit
|
||||
7bc750a5).
|
||||
|
||||
[1]: Except in power-saver mode where we always dim aggressively
|
||||
---
|
||||
plugins/power/gsd-power-constants.h | 2 +-
|
||||
plugins/power/gsdpowerconstants.py | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/plugins/power/gsd-power-constants.h b/plugins/power/gsd-power-constants.h
|
||||
index 91e2296a..8bf9c641 100644
|
||||
--- a/plugins/power/gsd-power-constants.h
|
||||
+++ b/plugins/power/gsd-power-constants.h
|
||||
@@ -25,7 +25,7 @@
|
||||
#define IDLE_DIM_BLANK_DISABLED_MIN 60 /* seconds */
|
||||
|
||||
/* Which fraction of the idle-delay is the idle-dim delay */
|
||||
-#define IDLE_DELAY_TO_IDLE_DIM_MULTIPLIER 4.0/5.0
|
||||
+#define IDLE_DELAY_TO_IDLE_DIM_MULTIPLIER 1.0/2.0
|
||||
|
||||
/* The dim delay under which we do not bother dimming */
|
||||
#define MINIMUM_IDLE_DIM_DELAY 10 /* seconds */
|
||||
diff --git a/plugins/power/gsdpowerconstants.py b/plugins/power/gsdpowerconstants.py
|
||||
index a07798ee..26fa5bfc 100644
|
||||
--- a/plugins/power/gsdpowerconstants.py
|
||||
+++ b/plugins/power/gsdpowerconstants.py
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
SCREENSAVER_TIMEOUT_BLANK = 15;
|
||||
IDLE_DIM_BLANK_DISABLED_MIN = 60;
|
||||
-IDLE_DELAY_TO_IDLE_DIM_MULTIPLIER = 4.0/5.0;
|
||||
+IDLE_DELAY_TO_IDLE_DIM_MULTIPLIER = 1.0/2.0;
|
||||
MINIMUM_IDLE_DIM_DELAY = 10;
|
||||
POWER_UP_TIME_ON_AC = 15;
|
||||
GSD_MOCK_DEFAULT_BRIGHTNESS = 50;
|
||||
--
|
||||
2.31.1
|
||||
|
@ -0,0 +1,53 @@
|
||||
From fbe9b7dba44cb284f649a1e916b2cf3ce8281211 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Berg <bberg@redhat.com>
|
||||
Date: Tue, 7 May 2019 15:40:20 +0200
|
||||
Subject: [PATCH] power: Only disable Suspend/Hibernate actions inside VM
|
||||
|
||||
While we theoretically only want a different default value inside a VM,
|
||||
we currently hack this by never doing a suspend action inside VMs.
|
||||
However, that also breaks automatic logout, which is an unintended side
|
||||
effect.
|
||||
|
||||
Move the check to not install the corresponding timeout (preventing
|
||||
sleep warnings from being displayed) and also only enforce the VM
|
||||
specific hack for the Suspend and Hibernate actions.
|
||||
---
|
||||
plugins/power/gsd-power-manager.c | 15 ++++++++-------
|
||||
1 file changed, 8 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/plugins/power/gsd-power-manager.c b/plugins/power/gsd-power-manager.c
|
||||
index f965f6f..dbaa262 100644
|
||||
--- a/plugins/power/gsd-power-manager.c
|
||||
+++ b/plugins/power/gsd-power-manager.c
|
||||
@@ -1520,13 +1520,6 @@ idle_set_mode (GsdPowerManager *manager, GsdPowerIdleMode mode)
|
||||
return;
|
||||
}
|
||||
|
||||
- /* don't do any power saving if we're a VM */
|
||||
- if (manager->priv->is_virtual_machine) {
|
||||
- g_debug ("ignoring state transition to %s as virtual machine",
|
||||
- idle_mode_to_string (mode));
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
manager->priv->current_idle_mode = mode;
|
||||
g_debug ("Doing a state transition: %s", idle_mode_to_string (mode));
|
||||
|
||||
@@ -1727,6 +1720,14 @@ idle_configure (GsdPowerManager *manager)
|
||||
clear_idle_watch (manager->priv->idle_monitor,
|
||||
&manager->priv->idle_sleep_warning_id);
|
||||
|
||||
+ /* don't do any power saving if we're a VM */
|
||||
+ if (manager->priv->is_virtual_machine &&
|
||||
+ (action_type == GSD_POWER_ACTION_SUSPEND ||
|
||||
+ action_type == GSD_POWER_ACTION_HIBERNATE)) {
|
||||
+ g_debug ("Ignoring sleep timeout with suspend action inside VM");
|
||||
+ timeout_sleep = 0;
|
||||
+ }
|
||||
+
|
||||
if (timeout_sleep != 0) {
|
||||
g_debug ("setting up sleep callback %is", timeout_sleep);
|
||||
|
||||
--
|
||||
2.31.1
|
||||
|
@ -1,6 +1,6 @@
|
||||
From f71fb47c3f783f3405bd910e1e170dc5e1f10e7c Mon Sep 17 00:00:00 2001
|
||||
From 0e2c4aec104b65d2f8ea7167269e91c303908a6f Mon Sep 17 00:00:00 2001
|
||||
From: Felipe Borges <felipeborges@gnome.org>
|
||||
Date: Wed, 4 Jan 2023 13:41:31 +0100
|
||||
Date: Wed, 4 Jan 2023 15:30:15 +0100
|
||||
Subject: [PATCH] power: Respect the "nothing" power-button-action for VMs
|
||||
|
||||
There are use-cases when one wants to forcefully make the guest ignore
|
||||
@ -10,12 +10,12 @@ See https://bugzilla.redhat.com/2062051
|
||||
|
||||
See also https://gitlab.gnome.org/GNOME/gnome-settings-daemon/-/issues/46
|
||||
---
|
||||
....gnome.settings-daemon.plugins.power.gschema.xml.in | 2 +-
|
||||
plugins/media-keys/gsd-media-keys-manager.c | 10 +++++++---
|
||||
2 files changed, 8 insertions(+), 4 deletions(-)
|
||||
...org.gnome.settings-daemon.plugins.power.gschema.xml.in | 2 +-
|
||||
plugins/media-keys/gsd-media-keys-manager.c | 8 +++++---
|
||||
2 files changed, 6 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/data/org.gnome.settings-daemon.plugins.power.gschema.xml.in b/data/org.gnome.settings-daemon.plugins.power.gschema.xml.in
|
||||
index 04b287bd..e1a8787b 100644
|
||||
index 93c704e9..fc61d133 100644
|
||||
--- a/data/org.gnome.settings-daemon.plugins.power.gschema.xml.in
|
||||
+++ b/data/org.gnome.settings-daemon.plugins.power.gschema.xml.in
|
||||
@@ -39,7 +39,7 @@
|
||||
@ -25,30 +25,32 @@ index 04b287bd..e1a8787b 100644
|
||||
- <description>The action to take when the system power button is pressed. This action is hard-coded (and the setting ignored) on virtual machines (power off) and tablets (suspend).</description>
|
||||
+ <description>The action to take when the system power button is pressed. Virtual machines only honor the 'nothing' action, and will shutdown otherwise. Tablets always suspend, ignoring all the other action options.</description>
|
||||
</key>
|
||||
<key name="power-saver-profile-on-low-battery" type="b">
|
||||
<default>true</default>
|
||||
</schema>
|
||||
</schemalist>
|
||||
diff --git a/plugins/media-keys/gsd-media-keys-manager.c b/plugins/media-keys/gsd-media-keys-manager.c
|
||||
index 15e96e0e..60ff2ced 100644
|
||||
index a526d5cf..ac6f7ab4 100644
|
||||
--- a/plugins/media-keys/gsd-media-keys-manager.c
|
||||
+++ b/plugins/media-keys/gsd-media-keys-manager.c
|
||||
@@ -2041,13 +2041,17 @@ do_config_power_button_action (GsdMediaKeysManager *manager,
|
||||
if (priv->power_button_disabled)
|
||||
@@ -2083,9 +2083,12 @@ do_config_power_button_action (GsdMediaKeysManager *manager,
|
||||
if (manager->priv->power_button_disabled)
|
||||
return;
|
||||
|
||||
- /* Always power off VMs when power off is pressed in the menus */
|
||||
+ action_type = g_settings_get_enum (priv->power_settings, "power-button-action");
|
||||
+ action_type = g_settings_get_enum (manager->priv->power_settings, "power-button-action");
|
||||
+ /* Always power off VMs, except when power-button-action is "nothing" */
|
||||
if (g_strcmp0 (priv->chassis_type, "vm") == 0) {
|
||||
if (g_strcmp0 (manager->priv->chassis_type, "vm") == 0) {
|
||||
- power_action (manager, "PowerOff", !in_lock_screen);
|
||||
+ g_warning_once ("Virtual machines only honor the 'nothing' power-button-action, and will shutdown otherwise");
|
||||
+
|
||||
+ if (action_type != GSD_POWER_BUTTON_ACTION_NOTHING)
|
||||
+ power_action (manager, "PowerOff", FALSE);
|
||||
+ power_action (manager, "PowerOff", !in_lock_screen);
|
||||
+
|
||||
return;
|
||||
}
|
||||
|
||||
- action_type = g_settings_get_enum (priv->power_settings, "power-button-action");
|
||||
@@ -2095,7 +2098,6 @@ do_config_power_button_action (GsdMediaKeysManager *manager,
|
||||
return;
|
||||
}
|
||||
|
||||
- action_type = g_settings_get_enum (manager->priv->power_settings, "power-button-action");
|
||||
switch (action_type) {
|
||||
case GSD_POWER_BUTTON_ACTION_SUSPEND:
|
||||
action = GSD_POWER_ACTION_SUSPEND;
|
||||
|
@ -0,0 +1,58 @@
|
||||
From a1c2685bc6b255f22b6ce4645c001d428cb67907 Mon Sep 17 00:00:00 2001
|
||||
From: Marek Kasik <mkasik@redhat.com>
|
||||
Date: Wed, 22 May 2019 14:56:42 +0200
|
||||
Subject: [PATCH] smartcard: Cancel cancellable when stopping
|
||||
|
||||
self->cancellable in GsdSmartcardManager is not cancelled
|
||||
at gsd_smartcard_manager_stop() and hence some callbacks are
|
||||
still called after unload_nss() which clears SECMODListLock
|
||||
which is used by SECMOD_GetReadLock() / SECMOD_ReleaseReadLock().
|
||||
|
||||
This leads to crashes in NSSRWLock_LockRead_Util() and
|
||||
NSSRWLock_UnlockRead_Util() probably.
|
||||
|
||||
Also check for return value of g_cancellable_connect()
|
||||
and initialize pointer to PK11SlotInfo.
|
||||
|
||||
See https://bugzilla.redhat.com/show_bug.cgi?id=1646359,
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=1688791 and
|
||||
their duplicates for additional info.
|
||||
---
|
||||
plugins/smartcard/gsd-smartcard-manager.c | 7 +++++--
|
||||
1 file changed, 5 insertions(+), 2 deletion(-)
|
||||
|
||||
diff --git a/plugins/smartcard/gsd-smartcard-manager.c b/plugins/smartcard/gsd-smartcard-manager.c
|
||||
index 014c17be..da1e0d6d 100644
|
||||
--- a/plugins/smartcard/gsd-smartcard-manager.c
|
||||
+++ b/plugins/smartcard/gsd-smartcard-manager.c
|
||||
@@ -184,7 +184,7 @@
|
||||
GError **error)
|
||||
{
|
||||
GsdSmartcardManagerPrivate *priv = self->priv;
|
||||
- PK11SlotInfo *card, *old_card;
|
||||
+ PK11SlotInfo *card = NULL, *old_card;
|
||||
CK_SLOT_ID slot_id;
|
||||
gulong handler_id;
|
||||
int old_slot_series = -1, slot_series;
|
||||
@@ -190,7 +190,8 @@ watch_one_event_from_driver (GsdSmartcardManager *self,
|
||||
operation,
|
||||
NULL);
|
||||
|
||||
- card = SECMOD_WaitForAnyTokenEvent (operation->driver, 0, PR_SecondsToInterval (1));
|
||||
+ if (handler_id != 0)
|
||||
+ card = SECMOD_WaitForAnyTokenEvent (operation->driver, 0, PR_SecondsToInterval (1));
|
||||
|
||||
g_cancellable_disconnect (cancellable, handler_id);
|
||||
|
||||
@@ -773,6 +774,8 @@ gsd_smartcard_manager_stop (GsdSmartcardManager *self)
|
||||
|
||||
g_debug ("Stopping smartcard manager");
|
||||
|
||||
+ g_cancellable_cancel (priv->cancellable);
|
||||
+
|
||||
unload_nss (self);
|
||||
|
||||
g_clear_object (&priv->settings);
|
||||
--
|
||||
2.23.0
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,25 @@
|
||||
From 6e790966c2b6e1db8dd2c145119d3fdd19e0c18f Mon Sep 17 00:00:00 2001
|
||||
From: Matthias Clasen <mclasen@redhat.com>
|
||||
Date: Wed, 22 May 2019 16:04:42 -0400
|
||||
Subject: [PATCH] xsettings: Add an entry for the overlay scrolling setting
|
||||
|
||||
This will be used by GTK.
|
||||
---
|
||||
plugins/xsettings/gsd-xsettings-manager.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/plugins/xsettings/gsd-xsettings-manager.c b/plugins/xsettings/gsd-xsettings-manager.c
|
||||
index c3ac7892..4164de40 100644
|
||||
--- a/plugins/xsettings/gsd-xsettings-manager.c
|
||||
+++ b/plugins/xsettings/gsd-xsettings-manager.c
|
||||
@@ -478,6 +478,7 @@ static TranslationEntry translations [] = {
|
||||
{ "org.gnome.desktop.interface", "icon-theme", "Net/IconThemeName", translate_string_string },
|
||||
{ "org.gnome.desktop.interface", "cursor-theme", "Gtk/CursorThemeName", translate_string_string },
|
||||
{ "org.gnome.desktop.interface", "gtk-enable-primary-paste", "Gtk/EnablePrimaryPaste", translate_bool_int },
|
||||
+ { "org.gnome.desktop.interface", "overlay-scrolling", "Gtk/OverlayScrolling", translate_bool_int },
|
||||
/* cursor-size is handled via the Xft side as it needs the scaling factor */
|
||||
|
||||
{ "org.gnome.desktop.sound", "theme-name", "Net/SoundThemeName", translate_string_string },
|
||||
--
|
||||
2.23.0
|
||||
|
@ -0,0 +1,271 @@
|
||||
From ad0fd6c905011b7bb9eac9fa8cb91f58d71e4a29 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Mon, 6 Nov 2017 15:49:58 -0500
|
||||
Subject: [PATCH 2/4] account: reshow the notification when screen unlocks
|
||||
|
||||
---
|
||||
plugins/account/gsd-account-manager.c | 48 ++++++++++++++++++++++++---
|
||||
1 file changed, 43 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/plugins/account/gsd-account-manager.c b/plugins/account/gsd-account-manager.c
|
||||
index 40b91cb6..cb37f466 100644
|
||||
--- a/plugins/account/gsd-account-manager.c
|
||||
+++ b/plugins/account/gsd-account-manager.c
|
||||
@@ -11,72 +11,75 @@
|
||||
* 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 <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <locale.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <glib/gstdio.h>
|
||||
|
||||
#include <cups/cups.h>
|
||||
#include <cups/ppd.h>
|
||||
#include <libnotify/notify.h>
|
||||
|
||||
#include "gnome-settings-profile.h"
|
||||
+#include "gnome-settings-bus.h"
|
||||
#include "gsd-account-manager.h"
|
||||
#include "org.freedesktop.Accounts.h"
|
||||
#include "org.freedesktop.Accounts.User.h"
|
||||
|
||||
#define GSD_ACCOUNT_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_ACCOUNT_MANAGER, GsdAccountManagerPrivate))
|
||||
|
||||
struct GsdAccountManagerPrivate
|
||||
{
|
||||
GsdAccounts *accounts_proxy;
|
||||
GsdAccountsUser *accounts_user_proxy;
|
||||
GCancellable *cancellable;
|
||||
|
||||
+ GsdScreenSaver *screensaver_proxy;
|
||||
+
|
||||
gint64 expiration_time;
|
||||
gint64 last_change_time;
|
||||
gint64 min_days_between_changes;
|
||||
gint64 max_days_between_changes;
|
||||
gint64 days_to_warn;
|
||||
gint64 days_after_expiration_until_lock;
|
||||
|
||||
NotifyNotification *notification;
|
||||
};
|
||||
|
||||
static void gsd_account_manager_class_init (GsdAccountManagerClass *klass);
|
||||
static void gsd_account_manager_init (GsdAccountManager *account_manager);
|
||||
static void gsd_account_manager_finalize (GObject *object);
|
||||
|
||||
G_DEFINE_TYPE (GsdAccountManager, gsd_account_manager, G_TYPE_OBJECT)
|
||||
|
||||
static gpointer manager_object = NULL;
|
||||
|
||||
static void
|
||||
on_notification_closed (NotifyNotification *notification,
|
||||
gpointer user_data)
|
||||
{
|
||||
GsdAccountManager *manager = user_data;
|
||||
|
||||
g_clear_object (&manager->priv->notification);
|
||||
}
|
||||
|
||||
static void
|
||||
hide_notification (GsdAccountManager *manager)
|
||||
{
|
||||
@@ -221,77 +224,111 @@ on_got_password_expiration_policy (GsdAccountsUser *accounts_user_proxy,
|
||||
gint64 days_after_expiration_until_lock;
|
||||
|
||||
gnome_settings_profile_start (NULL);
|
||||
succeeded = gsd_accounts_user_call_get_password_expiration_policy_finish (accounts_user_proxy,
|
||||
&expiration_time,
|
||||
&last_change_time,
|
||||
&min_days_between_changes,
|
||||
&max_days_between_changes,
|
||||
&days_to_warn,
|
||||
&days_after_expiration_until_lock,
|
||||
res,
|
||||
&error);
|
||||
|
||||
if (!succeeded) {
|
||||
g_warning ("Failed to get password expiration policy for user: %s", error->message);
|
||||
goto out;
|
||||
}
|
||||
|
||||
set_policy_number (&manager->priv->expiration_time, expiration_time);
|
||||
set_policy_number (&manager->priv->last_change_time, last_change_time);
|
||||
set_policy_number (&manager->priv->min_days_between_changes, min_days_between_changes);
|
||||
set_policy_number (&manager->priv->max_days_between_changes, max_days_between_changes);
|
||||
set_policy_number (&manager->priv->days_to_warn, days_to_warn);
|
||||
set_policy_number (&manager->priv->days_after_expiration_until_lock, days_after_expiration_until_lock);
|
||||
|
||||
update_password_notification (manager);
|
||||
out:
|
||||
gnome_settings_profile_end (NULL);
|
||||
}
|
||||
|
||||
+static void
|
||||
+fetch_password_expiration_policy (GsdAccountManager *manager)
|
||||
+{
|
||||
+ gsd_accounts_user_call_get_password_expiration_policy (manager->priv->accounts_user_proxy,
|
||||
+ manager->priv->cancellable,
|
||||
+ (GAsyncReadyCallback)
|
||||
+ on_got_password_expiration_policy,
|
||||
+ manager);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+on_screensaver_signal (GDBusProxy *proxy,
|
||||
+ const gchar *sender_name,
|
||||
+ const gchar *signal_name,
|
||||
+ GVariant *parameters,
|
||||
+ gpointer user_data)
|
||||
+{
|
||||
+ GsdAccountManager *manager = user_data;
|
||||
+
|
||||
+ if (g_strcmp0 (signal_name, "ActiveChanged") == 0) {
|
||||
+ gboolean active;
|
||||
+
|
||||
+ g_variant_get (parameters, "(b)", &active);
|
||||
+
|
||||
+ if (!active) {
|
||||
+ fetch_password_expiration_policy (manager);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void
|
||||
on_got_accounts_user_proxy (GObject *source_object,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
GsdAccountManager *manager = user_data;
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
gnome_settings_profile_start (NULL);
|
||||
manager->priv->accounts_user_proxy = gsd_accounts_user_proxy_new_finish (res, &error);
|
||||
|
||||
if (manager->priv->accounts_user_proxy != NULL) {
|
||||
- gsd_accounts_user_call_get_password_expiration_policy (manager->priv->accounts_user_proxy,
|
||||
- manager->priv->cancellable,
|
||||
- (GAsyncReadyCallback)
|
||||
- on_got_password_expiration_policy,
|
||||
- manager);
|
||||
+ fetch_password_expiration_policy (manager);
|
||||
+
|
||||
+ manager->priv->screensaver_proxy = gnome_settings_bus_get_screen_saver_proxy ();
|
||||
+
|
||||
+ g_signal_connect (manager->priv->screensaver_proxy,
|
||||
+ "g-signal",
|
||||
+ G_CALLBACK (on_screensaver_signal),
|
||||
+ manager);
|
||||
+
|
||||
} else {
|
||||
g_warning ("Failed to get user proxy to accounts service: %s", error->message);
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
gnome_settings_profile_end (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
on_got_user_object_path (GsdAccounts *accounts_proxy,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
GsdAccountManager *manager = user_data;
|
||||
g_autoptr(GError) error = NULL;
|
||||
gboolean succeeded;
|
||||
gchar *object_path;
|
||||
GDBusConnection *connection;
|
||||
|
||||
gnome_settings_profile_start (NULL);
|
||||
|
||||
succeeded = gsd_accounts_call_find_user_by_id_finish (accounts_proxy,
|
||||
&object_path,
|
||||
res,
|
||||
&error);
|
||||
|
||||
if (!succeeded) {
|
||||
g_warning ("Unable to find current user in accounts service: %s",
|
||||
error->message);
|
||||
@@ -343,60 +380,61 @@ gsd_account_manager_start (GsdAccountManager *manager,
|
||||
g_debug ("Starting accounts manager");
|
||||
|
||||
gnome_settings_profile_start (NULL);
|
||||
manager->priv->cancellable = g_cancellable_new ();
|
||||
gsd_accounts_proxy_new_for_bus (G_BUS_TYPE_SYSTEM,
|
||||
G_DBUS_PROXY_FLAGS_NONE,
|
||||
"org.freedesktop.Accounts",
|
||||
"/org/freedesktop/Accounts",
|
||||
manager->priv->cancellable,
|
||||
(GAsyncReadyCallback)
|
||||
on_got_accounts_proxy,
|
||||
manager);
|
||||
gnome_settings_profile_end (NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
gsd_account_manager_stop (GsdAccountManager *manager)
|
||||
{
|
||||
g_debug ("Stopping accounts manager");
|
||||
|
||||
if (manager->priv->cancellable != NULL) {
|
||||
g_cancellable_cancel (manager->priv->cancellable);
|
||||
g_clear_object (&manager->priv->cancellable);
|
||||
}
|
||||
|
||||
g_clear_object (&manager->priv->accounts_proxy);
|
||||
g_clear_object (&manager->priv->accounts_user_proxy);
|
||||
g_clear_object (&manager->priv->notification);
|
||||
+ g_clear_object (&manager->priv->screensaver_proxy);
|
||||
}
|
||||
|
||||
static void
|
||||
gsd_account_manager_class_init (GsdAccountManagerClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = gsd_account_manager_finalize;
|
||||
|
||||
notify_init ("gnome-settings-daemon");
|
||||
|
||||
g_type_class_add_private (klass, sizeof (GsdAccountManagerPrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
gsd_account_manager_init (GsdAccountManager *manager)
|
||||
{
|
||||
manager->priv = GSD_ACCOUNT_MANAGER_GET_PRIVATE (manager);
|
||||
}
|
||||
|
||||
static void
|
||||
gsd_account_manager_finalize (GObject *object)
|
||||
{
|
||||
GsdAccountManager *manager;
|
||||
|
||||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (GSD_IS_ACCOUNT_MANAGER (object));
|
||||
|
||||
manager = GSD_ACCOUNT_MANAGER (object);
|
||||
|
||||
--
|
||||
2.21.0
|
||||
|
@ -0,0 +1,49 @@
|
||||
From f2cd5fb30892e3868732fca1d38fc15fdb73ec18 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Berg <bberg@redhat.com>
|
||||
Date: Tue, 27 Oct 2020 10:20:34 +0100
|
||||
Subject: [PATCH 2/2] power: Never register sleep timeout for logout in GDM
|
||||
|
||||
We already suppress logout actions in GDM (10aa1714b05b, power: Avoid
|
||||
automatic logout in GDM/greeter). However, while this prevents the
|
||||
action, we may still warn.
|
||||
|
||||
Change it so that the corresponding timeouts will never be registered.
|
||||
Leave the guard in gnome_session_logout but add a warning as we should
|
||||
never be hitting that code path.
|
||||
---
|
||||
plugins/power/gsd-power-manager.c | 11 ++++++++++-
|
||||
1 file changed, 10 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/plugins/power/gsd-power-manager.c b/plugins/power/gsd-power-manager.c
|
||||
index 9f2e858e..ed855b6b 100644
|
||||
--- a/plugins/power/gsd-power-manager.c
|
||||
+++ b/plugins/power/gsd-power-manager.c
|
||||
@@ -872,8 +872,10 @@ static void
|
||||
gnome_session_logout (GsdPowerManager *manager,
|
||||
guint logout_mode)
|
||||
{
|
||||
- if (g_getenv("RUNNING_UNDER_GDM"))
|
||||
+ if (g_getenv ("RUNNING_UNDER_GDM")) {
|
||||
+ g_warning ("Prevented logout from GDM session! This indicates an issue in gsd-power.");
|
||||
return;
|
||||
+ }
|
||||
|
||||
g_dbus_proxy_call (G_DBUS_PROXY (manager->priv->session),
|
||||
"Logout",
|
||||
@@ -1773,6 +1775,13 @@ idle_configure (GsdPowerManager *manager)
|
||||
timeout_sleep = 0;
|
||||
}
|
||||
|
||||
+ /* don't do any automatic logout if we are in GDM */
|
||||
+ if (g_getenv ("RUNNING_UNDER_GDM") &&
|
||||
+ (action_type == GSD_POWER_ACTION_LOGOUT)) {
|
||||
+ g_debug ("Ignoring sleep timeout with logout action inside GDM");
|
||||
+ timeout_sleep = 0;
|
||||
+ }
|
||||
+
|
||||
if (timeout_sleep != 0) {
|
||||
g_debug ("setting up sleep callback %is", timeout_sleep);
|
||||
|
||||
--
|
||||
2.26.2
|
||||
|
@ -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
|
||||
|
451
SOURCES/0003-account-display-nag-screen-periodically.patch
Normal file
451
SOURCES/0003-account-display-nag-screen-periodically.patch
Normal file
@ -0,0 +1,451 @@
|
||||
From 31844edad70876e26ab995179bc67fb3b23a1793 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Mon, 6 Nov 2017 16:39:55 -0500
|
||||
Subject: [PATCH 3/4] account: display nag screen periodically
|
||||
|
||||
This is configurable via a gsettings key.
|
||||
---
|
||||
data/meson.build | 1 +
|
||||
...ings-daemon.plugins.account.gschema.xml.in | 9 +++
|
||||
plugins/account/gsd-account-manager.c | 55 +++++++++++++++++++
|
||||
3 files changed, 65 insertions(+)
|
||||
create mode 100644 data/org.gnome.settings-daemon.plugins.account.gschema.xml.in
|
||||
|
||||
diff --git a/data/meson.build b/data/meson.build
|
||||
index e93ba641..5a2cd5a7 100644
|
||||
--- a/data/meson.build
|
||||
+++ b/data/meson.build
|
||||
@@ -1,36 +1,37 @@
|
||||
data_inc = include_directories('.')
|
||||
|
||||
schemas = [
|
||||
'org.gnome.settings-daemon.peripherals.gschema.xml',
|
||||
'org.gnome.settings-daemon.peripherals.wacom.gschema.xml',
|
||||
'org.gnome.settings-daemon.plugins.gschema.xml',
|
||||
+ 'org.gnome.settings-daemon.plugins.account.gschema.xml',
|
||||
'org.gnome.settings-daemon.plugins.color.gschema.xml',
|
||||
'org.gnome.settings-daemon.plugins.housekeeping.gschema.xml',
|
||||
'org.gnome.settings-daemon.plugins.media-keys.gschema.xml',
|
||||
'org.gnome.settings-daemon.plugins.power.gschema.xml',
|
||||
'org.gnome.settings-daemon.plugins.sharing.gschema.xml',
|
||||
'org.gnome.settings-daemon.plugins.xsettings.gschema.xml'
|
||||
]
|
||||
|
||||
schema_conf = configuration_data()
|
||||
schema_conf.set('GETTEXT_PACKAGE', meson.project_name())
|
||||
|
||||
schemas_xml = []
|
||||
foreach schema: schemas
|
||||
schemas_xml += [configure_file(
|
||||
input: schema + '.in',
|
||||
output: schema,
|
||||
configuration: schema_conf,
|
||||
install: true,
|
||||
install_dir: gsd_schemadir
|
||||
)]
|
||||
endforeach
|
||||
|
||||
enums_header = files('gsd-enums.h')
|
||||
|
||||
mkenums = gnome.mkenums(
|
||||
'org.gnome.settings-daemon.enums.xml',
|
||||
sources: enums_header,
|
||||
comments: '<!-- @comment@ -->',
|
||||
fhead: '<schemalist>',
|
||||
vhead: ' <@type@ id="org.gnome.settings-daemon.@EnumName@">',
|
||||
diff --git a/data/org.gnome.settings-daemon.plugins.account.gschema.xml.in b/data/org.gnome.settings-daemon.plugins.account.gschema.xml.in
|
||||
new file mode 100644
|
||||
index 00000000..f3d59e81
|
||||
--- /dev/null
|
||||
+++ b/data/org.gnome.settings-daemon.plugins.account.gschema.xml.in
|
||||
@@ -0,0 +1,9 @@
|
||||
+<schemalist>
|
||||
+ <schema gettext-domain="@GETTEXT_PACKAGE@" id="org.gnome.settings-daemon.plugins.account" path="/org/gnome/settings-daemon/plugins/account/">
|
||||
+ <key name="notify-period" type="i">
|
||||
+ <default>1440</default>
|
||||
+ <summary>Time before repeated warning about account password expiration</summary>
|
||||
+ <description>If a user's account is expiring, a notification will get displayed periodically after the specified number of minutes</description>
|
||||
+ </key>
|
||||
+ </schema>
|
||||
+</schemalist>
|
||||
diff --git a/plugins/account/gsd-account-manager.c b/plugins/account/gsd-account-manager.c
|
||||
index cb37f466..ff054edd 100644
|
||||
--- a/plugins/account/gsd-account-manager.c
|
||||
+++ b/plugins/account/gsd-account-manager.c
|
||||
@@ -20,126 +20,135 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <locale.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <glib/gstdio.h>
|
||||
|
||||
#include <cups/cups.h>
|
||||
#include <cups/ppd.h>
|
||||
#include <libnotify/notify.h>
|
||||
|
||||
#include "gnome-settings-profile.h"
|
||||
#include "gnome-settings-bus.h"
|
||||
#include "gsd-account-manager.h"
|
||||
#include "org.freedesktop.Accounts.h"
|
||||
#include "org.freedesktop.Accounts.User.h"
|
||||
|
||||
#define GSD_ACCOUNT_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_ACCOUNT_MANAGER, GsdAccountManagerPrivate))
|
||||
|
||||
struct GsdAccountManagerPrivate
|
||||
{
|
||||
+ GSettings *settings;
|
||||
+
|
||||
GsdAccounts *accounts_proxy;
|
||||
GsdAccountsUser *accounts_user_proxy;
|
||||
GCancellable *cancellable;
|
||||
|
||||
GsdScreenSaver *screensaver_proxy;
|
||||
|
||||
gint64 expiration_time;
|
||||
gint64 last_change_time;
|
||||
gint64 min_days_between_changes;
|
||||
gint64 max_days_between_changes;
|
||||
gint64 days_to_warn;
|
||||
gint64 days_after_expiration_until_lock;
|
||||
|
||||
NotifyNotification *notification;
|
||||
+
|
||||
+ gint64 last_notify_time;
|
||||
+ int notify_period;
|
||||
+ guint notify_period_timeout_id;
|
||||
};
|
||||
|
||||
static void gsd_account_manager_class_init (GsdAccountManagerClass *klass);
|
||||
static void gsd_account_manager_init (GsdAccountManager *account_manager);
|
||||
static void gsd_account_manager_finalize (GObject *object);
|
||||
+static void fetch_password_expiration_policy (GsdAccountManager *manager);
|
||||
|
||||
G_DEFINE_TYPE (GsdAccountManager, gsd_account_manager, G_TYPE_OBJECT)
|
||||
|
||||
static gpointer manager_object = NULL;
|
||||
|
||||
static void
|
||||
on_notification_closed (NotifyNotification *notification,
|
||||
gpointer user_data)
|
||||
{
|
||||
GsdAccountManager *manager = user_data;
|
||||
|
||||
g_clear_object (&manager->priv->notification);
|
||||
}
|
||||
|
||||
static void
|
||||
hide_notification (GsdAccountManager *manager)
|
||||
{
|
||||
if (manager->priv->notification == NULL)
|
||||
return;
|
||||
|
||||
notify_notification_close (manager->priv->notification, NULL);
|
||||
g_clear_object (&manager->priv->notification);
|
||||
}
|
||||
|
||||
static void
|
||||
show_notification (GsdAccountManager *manager,
|
||||
const char *primary_text,
|
||||
const char *secondary_text)
|
||||
{
|
||||
g_assert (manager->priv->notification == NULL);
|
||||
|
||||
manager->priv->notification = notify_notification_new (primary_text,
|
||||
secondary_text,
|
||||
"avatar-default-symbolic");
|
||||
notify_notification_set_app_name (manager->priv->notification, _("User Account"));
|
||||
notify_notification_set_hint (manager->priv->notification,
|
||||
"resident",
|
||||
g_variant_new_boolean (TRUE));
|
||||
notify_notification_set_timeout (manager->priv->notification,
|
||||
NOTIFY_EXPIRES_NEVER);
|
||||
|
||||
g_signal_connect (manager->priv->notification,
|
||||
"closed",
|
||||
G_CALLBACK (on_notification_closed),
|
||||
manager);
|
||||
|
||||
notify_notification_show (manager->priv->notification, NULL);
|
||||
+
|
||||
+ manager->priv->last_notify_time = g_get_monotonic_time ();
|
||||
}
|
||||
|
||||
static void
|
||||
update_password_notification (GsdAccountManager *manager)
|
||||
{
|
||||
gint64 days_since_epoch;
|
||||
gint64 days_until_expiration = -1;
|
||||
gint64 days_since_last_change = -1;
|
||||
gint64 days_left = -1;
|
||||
g_autofree char *primary_text = NULL;
|
||||
g_autofree char *secondary_text = NULL;
|
||||
gboolean password_already_expired = FALSE;
|
||||
|
||||
hide_notification (manager);
|
||||
|
||||
days_since_epoch = g_get_real_time () / G_USEC_PER_SEC / 60 / 60 / 24;
|
||||
|
||||
if (manager->priv->expiration_time > 0) {
|
||||
days_until_expiration = manager->priv->expiration_time - days_since_epoch;
|
||||
|
||||
if (days_until_expiration <= 0) {
|
||||
password_already_expired = TRUE;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (manager->priv->last_change_time == 0) {
|
||||
password_already_expired = TRUE;
|
||||
goto out;
|
||||
}
|
||||
@@ -181,99 +190,127 @@ out:
|
||||
primary_text = g_strdup_printf (_("Password Expired"));
|
||||
secondary_text = g_strdup_printf (_("Your password is expired. Please update it."));
|
||||
} else if (days_left >= 0) {
|
||||
primary_text = g_strdup_printf (_("Password Expiring Soon"));
|
||||
if (days_left == 0)
|
||||
secondary_text = g_strdup_printf (_("Your password is expiring today."));
|
||||
else if (days_left == 1)
|
||||
secondary_text = g_strdup_printf (_("Your password is expiring in a day."));
|
||||
else
|
||||
secondary_text = g_strdup_printf (_("Your password is expiring in %ld days."),
|
||||
days_left);
|
||||
}
|
||||
|
||||
if (primary_text != NULL && secondary_text != NULL)
|
||||
show_notification (manager,
|
||||
primary_text,
|
||||
secondary_text);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
set_policy_number (gint64 *destination,
|
||||
gint64 source)
|
||||
{
|
||||
if (*destination == source)
|
||||
return FALSE;
|
||||
|
||||
*destination = source;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+static gboolean
|
||||
+on_notify_period_elapsed (GsdAccountManager *manager)
|
||||
+{
|
||||
+ manager->priv->notify_period_timeout_id = 0;
|
||||
+ fetch_password_expiration_policy (manager);
|
||||
+ return G_SOURCE_REMOVE;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+queue_periodic_timeout (GsdAccountManager *manager)
|
||||
+{
|
||||
+ if (manager->priv->notify_period_timeout_id != 0) {
|
||||
+ g_source_remove (manager->priv->notify_period_timeout_id);
|
||||
+ manager->priv->notify_period_timeout_id = 0;
|
||||
+ }
|
||||
+
|
||||
+ if (manager->priv->notify_period > 0) {
|
||||
+ gint64 already_elapsed_time;
|
||||
+
|
||||
+ already_elapsed_time = MAX (0, (g_get_monotonic_time () - manager->priv->last_notify_time) / G_USEC_PER_SEC);
|
||||
+
|
||||
+ manager->priv->notify_period_timeout_id = g_timeout_add_seconds (MAX (0, manager->priv->notify_period * 60 - already_elapsed_time),
|
||||
+ (GSourceFunc) on_notify_period_elapsed,
|
||||
+ manager);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void
|
||||
on_got_password_expiration_policy (GsdAccountsUser *accounts_user_proxy,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
GsdAccountManager *manager = user_data;
|
||||
g_autoptr(GError) error = NULL;
|
||||
gboolean succeeded;
|
||||
gint64 expiration_time;
|
||||
gint64 last_change_time;
|
||||
gint64 min_days_between_changes;
|
||||
gint64 max_days_between_changes;
|
||||
gint64 days_to_warn;
|
||||
gint64 days_after_expiration_until_lock;
|
||||
|
||||
gnome_settings_profile_start (NULL);
|
||||
succeeded = gsd_accounts_user_call_get_password_expiration_policy_finish (accounts_user_proxy,
|
||||
&expiration_time,
|
||||
&last_change_time,
|
||||
&min_days_between_changes,
|
||||
&max_days_between_changes,
|
||||
&days_to_warn,
|
||||
&days_after_expiration_until_lock,
|
||||
res,
|
||||
&error);
|
||||
|
||||
if (!succeeded) {
|
||||
g_warning ("Failed to get password expiration policy for user: %s", error->message);
|
||||
goto out;
|
||||
}
|
||||
|
||||
set_policy_number (&manager->priv->expiration_time, expiration_time);
|
||||
set_policy_number (&manager->priv->last_change_time, last_change_time);
|
||||
set_policy_number (&manager->priv->min_days_between_changes, min_days_between_changes);
|
||||
set_policy_number (&manager->priv->max_days_between_changes, max_days_between_changes);
|
||||
set_policy_number (&manager->priv->days_to_warn, days_to_warn);
|
||||
set_policy_number (&manager->priv->days_after_expiration_until_lock, days_after_expiration_until_lock);
|
||||
|
||||
update_password_notification (manager);
|
||||
+ queue_periodic_timeout (manager);
|
||||
out:
|
||||
gnome_settings_profile_end (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
fetch_password_expiration_policy (GsdAccountManager *manager)
|
||||
{
|
||||
gsd_accounts_user_call_get_password_expiration_policy (manager->priv->accounts_user_proxy,
|
||||
manager->priv->cancellable,
|
||||
(GAsyncReadyCallback)
|
||||
on_got_password_expiration_policy,
|
||||
manager);
|
||||
}
|
||||
|
||||
static void
|
||||
on_screensaver_signal (GDBusProxy *proxy,
|
||||
const gchar *sender_name,
|
||||
const gchar *signal_name,
|
||||
GVariant *parameters,
|
||||
gpointer user_data)
|
||||
{
|
||||
GsdAccountManager *manager = user_data;
|
||||
|
||||
if (g_strcmp0 (signal_name, "ActiveChanged") == 0) {
|
||||
gboolean active;
|
||||
|
||||
g_variant_get (parameters, "(b)", &active);
|
||||
|
||||
if (!active) {
|
||||
fetch_password_expiration_policy (manager);
|
||||
@@ -346,91 +383,109 @@ on_got_user_object_path (GsdAccounts *accounts_proxy,
|
||||
manager);
|
||||
|
||||
out:
|
||||
gnome_settings_profile_end (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
on_got_accounts_proxy (GObject *source_object,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
GsdAccountManager *manager = user_data;
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
gnome_settings_profile_start (NULL);
|
||||
manager->priv->accounts_proxy = gsd_accounts_proxy_new_for_bus_finish (res, &error);
|
||||
|
||||
if (manager->priv->accounts_proxy != NULL) {
|
||||
gsd_accounts_call_find_user_by_id (manager->priv->accounts_proxy,
|
||||
getuid (),
|
||||
manager->priv->cancellable,
|
||||
(GAsyncReadyCallback)
|
||||
on_got_user_object_path,
|
||||
manager);
|
||||
} else {
|
||||
g_warning ("Failed to get proxy to accounts service: %s", error->message);
|
||||
}
|
||||
gnome_settings_profile_end (NULL);
|
||||
}
|
||||
|
||||
+static void
|
||||
+on_notify_period_changed (GsdAccountManager *manager)
|
||||
+{
|
||||
+ manager->priv->notify_period = g_settings_get_int (manager->priv->settings, "notify-period");
|
||||
+
|
||||
+ queue_periodic_timeout (manager);
|
||||
+}
|
||||
+
|
||||
gboolean
|
||||
gsd_account_manager_start (GsdAccountManager *manager,
|
||||
GError **error)
|
||||
{
|
||||
g_debug ("Starting accounts manager");
|
||||
|
||||
gnome_settings_profile_start (NULL);
|
||||
manager->priv->cancellable = g_cancellable_new ();
|
||||
+ manager->priv->settings = g_settings_new ("org.gnome.settings-daemon.plugins.account");
|
||||
+
|
||||
+ manager->priv->notify_period = g_settings_get_int (manager->priv->settings, "notify-period");
|
||||
+ g_signal_connect_object (G_OBJECT (manager->priv->settings),
|
||||
+ "changed::notify-period",
|
||||
+ G_CALLBACK (on_notify_period_changed),
|
||||
+ manager,
|
||||
+ G_CONNECT_SWAPPED);
|
||||
+
|
||||
gsd_accounts_proxy_new_for_bus (G_BUS_TYPE_SYSTEM,
|
||||
G_DBUS_PROXY_FLAGS_NONE,
|
||||
"org.freedesktop.Accounts",
|
||||
"/org/freedesktop/Accounts",
|
||||
manager->priv->cancellable,
|
||||
(GAsyncReadyCallback)
|
||||
on_got_accounts_proxy,
|
||||
manager);
|
||||
gnome_settings_profile_end (NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
gsd_account_manager_stop (GsdAccountManager *manager)
|
||||
{
|
||||
g_debug ("Stopping accounts manager");
|
||||
|
||||
if (manager->priv->cancellable != NULL) {
|
||||
g_cancellable_cancel (manager->priv->cancellable);
|
||||
g_clear_object (&manager->priv->cancellable);
|
||||
}
|
||||
|
||||
+ g_clear_object (&manager->priv->settings);
|
||||
g_clear_object (&manager->priv->accounts_proxy);
|
||||
g_clear_object (&manager->priv->accounts_user_proxy);
|
||||
g_clear_object (&manager->priv->notification);
|
||||
g_clear_object (&manager->priv->screensaver_proxy);
|
||||
}
|
||||
|
||||
static void
|
||||
gsd_account_manager_class_init (GsdAccountManagerClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = gsd_account_manager_finalize;
|
||||
|
||||
notify_init ("gnome-settings-daemon");
|
||||
|
||||
g_type_class_add_private (klass, sizeof (GsdAccountManagerPrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
gsd_account_manager_init (GsdAccountManager *manager)
|
||||
{
|
||||
manager->priv = GSD_ACCOUNT_MANAGER_GET_PRIVATE (manager);
|
||||
}
|
||||
|
||||
static void
|
||||
gsd_account_manager_finalize (GObject *object)
|
||||
{
|
||||
GsdAccountManager *manager;
|
||||
|
||||
g_return_if_fail (object != NULL);
|
||||
--
|
||||
2.21.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
|
||||
|
@ -0,0 +1,110 @@
|
||||
From ff98c03c88e53041dcc861de3b3a3351d55297fe Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Fri, 9 Nov 2018 10:39:11 -0500
|
||||
Subject: [PATCH 4/4] account: don't poll more frequently than notification
|
||||
period
|
||||
|
||||
At the moment, if an account has no reason to receive a notification,
|
||||
the account plugin ends up polling continuously, desperately,
|
||||
and unsuccessfully trying to find a reason to notify. That leads
|
||||
to unnecessary CPU utilization.
|
||||
|
||||
The reason is an apparent think-o in the code. The code tracks
|
||||
the last time a notification was shown, so it knows when to show
|
||||
the next notification later, even if the notification period, or
|
||||
account policy is updated by the admin in the interim.
|
||||
|
||||
The problem is that it's wrong to look at the last notification
|
||||
time if there's no reason to show a notification. In that case
|
||||
the wakeup is merely to poll updates on the account policy.
|
||||
|
||||
This commit addresses the problem by only looking at the previous
|
||||
notification time, if it was within the current notification period.
|
||||
---
|
||||
plugins/account/gsd-account-manager.c | 14 +++++++++++---
|
||||
1 file changed, 11 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/plugins/account/gsd-account-manager.c b/plugins/account/gsd-account-manager.c
|
||||
index ff054edd..b48c0fe8 100644
|
||||
--- a/plugins/account/gsd-account-manager.c
|
||||
+++ b/plugins/account/gsd-account-manager.c
|
||||
@@ -207,65 +207,73 @@ out:
|
||||
}
|
||||
|
||||
static gboolean
|
||||
set_policy_number (gint64 *destination,
|
||||
gint64 source)
|
||||
{
|
||||
if (*destination == source)
|
||||
return FALSE;
|
||||
|
||||
*destination = source;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_notify_period_elapsed (GsdAccountManager *manager)
|
||||
{
|
||||
manager->priv->notify_period_timeout_id = 0;
|
||||
fetch_password_expiration_policy (manager);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
queue_periodic_timeout (GsdAccountManager *manager)
|
||||
{
|
||||
if (manager->priv->notify_period_timeout_id != 0) {
|
||||
g_source_remove (manager->priv->notify_period_timeout_id);
|
||||
manager->priv->notify_period_timeout_id = 0;
|
||||
}
|
||||
|
||||
if (manager->priv->notify_period > 0) {
|
||||
- gint64 already_elapsed_time;
|
||||
+ gint64 seconds_since_last_notification;
|
||||
+ guint seconds_between_notifications;
|
||||
+ guint seconds_until_next_notification;
|
||||
|
||||
- already_elapsed_time = MAX (0, (g_get_monotonic_time () - manager->priv->last_notify_time) / G_USEC_PER_SEC);
|
||||
+ seconds_since_last_notification = MAX (0, (g_get_monotonic_time () - manager->priv->last_notify_time) / G_USEC_PER_SEC);
|
||||
+ seconds_between_notifications = manager->priv->notify_period * 60;
|
||||
|
||||
- manager->priv->notify_period_timeout_id = g_timeout_add_seconds (MAX (0, manager->priv->notify_period * 60 - already_elapsed_time),
|
||||
+ if (seconds_since_last_notification > seconds_between_notifications)
|
||||
+ seconds_until_next_notification = seconds_between_notifications;
|
||||
+ else
|
||||
+ seconds_until_next_notification = seconds_between_notifications - seconds_since_last_notification;
|
||||
+
|
||||
+ manager->priv->notify_period_timeout_id = g_timeout_add_seconds (seconds_until_next_notification,
|
||||
(GSourceFunc) on_notify_period_elapsed,
|
||||
manager);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_got_password_expiration_policy (GsdAccountsUser *accounts_user_proxy,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
GsdAccountManager *manager = user_data;
|
||||
g_autoptr(GError) error = NULL;
|
||||
gboolean succeeded;
|
||||
gint64 expiration_time;
|
||||
gint64 last_change_time;
|
||||
gint64 min_days_between_changes;
|
||||
gint64 max_days_between_changes;
|
||||
gint64 days_to_warn;
|
||||
gint64 days_after_expiration_until_lock;
|
||||
|
||||
gnome_settings_profile_start (NULL);
|
||||
succeeded = gsd_accounts_user_call_get_password_expiration_policy_finish (accounts_user_proxy,
|
||||
&expiration_time,
|
||||
&last_change_time,
|
||||
&min_days_between_changes,
|
||||
&max_days_between_changes,
|
||||
&days_to_warn,
|
||||
&days_after_expiration_until_lock,
|
||||
res,
|
||||
&error);
|
||||
--
|
||||
2.21.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
|
||||
|
10198
SOURCES/0017-Update-translations.patch
Normal file
10198
SOURCES/0017-Update-translations.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,561 +0,0 @@
|
||||
From 6ab152961de63dec953981aea24a7f0b4e7949ec Mon Sep 17 00:00:00 2001
|
||||
From: Carlos Garnacho <carlosg@gnome.org>
|
||||
Date: Fri, 3 Dec 2021 23:38:50 +0100
|
||||
Subject: [PATCH 1/3] xsettings: Adopt code to look up GTK IM module
|
||||
|
||||
Right now, gsd-keyboard and gsd-xsettings have a strange relation
|
||||
where the first sets the gtk-im-module dconf setting for the latter
|
||||
to read the setting and forward it through XSettings.
|
||||
|
||||
Since this detection is highly X11 specific, make it happen in the
|
||||
Xsettings daemon itself, from the relevant setting and device presence.
|
||||
|
||||
This makes users still able to shoot themselves in the foot by changing
|
||||
the setting, X11 clients able to be told to switch to ibus if it turns
|
||||
out necessary, and Wayland clients unaffected otherwise.
|
||||
|
||||
Related: https://gitlab.gnome.org/GNOME/gtk/-/issues/4443
|
||||
---
|
||||
plugins/keyboard/gsd-keyboard-manager.c | 147 ---------------------
|
||||
plugins/xsettings/gsd-xsettings-manager.c | 153 ++++++++++++++++++++++
|
||||
2 files changed, 153 insertions(+), 147 deletions(-)
|
||||
|
||||
diff --git a/plugins/keyboard/gsd-keyboard-manager.c b/plugins/keyboard/gsd-keyboard-manager.c
|
||||
index cb4ea98b..d41393bc 100644
|
||||
--- a/plugins/keyboard/gsd-keyboard-manager.c
|
||||
+++ b/plugins/keyboard/gsd-keyboard-manager.c
|
||||
@@ -57,10 +57,6 @@
|
||||
|
||||
#define GNOME_DESKTOP_INTERFACE_DIR "org.gnome.desktop.interface"
|
||||
|
||||
-#define KEY_GTK_IM_MODULE "gtk-im-module"
|
||||
-#define GTK_IM_MODULE_SIMPLE "gtk-im-context-simple"
|
||||
-#define GTK_IM_MODULE_IBUS "ibus"
|
||||
-
|
||||
#define GNOME_DESKTOP_INPUT_SOURCES_DIR "org.gnome.desktop.input-sources"
|
||||
|
||||
#define KEY_INPUT_SOURCES "sources"
|
||||
@@ -71,9 +67,6 @@
|
||||
|
||||
#define DEFAULT_LAYOUT "us"
|
||||
|
||||
-#define GNOME_A11Y_APPLICATIONS_INTERFACE_DIR "org.gnome.desktop.a11y.applications"
|
||||
-#define KEY_OSK_ENABLED "screen-keyboard-enabled"
|
||||
-
|
||||
struct _GsdKeyboardManager
|
||||
{
|
||||
GObject parent;
|
||||
@@ -81,21 +74,14 @@ struct _GsdKeyboardManager
|
||||
guint start_idle_id;
|
||||
GSettings *settings;
|
||||
GSettings *input_sources_settings;
|
||||
- GSettings *a11y_settings;
|
||||
GDBusProxy *localed;
|
||||
GCancellable *cancellable;
|
||||
-
|
||||
- GdkDeviceManager *device_manager;
|
||||
- guint device_added_id;
|
||||
- guint device_removed_id;
|
||||
};
|
||||
|
||||
static void gsd_keyboard_manager_class_init (GsdKeyboardManagerClass *klass);
|
||||
static void gsd_keyboard_manager_init (GsdKeyboardManager *keyboard_manager);
|
||||
static void gsd_keyboard_manager_finalize (GObject *object);
|
||||
|
||||
-static void update_gtk_im_module (GsdKeyboardManager *manager);
|
||||
-
|
||||
G_DEFINE_TYPE (GsdKeyboardManager, gsd_keyboard_manager, G_TYPE_OBJECT)
|
||||
|
||||
static gpointer manager_object = NULL;
|
||||
@@ -218,121 +204,6 @@ settings_changed (GSettings *settings,
|
||||
|
||||
}
|
||||
|
||||
-static void
|
||||
-device_added_cb (GdkDeviceManager *device_manager,
|
||||
- GdkDevice *device,
|
||||
- GsdKeyboardManager *manager)
|
||||
-{
|
||||
- GdkInputSource source;
|
||||
-
|
||||
- source = gdk_device_get_source (device);
|
||||
- if (source == GDK_SOURCE_TOUCHSCREEN) {
|
||||
- update_gtk_im_module (manager);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-static void
|
||||
-device_removed_cb (GdkDeviceManager *device_manager,
|
||||
- GdkDevice *device,
|
||||
- GsdKeyboardManager *manager)
|
||||
-{
|
||||
- GdkInputSource source;
|
||||
-
|
||||
- source = gdk_device_get_source (device);
|
||||
- if (source == GDK_SOURCE_TOUCHSCREEN)
|
||||
- update_gtk_im_module (manager);
|
||||
-}
|
||||
-
|
||||
-static void
|
||||
-set_devicepresence_handler (GsdKeyboardManager *manager)
|
||||
-{
|
||||
- GdkDeviceManager *device_manager;
|
||||
-
|
||||
- if (gnome_settings_is_wayland ())
|
||||
- return;
|
||||
-
|
||||
- device_manager = gdk_display_get_device_manager (gdk_display_get_default ());
|
||||
-
|
||||
- manager->device_added_id = g_signal_connect (G_OBJECT (device_manager), "device-added",
|
||||
- G_CALLBACK (device_added_cb), manager);
|
||||
- manager->device_removed_id = g_signal_connect (G_OBJECT (device_manager), "device-removed",
|
||||
- G_CALLBACK (device_removed_cb), manager);
|
||||
- manager->device_manager = device_manager;
|
||||
-}
|
||||
-
|
||||
-static gboolean
|
||||
-need_ibus (GVariant *sources)
|
||||
-{
|
||||
- GVariantIter iter;
|
||||
- const gchar *type;
|
||||
-
|
||||
- g_variant_iter_init (&iter, sources);
|
||||
- while (g_variant_iter_next (&iter, "(&s&s)", &type, NULL))
|
||||
- if (g_str_equal (type, INPUT_SOURCE_TYPE_IBUS))
|
||||
- return TRUE;
|
||||
-
|
||||
- return FALSE;
|
||||
-}
|
||||
-
|
||||
-static gboolean
|
||||
-need_osk (GsdKeyboardManager *manager)
|
||||
-{
|
||||
- gboolean has_touchscreen = FALSE;
|
||||
- GList *devices;
|
||||
- GdkSeat *seat;
|
||||
-
|
||||
- if (g_settings_get_boolean (manager->a11y_settings,
|
||||
- KEY_OSK_ENABLED))
|
||||
- return TRUE;
|
||||
-
|
||||
- seat = gdk_display_get_default_seat (gdk_display_get_default ());
|
||||
- devices = gdk_seat_get_slaves (seat, GDK_SEAT_CAPABILITY_TOUCH);
|
||||
-
|
||||
- has_touchscreen = devices != NULL;
|
||||
-
|
||||
- g_list_free (devices);
|
||||
-
|
||||
- return has_touchscreen;
|
||||
-}
|
||||
-
|
||||
-static void
|
||||
-set_gtk_im_module (GsdKeyboardManager *manager,
|
||||
- GSettings *settings,
|
||||
- GVariant *sources)
|
||||
-{
|
||||
- const gchar *new_module;
|
||||
- gchar *current_module;
|
||||
-
|
||||
- if (need_ibus (sources) || need_osk (manager))
|
||||
- new_module = GTK_IM_MODULE_IBUS;
|
||||
- else
|
||||
- new_module = GTK_IM_MODULE_SIMPLE;
|
||||
-
|
||||
- current_module = g_settings_get_string (settings, KEY_GTK_IM_MODULE);
|
||||
- if (!g_str_equal (current_module, new_module))
|
||||
- g_settings_set_string (settings, KEY_GTK_IM_MODULE, new_module);
|
||||
- g_free (current_module);
|
||||
-}
|
||||
-
|
||||
-static void
|
||||
-update_gtk_im_module (GsdKeyboardManager *manager)
|
||||
-{
|
||||
- GSettings *interface_settings;
|
||||
- GVariant *sources;
|
||||
-
|
||||
- /* Gtk+ uses the IM module advertised in XSETTINGS so, if we
|
||||
- * have IBus input sources, we want it to load that
|
||||
- * module. Otherwise we can use the default "simple" module
|
||||
- * which is builtin gtk+
|
||||
- */
|
||||
- interface_settings = g_settings_new (GNOME_DESKTOP_INTERFACE_DIR);
|
||||
- sources = g_settings_get_value (manager->input_sources_settings,
|
||||
- KEY_INPUT_SOURCES);
|
||||
- set_gtk_im_module (manager, interface_settings, sources);
|
||||
- g_object_unref (interface_settings);
|
||||
- g_variant_unref (sources);
|
||||
-}
|
||||
-
|
||||
static void
|
||||
get_sources_from_xkb_config (GsdKeyboardManager *manager)
|
||||
{
|
||||
@@ -580,18 +451,7 @@ start_keyboard_idle_cb (GsdKeyboardManager *manager)
|
||||
|
||||
manager->settings = g_settings_new (GSD_KEYBOARD_DIR);
|
||||
|
||||
- set_devicepresence_handler (manager);
|
||||
-
|
||||
manager->input_sources_settings = g_settings_new (GNOME_DESKTOP_INPUT_SOURCES_DIR);
|
||||
- g_signal_connect_swapped (manager->input_sources_settings,
|
||||
- "changed::" KEY_INPUT_SOURCES,
|
||||
- G_CALLBACK (update_gtk_im_module), manager);
|
||||
-
|
||||
- manager->a11y_settings = g_settings_new (GNOME_A11Y_APPLICATIONS_INTERFACE_DIR);
|
||||
- g_signal_connect_swapped (manager->a11y_settings,
|
||||
- "changed::" KEY_OSK_ENABLED,
|
||||
- G_CALLBACK (update_gtk_im_module), manager);
|
||||
- update_gtk_im_module (manager);
|
||||
|
||||
manager->cancellable = g_cancellable_new ();
|
||||
|
||||
@@ -645,14 +505,7 @@ gsd_keyboard_manager_stop (GsdKeyboardManager *manager)
|
||||
|
||||
g_clear_object (&manager->settings);
|
||||
g_clear_object (&manager->input_sources_settings);
|
||||
- g_clear_object (&manager->a11y_settings);
|
||||
g_clear_object (&manager->localed);
|
||||
-
|
||||
- if (manager->device_manager != NULL) {
|
||||
- g_signal_handler_disconnect (manager->device_manager, manager->device_added_id);
|
||||
- g_signal_handler_disconnect (manager->device_manager, manager->device_removed_id);
|
||||
- manager->device_manager = NULL;
|
||||
- }
|
||||
}
|
||||
|
||||
static void
|
||||
diff --git a/plugins/xsettings/gsd-xsettings-manager.c b/plugins/xsettings/gsd-xsettings-manager.c
|
||||
index 5f1b4583..1aa020db 100644
|
||||
--- a/plugins/xsettings/gsd-xsettings-manager.c
|
||||
+++ b/plugins/xsettings/gsd-xsettings-manager.c
|
||||
@@ -56,6 +56,9 @@
|
||||
#define PRIVACY_SETTINGS_SCHEMA "org.gnome.desktop.privacy"
|
||||
#define WM_SETTINGS_SCHEMA "org.gnome.desktop.wm.preferences"
|
||||
#define A11Y_SCHEMA "org.gnome.desktop.a11y"
|
||||
+#define A11Y_INTERFACE_SCHEMA "org.gnome.desktop.a11y.interface"
|
||||
+#define A11Y_APPLICATIONS_SCHEMA "org.gnome.desktop.a11y.applications"
|
||||
+#define INPUT_SOURCES_SCHEMA "org.gnome.desktop.input-sources"
|
||||
#define CLASSIC_WM_SETTINGS_SCHEMA "org.gnome.shell.extensions.classic-overrides"
|
||||
|
||||
#define XSETTINGS_PLUGIN_SCHEMA "org.gnome.settings-daemon.plugins.xsettings"
|
||||
@@ -72,9 +75,18 @@
|
||||
#define FONT_HINTING_KEY "font-hinting"
|
||||
#define FONT_RGBA_ORDER_KEY "font-rgba-order"
|
||||
|
||||
+#define INPUT_SOURCES_KEY "sources"
|
||||
+#define OSK_ENABLED_KEY "screen-keyboard-enabled"
|
||||
+#define GTK_IM_MODULE_KEY "gtk-im-module"
|
||||
+
|
||||
#define GTK_SETTINGS_DBUS_PATH "/org/gtk/Settings"
|
||||
#define GTK_SETTINGS_DBUS_NAME "org.gtk.Settings"
|
||||
|
||||
+#define INPUT_SOURCE_TYPE_IBUS "ibus"
|
||||
+
|
||||
+#define GTK_IM_MODULE_SIMPLE "gtk-im-context-simple"
|
||||
+#define GTK_IM_MODULE_IBUS "ibus"
|
||||
+
|
||||
static const gchar introspection_xml[] =
|
||||
"<node name='/org/gtk/Settings'>"
|
||||
" <interface name='org.gtk.Settings'>"
|
||||
@@ -277,6 +289,11 @@ struct _GsdXSettingsManager
|
||||
FcMonitor *fontconfig_monitor;
|
||||
gint64 fontconfig_timestamp;
|
||||
|
||||
+ GSettings *interface_settings;
|
||||
+ GSettings *input_sources_settings;
|
||||
+ GSettings *a11y_settings;
|
||||
+ GdkSeat *user_seat;
|
||||
+
|
||||
GsdXSettingsGtk *gtk;
|
||||
|
||||
guint introspect_properties_changed_id;
|
||||
@@ -286,6 +303,9 @@ struct _GsdXSettingsManager
|
||||
guint display_config_watch_id;
|
||||
guint monitors_changed_id;
|
||||
|
||||
+ guint device_added_id;
|
||||
+ guint device_removed_id;
|
||||
+
|
||||
guint shell_name_watch_id;
|
||||
gboolean have_shell;
|
||||
|
||||
@@ -1291,6 +1311,112 @@ migrate_settings (void)
|
||||
mouse_entries, G_N_ELEMENTS (mouse_entries));
|
||||
}
|
||||
|
||||
+static gboolean
|
||||
+need_ibus (GsdXSettingsManager *manager)
|
||||
+{
|
||||
+ GVariant *sources;
|
||||
+ GVariantIter iter;
|
||||
+ const gchar *type;
|
||||
+ gboolean needs_ibus = FALSE;
|
||||
+
|
||||
+ sources = g_settings_get_value (manager->input_sources_settings,
|
||||
+ INPUT_SOURCES_KEY);
|
||||
+
|
||||
+ g_variant_iter_init (&iter, sources);
|
||||
+ while (g_variant_iter_next (&iter, "(&s&s)", &type, NULL)) {
|
||||
+ if (g_str_equal (type, INPUT_SOURCE_TYPE_IBUS)) {
|
||||
+ needs_ibus = TRUE;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ g_variant_unref (sources);
|
||||
+
|
||||
+ return needs_ibus;
|
||||
+}
|
||||
+
|
||||
+static gboolean
|
||||
+need_osk (GsdXSettingsManager *manager)
|
||||
+{
|
||||
+ gboolean has_touchscreen = FALSE;
|
||||
+ GList *devices;
|
||||
+ GdkSeat *seat;
|
||||
+
|
||||
+ if (g_settings_get_boolean (manager->a11y_settings,
|
||||
+ OSK_ENABLED_KEY))
|
||||
+ return TRUE;
|
||||
+
|
||||
+ seat = gdk_display_get_default_seat (gdk_display_get_default ());
|
||||
+ devices = gdk_seat_get_slaves (seat, GDK_SEAT_CAPABILITY_TOUCH);
|
||||
+
|
||||
+ has_touchscreen = devices != NULL;
|
||||
+
|
||||
+ g_list_free (devices);
|
||||
+
|
||||
+ return has_touchscreen;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+update_gtk_im_module (GsdXSettingsManager *manager)
|
||||
+{
|
||||
+ const gchar *module;
|
||||
+ gchar *setting;
|
||||
+
|
||||
+ setting = g_settings_get_string (manager->interface_settings,
|
||||
+ GTK_IM_MODULE_KEY);
|
||||
+ if (setting && *setting)
|
||||
+ module = setting;
|
||||
+ else if (need_ibus (manager) || need_osk (manager))
|
||||
+ module = GTK_IM_MODULE_IBUS;
|
||||
+ else
|
||||
+ module = GTK_IM_MODULE_SIMPLE;
|
||||
+
|
||||
+ xsettings_manager_set_string (manager->manager, "Gtk/IMModule", module);
|
||||
+ g_free (setting);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+device_added_cb (GdkSeat *user_seat,
|
||||
+ GdkDevice *device,
|
||||
+ GsdXSettingsManager *manager)
|
||||
+{
|
||||
+ GdkInputSource source;
|
||||
+
|
||||
+ source = gdk_device_get_source (device);
|
||||
+ if (source == GDK_SOURCE_TOUCHSCREEN) {
|
||||
+ update_gtk_im_module (manager);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+device_removed_cb (GdkSeat *user_seat,
|
||||
+ GdkDevice *device,
|
||||
+ GsdXSettingsManager *manager)
|
||||
+{
|
||||
+ GdkInputSource source;
|
||||
+
|
||||
+ source = gdk_device_get_source (device);
|
||||
+ if (source == GDK_SOURCE_TOUCHSCREEN)
|
||||
+ update_gtk_im_module (manager);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+set_devicepresence_handler (GsdXSettingsManager *manager)
|
||||
+{
|
||||
+ GdkSeat *user_seat;
|
||||
+
|
||||
+ if (gnome_settings_is_wayland ())
|
||||
+ return;
|
||||
+
|
||||
+ user_seat = gdk_display_get_default_seat (gdk_display_get_default ());
|
||||
+
|
||||
+ manager->device_added_id = g_signal_connect (G_OBJECT (user_seat), "device-added",
|
||||
+ G_CALLBACK (device_added_cb), manager);
|
||||
+ manager->device_removed_id = g_signal_connect (G_OBJECT (user_seat), "device-removed",
|
||||
+ G_CALLBACK (device_removed_cb), manager);
|
||||
+ manager->user_seat = user_seat;
|
||||
+}
|
||||
+
|
||||
gboolean
|
||||
gsd_xsettings_manager_start (GsdXSettingsManager *manager,
|
||||
GError **error)
|
||||
@@ -1312,6 +1438,23 @@ gsd_xsettings_manager_start (GsdXSettingsManager *manager,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
+ set_devicepresence_handler (manager);
|
||||
+ manager->interface_settings = g_settings_new (INTERFACE_SETTINGS_SCHEMA);
|
||||
+ g_signal_connect_swapped (manager->interface_settings,
|
||||
+ "changed::" GTK_IM_MODULE_KEY,
|
||||
+ G_CALLBACK (update_gtk_im_module), manager);
|
||||
+
|
||||
+ manager->input_sources_settings = g_settings_new (INPUT_SOURCES_SCHEMA);
|
||||
+ g_signal_connect_swapped (manager->input_sources_settings,
|
||||
+ "changed::" INPUT_SOURCES_KEY,
|
||||
+ G_CALLBACK (update_gtk_im_module), manager);
|
||||
+
|
||||
+ manager->a11y_settings = g_settings_new (A11Y_APPLICATIONS_SCHEMA);
|
||||
+ g_signal_connect_swapped (manager->a11y_settings,
|
||||
+ "changed::" OSK_ENABLED_KEY,
|
||||
+ G_CALLBACK (update_gtk_im_module), manager);
|
||||
+ update_gtk_im_module (manager);
|
||||
+
|
||||
manager->monitors_changed_id =
|
||||
g_dbus_connection_signal_subscribe (manager->dbus_connection,
|
||||
"org.gnome.Mutter.DisplayConfig",
|
||||
@@ -1507,6 +1650,16 @@ gsd_xsettings_manager_stop (GsdXSettingsManager *manager)
|
||||
g_object_unref (manager->gtk);
|
||||
manager->gtk = NULL;
|
||||
}
|
||||
+
|
||||
+ if (manager->user_seat != NULL) {
|
||||
+ g_signal_handler_disconnect (manager->user_seat, manager->device_added_id);
|
||||
+ g_signal_handler_disconnect (manager->user_seat, manager->device_removed_id);
|
||||
+ manager->user_seat = NULL;
|
||||
+ }
|
||||
+
|
||||
+ g_clear_object (&manager->a11y_settings);
|
||||
+ g_clear_object (&manager->input_sources_settings);
|
||||
+ g_clear_object (&manager->interface_settings);
|
||||
}
|
||||
|
||||
static void
|
||||
--
|
||||
2.37.1
|
||||
|
||||
|
||||
From c1de15e0c7f145491482045c688e9f2d444cb041 Mon Sep 17 00:00:00 2001
|
||||
From: Carlos Garnacho <carlosg@gnome.org>
|
||||
Date: Tue, 15 Mar 2022 13:31:23 +0100
|
||||
Subject: [PATCH 2/3] keyboard: "Migrate" gtk-im-context setting before giving
|
||||
control to user
|
||||
|
||||
This setting used to be modified by gsd-keyboard at runtime, but it no
|
||||
longer does. We want to leave this setting in a pristine state before
|
||||
we lend control to the user in order to avoid setting leftovers make
|
||||
GTK and others use the unintended IM module.
|
||||
|
||||
Since the setting is actually staying on the same schema/path, there is
|
||||
no nice mechanism that would help us in doing a one-time port, so rely
|
||||
on a file at ~/.cache to make this happen once. In the common case, it
|
||||
just adds one stat() more at startup.
|
||||
|
||||
After this migration is done, the gtk-im-module setting can be considered
|
||||
in full control of the user.
|
||||
---
|
||||
plugins/keyboard/gsd-keyboard-manager.c | 35 +++++++++++++++++++++++++
|
||||
1 file changed, 35 insertions(+)
|
||||
|
||||
diff --git a/plugins/keyboard/gsd-keyboard-manager.c b/plugins/keyboard/gsd-keyboard-manager.c
|
||||
index d41393bc..15247c78 100644
|
||||
--- a/plugins/keyboard/gsd-keyboard-manager.c
|
||||
+++ b/plugins/keyboard/gsd-keyboard-manager.c
|
||||
@@ -67,6 +67,8 @@
|
||||
|
||||
#define DEFAULT_LAYOUT "us"
|
||||
|
||||
+#define SETTINGS_PORTED_FILE ".gsd-keyboard.settings-ported"
|
||||
+
|
||||
struct _GsdKeyboardManager
|
||||
{
|
||||
GObject parent;
|
||||
@@ -541,6 +543,14 @@ gsd_keyboard_manager_finalize (GObject *object)
|
||||
G_OBJECT_CLASS (gsd_keyboard_manager_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
+static GVariant *
|
||||
+reset_gtk_im_module (GVariant *variant,
|
||||
+ GVariant *old_default,
|
||||
+ GVariant *new_default)
|
||||
+{
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
static void
|
||||
migrate_keyboard_settings (void)
|
||||
{
|
||||
@@ -550,12 +560,37 @@ migrate_keyboard_settings (void)
|
||||
{ "delay", "delay", NULL },
|
||||
{ "remember-numlock-state", "remember-numlock-state", NULL },
|
||||
};
|
||||
+ g_autofree char *filename = NULL;
|
||||
|
||||
gsd_settings_migrate_check ("org.gnome.settings-daemon.peripherals.keyboard.deprecated",
|
||||
"/org/gnome/settings-daemon/peripherals/keyboard/",
|
||||
"org.gnome.desktop.peripherals.keyboard",
|
||||
"/org/gnome/desktop/peripherals/keyboard/",
|
||||
entries, G_N_ELEMENTS (entries));
|
||||
+
|
||||
+ /* In prior versions to GNOME 42, the gtk-im-module setting was
|
||||
+ * owned by gsd-keyboard. Reset it once before giving it back
|
||||
+ * to the user.
|
||||
+ */
|
||||
+ filename = g_build_filename (g_get_user_config_dir (),
|
||||
+ SETTINGS_PORTED_FILE,
|
||||
+ NULL);
|
||||
+
|
||||
+ if (!g_file_test (filename, G_FILE_TEST_EXISTS)) {
|
||||
+ GsdSettingsMigrateEntry im_entry[] = {
|
||||
+ { "gtk-im-module", "gtk-im-module", reset_gtk_im_module },
|
||||
+ };
|
||||
+ g_autoptr(GError) error = NULL;
|
||||
+
|
||||
+ gsd_settings_migrate_check ("org.gnome.desktop.interface",
|
||||
+ "/org/gnome/desktop/interface/",
|
||||
+ "org.gnome.desktop.interface",
|
||||
+ "/org/gnome/desktop/interface/",
|
||||
+ im_entry, G_N_ELEMENTS (im_entry));
|
||||
+
|
||||
+ if (!g_file_set_contents (filename, "", -1, &error))
|
||||
+ g_warning ("Error migrating gtk-im-module: %s", error->message);
|
||||
+ }
|
||||
}
|
||||
|
||||
GsdKeyboardManager *
|
||||
--
|
||||
2.37.1
|
||||
|
||||
|
||||
From 46452c04aee1bfd51e23a53dba89ac95e0c06823 Mon Sep 17 00:00:00 2001
|
||||
From: Carlos Garnacho <carlosg@gnome.org>
|
||||
Date: Fri, 29 Apr 2022 14:37:27 +0200
|
||||
Subject: [PATCH 3/3] xsettings: Remove direct mapping from gtk-im-module to
|
||||
Gtk/IMModule
|
||||
|
||||
This is now handled dynamically since commit e2d268eb00, so we should
|
||||
not tie dconf setting and Xsetting automatically here. Doing so, we
|
||||
are clobbering the dynamic value on startup, making it only effective
|
||||
on later changes.
|
||||
|
||||
Fixes: https://gitlab.gnome.org/GNOME/gnome-settings-daemon/-/issues/682
|
||||
---
|
||||
plugins/xsettings/gsd-xsettings-manager.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/plugins/xsettings/gsd-xsettings-manager.c b/plugins/xsettings/gsd-xsettings-manager.c
|
||||
index 1aa020db..d692cefb 100644
|
||||
--- a/plugins/xsettings/gsd-xsettings-manager.c
|
||||
+++ b/plugins/xsettings/gsd-xsettings-manager.c
|
||||
@@ -498,7 +498,6 @@ static TranslationEntry translations [] = {
|
||||
{ "org.gnome.desktop.interface", "cursor-blink-time", "Net/CursorBlinkTime", translate_int_int },
|
||||
{ "org.gnome.desktop.interface", "cursor-blink-timeout", "Gtk/CursorBlinkTimeout", translate_int_int },
|
||||
{ "org.gnome.desktop.interface", "gtk-theme", "Net/ThemeName", translate_string_string },
|
||||
- { "org.gnome.desktop.interface", "gtk-im-module", "Gtk/IMModule", translate_string_string },
|
||||
{ "org.gnome.desktop.interface", "icon-theme", "Net/IconThemeName", translate_string_string },
|
||||
{ "org.gnome.desktop.interface", "cursor-theme", "Gtk/CursorThemeName", translate_string_string },
|
||||
{ "org.gnome.desktop.interface", "gtk-enable-primary-paste", "Gtk/EnablePrimaryPaste", translate_bool_int },
|
||||
--
|
||||
2.37.1
|
||||
|
@ -1,2 +1,3 @@
|
||||
[org.gnome.settings-daemon.plugins.power]
|
||||
sleep-inactive-ac-timeout=0
|
||||
sleep-inactive-battery-timeout=0
|
||||
|
@ -1,45 +0,0 @@
|
||||
--- gnome-settings-daemon-40.0.1/plugins/print-notifications/gsd-print-notifications-manager.c
|
||||
+++ gnome-settings-daemon-40.0.1/plugins/print-notifications/gsd-print-notifications-manager.c
|
||||
@@ -1268,6 +1268,7 @@ scp_handler (GsdPrintNotificationsManage
|
||||
kill (manager->scp_handler_pid, SIGHUP);
|
||||
g_spawn_close_pid (manager->scp_handler_pid);
|
||||
manager->scp_handler_spawned = FALSE;
|
||||
+ manager->scp_handler_pid = -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1636,8 +1636,10 @@ gsd_print_notifications_manager_stop (Gs
|
||||
manager->check_source_id = 0;
|
||||
}
|
||||
|
||||
- if (manager->subscription_id >= 0)
|
||||
+ if (manager->subscription_id >= 0) {
|
||||
cancel_subscription (manager->subscription_id);
|
||||
+ manager->subscription_id = -1;
|
||||
+ }
|
||||
|
||||
g_clear_pointer (&manager->printing_printers, g_hash_table_destroy);
|
||||
|
||||
@@ -1649,6 +1651,7 @@ gsd_print_notifications_manager_stop (Gs
|
||||
g_source_remove (data->timeout_id);
|
||||
}
|
||||
g_list_free_full (manager->timeouts, free_timeout_data);
|
||||
+ manager->timeouts = NULL;
|
||||
|
||||
for (tmp = manager->active_notifications; tmp; tmp = g_list_next (tmp)) {
|
||||
reason_data = (ReasonData *) tmp->data;
|
||||
@@ -1665,12 +1668,14 @@ gsd_print_notifications_manager_stop (Gs
|
||||
}
|
||||
}
|
||||
g_list_free_full (manager->active_notifications, free_reason_data);
|
||||
+ manager->active_notifications = NULL;
|
||||
|
||||
for (tmp = manager->held_jobs; tmp; tmp = g_list_next (tmp)) {
|
||||
job = (HeldJob *) tmp->data;
|
||||
g_source_remove (job->timeout_id);
|
||||
}
|
||||
g_list_free_full (manager->held_jobs, free_held_job);
|
||||
+ manager->held_jobs = NULL;
|
||||
|
||||
scp_handler (manager, FALSE);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,22 +1,23 @@
|
||||
%global glib2_version 2.56
|
||||
%global colord_version 1.4.5
|
||||
%global geocode_glib_version 3.10.0
|
||||
%global gnome_desktop_version 3.37.1
|
||||
%global gsettings_desktop_schemas_version 40
|
||||
%global gnome_desktop_version 3.27.90
|
||||
%global gsettings_desktop_schemas_version 3.32.0-4
|
||||
%global gtk3_version 3.15.3
|
||||
%global libgweather_version 40~alpha
|
||||
%global libgweather_version 3.9.5
|
||||
%global geoclue_version 2.3.1
|
||||
|
||||
%global tarball_version %%(echo %{version} | tr '~' '.')
|
||||
%if %{undefined centos}
|
||||
%bcond_without subman
|
||||
%endif
|
||||
|
||||
Name: gnome-settings-daemon
|
||||
Version: 40.0.1
|
||||
Release: 16%{?dist}
|
||||
Version: 3.32.0
|
||||
Release: 19%{?dist}
|
||||
Summary: The daemon sharing settings from GNOME to GTK+/KDE applications
|
||||
|
||||
License: GPLv2+
|
||||
URL: https://download.gnome.org/sources/%{name}
|
||||
Source0: https://download.gnome.org/sources/%{name}/40/%{name}-%{tarball_version}.tar.xz
|
||||
Source0: https://download.gnome.org/sources/%{name}/3.32/%{name}-%{version}.tar.xz
|
||||
Source1: org.gnome.settings-daemon.plugins.power.gschema.override
|
||||
|
||||
BuildRequires: meson >= 0.44.0
|
||||
@ -24,10 +25,10 @@ BuildRequires: gcc
|
||||
BuildRequires: cups-devel
|
||||
BuildRequires: gettext
|
||||
BuildRequires: perl-interpreter
|
||||
BuildRequires: git
|
||||
BuildRequires: pkgconfig(alsa)
|
||||
BuildRequires: pkgconfig(colord) >= %{colord_version}
|
||||
BuildRequires: pkgconfig(colord) >= 1.0.2
|
||||
BuildRequires: pkgconfig(fontconfig)
|
||||
BuildRequires: pkgconfig(gcr-base-3)
|
||||
BuildRequires: pkgconfig(geoclue-2.0) >= %{geoclue_version}
|
||||
BuildRequires: pkgconfig(geocode-glib-1.0) >= %{geocode_glib_version}
|
||||
BuildRequires: pkgconfig(glib-2.0) >= %{glib2_version}
|
||||
@ -36,7 +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)
|
||||
@ -45,7 +48,6 @@ BuildRequires: pkgconfig(libnotify)
|
||||
BuildRequires: pkgconfig(libpulse)
|
||||
BuildRequires: pkgconfig(libpulse-mainloop-glib)
|
||||
BuildRequires: pkgconfig(librsvg-2.0)
|
||||
BuildRequires: pkgconfig(mm-glib)
|
||||
BuildRequires: pkgconfig(nss)
|
||||
BuildRequires: pkgconfig(polkit-gobject-1)
|
||||
BuildRequires: pkgconfig(upower-glib)
|
||||
@ -57,7 +59,7 @@ BuildRequires: pkgconfig(libwacom) >= 0.7
|
||||
BuildRequires: pkgconfig(xorg-wacom)
|
||||
%endif
|
||||
|
||||
Requires: colord >= %{colord_version}
|
||||
Requires: colord
|
||||
Requires: iio-sensor-proxy
|
||||
Requires: geoclue2 >= %{geoclue_version}
|
||||
Requires: geocode-glib%{?_isa} >= %{geocode_glib_version}
|
||||
@ -67,11 +69,63 @@ Requires: gsettings-desktop-schemas%{?_isa} >= %{gsettings_desktop_schemas_versi
|
||||
Requires: gtk3%{?_isa} >= %{gtk3_version}
|
||||
Requires: libgweather%{?_isa} >= %{libgweather_version}
|
||||
|
||||
Patch00001: 0001-power-Enable-power-saver-profile-when-low-on-battery.patch
|
||||
Patch00002: subscription-manager-support.patch
|
||||
Patch00003: im-module-setting-fix.patch
|
||||
Patch00004: print-notifications-clear-in-stop.patch
|
||||
Patch00005: 0001-power-Respect-the-nothing-power-button-action-for-VM.patch
|
||||
Obsoletes: %{name}-updates < 3.13.1
|
||||
Obsoletes: drwright < 3.5.0-3
|
||||
Obsoletes: gnome-settings-daemon-devel < 3.23.1
|
||||
|
||||
# The "org.gnome.SettingsDaemon.A11yKeyboard" has been been removed, now
|
||||
# handled in gnome-shell/mutter instead; this conflict here makes sure not to
|
||||
# break older gdm and gnome-session releases that expect the functionality
|
||||
Conflicts: gdm < 1:3.27.90
|
||||
Conflicts: gnome-session < 3.27.90
|
||||
# The orientation and xrandr plugins were removed in 3.25.4 and their
|
||||
# functionality was moved to mutter; this conflict here makes sure not to break
|
||||
# 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
|
||||
|
||||
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
|
||||
|
||||
Patch60001: 0001-power-Only-disable-Suspend-Hibernate-actions-inside-.patch
|
||||
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=2062051
|
||||
Patch70001: 0001-power-Respect-the-nothing-power-button-action-for-VM.patch
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=2018606
|
||||
Patch70002: 0001-power-Avoid-automatic-logout-in-GDM-greeter.patch
|
||||
Patch70003: 0002-power-Never-register-sleep-timeout-for-logout-in-GDM.patch
|
||||
Patch70004: 0001-Make-power-button-action-always-power-off-when-chass.patch
|
||||
|
||||
%description
|
||||
A daemon to share settings from GNOME to other applications. It also
|
||||
@ -86,7 +140,7 @@ The %{name}-devel package contains libraries and header files for
|
||||
developing applications that use %{name}.
|
||||
|
||||
%prep
|
||||
%autosetup -p1 -n %{name}-%{tarball_version}
|
||||
%autosetup -S git
|
||||
|
||||
%build
|
||||
%meson
|
||||
@ -99,15 +153,26 @@ cp %{SOURCE1} $RPM_BUILD_ROOT%{_datadir}/glib-2.0/schemas
|
||||
|
||||
%find_lang %{name} --with-gnome
|
||||
|
||||
mkdir $RPM_BUILD_ROOT%{_libdir}/gnome-settings-daemon-3.0/gtk-modules
|
||||
|
||||
%files -f %{name}.lang
|
||||
%license COPYING
|
||||
%doc AUTHORS NEWS
|
||||
|
||||
# list daemons explicitly, so we notice if one goes missing
|
||||
# some of these don't have a separate gschema
|
||||
%{_libexecdir}/gsd-account
|
||||
%{_sysconfdir}/xdg/autostart/org.gnome.SettingsDaemon.Account.desktop
|
||||
%{_datadir}/glib-2.0/schemas/org.gnome.settings-daemon.plugins.account.gschema.xml
|
||||
|
||||
%{_libexecdir}/gsd-clipboard
|
||||
%{_sysconfdir}/xdg/autostart/org.gnome.SettingsDaemon.Clipboard.desktop
|
||||
|
||||
%{_libexecdir}/gsd-datetime
|
||||
%{_sysconfdir}/xdg/autostart/org.gnome.SettingsDaemon.Datetime.desktop
|
||||
|
||||
%{_libexecdir}/gsd-dummy
|
||||
|
||||
%{_libexecdir}/gsd-housekeeping
|
||||
%{_sysconfdir}/xdg/autostart/org.gnome.SettingsDaemon.Housekeeping.desktop
|
||||
%{_datadir}/glib-2.0/schemas/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml
|
||||
@ -119,6 +184,10 @@ cp %{SOURCE1} $RPM_BUILD_ROOT%{_datadir}/glib-2.0/schemas
|
||||
%{_sysconfdir}/xdg/autostart/org.gnome.SettingsDaemon.MediaKeys.desktop
|
||||
%{_datadir}/glib-2.0/schemas/org.gnome.settings-daemon.plugins.media-keys.gschema.xml
|
||||
|
||||
%{_libexecdir}/gsd-mouse
|
||||
%{_sysconfdir}/xdg/autostart/org.gnome.SettingsDaemon.Mouse.desktop
|
||||
%{_libexecdir}/gsd-locate-pointer
|
||||
|
||||
%{_libexecdir}/gsd-backlight-helper
|
||||
%{_datadir}/polkit-1/actions/org.gnome.settings-daemon.plugins.power.policy
|
||||
%{_libexecdir}/gsd-power
|
||||
@ -142,15 +211,13 @@ cp %{SOURCE1} $RPM_BUILD_ROOT%{_datadir}/glib-2.0/schemas
|
||||
%{_libexecdir}/gsd-sound
|
||||
%{_sysconfdir}/xdg/autostart/org.gnome.SettingsDaemon.Sound.desktop
|
||||
|
||||
%{_libexecdir}/gsd-usb-protection
|
||||
%{_sysconfdir}/xdg/autostart/org.gnome.SettingsDaemon.UsbProtection.desktop
|
||||
|
||||
%{_datadir}/glib-2.0/schemas/org.gnome.settings-daemon.peripherals.gschema.xml
|
||||
%{_datadir}/glib-2.0/schemas/org.gnome.settings-daemon.peripherals.wacom.gschema.xml
|
||||
%{_sysconfdir}/xdg/autostart/org.gnome.SettingsDaemon.Wacom.desktop
|
||||
|
||||
%ifnarch s390 s390x
|
||||
%{_libexecdir}/gsd-wacom
|
||||
%{_libexecdir}/gsd-wacom-led-helper
|
||||
%{_libexecdir}/gsd-wacom-oled-helper
|
||||
%{_datadir}/polkit-1/actions/org.gnome.settings-daemon.plugins.wacom.policy
|
||||
%endif
|
||||
@ -170,21 +237,14 @@ cp %{SOURCE1} $RPM_BUILD_ROOT%{_datadir}/glib-2.0/schemas
|
||||
%{_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.Wwan.desktop
|
||||
%{_libexecdir}/gsd-wwan
|
||||
%{_datadir}/glib-2.0/schemas/org.gnome.settings-daemon.plugins.wwan.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
|
||||
|
||||
%dir %{_libdir}/gnome-settings-daemon-40
|
||||
%{_libdir}/gnome-settings-daemon-40/libgsd.so
|
||||
%{_libdir}/gnome-settings-daemon-3.0/libgsd.so
|
||||
|
||||
%{_sysconfdir}/xdg/Xwayland-session.d/00-xrdb
|
||||
%{_userunitdir}/*
|
||||
/usr/lib/udev/rules.d/*.rules
|
||||
%{_datadir}/gnome-settings-daemon/
|
||||
%{_datadir}/GConf/gsettings/gnome-settings-daemon.convert
|
||||
@ -193,219 +253,97 @@ cp %{SOURCE1} $RPM_BUILD_ROOT%{_datadir}/glib-2.0/schemas
|
||||
%{_datadir}/glib-2.0/schemas/org.gnome.settings-daemon.plugins.gschema.xml
|
||||
|
||||
%files devel
|
||||
%{_includedir}/gnome-settings-daemon-40
|
||||
%{_includedir}/gnome-settings-daemon-3.0
|
||||
%{_libdir}/pkgconfig/gnome-settings-daemon.pc
|
||||
|
||||
%changelog
|
||||
* Thu Jan 18 2024 Ray Strode <rstrode@redhat.com> - 40.0.1-16
|
||||
- Try to start rhsm if it's not already running
|
||||
Related: RHEL-20449
|
||||
* Fri Feb 17 2023 Felipe Borges <feborges@redhat.com> - 4.32.0-19
|
||||
- Make power-button-action default to poweroff on servers
|
||||
- Resolves: #1920829
|
||||
|
||||
* Tue Jan 09 2024 Ray Strode <rstrode@redhat.com> - 40.0.1-15
|
||||
- Fix crashers in g-s-d and control-center related to
|
||||
making subscription-manager a soft dep
|
||||
Related: RHEL-20449
|
||||
* Tue Jan 24 2023 Felipe Borges <feborges@redhat.com> - 3.32.0-18
|
||||
- Prevent automatic logout warning in greeter sessions
|
||||
- Resolves: #2018606
|
||||
|
||||
* Thu Jan 04 2024 Ray Strode <rstrode@redhat.com> - 40.0.1-14
|
||||
- Make subman plugin sit dormant until subscription-manager is running
|
||||
Related: RHEL-20449
|
||||
* Wed Jan 04 2023 Felipe Borges <feborges@redhat.com> - 3.32.0-17
|
||||
- Make power-button-action respect the "nothing" action on VMs
|
||||
- Resolves: #2062051
|
||||
|
||||
* Fri Jun 16 2023 Ray Strode <rstrode@redhat.com> - 40.0.1-13
|
||||
- Revert hard dependency on subscription-manager since we're going to put it in gnome-session instead
|
||||
Related: #2175675
|
||||
* Fri Sep 10 2021 Kalev Lember <klember@redhat.com> - 3.32.0-16
|
||||
- Update pt_BR translations
|
||||
- Resolves: #2003069
|
||||
|
||||
* Thu May 04 2023 Ray Strode <rstrode@redhat.com> - 40.0.1-12
|
||||
- Add hard dependency on subscription-manager
|
||||
Resolves: #2175675
|
||||
* Fri Aug 06 2021 Carlos Garnacho <cgarnach@redhat.com> - 3.32.0-15
|
||||
- Keep auto-logout working inside VMs
|
||||
Resolves: #1904139
|
||||
|
||||
* Tue Mar 28 2023 Felipe Borges <feborges@redhat.com> - 40.0.1-11
|
||||
- Revert "power-button-action" always poweroff on Server chassis
|
||||
Resolves: #2182380
|
||||
* Mon Mar 01 2021 Kalev Lember <klember@redhat.com> - 3.32.0-14
|
||||
- Update fr, ja, zh_CN translations
|
||||
- Resolves: #1876291
|
||||
|
||||
* Wed Feb 22 2023 Felipe Borges <feborges@redhat.com> - 40.0.1-10
|
||||
- Default power-button-action to poweroff on servers
|
||||
(except when power-button-action=nothing)
|
||||
Resolves: #1885639
|
||||
* Thu Jan 21 2021 Ray Strode <rstrode@redhat.com> - 3.32.0-13
|
||||
- Add back subscription-manager plugin
|
||||
Related: #1870837
|
||||
|
||||
* Mon Feb 20 2023 Marek Kasik <mkasik@redhat.com> - 40.0.1-9
|
||||
- Clear members of GsdPrintNotificationsManager in stop()
|
||||
Resolves: #2166842
|
||||
* Tue Jan 05 2021 Jonas Ådahl <jadahl@redhat.com> - 3.32.0-12
|
||||
- Handle org.gnome.Shell.Screencast Stopped signal
|
||||
Related: #1705392
|
||||
|
||||
* Mon Aug 01 2022 Felipe Borges <feborges@redhat.com> - 40.0.1-8
|
||||
- Fix registration with activation key
|
||||
Resolves: #2100467
|
||||
* Wed Sep 02 2020 Ray Strode <rstrode@redhat.com> - 3.32.0-11
|
||||
- Remove subman plugin for now
|
||||
Resolves: #1872457
|
||||
|
||||
* Wed Jul 13 2022 Carlos Garnacho <cgarnach@redhat.com> - 40.0.1-7
|
||||
- Manage im-context Xsetting dynamically
|
||||
Resolves: #2087031
|
||||
* Thu Aug 13 2020 Carl George <carl@redhat.com> - 3.32.0-10
|
||||
- Disable subman plugin on CentOS
|
||||
Resolves: #1827030
|
||||
|
||||
* Mon Feb 14 2022 Ray Strode <rstrode@redhat.com> - 40.0.1-6
|
||||
- Update for non-deprecated subscription management API
|
||||
Resolves: #2049734
|
||||
* Fri Nov 22 2019 Benjamin Otte <otte@redhat.com> - 3.32.0-9
|
||||
- Update gsettings-deskto-schemas dependency for new setting
|
||||
Resolves: #1775683, #1723462
|
||||
|
||||
* Wed Sep 08 2021 Kalev Lember <klember@redhat.com> - 40.0.1-5
|
||||
- Fix the icon shown for subscription manager notifications
|
||||
- Related: #1937113
|
||||
* Thu Nov 21 2019 Benjamin Otte <otte@redhat.com> - 3.32.0-8
|
||||
- Add upstream setting for overlay scrolling
|
||||
Resolves: #1723462
|
||||
|
||||
* Thu Sep 02 2021 Kalev Lember <klember@redhat.com> - 40.0.1-4
|
||||
- Forward port subscription manager support from RHEL 8
|
||||
- Resolves: #1937113
|
||||
* Mon Nov 18 2019 Kalev Lember <klember@redhat.com> - 3.32.0-7
|
||||
- Add a new plugin to provide system subscription information
|
||||
- Resolves: #1720249
|
||||
|
||||
* Thu Aug 19 2021 Carlos Garnacho <cgarnach@redhat.com> - 40.0.1-3
|
||||
- Backport power saving changes
|
||||
Resolves: #1994476
|
||||
* Mon Nov 04 2019 Marek Kasik <mkasik@redhat.com> - 3.32.0-6
|
||||
- Initialize a variable from previous commit.
|
||||
- Previous commit made it possible to use uninitialized variable.
|
||||
- Detected by Coverity.
|
||||
- Related: #1742710
|
||||
|
||||
* Mon Aug 09 2021 Mohan Boddu <mboddu@redhat.com> - 40.0.1-2
|
||||
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
|
||||
Related: rhbz#1991688
|
||||
* Mon Nov 04 2019 Marek Kasik <mkasik@redhat.com> - 3.32.0-5
|
||||
- Cancel cancellable when stopping smartcard plugin to avoid crash
|
||||
- Resolves: #1742710
|
||||
|
||||
* Fri May 07 2021 Kalev Lember <klember@redhat.com> - 40.0.1-1
|
||||
- Update to 40.0.1
|
||||
* Tue Jul 09 2019 Richard Hughes <rhughes@redhat.com> - 3.32.0-4
|
||||
- Remove the subman plugin -- move to a 8.2 feature instead.
|
||||
- Resolves: #1720249
|
||||
|
||||
* Thu Apr 15 2021 Mohan Boddu <mboddu@redhat.com> - 40.0-2
|
||||
- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937
|
||||
* Mon Jun 17 2019 Richard Hughes <rhughes@redhat.com> - 3.32.0-3
|
||||
- Add a new plugin to provide system subscription information
|
||||
- Resolves: #1720249
|
||||
|
||||
* Mon Mar 22 2021 Kalev Lember <klember@redhat.com> - 40.0-1
|
||||
- Update to 40.0
|
||||
- Drop old obsoletes/conflicts
|
||||
* Mon Jun 10 2019 Ray Strode <rstrode@redhat.com> - 3.32.0-2
|
||||
- Add dropped patches
|
||||
Related: #1674382
|
||||
|
||||
* Mon Mar 15 2021 Kalev Lember <klember@redhat.com> - 40~rc-1
|
||||
- Update to 40.rc
|
||||
|
||||
* Mon Feb 15 2021 Kalev Lember <klember@redhat.com> - 40~beta-2
|
||||
- Fix loading gtk modules
|
||||
- Update versioned dependencies
|
||||
|
||||
* Mon Feb 15 2021 Florian Müllner <fmuellner@redhat.com> - 40~beta-1
|
||||
- Update to 40.beta
|
||||
|
||||
* Mon Feb 15 2021 Florian Müllner <fmuellner@redhat.com> - 40~alpha.1-1
|
||||
- Update to 40.alpha.1
|
||||
|
||||
* Tue Jan 26 2021 Fedora Release Engineering <releng@fedoraproject.org> - 3.38.1-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
|
||||
|
||||
* Fri Oct 9 2020 Kalev Lember <klember@redhat.com> - 3.38.1-1
|
||||
- Update to 3.38.1
|
||||
|
||||
* Mon Sep 14 2020 Kalev Lember <klember@redhat.com> - 3.38.0-1
|
||||
- Update to 3.38.0
|
||||
|
||||
* Mon Sep 07 2020 Kalev Lember <klember@redhat.com> - 3.37.92-1
|
||||
- Update to 3.37.92
|
||||
|
||||
* Sat Aug 29 2020 Kalev Lember <klember@redhat.com> - 3.37.1-1
|
||||
- Update to 3.37.1
|
||||
|
||||
* Mon Aug 17 2020 Kalev Lember <klember@redhat.com> - 3.37.0-1
|
||||
- Update to 3.37.0
|
||||
|
||||
* Sat Aug 01 2020 Fedora Release Engineering <releng@fedoraproject.org> - 3.36.1-3
|
||||
- Second attempt - Rebuilt for
|
||||
https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
|
||||
|
||||
* Mon Jul 27 2020 Fedora Release Engineering <releng@fedoraproject.org> - 3.36.1-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
|
||||
|
||||
* Thu Apr 30 2020 Kalev Lember <klember@redhat.com> - 3.36.1-1
|
||||
- Update to 3.36.1
|
||||
|
||||
* Mon Mar 09 2020 Kalev Lember <klember@redhat.com> - 3.36.0-1
|
||||
- Update to 3.36.0
|
||||
|
||||
* Mon Mar 02 2020 Kalev Lember <klember@redhat.com> - 3.35.92-1
|
||||
- Update to 3.35.92
|
||||
|
||||
* Tue Feb 18 2020 Kalev Lember <klember@redhat.com> - 3.35.91-1
|
||||
- Update to 3.35.91
|
||||
|
||||
* Tue Jan 28 2020 Fedora Release Engineering <releng@fedoraproject.org> - 3.35.0-3
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
|
||||
|
||||
* Thu Jan 16 2020 Kalev Lember <klember@redhat.com> - 3.35.0-2
|
||||
- Rebuilt for libgnome-desktop soname bump
|
||||
|
||||
* Tue Jan 07 2020 Kalev Lember <klember@redhat.com> - 3.35.0-1
|
||||
- Update to 3.35.0
|
||||
|
||||
* Mon Oct 14 2019 Kalev Lember <klember@redhat.com> - 3.34.1-1
|
||||
- Update to 3.34.1
|
||||
|
||||
* Mon Sep 09 2019 Kalev Lember <klember@redhat.com> - 3.34.0-1
|
||||
- Update to 3.34.0
|
||||
|
||||
* Fri Sep 06 2019 Kalev Lember <klember@redhat.com> - 3.33.92-1
|
||||
- Update to 3.33.92
|
||||
|
||||
* Mon Aug 26 2019 Kalev Lember <klember@redhat.com> - 3.33.90-1
|
||||
- Update to 3.33.90
|
||||
- Drop old versioned conflicts
|
||||
|
||||
* Thu Jul 25 2019 Fedora Release Engineering <releng@fedoraproject.org> - 3.33.0-4
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
|
||||
|
||||
* Sun Jul 21 2019 Kalev Lember <klember@redhat.com> - 3.33.0-3
|
||||
- Rebuilt for libgnome-desktop soname bump
|
||||
|
||||
* Mon Jul 08 2019 Kalev Lember <klember@redhat.com> - 3.33.0-2
|
||||
- Rebuilt for libgweather soname bump
|
||||
|
||||
* Tue Jun 25 2019 Kalev Lember <klember@redhat.com> - 3.33.0-1
|
||||
- Update to 3.33.0
|
||||
|
||||
* Wed Jun 19 2019 Kalev Lember <klember@redhat.com> - 3.32.1-1
|
||||
- Update to 3.32.1
|
||||
|
||||
* Tue May 28 2019 Marek Kasik <mkasik@redhat.com> - 3.32.0-2
|
||||
- Fix NSS crash at smartcard plugin (#1688791)
|
||||
|
||||
* Mon Mar 11 2019 Kalev Lember <klember@redhat.com> - 3.32.0-1
|
||||
* Thu May 23 2019 Florian Müllner <fmuellner@redhat.com> - 3.32.0-1
|
||||
- Update to 3.32.0
|
||||
Resolves: #1698929
|
||||
|
||||
* Wed Mar 06 2019 Kalev Lember <klember@redhat.com> - 3.31.92-1
|
||||
- Update to 3.31.92
|
||||
|
||||
* Wed Feb 20 2019 Kalev Lember <klember@redhat.com> - 3.31.91-1
|
||||
- Update to 3.31.91
|
||||
|
||||
* Wed Feb 06 2019 Kalev Lember <klember@redhat.com> - 3.31.90-1
|
||||
- Update to 3.31.90
|
||||
|
||||
* Thu Jan 31 2019 Fedora Release Engineering <releng@fedoraproject.org> - 3.31.2-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
|
||||
|
||||
* Wed Jan 09 2019 Kalev Lember <klember@redhat.com> - 3.31.2-1
|
||||
- Update to 3.31.2
|
||||
|
||||
* Tue Nov 20 2018 Pete Walter <pwalter@fedoraproject.org> - 3.30.1.2-3
|
||||
- Move gnome-remote-desktop recommends to gnome-control-center
|
||||
|
||||
* Fri Nov 09 2018 Ray Strode <rstrode@redhat.com> - 3.30.1.2-2
|
||||
- Add recommends for gnome-remote-desktop after irc discussion
|
||||
|
||||
* Thu Oct 04 2018 Kalev Lember <klember@redhat.com> - 3.30.1.2-1
|
||||
- Update to 3.30.1.2
|
||||
|
||||
* Fri Sep 28 2018 Kalev Lember <klember@redhat.com> - 3.30.1.1-1
|
||||
- Update to 3.30.1.1
|
||||
|
||||
* Thu Sep 06 2018 Kalev Lember <klember@redhat.com> - 3.30.0-1
|
||||
- Update to 3.30.0
|
||||
|
||||
* Sun Aug 12 2018 Kalev Lember <klember@redhat.com> - 3.29.90.1-1
|
||||
- Update to 3.29.90.1
|
||||
|
||||
* Tue Jul 31 2018 Florian Weimer <fweimer@redhat.com> - 3.28.1-3
|
||||
- Rebuild with fixed binutils
|
||||
|
||||
* Fri Jul 13 2018 Fedora Release Engineering <releng@fedoraproject.org> - 3.28.1-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
|
||||
* Mon Jan 14 2019 Carlos Garnacho <cgarnach@redhat.com> - 3.28.1-2
|
||||
- Enable IBus for OSK purposes, necessary for focus tracking
|
||||
Resolves: #1626105
|
||||
|
||||
* Thu Apr 12 2018 Kalev Lember <klember@redhat.com> - 3.28.1-1
|
||||
- Update to 3.28.1
|
||||
|
||||
* Tue Apr 10 2018 Michael Catanzaro <mcatanzaro@gnome.org> - 3.28.0-2
|
||||
- Disable automatic suspend, except when on battery power
|
||||
- Disable automatic suspend
|
||||
|
||||
* Mon Mar 12 2018 Kalev Lember <klember@redhat.com> - 3.28.0-1
|
||||
- Update to 3.28.0
|
||||
|
Loading…
Reference in New Issue
Block a user