diff --git a/dnf5/context.cpp b/dnf5/context.cpp index fe9b73deb..0cedb106e 100644 --- a/dnf5/context.cpp +++ b/dnf5/context.cpp @@ -325,10 +325,30 @@ 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); - 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; @@ -337,19 +357,9 @@ void Context::Impl::store_offline(libdnf5::base::Transaction & transaction) { libdnf5::offline::OfflineTransactionState state{state_path}; auto & offline_data = state.get_data(); - if (offline_data.get_status() != libdnf5::offline::STATUS_DOWNLOAD_INCOMPLETE) { - print_error(_("There is already an offline transaction queued, initiated by the following command:")); - print_error(fmt::format("\t{}", offline_data.get_cmd_line())); - print_error(_("Continuing will cancel the old offline transaction and replace it with this one.")); - if (!libdnf5::cli::utils::userconfirm::userconfirm(base.get_config())) { - throw libdnf5::cli::AbortedByUserError(); - } - } - 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; @@ -357,33 +367,6 @@ void Context::Impl::store_offline(libdnf5::base::Transaction & transaction) { 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(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); @@ -443,6 +426,19 @@ void Context::Impl::download_and_run(libdnf5::base::Transaction & 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); + const std::filesystem::path state_path{offline_datadir / libdnf5::offline::TRANSACTION_STATE_FILENAME}; + libdnf5::offline::OfflineTransactionState state{state_path}; + + // Check whether there is another pending offline transaction present + auto & offline_data = state.get_data(); + if (offline_data.get_status() != libdnf5::offline::STATUS_DOWNLOAD_INCOMPLETE) { + print_error(_("There is already an offline transaction queued, initiated by the following command:")); + print_error(fmt::format("\t{}", offline_data.get_cmd_line())); + print_error(_("Continuing will cancel the old offline transaction and replace it with this one.")); + if (!libdnf5::cli::utils::userconfirm::userconfirm(base.get_config())) { + throw libdnf5::cli::AbortedByUserError(); + } + } base.get_config().get_destdir_option().set(offline_datadir / "packages"); transaction.set_download_local_pkgs(true);