diff --git a/dnf5daemon-client/commands/system-upgrade/system-upgrade.cpp b/dnf5daemon-client/commands/system-upgrade/system-upgrade.cpp
new file mode 100644
index 000000000..9e09e8120
--- /dev/null
+++ b/dnf5daemon-client/commands/system-upgrade/system-upgrade.cpp
@@ -0,0 +1,81 @@
+/*
+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 .
+*/
+
+#include "system-upgrade.hpp"
+
+#include "commands/shared_options.hpp"
+#include "context.hpp"
+#include "exception.hpp"
+#include "utils/auth.hpp"
+
+#include
+#include
+
+namespace dnfdaemon::client {
+
+using namespace libdnf5::cli;
+
+void SystemUpgradeCommand::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 SystemUpgradeCommand::set_argument_parser() {
+ auto & parser = get_context().get_argument_parser();
+ auto & cmd = *get_argument_parser_command();
+
+ cmd.set_description("prepare system for upgrade to a new release");
+
+ auto no_downgrade = parser.add_new_named_arg("no_downgrade");
+ no_downgrade->set_long_name("no-downgrade");
+ no_downgrade->set_description(
+ "Do not install packages from the new release if they are older than what is currently installed");
+ no_downgrade->set_has_value(true);
+ no_downgrade->set_arg_value_help("");
+ no_downgrade->link_value(&no_downgrade_option);
+ cmd.register_named_arg(no_downgrade);
+
+ // TODO(mblaha): set the releasever named arg as required (currently no API for this)
+}
+
+void SystemUpgradeCommand::run() {
+ auto & ctx = get_context();
+
+ if (!libdnf5::utils::am_i_root()) {
+ throw UnprivilegedUserError();
+ }
+
+ // TODO(mblaha): check the target releasever is set and different from the detected one
+
+ dnfdaemon::KeyValueMap options = {};
+ if (no_downgrade_option.get_value()) {
+ options["mode"] = "upgrade";
+ }
+
+ ctx.session_proxy->callMethod("system_upgrade")
+ .onInterface(dnfdaemon::INTERFACE_RPM)
+ .withTimeout(static_cast(-1))
+ .withArguments(options);
+
+ run_transaction(true);
+}
+
+} // namespace dnfdaemon::client
diff --git a/dnf5daemon-client/commands/system-upgrade/system-upgrade.hpp b/dnf5daemon-client/commands/system-upgrade/system-upgrade.hpp
new file mode 100644
index 000000000..7d54b0b84
--- /dev/null
+++ b/dnf5daemon-client/commands/system-upgrade/system-upgrade.hpp
@@ -0,0 +1,42 @@
+/*
+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 .
+*/
+
+#ifndef DNF5DAEMON_CLIENT_COMMANDS_SYSTEM_UPGRADE_SYSTEM_UPGRADE_HPP
+#define DNF5DAEMON_CLIENT_COMMANDS_SYSTEM_UPGRADE_SYSTEM_UPGRADE_HPP
+
+#include "commands/command.hpp"
+
+#include
+
+namespace dnfdaemon::client {
+
+class SystemUpgradeCommand : public TransactionCommand {
+public:
+ explicit SystemUpgradeCommand(Context & context) : TransactionCommand(context, "system-upgrade") {}
+ void set_parent_command() override;
+ void set_argument_parser() override;
+ void run() override;
+
+private:
+ libdnf5::OptionBool no_downgrade_option{false};
+};
+
+} // namespace dnfdaemon::client
+
+#endif
diff --git a/dnf5daemon-client/main.cpp b/dnf5daemon-client/main.cpp
index 5c6638adf..7ac80bae5 100644
--- a/dnf5daemon-client/main.cpp
+++ b/dnf5daemon-client/main.cpp
@@ -28,6 +28,7 @@ along with libdnf. If not, see .
#include "commands/repo/repo.hpp"
#include "commands/repolist/repolist.hpp"
#include "commands/repoquery/repoquery.hpp"
+#include "commands/system-upgrade/system-upgrade.hpp"
#include "commands/upgrade/upgrade.hpp"
#include "context.hpp"
@@ -211,6 +212,7 @@ static void add_commands(Context & context) {
context.add_and_initialize_command(std::make_unique(context));
context.add_and_initialize_command(std::make_unique(context));
+ context.add_and_initialize_command(std::make_unique(context));
}
} // namespace dnfdaemon::client