[gnome-packagekit] Add optional systemd support
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-packagekit] Add optional systemd support
- Date: Tue, 17 Jan 2012 14:27:57 +0000 (UTC)
commit b139de03145f577d32bdc1c549a7b08e71ef4061
Author: Matthias Clasen <mclasen redhat com>
Date: Sat Dec 24 01:09:33 2011 -0500
Add optional systemd support
This patch adds a --enable-systemd configure flag that makes
gnome-packagekit use systemd instead of ConsoleKit for rebooting.
https://bugzilla.gnome.org/show_bug.cgi?id=666788
configure.ac | 36 +++++++++++++++
src/Makefile.am | 14 +++++-
src/gpk-distro-upgrade.c | 25 +++++++++++
src/gpk-update-viewer.c | 25 +++++++++++
src/systemd-proxy.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++
src/systemd-proxy.h | 41 +++++++++++++++++
6 files changed, 246 insertions(+), 2 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 7d75864..b468bde 100644
--- a/configure.ac
+++ b/configure.ac
@@ -138,6 +138,42 @@ fi
AM_CONDITIONAL(HAVE_GUDEV, test x$HAVE_GUDEV = xyes)
dnl ---------------------------------------------------------------------------
+dnl systemd integration
+dnl ---------------------------------------------------------------------------
+AC_ARG_ENABLE([systemd],
+ AS_HELP_STRING([--enable-systemd], [Use systemd]),
+ [with_systemd=$enableval],
+ [with_systemd=auto])
+
+PKG_CHECK_MODULES(SYSTEMD,
+ [libsystemd-login polkit-gobject-1],
+ [have_systemd=yes], [have_systemd=no])
+
+AC_MSG_CHECKING([whether to use systemd])
+
+if test x$with_systemd = xauto ; then
+ if test x$have_systemd = xno ; then
+ with_systemd=no
+ else
+ with_systemd=yes
+ fi
+fi
+
+AC_MSG_RESULT($with_systemd)
+
+if test x$with_systemd = xyes; then
+ if test x$have_systemd = xno; then
+ AC_MSG_ERROR([Systemd support explicitly required, but systemd not found])
+ fi
+ AC_DEFINE(HAVE_SYSTEMD, 1, [Define if systemd is used for session tracking])
+fi
+
+AC_SUBST(SYSTEMD_CFLAGS)
+AC_SUBST(SYSTEMD_LIBS)
+
+AM_CONDITIONAL(WITH_SYSTEMD, [test "$with_systemd" = "yes"], [Using systemd])
+
+dnl ---------------------------------------------------------------------------
dnl - Enable small form factor code
dnl ---------------------------------------------------------------------------
AC_ARG_ENABLE(small_form_factor, AS_HELP_STRING([--enable-small-form-factor],[enable small form factor code]),
diff --git a/src/Makefile.am b/src/Makefile.am
index 7c3e974..c15f6b8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -11,6 +11,7 @@ INCLUDES = \
$(NOTIFY_CFLAGS) \
$(PACKAGEKIT_CFLAGS) \
$(GUDEV_CFLAGS) \
+ $(SYSTEMD_CFLAGS) \
$(GNOME_MENUS_CFLAGS) \
-DI_KNOW_THE_UPOWER_API_IS_SUBJECT_TO_CHANGE \
-DI_KNOW_THE_PACKAGEKIT_GLIB2_API_IS_SUBJECT_TO_CHANGE \
@@ -50,8 +51,6 @@ libgpkshared_a_SOURCES = \
egg-string.h \
egg-markdown.c \
egg-markdown.h \
- egg-console-kit.c \
- egg-console-kit.h \
egg-dbus-monitor.c \
egg-dbus-monitor.h \
gpk-debug.c \
@@ -90,6 +89,16 @@ libgpkshared_a_SOURCES = \
gpk-error.h \
$(NULL)
+if WITH_SYSTEMD
+libgpkshared_a_SOURCES += \
+ systemd-proxy.c \
+ systemd-proxy.h
+else
+libgpkshared_a_SOURCES += \
+ egg-console-kit.c \
+ egg-console-kit.h
+endif
+
shared_LIBS = \
$(GLIB_LIBS) \
$(GIO_LIBS) \
@@ -97,6 +106,7 @@ shared_LIBS = \
$(GTK_LIBS) \
$(GUDEV_LIBS) \
$(NOTIFY_LIBS) \
+ $(SYSTEMD_LIBS) \
$(PACKAGEKIT_LIBS) \
$(GNOME_MENUS_LIBS) \
$(UPOWER_LIBS) \
diff --git a/src/gpk-distro-upgrade.c b/src/gpk-distro-upgrade.c
index f74d14c..566a26f 100644
--- a/src/gpk-distro-upgrade.c
+++ b/src/gpk-distro-upgrade.c
@@ -26,7 +26,12 @@
#include <locale.h>
#include <packagekit-glib2/packagekit.h>
+#ifdef HAVE_SYSTEMD
+#include "systemd-proxy.h"
+#else
#include "egg-console-kit.h"
+#endif
+
#include "gpk-animated-icon.h"
#include "gpk-common.h"
#include "gpk-debug.h"
@@ -40,7 +45,11 @@ enum {
};
typedef struct {
+#ifdef HAVE_SYSTEMD
+ SystemdProxy *systemd_proxy;
+#else
EggConsoleKit *console_kit;
+#endif
GCancellable *cancellable;
GtkListStore *distro_upgrade_store;
GtkWidget *assistant;
@@ -108,7 +117,11 @@ gpk_distro_upgrade_restart_response_cb (GtkDialog *dialog, gint response_id, Gpk
/* restart */
if (response_id == GTK_RESPONSE_OK) {
+#ifdef HAVE_SYSTEMD
+ ret = systemd_proxy_restart (priv->systemd_proxy, &error);
+#else
ret = egg_console_kit_restart (priv->console_kit, &error);
+#endif
if (!ret) {
g_warning ("Cannot restart: %s", error->message);
g_error_free (error);
@@ -164,8 +177,12 @@ gpk_distro_upgrade_upgrade_system_cb (PkClient *client, GAsyncResult *res, GpkDi
_("When you are ready, you can restart your system and continue the upgrade process."),
_("Make sure you have saved any unsaved work before restarting."));
+#ifdef HAVE_SYSTEMD
+ ret = systemd_proxy_can_restart (priv->systemd_proxy, &can_restart, &error);
+#else
/* check with ConsoleKit we can restart */
ret = egg_console_kit_can_restart (priv->console_kit, &can_restart, &error);
+#endif
if (!ret) {
g_warning ("cannot get consolekit CanRestart data: %s", error->message);
g_error_free (error);
@@ -764,7 +781,11 @@ main (int argc, char *argv[])
g_type_init ();
gtk_init (&argc, &argv);
priv = g_new0 (GpkDistroUpgradePrivate, 1);
+#ifdef HAVE_SYSTEMD
+ priv->systemd_proxy = systemd_proxy_new ();
+#else
priv->console_kit = egg_console_kit_new ();
+#endif
priv->cancellable = g_cancellable_new ();
priv->client = pk_client_new ();
g_object_set (priv->client,
@@ -799,7 +820,11 @@ main (int argc, char *argv[])
out:
g_object_unref (priv->cancellable);
g_object_unref (priv->client);
+#ifdef HAVE_SYSTEMD
+ systemd_proxy_free (priv->systemd_proxy);
+#else
g_object_unref (priv->console_kit);
+#endif
g_free (priv);
if (application)
g_object_unref (application);
diff --git a/src/gpk-update-viewer.c b/src/gpk-update-viewer.c
index 67caffd..100cd2e 100644
--- a/src/gpk-update-viewer.c
+++ b/src/gpk-update-viewer.c
@@ -32,7 +32,11 @@
#include "egg-string.h"
#include "egg-markdown.h"
+#ifdef HAVE_SYSTEMD
+#include "systemd-proxy.h"
+#else
#include "egg-console-kit.h"
+#endif
#include "gpk-cell-renderer-info.h"
#include "gpk-cell-renderer-restart.h"
@@ -57,7 +61,11 @@ static guint auto_shutdown_id = 0;
static guint size_total = 0;
static guint number_total = 0;
static PkRestartEnum restart_worst = 0;
+#ifdef HAVE_SYSTEMD
+static SystemdProxy *proxy = NULL;
+#else
static EggConsoleKit *console = NULL;
+#endif
static EggMarkdown *markdown = NULL;
static GCancellable *cancellable = NULL;
static GSettings *settings = NULL;
@@ -240,7 +248,11 @@ gpk_update_viewer_check_restart (void)
/* check to see if restart is possible */
if (restart_update == PK_RESTART_ENUM_SYSTEM ||
restart_update == PK_RESTART_ENUM_SECURITY_SYSTEM) {
+#ifdef HAVE_SYSTEMD
+ systemd_proxy_can_restart (proxy, &show_button, NULL);
+#else
egg_console_kit_can_restart (console, &show_button, NULL);
+#endif
}
/* only show the button if we can do the action */
@@ -260,8 +272,12 @@ gpk_update_viewer_check_restart (void)
/* do the action */
if (restart_update == PK_RESTART_ENUM_SYSTEM)
+#ifdef HAVE_SYSTEMD
+ ret = systemd_proxy_restart (proxy, &error);
+#else
/* use consolekit to restart */
ret = egg_console_kit_restart (console, &error);
+#endif
if (!ret) {
/* TRANSLATORS: the PackageKit request did not complete, and it did not send an error */
gpk_update_viewer_error_dialog (_("Could not restart"), NULL, error->message);
@@ -3149,7 +3165,11 @@ gpk_update_viewer_application_startup_cb (GtkApplication *_application, gpointer
restart_update = PK_RESTART_ENUM_NONE;
settings = g_settings_new (GPK_SETTINGS_SCHEMA);
+#ifdef HAVE_SYSTEMD
+ proxy = systemd_proxy_new ();
+#else
console = egg_console_kit_new ();
+#endif
cancellable = g_cancellable_new ();
markdown = egg_markdown_new ();
egg_markdown_set_output (markdown, EGG_MARKDOWN_OUTPUT_PANGO);
@@ -3391,8 +3411,13 @@ main (int argc, char *argv[])
g_object_unref (builder);
if (cancellable != NULL)
g_object_unref (cancellable);
+#ifdef HAVE_SYSTEMD
+ if (proxy != NULL)
+ systemd_proxy_free (proxy);
+#else
if (console != NULL)
g_object_unref (console);
+#endif
if (control != NULL)
g_object_unref (control);
if (settings != NULL)
diff --git a/src/systemd-proxy.c b/src/systemd-proxy.c
new file mode 100644
index 0000000..50fec25
--- /dev/null
+++ b/src/systemd-proxy.c
@@ -0,0 +1,107 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2011 Matthias Clasen
+ *
+ * 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 <gio/gio.h>
+#include <polkit/polkit.h>
+
+#include "systemd-proxy.h"
+
+#define SYSTEMD_DBUS_NAME "org.freedesktop.login1"
+#define SYSTEMD_DBUS_PATH "/org/freedesktop/login1"
+#define SYSTEMD_DBUS_INTERFACE "org.freedesktop.login1.Manager"
+#define SYSTEMD_REBOOT_ACTION "org.freedesktop.login1.reboot"
+
+struct _SystemdProxy {
+ PolkitAuthority *authority;
+ PolkitSubject *subject;
+};
+
+SystemdProxy *
+systemd_proxy_new (void)
+{
+ SystemdProxy *proxy;
+
+ proxy = g_new0 (SystemdProxy, 1);
+
+ proxy->authority = polkit_authority_get_sync (NULL, NULL);
+ proxy->subject = polkit_unix_session_new_for_process_sync (getpid(), NULL, NULL);
+
+ return proxy;
+}
+
+void
+systemd_proxy_free (SystemdProxy *proxy)
+{
+ g_object_unref (proxy->authority);
+ g_object_unref (proxy->subject);
+
+ g_free (proxy);
+}
+
+gboolean
+systemd_proxy_can_restart (SystemdProxy *proxy,
+ gboolean *can_restart,
+ GError **error)
+{
+ PolkitAuthorizationResult *res;
+ GError *local_error = NULL;
+
+ *can_restart = FALSE;
+ res = polkit_authority_check_authorization_sync (proxy->authority,
+ proxy->subject,
+ SYSTEMD_REBOOT_ACTION,
+ NULL,
+ POLKIT_CHECK_AUTHORIZATION_FLAGS_NONE,
+ NULL,
+ &local_error);
+ if (res == NULL) {
+ g_propagate_error (error, local_error);
+ return FALSE;
+ }
+
+ *can_restart = polkit_authorization_result_get_is_authorized (res) ||
+ polkit_authorization_result_get_is_challenge (res);
+
+ g_object_unref (res);
+
+ return TRUE;
+}
+
+gboolean
+systemd_proxy_restart (SystemdProxy *proxy,
+ GError **error)
+{
+ GDBusConnection *bus;
+
+ bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL);
+ g_dbus_connection_call (bus,
+ SYSTEMD_DBUS_NAME,
+ SYSTEMD_DBUS_PATH,
+ SYSTEMD_DBUS_INTERFACE,
+ "Reboot",
+ g_variant_new ("(b)", TRUE),
+ NULL, 0, G_MAXINT, NULL, NULL, NULL);
+ g_object_unref (bus);
+
+ return TRUE;
+}
diff --git a/src/systemd-proxy.h b/src/systemd-proxy.h
new file mode 100644
index 0000000..133be52
--- /dev/null
+++ b/src/systemd-proxy.h
@@ -0,0 +1,41 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2011 Matthias Clasen
+ *
+ * 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.
+ */
+
+#ifndef __SYSTEMD_PROXY_H__
+#define __SYSTEMD_PROXY_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+typedef struct _SystemdProxy SystemdProxy;
+
+SystemdProxy *systemd_proxy_new (void);
+void systemd_proxy_free (SystemdProxy *proxy);
+gboolean systemd_proxy_can_restart (SystemdProxy *proxy,
+ gboolean *can_restart,
+ GError **error);
+gboolean systemd_proxy_restart (SystemdProxy *proxy,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* __SYSTEMD_PROXY_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]