Skip to content

Commit

Permalink
dnf5daemon-server: Run transaction test for offline transactions
Browse files Browse the repository at this point in the history
A serialized offline transaction consists only of local packages
downloaded to the `<system state dir>/offline` location. Unfortunately,
PGP checks for these packages are disabled by default due to the
`localpkg_gpgcheck` option default value.
Instead of testing the serialized transaction, this patch performs an
RPM transaction test on the originally resolved transaction, which still
retains information about the repositories from which the packages were
downloaded.
This approach also saves time required for deserialization and resolving
the testing transaction.

This ports the fix from rpm-software-management#1672
to dnf5daemon.
  • Loading branch information
kontura committed Sep 20, 2024
1 parent 30c7697 commit 8a447f4
Showing 1 changed file with 15 additions and 21 deletions.
36 changes: 15 additions & 21 deletions dnf5daemon-server/session.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -308,13 +308,28 @@ void Session::download_transaction_packages() {
}

void Session::store_transaction_offline() {
// Download transaction packages
const auto & installroot = base->get_config().get_installroot_option().get_value();
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);
download_transaction_packages();
set_cancel_download(Session::CancelDownload::NOT_ALLOWED);

// Test the transaction
// TODO(mblaha): store transaction test/run problems in the session and add an API
// to retrieve it
base->get_config().get_tsflags_option().set(libdnf5::Option::Priority::RUNTIME, "test");
auto result = transaction->run();
if (result != libdnf5::base::Transaction::TransactionRunResult::SUCCESS) {
throw sdbus::Error(
dnfdaemon::ERROR_TRANSACTION,
fmt::format(
"offline rpm transaction test failed with code {}.",
static_cast<std::underlying_type_t<libdnf5::base::Transaction::TransactionRunResult>>(result)));
}

// Serialize the transaction
const auto & offline_datadir = installroot / libdnf5::offline::DEFAULT_DATADIR.relative_path();
std::filesystem::create_directories(offline_datadir);

Expand All @@ -330,34 +345,13 @@ void Session::store_transaction_offline() {
state_data.set_status(libdnf5::offline::STATUS_DOWNLOAD_INCOMPLETE);
state.write();

// First, serialize the transaction
transaction->store_comps(comps_location);

const auto transaction_json_path = offline_datadir / "transaction.json";
libdnf5::utils::fs::File transaction_json_file{transaction_json_path, "w"};
transaction_json_file.write(transaction->serialize(packages_in_trans_dir, comps_in_trans_dir));
transaction_json_file.close();

// Then, test the serialized transaction
// TODO(mblaha): store transaction test/run problems in the session and add an API
// to retrieve it
const auto & test_goal = std::make_unique<libdnf5::Goal>(*base);
test_goal->add_serialized_transaction(transaction_json_path);
auto test_transaction = test_goal->resolve();
if (test_transaction.get_problems() != libdnf5::GoalProblem::NO_PROBLEM) {
throw sdbus::Error(dnfdaemon::ERROR_TRANSACTION, "failed to resolve serialized offline transaction.");
}
base->get_config().get_tsflags_option().set(libdnf5::Option::Priority::RUNTIME, "test");

auto result = test_transaction.run();
if (result != libdnf5::base::Transaction::TransactionRunResult::SUCCESS) {
throw sdbus::Error(
dnfdaemon::ERROR_TRANSACTION,
fmt::format(
"offline rpm transaction test failed with code {}.",
static_cast<std::underlying_type_t<libdnf5::base::Transaction::TransactionRunResult>>(result)));
}

// Download and transaction test complete. Fill out entries in offline
// transaction state file.
state_data.set_cachedir(base->get_config().get_cachedir_option().get_value());
Expand Down

0 comments on commit 8a447f4

Please sign in to comment.