dnfdaemon: Enable Download only transaction execution
With the new "downloadonly" option passed to the "do_transaction" method, packages are now only downloaded to the cache, but the RPM transaction is not executed. No special permissions are required for download-only transactions.
This commit is contained in:
parent
f30888b5b8
commit
c12ade0aaf
|
@ -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.
|
||||
-->
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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(); }
|
||||
|
|
Loading…
Reference in New Issue