Skip to content

Commit

Permalink
dnf5: 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.
  • Loading branch information
m-blaha authored and pkratoch committed Sep 17, 2024
1 parent 95593e1 commit f16dc7d
Showing 1 changed file with 21 additions and 28 deletions.
49 changes: 21 additions & 28 deletions dnf5/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,27 @@ void Context::Impl::load_repos(bool load_system) {
}

void Context::Impl::store_offline(libdnf5::base::Transaction & transaction) {
// Test the transaction
base.get_config().get_tsflags_option().set(libdnf5::Option::Priority::RUNTIME, "test");
print_info(_("Testing offline transaction"));
auto result = transaction.run();
if (result != libdnf5::base::Transaction::TransactionRunResult::SUCCESS) {
print_error(libdnf5::utils::sformat(
_("Transaction failed: {}"), libdnf5::base::Transaction::transaction_result_to_string(result)));
for (auto const & entry : transaction.get_gpg_signature_problems()) {
print_error(entry);
}
for (auto & problem : transaction.get_transaction_problems()) {
print_error(libdnf5::utils::sformat(_(" - {}"), problem));
}
throw libdnf5::cli::SilentCommandExitError(1);
}

for (auto const & entry : transaction.get_gpg_signature_problems()) {
print_error(entry);
}

// Serialize the transaction
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);
Expand All @@ -349,41 +370,13 @@ void Context::Impl::store_offline(libdnf5::base::Transaction & transaction) {
offline_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
const auto & goal = std::make_unique<libdnf5::Goal>(base);
goal->add_serialized_transaction(transaction_json_path);
auto test_transaction = goal->resolve();
if (test_transaction.get_problems() != libdnf5::GoalProblem::NO_PROBLEM) {
throw libdnf5::cli::GoalResolveError(transaction);
}
base.get_config().get_tsflags_option().set(libdnf5::Option::Priority::RUNTIME, "test");

print_info(_("Testing offline transaction"));
auto result = test_transaction.run();
if (result != libdnf5::base::Transaction::TransactionRunResult::SUCCESS) {
print_error(libdnf5::utils::sformat(
_("Transaction failed: {}"), libdnf5::base::Transaction::transaction_result_to_string(result)));
for (auto const & entry : transaction.get_gpg_signature_problems()) {
print_error(entry);
}
for (auto & problem : test_transaction.get_transaction_problems()) {
print_error(libdnf5::utils::sformat(_(" - {}"), problem));
}
throw libdnf5::cli::SilentCommandExitError(1);
}

for (auto const & entry : test_transaction.get_gpg_signature_problems()) {
print_error(entry);
}

// Download and transaction test complete. Fill out entries in offline
// transaction state file.
offline_data.set_status(libdnf5::offline::STATUS_DOWNLOAD_COMPLETE);
Expand Down

0 comments on commit f16dc7d

Please sign in to comment.