diff --git a/backends/dnf/meson.build b/backends/dnf/meson.build index 814b0d932..fab5fb57c 100644 --- a/backends/dnf/meson.build +++ b/backends/dnf/meson.build @@ -1,6 +1,8 @@ appstream_dep = dependency('appstream', version: '>=0.14.0') dnf_dep = dependency('libdnf', version: '>=0.43.1') +dnf5_dep = dependency('libdnf5').partial_dependency(includes: true, compile_args: true) rpm_dep = dependency('rpm') +sdbus_cpp_dep = dependency('sdbus-c++') c_args = ['-DG_LOG_DOMAIN="PackageKit-DNF"'] if meson.get_compiler('c').has_function('hy_query_get_advisory_pkgs', prefix: '#include ', dependencies: dnf_dep) @@ -20,6 +22,26 @@ install_data( install_dir: join_paths(python_package_dir), ) +add_languages('cpp') +shared_module( + 'notify_packagekit', + 'notify_packagekit.cpp', + cpp_args: '-std=c++20', + include_directories: packagekit_glib2_includes, + dependencies: [ + dnf5_dep, + sdbus_cpp_dep, + ], + name_prefix: '', + install: true, + install_dir: get_option('libdir') / 'libdnf5/plugins/', +) + +install_data( + 'notify_packagekit.conf', + install_dir: get_option('sysconfdir') / 'dnf/libdnf5-plugins/' +) + shared_module( 'pk_backend_dnf', 'dnf-backend-vendor-@0@.c'.format(get_option('dnf_vendor')), diff --git a/backends/dnf/notify_packagekit.conf b/backends/dnf/notify_packagekit.conf new file mode 100644 index 000000000..80b956b1a --- /dev/null +++ b/backends/dnf/notify_packagekit.conf @@ -0,0 +1,3 @@ +[main] +name = notify_packagekit +enabled = yes diff --git a/backends/dnf/notify_packagekit.cpp b/backends/dnf/notify_packagekit.cpp new file mode 100644 index 000000000..f7a538765 --- /dev/null +++ b/backends/dnf/notify_packagekit.cpp @@ -0,0 +1,90 @@ +// Copyright (C) 2024 Alessandro Astone +// SPDX-License-Identifier: LGPL-2.1-or-later + +#include +#include + +#include + +#include +#include + +#include + +using namespace libdnf5; + +namespace { + +constexpr const char * PLUGIN_NAME{"notify_packagekit"}; + +constexpr plugin::Version PLUGIN_VERSION{.major = PK_MAJOR_VERSION, .minor = PK_MINOR_VERSION, .micro = PK_MICRO_VERSION}; + +constexpr const char * attrs[]{"author.name", "author.email", "description", nullptr}; +constexpr const char * attrs_value[]{"Alessandro Astone", "ales.astone@gmail.com", + "Notify packagekitd when packages are installed, updated, or removed."}; + +class NotifyPackagekitPlugin : public plugin::IPlugin { +public: + NotifyPackagekitPlugin(libdnf5::Base & base, libdnf5::ConfigParser &) : IPlugin(base) {} + + const char * get_name() const noexcept override { return PLUGIN_NAME; } + + plugin::Version get_version() const noexcept override { return PLUGIN_VERSION; } + + PluginAPIVersion get_api_version() const noexcept override { return PLUGIN_API_VERSION; } + + /// Add custom attributes, such as information about yourself and a description of the plugin. + /// These can be used to query plugin-specific data through the API. + /// Optional to override. + const char * const * get_attributes() const noexcept override { return attrs; } + const char * get_attribute(const char * attribute) const noexcept override { + for (size_t i = 0; attrs[i]; ++i) { + if (std::strcmp(attribute, attrs[i]) == 0) { + return attrs_value[i]; + } + } + return nullptr; + } + + void post_transaction(const libdnf5::base::Transaction & transaction) override; +}; + +void NotifyPackagekitPlugin::post_transaction(const libdnf5::base::Transaction & transaction) { + auto packagekitProxy = sdbus::createProxy("org.freedesktop.PackageKit", "/org/freedesktop/PackageKit"); + auto method = packagekitProxy->createMethodCall("org.freedesktop.PackageKit", "StateHasChanged"); + method << "posttrans"; + packagekitProxy->callMethod(method); +} + +} // namespace + +/// Below is a block of functions with C linkage used for loading the plugin binaries from disk. +/// All of these are MANDATORY to implement. + +/// Return plugin's API version. +PluginAPIVersion libdnf_plugin_get_api_version(void) { + return PLUGIN_API_VERSION; +} + +/// Return plugin's name. +const char * libdnf_plugin_get_name(void) { + return PLUGIN_NAME; +} + +/// Return plugin's version. +plugin::Version libdnf_plugin_get_version(void) { + return PLUGIN_VERSION; +} + +/// Return the instance of the implemented plugin. +plugin::IPlugin * libdnf_plugin_new_instance( + [[maybe_unused]] LibraryVersion library_version, libdnf5::Base & base, libdnf5::ConfigParser & parser) try { + return new NotifyPackagekitPlugin(base, parser); +} catch (...) { + return nullptr; +} + +/// Delete the plugin instance. +void libdnf_plugin_delete_instance(plugin::IPlugin * plugin_object) { + delete plugin_object; +} diff --git a/tests/ci/Dockerfile-fedora b/tests/ci/Dockerfile-fedora index 3b1fc0ffc..c53a65c91 100644 --- a/tests/ci/Dockerfile-fedora +++ b/tests/ci/Dockerfile-fedora @@ -1,14 +1,17 @@ -FROM fedora:38 +FROM fedora:40 RUN dnf -y update RUN dnf -y install \ dnf-plugins-core \ libdnf-devel \ + libdnf5-devel \ redhat-rpm-config \ meson \ gcc \ + gcc-c++ \ ninja-build \ dbus-daemon \ + sdbus-cpp-devel \ appstream \ appstream-devel RUN dnf -y builddep PackageKit