Skip to content

Commit

Permalink
Add replay command to replay stored transactions
Browse files Browse the repository at this point in the history
In comparison to dnf4 the command:
- is no longer a `history` subcommand, it is a standalone command.
- accepts as an argument a path to a directory where the transaction is
  stored. This is because now any transaction can be stored using the
  `--store` option which also stores the elements (packages, groups..)
  of the transaction.
  • Loading branch information
kontura committed Jun 10, 2024
1 parent e1a48ca commit d08ca5d
Show file tree
Hide file tree
Showing 13 changed files with 158 additions and 41 deletions.
2 changes: 2 additions & 0 deletions dnf5.spec
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ Provides: dnf5-command(module)
Provides: dnf5-command(offline)
Provides: dnf5-command(provides)
Provides: dnf5-command(reinstall)
Provides: dnf5-command(replay)
Provides: dnf5-command(remove)
Provides: dnf5-command(repo)
Provides: dnf5-command(repoquery)
Expand Down Expand Up @@ -308,6 +309,7 @@ It supports RPM packages, modulemd modules, and comps groups & environments.
%{_mandir}/man8/dnf*-provides.8.*
%{_mandir}/man8/dnf*-reinstall.8.*
%{_mandir}/man8/dnf*-remove.8.*
%{_mandir}/man8/dnf*-replay.8.*
%{_mandir}/man8/dnf*-repo.8.*
%{_mandir}/man8/dnf*-repoquery.8.*
%{_mandir}/man8/dnf*-search.8.*
Expand Down
2 changes: 0 additions & 2 deletions dnf5/commands/history/history.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ along with libdnf. If not, see <https://www.gnu.org/licenses/>.
#include "history_info.hpp"
#include "history_list.hpp"
#include "history_redo.hpp"
#include "history_replay.hpp"
#include "history_rollback.hpp"
#include "history_store.hpp"
#include "history_undo.hpp"
Expand Down Expand Up @@ -61,7 +60,6 @@ void HistoryCommand::register_subcommands() {
// register_subcommand(std::make_unique<HistoryRedoCommand>(get_context()), software_management_commands_group);
// register_subcommand(std::make_unique<HistoryRollbackCommand>(get_context()), software_management_commands_group);
register_subcommand(std::make_unique<HistoryStoreCommand>(get_context()), software_management_commands_group);
// register_subcommand(std::make_unique<HistoryReplayCommand>(get_context()), software_management_commands_group);
}

void HistoryCommand::pre_configure() {
Expand Down
30 changes: 0 additions & 30 deletions dnf5/commands/history/history_replay.cpp

This file was deleted.

74 changes: 74 additions & 0 deletions dnf5/commands/replay/replay.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
Copyright Contributors to the libdnf project.
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 General Public License as published by
the Free Software Foundation, either version 2 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with libdnf. If not, see <https://www.gnu.org/licenses/>.
*/

#include "replay.hpp"

#include <dnf5/shared_options.hpp>
#include <libdnf5/utils/bgettext/bgettext-mark-domain.h>

namespace dnf5 {

void ReplayCommand::set_parent_command() {
auto * arg_parser_parent_cmd = get_session().get_argument_parser().get_root_command();
auto * arg_parser_this_cmd = get_argument_parser_command();
arg_parser_parent_cmd->register_command(arg_parser_this_cmd);
arg_parser_parent_cmd->get_group("software_management_commands").register_argument(arg_parser_this_cmd);
}

void ReplayCommand::set_argument_parser() {
auto & cmd = *get_argument_parser_command();
cmd.set_description("Replay a transaction that was previously stored to a directory");
auto & ctx = get_context();
auto & parser = ctx.get_argument_parser();

auto * transaction_path_arg = parser.add_new_positional_arg("transaction-path", 1, nullptr, nullptr);
transaction_path_arg->set_description("Path to a directory with stored transaction.");
transaction_path_arg->set_parse_hook_func([this](
[[maybe_unused]] libdnf5::cli::ArgumentParser::PositionalArg * arg,
[[maybe_unused]] int argc,
const char * const argv[]) {
transaction_path = argv[0];
return true;
});
cmd.register_positional_arg(transaction_path_arg);

auto skip_unavailable = std::make_unique<SkipUnavailableOption>(*this);
}

void ReplayCommand::configure() {
auto & context = get_context();
context.set_load_system_repo(true);
context.set_load_available_repos(Context::LoadAvailableRepos::ENABLED);
}

void ReplayCommand::run() {
auto & context = get_context();
auto settings = libdnf5::GoalJobSettings();

//TODO(amatej): add `--ignore-installed` and `--ignore-extras` options

try {
context.get_goal()->add_serialized_transaction(transaction_path + TRANSACTION_JSON, settings);
} catch (const libdnf5::Error & ex) {
throw libdnf5::cli::CommandExitError(
1, M_("Error while handling: {}: {}"), transaction_path, std::string(ex.what()));
}
}

} // namespace dnf5
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,29 @@ along with libdnf. If not, see <https://www.gnu.org/licenses/>.
*/


#ifndef DNF5_COMMANDS_HISTORY_HISTORY_REPLAY_HPP
#define DNF5_COMMANDS_HISTORY_HISTORY_REPLAY_HPP
#ifndef DNF5_COMMANDS_REPLAY__REPLAY_HPP
#define DNF5_COMMANDS_REPLAY__REPLAY_HPP

#include <dnf5/context.hpp>

#include <libdnf5/conf/option_bool.hpp>

namespace dnf5 {


class HistoryReplayCommand : public Command {
class ReplayCommand : public Command {
public:
explicit HistoryReplayCommand(Context & context) : Command(context, "replay") {}
explicit ReplayCommand(Context & context) : Command(context, "replay") {}
void set_parent_command() override;
void configure() override;
void set_argument_parser() override;
void run() override;

private:
std::string transaction_path;
};


} // namespace dnf5


#endif // DNF5_COMMANDS_HISTORY_HISTORY_REPLAY_HPP
#endif // DNF5_COMMANDS_REPLAY__REPLAY_HPP
2 changes: 2 additions & 0 deletions dnf5/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ along with libdnf. If not, see <https://www.gnu.org/licenses/>.
#include "commands/provides/provides.hpp"
#include "commands/reinstall/reinstall.hpp"
#include "commands/remove/remove.hpp"
#include "commands/replay/replay.hpp"
#include "commands/repo/repo.hpp"
#include "commands/repoquery/repoquery.hpp"
#include "commands/search/search.hpp"
Expand Down Expand Up @@ -674,6 +675,7 @@ static void add_commands(Context & context) {
context.add_and_initialize_command(std::make_unique<MarkCommand>(context));
context.add_and_initialize_command(std::make_unique<AutoremoveCommand>(context));
context.add_and_initialize_command(std::make_unique<ProvidesCommand>(context));
context.add_and_initialize_command(std::make_unique<ReplayCommand>(context));

context.add_and_initialize_command(std::make_unique<LeavesCommand>(context));
context.add_and_initialize_command(std::make_unique<RepoqueryCommand>(context));
Expand Down
1 change: 1 addition & 0 deletions doc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ if(WITH_MAN)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/man/dnf5-provides.8 DESTINATION share/man/man8)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/man/dnf5-reinstall.8 DESTINATION share/man/man8)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/man/dnf5-remove.8 DESTINATION share/man/man8)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/man/dnf5-replay.8 DESTINATION share/man/man8)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/man/dnf5-repo.8 DESTINATION share/man/man8)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/man/dnf5-repoquery.8 DESTINATION share/man/man8)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/man/dnf5-search.8 DESTINATION share/man/man8)
Expand Down
5 changes: 5 additions & 0 deletions doc/changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,11 @@ Changes to individual commands
``help``
* Dropped. The functionality is replaced by the ``--help`` option.

``history``
* ``store`` subcommand now outputs a directory with transaction JSON file instead of a single transaction JSON file directly.
* ``replay`` subcommand was moved to a standalone ``replay`` command, that now accepts a path to a directory instead of a single file.
The directory can be created with ``--store`` option and in addition to the JSON transaction can contain packages, group and environments used in the transaction.

``info``
* Dropped ``--all`` option since this behavior is the default one.
* Dropped ``--updates`` option, only ``--upgrades`` is available now.
Expand Down
3 changes: 0 additions & 3 deletions doc/commands/history.8.rst
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,6 @@ Subcommands
``store``
| Store the transaction into a directory.
``replay``
| Replay the transaction that was previously stored into the file.

Options
=======
Expand Down
1 change: 1 addition & 0 deletions doc/commands/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ DNF5 Commands
provides.8
reinstall.8
remove.8
replay.8
repo.8
repoquery.8
search.8
Expand Down
58 changes: 58 additions & 0 deletions doc/commands/replay.8.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
..
Copyright Contributors to the libdnf project.
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 General Public License as published by
the Free Software Foundation, either version 2 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 General Public License for more details.

You should have received a copy of the GNU General Public License
along with libdnf. If not, see <https://www.gnu.org/licenses/>.

.. _replay_command_ref-label:

###############
Replay Command
###############

Synopsis
========

``dnf5 replay [options] <transaction-path>``


Description
===========

Replay a transaction stored in a directory at ``<transaction-path>``. The transaction directory can be created either by
the ``--store`` option, available for all transaction commands, or by `History Store Command`. The replay will perform
the exact same operations on the packages as in the original transaction and will return with an error in case of any
differences in installed packages or their versions.

To run the replay the transaction directory has to contain a file with the transaction in JSON format named ``transaction.json``.
The directory can also contain packages, comps groups or comps environments that will be used used in the replayed transaction.


Options
=======

``--skip-unavailable``
| In case some packages stored in the transaction are not available on the target system,
| skip them instead of erroring out.

Examples
========

``dnf5 replay ./transaction``
| Replay a transaction stored at ./transaction.
``dnf5 replay ./transaction --skip-unavailable``
| Replay a transaction stored at ./transaction skipping unavailable packages.
1 change: 1 addition & 0 deletions doc/conf.py.in
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ man_pages = [
('commands/provides.8', 'dnf5-provides', 'Provides Command', AUTHORS, 8),
('commands/reinstall.8', 'dnf5-reinstall', 'Reinstall Command', AUTHORS, 8),
('commands/remove.8', 'dnf5-remove', 'Remove Command', AUTHORS, 8),
('commands/replay.8', 'dnf5-replay', 'Replay Command', AUTHORS, 8),
('commands/repo.8', 'dnf5-repo', 'Repo Command', AUTHORS, 8),
('commands/repoquery.8', 'dnf5-repoquery', 'Repoquery Command', AUTHORS, 8),
('commands/search.8', 'dnf5-search', 'Search Command', AUTHORS, 8),
Expand Down
3 changes: 3 additions & 0 deletions doc/dnf5.8.rst
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,9 @@ For more details see the separate man page for the specific command, f.e. ``man
:ref:`remove <remove_command_ref-label>`
| Remove packages.
:ref:`replay <replay_command_ref-label>`
| Replay stored transactions.
:ref:`repo <repo_command_ref-label>`
| Manage repositories.
Expand Down

0 comments on commit d08ca5d

Please sign in to comment.