diff options
author | Florian Festi <ffesti@redhat.com> | 2020-06-03 14:48:05 +0200 |
---|---|---|
committer | Panu Matilainen <pmatilai@redhat.com> | 2021-08-20 11:44:09 +0300 |
commit | 8193a6425740bfc674bd50bb21f05d25b5c79df6 (patch) | |
tree | 0ecce0cf1130c823de6032fcf1de5de3c318b301 | |
parent | 6f9c596d17ec8695aceaab5967e69f8fe1bba7c8 (diff) | |
download | rpm-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.am | 3 | ||||
-rw-r--r-- | docs/man/rpm-plugin-dbus-announce.8.md | 38 | ||||
-rw-r--r-- | macros.in | 1 | ||||
-rw-r--r-- | plugins/Makefile.am | 9 | ||||
-rw-r--r-- | plugins/dbus_announce.c | 142 | ||||
-rw-r--r-- | plugins/org.rpm.conf | 10 |
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) @@ -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> |