This commit is contained in:
Marek Blaha 2025-07-30 11:09:45 +02:00 committed by GitHub
commit f0a455b854
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 50 additions and 41 deletions

View File

@ -87,6 +87,8 @@ along with libdnf. If not, see <https://www.gnu.org/licenses/>.
Adds a comment to a transaction.
- offline: boolean, default false
If true, the transaction will be prepared to run during the next reboot. Otherwise, it will run immediately.
- downloadonly: boolean, default false
If true, only download the resolved package set without executing an RMP transaction. Along with the offline option, the offline transaction files are prepared, but the execution of the transaction is not initiated.
Unknown options are ignored.
-->

View File

@ -373,11 +373,17 @@ bool is_transaction_trusted(libdnf5::base::Transaction * transaction) {
sdbus::MethodReply Goal::do_transaction(sdbus::MethodCall & call) {
transaction_resolved_assert();
// read options from dbus call
dnfdaemon::KeyValueMap options;
call >> options;
bool downloadonly = dnfdaemon::key_value_map_get<bool>(options, "downloadonly", false);
auto * transaction = session.get_transaction();
if (!session.check_authorization(
is_transaction_trusted(transaction) ? dnfdaemon::POLKIT_EXECUTE_RPM_TRUSTED_TRANSACTION
: dnfdaemon::POLKIT_EXECUTE_RPM_TRANSACTION,
call.getSender())) {
if (!downloadonly && !session.check_authorization(
is_transaction_trusted(transaction) ? dnfdaemon::POLKIT_EXECUTE_RPM_TRUSTED_TRANSACTION
: dnfdaemon::POLKIT_EXECUTE_RPM_TRANSACTION,
call.getSender())) {
throw std::runtime_error("Not authorized");
}
@ -390,37 +396,35 @@ sdbus::MethodReply Goal::do_transaction(sdbus::MethodCall & call) {
session.set_cancel_download(Session::CancelDownload::NOT_REQUESTED);
// read options from dbus call
dnfdaemon::KeyValueMap options;
call >> options;
bool offline = dnfdaemon::key_value_map_get<bool>(options, "offline", false);
if (offline) {
session.store_transaction_offline();
session.store_transaction_offline(downloadonly);
// TODO(mblaha): signalize reboot?
} else {
session.download_transaction_packages();
session.set_cancel_download(Session::CancelDownload::NOT_ALLOWED);
if (!downloadonly) {
std::string comment;
if (options.find("comment") != options.end()) {
comment = dnfdaemon::key_value_map_get<std::string>(options, "comment");
}
std::string comment;
if (options.find("comment") != options.end()) {
comment = dnfdaemon::key_value_map_get<std::string>(options, "comment");
transaction->set_callbacks(std::make_unique<dnf5daemon::DbusTransactionCB>(session));
transaction->set_description("dnf5daemon-server");
transaction->set_comment(comment);
auto rpm_result = transaction->run();
if (rpm_result != libdnf5::base::Transaction::TransactionRunResult::SUCCESS) {
throw sdbus::Error(
dnfdaemon::ERROR_TRANSACTION,
fmt::format(
"rpm transaction failed with code {}.",
static_cast<std::underlying_type_t<libdnf5::base::Transaction::TransactionRunResult>>(
rpm_result)));
}
// TODO(mblaha): clean up downloaded packages after successful transaction
}
transaction->set_callbacks(std::make_unique<dnf5daemon::DbusTransactionCB>(session));
transaction->set_description("dnf5daemon-server");
transaction->set_comment(comment);
auto rpm_result = transaction->run();
if (rpm_result != libdnf5::base::Transaction::TransactionRunResult::SUCCESS) {
throw sdbus::Error(
dnfdaemon::ERROR_TRANSACTION,
fmt::format(
"rpm transaction failed with code {}.",
static_cast<std::underlying_type_t<libdnf5::base::Transaction::TransactionRunResult>>(rpm_result)));
}
// TODO(mblaha): clean up downloaded packages after successful transaction
}
auto reply = call.createReply();

View File

@ -345,9 +345,17 @@ void Session::download_transaction_packages() {
}
}
void Session::store_transaction_offline() {
// Download transaction packages
void Session::store_transaction_offline(bool downloadonly) {
const auto & installroot = base->get_config().get_installroot_option().get_value();
const auto & offline_datadir = installroot / libdnf5::offline::DEFAULT_DATADIR.relative_path();
std::filesystem::create_directories(offline_datadir);
const std::filesystem::path state_path{offline_datadir / libdnf5::offline::TRANSACTION_STATE_FILENAME};
libdnf5::offline::OfflineTransactionState state{state_path};
auto & state_data = state.get_data();
state_data.set_status(libdnf5::offline::STATUS_DOWNLOAD_INCOMPLETE);
state.write();
// Download transaction packages
const auto & dest_dir = installroot / libdnf5::offline::DEFAULT_DATADIR.relative_path() / "packages";
std::filesystem::create_directories(dest_dir);
base->get_config().get_destdir_option().set(dest_dir);
@ -368,18 +376,10 @@ void Session::store_transaction_offline() {
}
// Serialize the transaction
const auto & offline_datadir = installroot / libdnf5::offline::DEFAULT_DATADIR.relative_path();
std::filesystem::create_directories(offline_datadir);
constexpr const char * packages_in_trans_dir{"./packages"};
constexpr const char * comps_in_trans_dir{"./comps"};
const auto & comps_location = offline_datadir / comps_in_trans_dir;
const std::filesystem::path state_path{offline_datadir / libdnf5::offline::TRANSACTION_STATE_FILENAME};
libdnf5::offline::OfflineTransactionState state{state_path};
auto & state_data = state.get_data();
state_data.set_status(libdnf5::offline::STATUS_DOWNLOAD_INCOMPLETE);
state.write();
@ -408,11 +408,14 @@ void Session::store_transaction_offline() {
}
// create the magic symlink /system-update -> datadir
if (!std::filesystem::is_symlink(libdnf5::offline::MAGIC_SYMLINK)) {
std::filesystem::create_symlink(offline_datadir, libdnf5::offline::MAGIC_SYMLINK);
if (downloadonly) {
state_data.set_status(libdnf5::offline::STATUS_DOWNLOAD_COMPLETE);
} else {
if (!std::filesystem::is_symlink(libdnf5::offline::MAGIC_SYMLINK)) {
std::filesystem::create_symlink(offline_datadir, libdnf5::offline::MAGIC_SYMLINK);
}
state_data.set_status(libdnf5::offline::STATUS_READY);
}
state_data.set_status(libdnf5::offline::STATUS_READY);
state.write();
}

View File

@ -91,7 +91,7 @@ public:
/// download packages for the current transaction
void download_transaction_packages();
/// prepare the current transaction to run during the next reboot
void store_transaction_offline();
void store_transaction_offline(bool downloadonly);
/// Getter for download cancel request flag.
CancelDownload get_cancel_download() { return cancel_download.load(); }