Skip to content

Commit

Permalink
🧹 move systemd-boot installation into gucc
Browse files Browse the repository at this point in the history
needs refactor to be testable
  • Loading branch information
vnepogodin committed Jul 1, 2024
1 parent 5d53d8b commit 9c8f8f2
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 12 deletions.
1 change: 1 addition & 0 deletions gucc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
)
Expand Down
13 changes: 13 additions & 0 deletions gucc/include/gucc/bootloader.hpp
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions gucc/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
41 changes: 41 additions & 0 deletions gucc/src/bootloader.cpp
Original file line number Diff line number Diff line change
@@ -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
27 changes: 15 additions & 12 deletions src/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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");
Expand Down

0 comments on commit 9c8f8f2

Please sign in to comment.