From 4e8669d61b97686bab915c2f86547564d7ef9796 Mon Sep 17 00:00:00 2001 From: Marek Blaha Date: Wed, 19 Feb 2025 15:38:18 +0100 Subject: [PATCH 1/5] package: Fix package path for packages from RPM files Previously, the `Package::get_package_path()` method worked correctly only for packages in repositories of type `Repo::Type::COMMANDLINE`. When an RPM file was added to a regular `Repo::Type::AVAILABLE` repository, its package path incorrectly pointed to the cache directory instead of the local RPM file. This fix ensures the correct path is used. --- libdnf5/repo/repo.cpp | 4 +++- libdnf5/rpm/package.cpp | 3 ++- libdnf5/rpm/package_sack.cpp | 8 ++++++++ libdnf5/rpm/package_sack_impl.hpp | 6 ++++++ 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/libdnf5/repo/repo.cpp b/libdnf5/repo/repo.cpp index 3b9e8dcc7..912a6df75 100644 --- a/libdnf5/repo/repo.cpp +++ b/libdnf5/repo/repo.cpp @@ -501,7 +501,9 @@ rpm::Package Repo::add_rpm_package(const std::string & path, bool with_hdrid) { } p_impl->solv_repo->set_needs_internalizing(); - p_impl->base->get_rpm_package_sack()->p_impl->invalidate_provides(); + auto pkg_sack = p_impl->base->get_rpm_package_sack(); + pkg_sack->p_impl->register_local_rpm_id(new_id); + pkg_sack->p_impl->invalidate_provides(); return rpm::Package(p_impl->base, rpm::PackageId(new_id)); } diff --git a/libdnf5/rpm/package.cpp b/libdnf5/rpm/package.cpp index 40103b382..da9fb193f 100644 --- a/libdnf5/rpm/package.cpp +++ b/libdnf5/rpm/package.cpp @@ -388,7 +388,8 @@ std::vector Package::get_remote_locations(const std::setbase).id2solvable(p_impl->id.id); if (auto repo = static_cast(solvable->repo->appdata)) { - if (repo->get_type() == repo::Repo::Type::COMMANDLINE) { + if (repo->get_type() == repo::Repo::Type::COMMANDLINE || + p_impl->base->get_rpm_package_sack()->p_impl->is_local_rpm_id(p_impl->id.id)) { // Command line packages are used from their original location. return get_location(); } diff --git a/libdnf5/rpm/package_sack.cpp b/libdnf5/rpm/package_sack.cpp index 4ebbcc6b0..c9b3fd29f 100644 --- a/libdnf5/rpm/package_sack.cpp +++ b/libdnf5/rpm/package_sack.cpp @@ -637,4 +637,12 @@ rpm::Package PackageSack::get_running_kernel() { return rpm::Package(p_impl->base, p_impl->get_running_kernel_id()); } +void PackageSack::Impl::register_local_rpm_id(const Id id) { + local_rpm_ids.emplace(id); +} + +bool PackageSack::Impl::is_local_rpm_id(const Id id) { + return local_rpm_ids.contains(id); +} + } // namespace libdnf5::rpm diff --git a/libdnf5/rpm/package_sack_impl.hpp b/libdnf5/rpm/package_sack_impl.hpp index 91e6cbf60..14cded941 100644 --- a/libdnf5/rpm/package_sack_impl.hpp +++ b/libdnf5/rpm/package_sack_impl.hpp @@ -127,6 +127,9 @@ class PackageSack::Impl { /// And sets `considered_uptodate` to` true`. void recompute_considered_in_pool(); + void register_local_rpm_id(const Id id); + bool is_local_rpm_id(const Id id); + private: bool provides_ready{false}; @@ -161,6 +164,9 @@ class PackageSack::Impl { int cached_solvables_size{0}; PackageId running_kernel; + // ids of packages created from local rpm files + std::unordered_set local_rpm_ids; + friend PackageSack; friend Package; friend PackageSet; From 08944970527ea8fb10cf48f3594d000491180ac0 Mon Sep 17 00:00:00 2001 From: Marek Blaha Date: Wed, 19 Feb 2025 15:57:07 +0100 Subject: [PATCH 2/5] repo: Invalidate provides after adding a comps xml --- libdnf5/repo/repo.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libdnf5/repo/repo.cpp b/libdnf5/repo/repo.cpp index 912a6df75..06192528b 100644 --- a/libdnf5/repo/repo.cpp +++ b/libdnf5/repo/repo.cpp @@ -482,6 +482,7 @@ void Repo::add_xml_comps(const std::string & path) { throw RepoCompsError( M_("Failed to load xml Comps \"{}\": {}"), path, std::string(pool_errstr(p_impl->solv_repo->repo->pool))); } + p_impl->base->get_rpm_package_sack()->p_impl->invalidate_provides(); } rpm::Package Repo::add_rpm_package(const std::string & path, bool with_hdrid) { From 7f3a61c7c4062c50cfcdd7ede64d1c205a5fd9bc Mon Sep 17 00:00:00 2001 From: Marek Blaha Date: Wed, 19 Feb 2025 15:58:07 +0100 Subject: [PATCH 3/5] Use actual repository ID in stored transactions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, when replaying a stored transaction, all RPM files are placed into a single `@stored_transaction` repository. The user can see this artifitial repository when checking from which repositories the installed packages came: ❯ dnf repoquery --installed --queryformat="%{full_nevra} %{from_repo}\n" vlc-plugin-gstreamer-1:3.0.21-15.fc40.x86_64 @stored_transaction This can be confusing, especially during a system upgrade, which also uses stored transactions. With this patch, local RPM files from stored transactions are placed to the repository they originally came from: ❯ dnf repoquery --installed --queryformat="%{full_nevra} %{from_repo}\n" vlc-plugin-gstreamer-1:3.0.21-15.fc40.x86_64 updates Fixes: https://github.com/rpm-software-management/dnf5/issues/1851 --- include/libdnf5/repo/repo_sack.hpp | 2 +- libdnf5/base/goal.cpp | 4 ++-- libdnf5/repo/repo.cpp | 3 +++ libdnf5/repo/repo_sack.cpp | 16 ++++++++++++++-- 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/include/libdnf5/repo/repo_sack.hpp b/include/libdnf5/repo/repo_sack.hpp index 4a8d743e5..df74f6833 100644 --- a/include/libdnf5/repo/repo_sack.hpp +++ b/include/libdnf5/repo/repo_sack.hpp @@ -183,7 +183,7 @@ class LIBDNF_API RepoSack : public sack::Sack { /// @param calculate_checksum Whether libsolv should calculate and store checksum of added packages. Setting to true significantly reduces performance. /// @return Newly created rpm::Package object in cmdline repo LIBDNF_LOCAL libdnf5::rpm::Package add_stored_transaction_package( - const std::string & path, bool calculate_checksum = false); + const std::string & path, const std::string & repo_id, bool calculate_checksum = false); LIBDNF_LOCAL void internalize_repos(); diff --git a/libdnf5/base/goal.cpp b/libdnf5/base/goal.cpp index c90c166f7..5c3b206f0 100644 --- a/libdnf5/base/goal.cpp +++ b/libdnf5/base/goal.cpp @@ -791,8 +791,8 @@ GoalProblem Goal::Impl::add_replay_to_goal( std::optional local_pkg; if (!package_replay.package_path.empty()) { // Package paths are relative to replay location - local_pkg = - base->get_repo_sack()->add_stored_transaction_package(replay_location / package_replay.package_path); + local_pkg = base->get_repo_sack()->add_stored_transaction_package( + replay_location / package_replay.package_path, package_replay.repo_id); } const auto nevras = rpm::Nevra::parse(package_replay.nevra, {rpm::Nevra::Form::NEVRA}); diff --git a/libdnf5/repo/repo.cpp b/libdnf5/repo/repo.cpp index 06192528b..17399ec84 100644 --- a/libdnf5/repo/repo.cpp +++ b/libdnf5/repo/repo.cpp @@ -501,6 +501,9 @@ rpm::Package Repo::add_rpm_package(const std::string & path, bool with_hdrid) { M_("Failed to load RPM \"{}\": {}"), path, std::string(pool_errstr(p_impl->solv_repo->repo->pool))); } + // repo altered by adding an rpm package should not be written back to the cache + get_config().get_build_cache_option().set(libdnf5::Option::Priority::RUNTIME, false); + p_impl->solv_repo->set_needs_internalizing(); auto pkg_sack = p_impl->base->get_rpm_package_sack(); pkg_sack->p_impl->register_local_rpm_id(new_id); diff --git a/libdnf5/repo/repo_sack.cpp b/libdnf5/repo/repo_sack.cpp index a504032b5..0514b73db 100644 --- a/libdnf5/repo/repo_sack.cpp +++ b/libdnf5/repo/repo_sack.cpp @@ -192,8 +192,20 @@ void RepoSack::add_stored_transaction_comps(const std::string & path) { } -libdnf5::rpm::Package RepoSack::add_stored_transaction_package(const std::string & path, bool calculate_checksum) { - auto stored_repo = get_stored_transaction_repo(); +libdnf5::rpm::Package RepoSack::add_stored_transaction_package( + const std::string & path, const std::string & repo_id, bool calculate_checksum) { + RepoWeakPtr stored_repo; + if (!repo_id.empty()) { + for (const auto & existing_repo : get_data()) { + if (existing_repo->get_id() == repo_id) { + stored_repo = existing_repo->get_weak_ptr(); + break; + } + } + } + if (!stored_repo.is_valid()) { + stored_repo = get_stored_transaction_repo(); + } auto pkg = stored_repo->add_rpm_package(path, calculate_checksum); From e05b785345a3e7c7dc47bef99ecf5c7e04f07620 Mon Sep 17 00:00:00 2001 From: Marek Blaha Date: Wed, 19 Feb 2025 16:13:31 +0100 Subject: [PATCH 4/5] offline: Fix constructing vector from D-Bus value Use explicit std::vector constructor instead of uniform initialization to allow range based construction. --- dnf5/commands/offline/offline.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnf5/commands/offline/offline.cpp b/dnf5/commands/offline/offline.cpp index eb937c0f3..c6257e539 100644 --- a/dnf5/commands/offline/offline.cpp +++ b/dnf5/commands/offline/offline.cpp @@ -322,8 +322,8 @@ void OfflineRebootCommand::run() { .storeResultsTo(unit_object_path); auto unit_proxy = sdbus::createProxy(SYSTEMD_DESTINATION_NAME, unit_object_path); - const auto & wants = - std::vector{unit_proxy->getProperty("Wants").onInterface(SYSTEMD_UNIT_INTERFACE)}; + const auto wants = + std::vector(unit_proxy->getProperty("Wants").onInterface(SYSTEMD_UNIT_INTERFACE)); if (std::find(wants.begin(), wants.end(), SYSTEMD_SERVICE_NAME) == wants.end()) { throw libdnf5::cli::CommandExitError( 1, M_("{} is not wanted by system-update.target."), SYSTEMD_SERVICE_NAME); From 1c1e925c6d341ebbcac47ca532a79029a8f34550 Mon Sep 17 00:00:00 2001 From: Marek Blaha Date: Tue, 25 Feb 2025 14:49:37 +0100 Subject: [PATCH 5/5] offline: Use connection for creating D-Bus proxies Use prepared connection to the System Bus. Otherwise the default connection to Session Bus would be created. --- dnf5/commands/offline/offline.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/dnf5/commands/offline/offline.cpp b/dnf5/commands/offline/offline.cpp index c6257e539..be354f08a 100644 --- a/dnf5/commands/offline/offline.cpp +++ b/dnf5/commands/offline/offline.cpp @@ -245,11 +245,13 @@ void reboot(bool poweroff = false) { const std::string error_message{ex.what()}; throw libdnf5::cli::CommandExitError(1, M_("Couldn't connect to D-Bus: {}"), error_message); } - auto proxy = sdbus::createProxy(SYSTEMD_DESTINATION_NAME, SYSTEMD_OBJECT_PATH); - if (poweroff) { - proxy->callMethod("PowerOff").onInterface(SYSTEMD_MANAGER_INTERFACE); - } else { - proxy->callMethod("Reboot").onInterface(SYSTEMD_MANAGER_INTERFACE); + if (connection != nullptr) { + auto proxy = sdbus::createProxy(*connection, SYSTEMD_DESTINATION_NAME, SYSTEMD_OBJECT_PATH); + if (poweroff) { + proxy->callMethod("PowerOff").onInterface(SYSTEMD_MANAGER_INTERFACE); + } else { + proxy->callMethod("Reboot").onInterface(SYSTEMD_MANAGER_INTERFACE); + } } #else std::cerr << "Can't connect to D-Bus; this build of DNF 5 does not support D-Bus." << std::endl; @@ -313,7 +315,7 @@ void OfflineRebootCommand::run() { std::cerr << "Warning: couldn't connect to D-Bus: " << ex.what() << std::endl; } if (connection != nullptr) { - auto systemd_proxy = sdbus::createProxy(SYSTEMD_DESTINATION_NAME, SYSTEMD_OBJECT_PATH); + auto systemd_proxy = sdbus::createProxy(*connection, SYSTEMD_DESTINATION_NAME, SYSTEMD_OBJECT_PATH); sdbus::ObjectPath unit_object_path; systemd_proxy->callMethod("LoadUnit") @@ -321,7 +323,7 @@ void OfflineRebootCommand::run() { .withArguments("system-update.target") .storeResultsTo(unit_object_path); - auto unit_proxy = sdbus::createProxy(SYSTEMD_DESTINATION_NAME, unit_object_path); + auto unit_proxy = sdbus::createProxy(*connection, SYSTEMD_DESTINATION_NAME, unit_object_path); const auto wants = std::vector(unit_proxy->getProperty("Wants").onInterface(SYSTEMD_UNIT_INTERFACE)); if (std::find(wants.begin(), wants.end(), SYSTEMD_SERVICE_NAME) == wants.end()) {