Skip to content

Commit

Permalink
system-upgrade: misc fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
evan-goode committed Mar 14, 2024
1 parent 520d21b commit 6799f77
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 22 deletions.
8 changes: 6 additions & 2 deletions dnf5.spec
Original file line number Diff line number Diff line change
Expand Up @@ -262,8 +262,6 @@ It supports RPM packages, modulemd modules, and comps groups & environments.
%dir %{_datadir}/dnf5
%dir %{_datadir}/dnf5/aliases.d
%config %{_datadir}/dnf5/aliases.d/compatibility.conf
%config %{_unitdir}/dnf5-offline-transaction.service
%config %{_unitdir}/dnf5-offline-transaction-cleanup.service
%dir %{_libdir}/dnf5
%dir %{_libdir}/dnf5/plugins
%dir %{_datadir}/dnf5/dnf5-plugins
Expand Down Expand Up @@ -317,6 +315,12 @@ It supports RPM packages, modulemd modules, and comps groups & environments.
%{_mandir}/man5/dnf5.conf-todo.5.*
%{_mandir}/man5/dnf5.conf-deprecated.5.*

%if %{with systemd}
%{_unitdir}/dnf5-offline-transaction.service
%{_unitdir}/dnf5-offline-transaction-cleanup.service
%{_unitdir}/system-update.target.wants/dnf5-offline-transaction.service
%endif

# ========== libdnf5 ==========
%package -n libdnf5
Summary: Package management library
Expand Down
16 changes: 10 additions & 6 deletions dnf5/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ if(NOT WITH_DNF5)
return()
endif()

set(SYSTEMD_SYSTEM_UNIT_DIR /usr/lib/systemd/system)
pkg_check_modules(SYSTEMD REQUIRED systemd)
pkg_get_variable(SYSTEMD_SYSTEM_UNIT_DIR systemd systemdsystemunitdir)

find_package(Threads)

Expand Down Expand Up @@ -56,11 +57,14 @@ install(FILES bash-completion/dnf5 DESTINATION ${BASH_COMPLETION_COMPLETIONSDIR}
install(FILES "README.plugins" DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}/dnf5/plugins" RENAME "README")
install(DIRECTORY "config/usr/" DESTINATION "${CMAKE_INSTALL_PREFIX}" PATTERN ".gitkeep" EXCLUDE)
install(DIRECTORY "config/etc/" DESTINATION "${CMAKE_INSTALL_FULL_SYSCONFDIR}" PATTERN ".gitkeep" EXCLUDE)
install(DIRECTORY "config/systemd/system/" DESTINATION "${SYSTEMD_SYSTEM_UNIT_DIR}" PATTERN ".gitkeep" EXCLUDE)
install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink
${SYSTEMD_SYSTEM_UNIT_DIR}/dnf5-offline-transaction.service
${SYSTEMD_SYSTEM_UNIT_DIR}/system-update.target.wants/dnf5-offline-transaction.service)"
)

if(WITH_SYSTEMD)
install(DIRECTORY "config/systemd/system/" DESTINATION "${SYSTEMD_SYSTEM_UNIT_DIR}" PATTERN ".gitkeep" EXCLUDE)
install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink
${SYSTEMD_SYSTEM_UNIT_DIR}/dnf5-offline-transaction.service
${SYSTEMD_SYSTEM_UNIT_DIR}/system-update.target.wants/dnf5-offline-transaction.service)"
)
endif()

# Makes an empty directory for dnf5-plugins configuration files
install(DIRECTORY DESTINATION "${CMAKE_INSTALL_FULL_SYSCONFDIR}/dnf/dnf5-plugins")
Expand Down
48 changes: 38 additions & 10 deletions dnf5/commands/offline/offline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ using namespace libdnf5::cli;

const std::string & ID_TO_IDENTIFY_BOOTS = dnf5::offline::OFFLINE_STARTED_ID;

const std::string SYSTEMD_DESTINATION_NAME{"org.freedesktop.systemd1"};
const std::string SYSTEMD_OBJECT_PATH{"/org/freedesktop/systemd1"};
const std::string SYSTEMD_MANAGER_INTERFACE{"org.freedesktop.systemd1.Manager"};
const std::string SYSTEMD_UNIT_INTERFACE{"org.freedesktop.systemd1.Unit"};
const std::string SYSTEMD_SERVICE_NAME{"dnf5-offline-transaction.service"};

int call(const std::string & command, const std::vector<std::string> & args) {
std::vector<char *> c_args;
c_args.emplace_back(const_cast<char *>(command.c_str()));
Expand Down Expand Up @@ -192,6 +198,9 @@ OfflineSubcommand::OfflineSubcommand(Context & context, const std::string & name

void OfflineSubcommand::configure() {
auto & ctx = get_context();
// This value comes from systemd, see
// https://www.freedesktop.org/wiki/Software/systemd/SystemUpdates or
// systemd.offline-updates(7).
magic_symlink = "/system-update";

const std::filesystem::path installroot = ctx.base.get_config().get_installroot_option().get_value();
Expand Down Expand Up @@ -223,10 +232,6 @@ void check_state(const dnf5::offline::OfflineTransactionState & state) {
}

void reboot([[maybe_unused]] bool poweroff = false) {
const std::string systemd_destination_name{"org.freedesktop.systemd1"};
const std::string systemd_object_path{"/org/freedesktop/systemd1"};
const std::string systemd_manager_interface{"org.freedesktop.systemd1.Manager"};

if (std::getenv("DNF_SYSTEM_UPGRADE_NO_REBOOT")) {
std::cerr << "DNF_SYSTEM_UPGRADE_NO_REBOOT is set, not rebooting." << std::endl;
return;
Expand All @@ -241,11 +246,11 @@ void reboot([[maybe_unused]] bool poweroff = false) {
const std::string error_message{ex.what()};
throw libdnf5::cli::CommandExitError(1, M_("Couldn't connect to D-Bus: {}"), error_message);
}
auto proxy = sdbus::createProxy(systemd_destination_name, systemd_object_path);
auto proxy = sdbus::createProxy(SYSTEMD_DESTINATION_NAME, SYSTEMD_OBJECT_PATH);
if (poweroff) {
proxy->callMethod("Poweroff").onInterface(systemd_manager_interface);
proxy->callMethod("Poweroff").onInterface(SYSTEMD_MANAGER_INTERFACE);
} else {
proxy->callMethod("Reboot").onInterface(systemd_manager_interface);
proxy->callMethod("Reboot").onInterface(SYSTEMD_MANAGER_INTERFACE);
}
#else
std::cerr << "Can't connect to D-Bus; this build of DNF 5 does not support D-Bus." << std::endl;
Expand Down Expand Up @@ -290,9 +295,33 @@ void OfflineRebootCommand::run() {
throw libdnf5::cli::CommandExitError(1, M_("System is not ready for offline transaction."));
}
if (!std::filesystem::is_directory(get_datadir())) {
throw libdnf5::cli::CommandExitError(1, M_("data directory {} does not exist"), get_datadir().string());
throw libdnf5::cli::CommandExitError(1, M_("Data directory {} does not exist."), get_datadir().string());
}

#ifdef WITH_SYSTEMD
// Check that dnf5-offline-transaction.service is present and wanted by system-update.target
std::unique_ptr<sdbus::IConnection> connection;
try {
connection = sdbus::createSystemBusConnection();
} catch (const sdbus::Error & ex) {
const std::string error_message{ex.what()};
throw libdnf5::cli::CommandExitError(1, M_("Couldn't connect to D-Bus: {}"), error_message);
}
auto systemd_proxy = sdbus::createProxy(SYSTEMD_DESTINATION_NAME, SYSTEMD_OBJECT_PATH);

sdbus::ObjectPath unit_object_path;
systemd_proxy->callMethod("LoadUnit")
.onInterface(SYSTEMD_MANAGER_INTERFACE)
.withArguments("system-update.target")
.storeResultsTo(unit_object_path);

auto unit_proxy = sdbus::createProxy(SYSTEMD_DESTINATION_NAME, unit_object_path);
const std::vector<std::string> & wants = unit_proxy->getProperty("Wants").onInterface(SYSTEMD_UNIT_INTERFACE);
if (std::find(wants.begin(), wants.end(), SYSTEMD_SERVICE_NAME) == wants.end()) {
throw libdnf5::cli::CommandExitError(1, M_("{} is not wanted by system-update.target."), SYSTEMD_SERVICE_NAME);
}
#endif

if (state->get_data().verb == "system-upgrade download") {
std::cout << _("The system will now reboot to upgrade to release version ")
<< state->get_data().target_releasever << "." << std::endl;
Expand Down Expand Up @@ -396,8 +425,7 @@ void OfflineExecuteCommand::run() {
throw libdnf5::cli::CommandExitError(0, M_("Trigger file does not exist. Exiting."));
}

const auto & symlinked_path = std::filesystem::read_symlink(get_magic_symlink());
if (symlinked_path != get_datadir()) {
if (!std::filesystem::equivalent(get_magic_symlink(), get_datadir())) {
throw libdnf5::cli::CommandExitError(0, M_("Another offline transaction tool is running. Exiting."));
}

Expand Down
4 changes: 1 addition & 3 deletions dnf5/commands/system-upgrade/system-upgrade.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,7 @@ void SystemUpgradeDownloadCommand::run() {
ctx.set_should_store_offline(true);
ctx.download_and_run(transaction);

std::cout << _("Download complete! Use `dnf5 system-upgrade reboot` to start the upgrade.\n"
"To cancel the upgrade and delete the downloaded upgrade files, use `dnf5 system-upgrade clean`.")
<< std::endl;
std::cout << _("Download complete!") << std::endl;

dnf5::offline::log_status(
ctx, "Download finished.", dnf5::offline::DOWNLOAD_FINISHED_ID, system_releasever, target_releasever);
Expand Down
3 changes: 2 additions & 1 deletion dnf5/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,8 @@ void Context::download_and_run(libdnf5::base::Transaction & transaction) {
if (should_store_offline) {
store_offline(transaction);
std::cout << "Transaction stored to be performed offline. Run `dnf5 offline reboot` to reboot and run the "
"transaction."
"transaction. To cancel the transaction and delete the downloaded files, use `dnf5 "
"offline clean`."
<< std::endl;
}
}
Expand Down

0 comments on commit 6799f77

Please sign in to comment.