1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228
|
// Copyright Contributors to the DNF5 project.
// Copyright Contributors to the libdnf project.
// SPDX-License-Identifier: LGPL-2.1-or-later
//
// This file is part of libdnf: https://github.com/rpm-software-management/libdnf/
//
// Libdnf is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 2.1 of the License, or
// (at your option) any later version.
//
// Libdnf is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with libdnf. If not, see <https://www.gnu.org/licenses/>.
#ifndef LIBDNF5_BASE_TRANSACTION_HPP
#define LIBDNF5_BASE_TRANSACTION_HPP
#include "transaction_errors.hpp"
#include "libdnf5/base/base_weak.hpp"
#include "libdnf5/base/goal_elements.hpp"
#include "libdnf5/base/log_event.hpp"
#include "libdnf5/base/solver_problems.hpp"
#include "libdnf5/common/proc.hpp"
#include "libdnf5/defs.h"
#include "libdnf5/rpm/transaction_callbacks.hpp"
#include <optional>
namespace libdnf5::rpm {
class KeyInfo;
} // namespace libdnf5::rpm
namespace libdnf5::base {
class TransactionGroup;
class TransactionEnvironment;
class TransactionModule;
class TransactionPackage;
class LIBDNF_API Transaction {
public:
/// enum representing Transaction run result
enum class TransactionRunResult {
SUCCESS,
ERROR_RERUN,
ERROR_RESOLVE,
ERROR_LOCK,
ERROR_CHECK,
ERROR_RPM_RUN,
ERROR_GPG_CHECK,
};
Transaction(const Transaction & transaction);
Transaction(Transaction && transaction);
~Transaction();
/// Return basic overview about result of resolving transaction.
/// To get complete information, use get_resolve_logs().
libdnf5::GoalProblem get_problems();
/// Returns information about resolvement of Goal.
/// @return A vector of LogEvent instances.
const std::vector<libdnf5::base::LogEvent> & get_resolve_logs() const;
/// Returns information about resolvement of Goal as a list of printable messages
/// @return A vector of string representations of problems.
std::vector<std::string> get_resolve_logs_as_strings() const;
/// @return the transaction packages.
// TODO(jrohel): Return reference instead of copy?
std::vector<libdnf5::base::TransactionPackage> get_transaction_packages() const;
/// @return the number of transaction packages.
std::size_t get_transaction_packages_count() const;
/// @return the transaction groups.
std::vector<libdnf5::base::TransactionGroup> & get_transaction_groups() const;
/// @return the transaction modules.
std::vector<libdnf5::base::TransactionModule> & get_transaction_modules() const;
/// @return environmental groups that are part of the transaction.
std::vector<libdnf5::base::TransactionEnvironment> & get_transaction_environments() const;
/// @return list of packages skipped due to broken dependencies
std::vector<libdnf5::rpm::Package> get_broken_dependency_packages() const;
/// @return list of packages skipped due to conflicts
std::vector<libdnf5::rpm::Package> get_conflicting_packages() const;
/// @return `true` if the transaction is empty.
bool empty() const;
/// Download all inbound packages (packages that are being installed on the
/// system). Fails immediately on the first package download failure. Will
/// try to resume downloads of any partially-downloaded RPMs.
///
/// The destination directory for downloaded RPMs is taken from the `destdir`
/// configuration option. If it's not specified, the standard location of
/// repo cachedir/packages is used.
void download();
/// Check the transaction by running it with RPMTRANS_FLAG_TEST. The import
/// of any necessary public keys will be requested, and transaction checks
/// will be performed, but no changes to the installed package set will be
/// made. These checks are performed automatically by run(); it is
/// redundant to call test() before calling run().
/// @return An enum describing the result of the transaction
TransactionRunResult test();
/// @brief Prepare, check and run the transaction.
///
/// All the transaction metadata that was set (`description`, `user_id` or `comment`)
/// is stored in the history database.
///
/// To watch progress or trigger actions during specific transactions events,
/// setup the `callbacks` object.
///
/// After a successful transaction, any temporarily downloaded packages are removed
/// if the 'keepcache' option is set to 'false' and the transaction involved an inbound action.
/// Otherwise, the packages are preserved on the disk.
///
/// @return An enum describing the result of running the transaction.
TransactionRunResult run();
/// @brief Setup callbacks to be called during rpm transaction.
/// @param callbacks Implemented callbacks object.
void set_callbacks(std::unique_ptr<libdnf5::rpm::TransactionCallbacks> && callbacks);
/// @brief Setup a description of the transaction.
/// @param description Value could be the console command for CLI or verbose description for API usage.
void set_description(const std::string & description);
/// @brief Setup the id of the user that started the transaction. If not set, current login user UID is used.
/// @param user_id UID value.
void set_user_id(const uint32_t user_id);
/// @brief Setup a comment to store in the history database along with the transaction.
/// @param comment Any string value.
void set_comment(const std::string & comment);
/// Return string representation of the TransactionRunResult enum
static std::string transaction_result_to_string(const TransactionRunResult result);
/// Retrieve list of problems that occurred during transaction run attempt
std::vector<std::string> get_transaction_problems() const noexcept;
/// @brief Check signatures of packages in the resolved transaction.
///
/// @return True if all packages have correct signatures or checking is turned off with `pkg_gpgcheck` option,
/// otherwise false. More info about occurred problems can be retrieved using the `get_gpg_signature_problems`
/// method.
bool check_gpg_signatures();
/// Retrieve a list of the problems that occurred during `check_gpg_signatures` procedure.
std::vector<std::string> get_gpg_signature_problems() const noexcept;
/// @warning This method is experimental/unstable and should not be relied on. It may be removed without warning
/// Serialize the transaction into a json data format which can be later loaded
/// into a `libdnf5::Goal` and replayed.
/// @param packages_path If provided it is assumed all packages in this transaction are present there and
/// the resulting serialized transaction will contain paths to those packages.
/// @param comps_path If provided it is assumed all comps in this transaction are present there and
/// the resulting serialized transaction will contain paths to those xml comps files
/// (they can be stored using the `store_comps` method).
/// @param repo_prefix If provided each repository id (except for @System repo) used in this transaction
/// will be wrapped in brackets and prefix by repo_prefix.
std::string serialize(
const std::filesystem::path & packages_path = "",
const std::filesystem::path & comps_path = "",
const std::string repo_prefix = "") const;
/// @warning This method is experimental/unstable and should not be relied on. It may be removed without warning
/// Store each group and environment in this transaction as a separate xml file in the
/// specified path.
void store_comps(const std::filesystem::path & comps_path) const;
/// Set whether local packages should be copied to the destination directory during the download().
///
/// Default: false
void set_download_local_pkgs(bool value);
bool get_download_local_pkgs() const noexcept;
/// Retrieve output of the last executed rpm scriptlet.
std::string get_last_script_output();
/// Retrieve captured RPM log messages
std::vector<std::string> get_rpm_messages();
private:
friend class TransactionEnvironment;
friend class TransactionGroup;
friend class TransactionModule;
friend class TransactionPackage;
friend class libdnf5::Goal;
friend class libdnf5::rpm::
Transaction; // to access clear_last_script_output() from the rpm transaction SCRIPT_START callback
LIBDNF_LOCAL Transaction(const libdnf5::BaseWeakPtr & base);
class LIBDNF_LOCAL Impl;
std::unique_ptr<Impl> p_impl;
std::unique_ptr<libdnf5::rpm::TransactionCallbacks> callbacks;
std::optional<uint32_t> user_id;
std::string comment;
std::string description;
/// Clear the recorded last scriptlet output
LIBDNF_LOCAL void clear_last_script_output();
/// Store captured RPM log messages
LIBDNF_LOCAL void set_rpm_messages(std::vector<std::string> && rpm_messages);
};
} // namespace libdnf5::base
#endif // LIBDNF5_BASE_TRANSACTION_HPP
|