From 9c8f8f241e68942be36f648bbb46190f9442a573 Mon Sep 17 00:00:00 2001 From: Vladislav Nepogodin Date: Mon, 1 Jul 2024 22:21:08 +0400 Subject: [PATCH] =?UTF-8?q?=F0=9F=A7=B9=20move=20systemd-boot=20installati?= =?UTF-8?q?on=20into=20gucc?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit needs refactor to be testable --- gucc/CMakeLists.txt | 1 + gucc/include/gucc/bootloader.hpp | 13 ++++++++++ gucc/meson.build | 1 + gucc/src/bootloader.cpp | 41 ++++++++++++++++++++++++++++++++ src/utils.cpp | 27 +++++++++++---------- 5 files changed, 71 insertions(+), 12 deletions(-) create mode 100644 gucc/include/gucc/bootloader.hpp create mode 100644 gucc/src/bootloader.cpp diff --git a/gucc/CMakeLists.txt b/gucc/CMakeLists.txt index 34015dd..b7d49fd 100644 --- a/gucc/CMakeLists.txt +++ b/gucc/CMakeLists.txt @@ -24,6 +24,7 @@ add_library(${PROJECT_NAME} SHARED src/locale.cpp include/gucc/locale.hpp src/fstab.cpp include/gucc/fstab.hpp src/crypttab.cpp include/gucc/crypttab.hpp + src/bootloader.cpp include/gucc/bootloader.hpp #src/chwd_profiles.cpp src/chwd_profiles.hpp #src/disk.cpp src/disk.hpp ) diff --git a/gucc/include/gucc/bootloader.hpp b/gucc/include/gucc/bootloader.hpp new file mode 100644 index 0000000..70f7bb7 --- /dev/null +++ b/gucc/include/gucc/bootloader.hpp @@ -0,0 +1,13 @@ +#ifndef BOOTLOADER_HPP +#define BOOTLOADER_HPP + +#include // for string_view + +namespace gucc::bootloader { + +// Installs & configures systemd-boot on system +auto install_systemd_boot(std::string_view root_mountpoint, std::string_view efi_directory, bool is_volume_removable) noexcept -> bool; + +} // namespace gucc::bootloader + +#endif // BOOTLOADER_HPP diff --git a/gucc/meson.build b/gucc/meson.build index 38899cb..24d7df9 100644 --- a/gucc/meson.build +++ b/gucc/meson.build @@ -14,6 +14,7 @@ gucc_lib = library('gucc', 'src/locale.cpp', 'src/fstab.cpp', 'src/crypttab.cpp', + 'src/bootloader.cpp', ], include_directories : [include_directories('include')], dependencies: deps diff --git a/gucc/src/bootloader.cpp b/gucc/src/bootloader.cpp new file mode 100644 index 0000000..0717fd5 --- /dev/null +++ b/gucc/src/bootloader.cpp @@ -0,0 +1,41 @@ +#include "gucc/bootloader.hpp" +#include "gucc/initcpio.hpp" +#include "gucc/io_utils.hpp" + +#include +#include + +#include + +using namespace std::string_view_literals; + +namespace gucc::bootloader { + +auto install_systemd_boot(std::string_view root_mountpoint, std::string_view efi_directory, bool is_volume_removable) noexcept -> bool { + // Install systemd-boot onto EFI + const auto& bootctl_cmd = fmt::format(FMT_COMPILE("bootctl --path={} install"), efi_directory); + if (!utils::arch_chroot_checked(bootctl_cmd, root_mountpoint)) { + spdlog::error("Failed to run bootctl on path {} with: {}", root_mountpoint, bootctl_cmd); + return false; + } + + // Generate systemd-boot configuration entries with our sdboot + static constexpr auto sdboot_cmd = "sdboot-manage gen"sv; + if (!utils::arch_chroot_checked(bootctl_cmd, root_mountpoint)) { + spdlog::error("Failed to run sdboot-manage gen on mountpoint: {}", root_mountpoint); + return false; + } + + // if the volume is removable don't use autodetect + if (is_volume_removable) { + const auto& initcpio_filename = fmt::format(FMT_COMPILE("{}/etc/mkinitcpio.conf"), root_mountpoint); + + // Remove autodetect hook + auto initcpio = detail::Initcpio{initcpio_filename}; + initcpio.remove_hook("autodetect"); + spdlog::info("\"Autodetect\" hook was removed"); + } + return true; +} + +} // namespace gucc::bootloader diff --git a/src/utils.cpp b/src/utils.cpp index 09ca244..26b4169 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -6,6 +6,7 @@ #include "widgets.hpp" // import gucc +#include "gucc/bootloader.hpp" #include "gucc/cpu.hpp" #include "gucc/file_utils.hpp" #include "gucc/fs_utils.hpp" @@ -1158,25 +1159,27 @@ void install_systemd_boot() noexcept { #ifdef NDEVENV auto* config_instance = Config::instance(); auto& config_data = config_instance->data(); + const auto& mountpoint = std::get(config_data["MOUNTPOINT"]); const auto& uefi_mount = std::get(config_data["UEFI_MOUNT"]); - utils::arch_chroot(fmt::format(FMT_COMPILE("bootctl --path={} install"), uefi_mount), false); + // preinstall systemd-boot-manager. it has to be installed utils::install_from_pkglist("systemd-boot-manager"); - utils::arch_chroot("sdboot-manage gen", false); - // Check if the volume is removable. If so, don't use autodetect - const auto& root_name = gucc::utils::exec("mount | awk '/\\/mnt / {print $1}' | sed s~/dev/mapper/~~g | sed s~/dev/~~g"); + // Check if the volume is removable + + // NOTE: for /mnt on /dev/mapper/cryptroot `root_name` will be cryptroot + const auto& root_name = gucc::utils::exec("mount | awk '/\\/mnt / {print $1}' | sed s~/dev/mapper/~~g | sed s~/dev/~~g"); + + // NOTE: for /mnt on /dev/mapper/cryptroot on /dev/sda2 with `root_name`=cryptroot, `root_device` will be sda const auto& root_device = gucc::utils::exec(fmt::format(FMT_COMPILE("lsblk -i | tac | sed -r 's/^[^[:alnum:]]+//' | sed -n -e \"/{}/,/disk/p\" | {}"), root_name, "awk '/disk/ {print $1}'")); spdlog::info("root_name: {}. root_device: {}", root_name, root_device); - const auto& removable = gucc::utils::exec(fmt::format(FMT_COMPILE("cat /sys/block/{}/removable"), root_device)); - if (utils::to_int(removable) == 1) { - const auto& mountpoint = std::get(config_data["MOUNTPOINT"]); - const auto& initcpio_filename = fmt::format(FMT_COMPILE("{}/etc/mkinitcpio.conf"), mountpoint); - auto initcpio = gucc::detail::Initcpio{initcpio_filename}; + const auto& removable = gucc::utils::exec(fmt::format(FMT_COMPILE("cat /sys/block/{}/removable"), root_device)); + const bool is_volume_removable = (utils::to_int(removable) == 1); - // Remove autodetect hook - initcpio.remove_hook("autodetect"); - spdlog::info("\"Autodetect\" hook was removed"); + // start systemd-boot install & configuration + if (!gucc::bootloader::install_systemd_boot(mountpoint, uefi_mount, is_volume_removable)) { + spdlog::error("Failed to install systemd-boot"); + return; } #endif spdlog::info("Systemd-boot was installed");