Skip to content

Commit 0738f32

Browse files
committed
dnf5: Print details about concurrent running transaction
1 parent 2b88e60 commit 0738f32

File tree

1 file changed

+74
-0
lines changed

1 file changed

+74
-0
lines changed

dnf5/context.cpp

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#include <libdnf5/utils/fs/file.hpp>
4343
#include <libdnf5/utils/patterns.hpp>
4444
#include <rpm/rpmtypes.h>
45+
#include <signal.h>
4546

4647
#include <algorithm>
4748
#include <cctype>
@@ -58,6 +59,48 @@ namespace dnf5 {
5859

5960
namespace {
6061

62+
// Helper function to format active transaction information for error messages
63+
std::string format_active_transaction_info(const libdnf5::base::ActiveTransactionInfo & info) {
64+
std::string result;
65+
66+
if (!info.get_description().empty()) {
67+
result += libdnf5::utils::sformat(_("Command: {}"), info.get_description());
68+
}
69+
70+
if (info.get_pid() > 0) {
71+
if (!result.empty()) {
72+
result += "\n";
73+
}
74+
if (kill(info.get_pid(), 0) == 0) {
75+
result += libdnf5::utils::sformat(_("Process ID: {} (still running)"), info.get_pid());
76+
} else {
77+
result += libdnf5::utils::sformat(_("Process ID: {}"), info.get_pid());
78+
}
79+
}
80+
81+
if (info.get_start_time() > 0) {
82+
if (!result.empty()) {
83+
result += "\n";
84+
}
85+
auto start_time = static_cast<time_t>(info.get_start_time());
86+
auto time_str = std::string(std::ctime(&start_time));
87+
// Remove trailing newline from ctime
88+
if (!time_str.empty() && time_str.back() == '\n') {
89+
time_str.pop_back();
90+
}
91+
result += libdnf5::utils::sformat(_("Started: {}"), time_str);
92+
}
93+
94+
if (!info.get_comment().empty()) {
95+
if (!result.empty()) {
96+
result += "\n";
97+
}
98+
result += libdnf5::utils::sformat(_("Comment: {}"), info.get_comment());
99+
}
100+
101+
return result;
102+
}
103+
61104
// The `KeyImportRepoCB` class implements callback only for importing repository key.
62105
class KeyImportRepoCB : public libdnf5::repo::RepoCallbacks2_1 {
63106
public:
@@ -377,6 +420,24 @@ void Context::Impl::store_offline(libdnf5::base::Transaction & transaction) {
377420
if (result != libdnf5::base::Transaction::TransactionRunResult::SUCCESS) {
378421
print_error(libdnf5::utils::sformat(
379422
_("Transaction failed: {}"), libdnf5::base::Transaction::transaction_result_to_string(result)));
423+
424+
// For transaction lock errors, provide detailed information about the running transaction
425+
if (result == libdnf5::base::Transaction::TransactionRunResult::ERROR_LOCK) {
426+
auto active_info = base.get_active_transaction_info();
427+
if (active_info) {
428+
print_error(_("Details about the currently running transaction:"));
429+
auto info_str = format_active_transaction_info(*active_info);
430+
if (!info_str.empty()) {
431+
// Print each line of the formatted info with proper indentation
432+
std::istringstream ss(info_str);
433+
std::string line;
434+
while (std::getline(ss, line)) {
435+
print_error(libdnf5::utils::sformat(_(" {}"), line));
436+
}
437+
}
438+
}
439+
}
440+
380441
for (auto const & entry : transaction.get_gpg_signature_problems()) {
381442
print_error(entry);
382443
}
@@ -530,6 +591,19 @@ void Context::Impl::download_and_run(libdnf5::base::Transaction & transaction) {
530591
if (result != libdnf5::base::Transaction::TransactionRunResult::SUCCESS) {
531592
print_error(libdnf5::utils::sformat(
532593
_("Transaction failed: {}"), libdnf5::base::Transaction::transaction_result_to_string(result)));
594+
595+
// For transaction lock errors, provide detailed information about the running transaction
596+
if (result == libdnf5::base::Transaction::TransactionRunResult::ERROR_LOCK) {
597+
auto active_info = base.get_active_transaction_info();
598+
if (active_info) {
599+
auto info_str = format_active_transaction_info(*active_info);
600+
if (!info_str.empty()) {
601+
print_error(_("Details about the currently running transaction:"));
602+
print_error(info_str);
603+
}
604+
}
605+
}
606+
533607
for (auto const & entry : transaction.get_gpg_signature_problems()) {
534608
print_error(entry);
535609
}

0 commit comments

Comments
 (0)