🧹 move systemd-boot installation into gucc

needs refactor to be testable
This commit is contained in:
Vladislav Nepogodin 2024-07-01 22:21:08 +04:00
parent 5d53d8b923
commit 9c8f8f241e
No known key found for this signature in database
GPG Key ID: B62C3D10C54D5DA9
5 changed files with 71 additions and 12 deletions

View File

@ -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
)

View File

@ -0,0 +1,13 @@
#ifndef BOOTLOADER_HPP
#define BOOTLOADER_HPP
#include <string_view> // 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

View File

@ -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

41
gucc/src/bootloader.cpp Normal file
View File

@ -0,0 +1,41 @@
#include "gucc/bootloader.hpp"
#include "gucc/initcpio.hpp"
#include "gucc/io_utils.hpp"
#include <fmt/compile.h>
#include <fmt/format.h>
#include <spdlog/spdlog.h>
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

View File

@ -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<std::string>(config_data["MOUNTPOINT"]);
const auto& uefi_mount = std::get<std::string>(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<std::string>(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");