dnfdaemon: Add system_upgrade() method to Rpm interface

The method fills the goal to perform upgrade of the distribution to the
new release.
This commit is contained in:
Marek Blaha 2024-05-30 09:27:57 +02:00 committed by amatej
parent f85c7fad37
commit b23ceffe92
3 changed files with 72 additions and 0 deletions

View File

@ -212,6 +212,24 @@ along with libdnf. If not, see <https://www.gnu.org/licenses/>.
<arg name="options" type="a{sv}" direction="in" />
</method>
<!--
system_upgrade:
@options: an array of key/value pairs to modify system_upgrade behavior
Prepare a transaction for upgrade to the new distribution release. The prepared transaction should be executed during reboot (see `offline` option of the `do_transaction` method of the `Goal` interface).
The method relies on the `releasever` option being correctly set to the new distribution release during the `open_session()` call.
Following @options are supported:
- mode: string (one of "distrosync", "upgrade", default is "distrosync")
By default the system_upgrade behaves like `dnf distro-sync`, always installing packages from the new release, even if they are older than the currently installed version. If set to "upgrade", packages from the new release are not installed if they are older than what is currently installed (behave like `dnf upgrade`).
Unknown options are ignored.
-->
<method name="system_upgrade">
<arg name="options" type="a{sv}" direction="in" />
</method>
<!--
transaction_elem_progress:
@session_object_path: object path of the dnf5daemon session

View File

@ -113,6 +113,16 @@ void Rpm::dbus_register() {
[this](sdbus::MethodCall call) -> void {
session.get_threads_manager().handle_method(*this, &Rpm::remove, call, session.session_locale);
});
dbus_object->registerMethod(
dnfdaemon::INTERFACE_RPM,
"system_upgrade",
"a{sv}",
{"options"},
"",
{},
[this](sdbus::MethodCall call) -> void {
session.get_threads_manager().handle_method(*this, &Rpm::system_upgrade, call, session.session_locale);
});
dbus_object->registerSignal(
dnfdaemon::INTERFACE_RPM, dnfdaemon::SIGNAL_TRANSACTION_BEFORE_BEGIN, "ot", {"session_object_path", "total"});
@ -623,3 +633,46 @@ sdbus::MethodReply Rpm::remove(sdbus::MethodCall & call) {
auto reply = call.createReply();
return reply;
}
sdbus::MethodReply Rpm::system_upgrade(sdbus::MethodCall & call) {
if (!session.check_authorization(dnfdaemon::POLKIT_EXECUTE_RPM_TRANSACTION, call.getSender())) {
throw std::runtime_error("Not authorized");
}
auto base = session.get_base();
// read options from dbus call
dnfdaemon::KeyValueMap options;
call >> options;
// check that releasever is different than the detected one
auto target_releasever = base->get_vars()->get_value("releasever");
const std::filesystem::path installroot{base->get_config().get_installroot_option().get_value()};
const auto & detected_releasever = libdnf5::Vars::detect_release(base->get_weak_ptr(), installroot);
if (detected_releasever != nullptr) {
if (target_releasever == *detected_releasever) {
throw sdbus::Error(
dnfdaemon::ERROR, fmt::format("Need a 'releasever' different than the current system version."));
}
}
// get the upgrade mode
std::string upgrade_mode = dnfdaemon::key_value_map_get<std::string>(options, "mode", "distrosync");
// fill the goal
auto & goal = session.get_goal();
libdnf5::GoalJobSettings settings;
if (upgrade_mode == "upgrade") {
goal.add_rpm_upgrade(settings);
} else if (upgrade_mode == "distrosync") {
goal.add_rpm_distro_sync(settings);
} else {
throw sdbus::Error(
dnfdaemon::ERROR,
fmt::format(
"Unsupported system-upgrade mode \"{}\". Only \"distrosync\" and \"upgrade\" modes are supported.",
upgrade_mode));
}
auto reply = call.createReply();
return reply;
}

View File

@ -43,6 +43,7 @@ private:
sdbus::MethodReply distro_sync(sdbus::MethodCall & call);
sdbus::MethodReply downgrade(sdbus::MethodCall & call);
sdbus::MethodReply reinstall(sdbus::MethodCall & call);
sdbus::MethodReply system_upgrade(sdbus::MethodCall & call);
void list_fd(sdbus::MethodCall & call, const std::string & transfer_id);
};