summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Festi <ffesti@redhat.com>2020-06-03 14:48:05 +0200
committerPanu Matilainen <pmatilai@redhat.com>2021-08-20 11:44:09 +0300
commit8193a6425740bfc674bd50bb21f05d25b5c79df6 (patch)
tree0ecce0cf1130c823de6032fcf1de5de3c318b301
parent6f9c596d17ec8695aceaab5967e69f8fe1bba7c8 (diff)
downloadrpm-8193a6425740bfc674bd50bb21f05d25b5c79df6.tar.gz
Add dbus-announce plugin
The plugin announces start and end of transactions (cherry picked from commit 2a03b8fa12319d4650ee3cd1c48d1cd3ab8afe56)
-rw-r--r--docs/man/Makefile.am3
-rw-r--r--docs/man/rpm-plugin-dbus-announce.8.md38
-rw-r--r--macros.in1
-rw-r--r--plugins/Makefile.am9
-rw-r--r--plugins/dbus_announce.c142
-rw-r--r--plugins/org.rpm.conf10
6 files changed, 202 insertions, 1 deletions
diff --git a/docs/man/Makefile.am b/docs/man/Makefile.am
index e10959255..f32efa192 100644
--- a/docs/man/Makefile.am
+++ b/docs/man/Makefile.am
@@ -27,6 +27,7 @@ man_man8_DATA += rpm-plugin-audit.8
endif
if DBUS
man_man8_DATA += rpm-plugin-systemd-inhibit.8
+man_man8_DATA += rpm-plugin-dbus-announce.8
endif
if IMA
man_man8_DATA += rpm-plugin-ima.8
@@ -46,7 +47,7 @@ endif
EXTRA_DIST += rpm-plugins.8.md rpm-plugin-prioreset.8.md rpm-plugin-syslog.8.md
EXTRA_DIST += rpm-plugin-audit.8.md rpm-plugin-systemd-inhibit.8.md
EXTRA_DIST += rpm-plugin-ima.8.md rpm-plugin-selinux.8.md rpm2archive.8.md
-EXTRA_DIST += rpm-plugin-fapolicyd.8.md
+EXTRA_DIST += rpm-plugin-fapolicyd.8.md rpm-plugin-dbus-announce.8.md
# Package generated man pages
EXTRA_DIST += rpm-plugins.8 rpm-plugin-prioreset.8 rpm-plugin-syslog.8
diff --git a/docs/man/rpm-plugin-dbus-announce.8.md b/docs/man/rpm-plugin-dbus-announce.8.md
new file mode 100644
index 000000000..212a4de8b
--- /dev/null
+++ b/docs/man/rpm-plugin-dbus-announce.8.md
@@ -0,0 +1,38 @@
+---
+date: 03 Jun 2020
+section: 8
+title: 'RPM-DBUS-ANNOUNCE'
+---
+
+NAME
+====
+
+rpm-plugin-dbus-announce - DBus plugin for the RPM Package Manager
+
+Description
+===========
+
+The plugin writes basic information about rpm transactions to the system
+dbus - like packages installed or removed. Other programs can subscribe
+to the signals to be notified of the packages on the system change.
+
+DBus Signals
+============
+
+Sends **StartTransaction** and **EndTransaction** messages from the
+**/org/rpm/Transaction** object with the **org.rpm.Transaction**
+interface.
+
+The signal passes the DB cookie as a string and the transaction id as an
+unsigned 32 bit integer.
+
+Configuration
+=============
+
+There are currently no options for this plugin in particular. See
+**rpm-plugins**(8) on how to control plugins in general.
+
+SEE ALSO
+========
+
+*dbus-monitor*(1) *rpm-plugins*(8)
diff --git a/macros.in b/macros.in
index a1f795e5f..22f675cdb 100644
--- a/macros.in
+++ b/macros.in
@@ -1146,6 +1146,7 @@ package or when debugging this package.\
%__transaction_fsverity %{__plugindir}/fsverity.so
%__transaction_prioreset %{__plugindir}/prioreset.so
%__transaction_audit %{__plugindir}/audit.so
+%__transaction_dbus_announce %{__plugindir}/dbus_announce.so
#------------------------------------------------------------------------------
# Macros for further automated spec %setup and patch application
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index 963d53db4..3a929d0ce 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -27,6 +27,15 @@ systemd_inhibit_la_SOURCES = systemd_inhibit.c
systemd_inhibit_la_CPPFLAGS = $(AM_CPPFLAGS) @DBUS_CFLAGS@
systemd_inhibit_la_LIBADD = $(top_builddir)/lib/librpm.la $(top_builddir)/rpmio/librpmio.la @DBUS_LIBS@
plugins_LTLIBRARIES += systemd_inhibit.la
+
+dbus_announce_la_SOURCES = dbus_announce.c
+dbus_announce_la_CPPFLAGS = $(AM_CPPFLAGS) @DBUS_CFLAGS@
+dbus_announce_la_LIBADD = $(top_builddir)/lib/librpm.la $(top_builddir)/rpmio/librpmio.la @DBUS_LIBS@
+plugins_LTLIBRARIES += dbus_announce.la
+
+dbus_confdir=$(sysconfdir)/dbus-1/system.d/
+dbus_conf_DATA = org.rpm.conf
+EXTRA_DIST = org.rpm.conf
endif
prioreset_la_SOURCES = prioreset.c
diff --git a/plugins/dbus_announce.c b/plugins/dbus_announce.c
new file mode 100644
index 000000000..a82b23908
--- /dev/null
+++ b/plugins/dbus_announce.c
@@ -0,0 +1,142 @@
+#include "system.h"
+
+#include <dbus/dbus.h>
+#include <rpm/rpmlog.h>
+#include <rpm/rpmts.h>
+#include <rpm/rpmdb.h>
+#include "lib/rpmplugin.h"
+
+struct dbus_announce_data {
+ DBusConnection * bus;
+};
+
+static rpmRC dbus_announce_init(rpmPlugin plugin, rpmts ts)
+{
+ struct dbus_announce_data * state = rcalloc(1, sizeof(*state));
+ rpmPluginSetData(plugin, state);
+ return RPMRC_OK;
+}
+
+static void dbus_announce_close_bus(struct dbus_announce_data * state)
+{
+ if (state->bus) {
+ dbus_connection_close(state->bus);
+ dbus_connection_unref(state->bus);
+ state->bus = NULL;
+ }
+}
+
+static rpmRC open_dbus(rpmPlugin plugin, rpmts ts)
+{
+ DBusError err;
+ int rc = 0;
+ struct dbus_announce_data * state = rpmPluginGetData(plugin);
+
+ /* Already open */
+ if (state->bus)
+ return RPMRC_OK;
+
+ /* ...don't notify on test transactions */
+ if (rpmtsFlags(ts) & (RPMTRANS_FLAG_TEST|RPMTRANS_FLAG_BUILD_PROBS))
+ return RPMRC_OK;
+
+ /* ...don't notify on chroot transactions */
+ if (!rstreq(rpmtsRootDir(ts), "/"))
+ return RPMRC_OK;
+
+ dbus_error_init(&err);
+
+ state->bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &err);
+ if (dbus_error_is_set(&err))
+ goto err;
+
+ if (state->bus)
+ rc = dbus_bus_request_name(state->bus, "org.rpm.announce",
+ DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
+
+ if (dbus_error_is_set(&err))
+ goto err;
+
+ if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != rc) {
+ dbus_announce_close_bus(state);
+ goto err;
+ }
+ return RPMRC_OK;
+ err:
+ rpmlog(RPMLOG_WARNING,
+ "dbus_announce plugin: Error connecting to dbus (%s)\n",
+ err.message);
+ dbus_error_free(&err);
+ return RPMRC_OK;
+}
+
+static void dbus_announce_cleanup(rpmPlugin plugin)
+{
+ struct dbus_announce_data * state = rpmPluginGetData(plugin);
+ dbus_announce_close_bus(state);
+ free(state);
+}
+
+static rpmRC send_ts_message(rpmPlugin plugin,
+ const char * name,
+ rpmts ts,
+ int res)
+{
+ struct dbus_announce_data * state = rpmPluginGetData(plugin);
+ DBusMessage* msg;
+ char * dbcookie = NULL;
+
+ if (!state->bus)
+ return RPMRC_OK;
+
+ msg = dbus_message_new_signal("/org/rpm/Transaction", /* object name */
+ "org.rpm.Transaction", /* interface name */
+ name); /* signal name */
+ if (msg == NULL)
+ goto err;
+
+ dbcookie = rpmdbCookie(rpmtsGetRdb(ts));
+ rpm_tid_t tid = rpmtsGetTid(ts);
+ if (!dbus_message_append_args(msg,
+ DBUS_TYPE_STRING, &dbcookie,
+ DBUS_TYPE_UINT32, &tid,
+ DBUS_TYPE_INVALID))
+ goto err;
+
+ if (!dbus_connection_send(state->bus, msg, NULL))
+ goto err;
+
+ dbus_connection_flush(state->bus);
+ dbcookie = _free(dbcookie);
+
+ return RPMRC_OK;
+
+ err:
+ rpmlog(RPMLOG_WARNING,
+ "dbus_announce plugin: Error sending message (%s)\n",
+ name);
+ dbcookie = _free(dbcookie);
+ return RPMRC_OK;
+}
+
+static rpmRC dbus_announce_tsm_pre(rpmPlugin plugin, rpmts ts)
+{
+ int rc;
+
+ rc = open_dbus(plugin, ts);
+ if (rc != RPMRC_OK)
+ return rc;
+ return send_ts_message(plugin, "StartTransaction", ts, RPMRC_OK);
+}
+
+static rpmRC dbus_announce_tsm_post(rpmPlugin plugin, rpmts ts, int res)
+{
+ return send_ts_message(plugin, "EndTransaction", ts, res);
+}
+
+struct rpmPluginHooks_s dbus_announce_hooks = {
+ .init = dbus_announce_init,
+ .cleanup = dbus_announce_cleanup,
+ .tsm_pre = dbus_announce_tsm_pre,
+ .tsm_post = dbus_announce_tsm_post,
+};
diff --git a/plugins/org.rpm.conf b/plugins/org.rpm.conf
new file mode 100644
index 000000000..7def6d506
--- /dev/null
+++ b/plugins/org.rpm.conf
@@ -0,0 +1,10 @@
+<!DOCTYPE busconfig PUBLIC
+ "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+<busconfig>
+
+<policy user="root">
+ <allow own="org.rpm.announce"/>
+</policy>
+
+</busconfig>