diff --git a/src/initcpio.hpp b/src/initcpio.hpp index 7a363ee..65ad2d4 100644 --- a/src/initcpio.hpp +++ b/src/initcpio.hpp @@ -61,6 +61,17 @@ class Initcpio { hooks.emplace_back(std::move(hook)); return this->write(); } + inline bool append_hooks(std::vector&& hook) noexcept { + /* clang-format off */ + if (!this->parse_file()) { return false; } + auto&& filtered_input = hook | ranges::views::filter([&](auto&& el) { + return !ranges::contains(hooks, el); + }) | ranges::to>(); + if (filtered_input.empty()) { return false; } + + hooks.insert(hooks.end(), filtered_input.begin(), filtered_input.end()); + return this->write(); + } inline bool insert_hook(std::string&& needle, std::string&& hook) noexcept { /* clang-format off */ if (!this->parse_file()) { return false; } diff --git a/src/utils.cpp b/src/utils.cpp index 0494436..f4cb974 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -747,6 +747,10 @@ void install_base(const std::string_view& packages) noexcept { const auto& initcpio_filename = fmt::format(FMT_COMPILE("{}/etc/mkinitcpio.conf"), mountpoint); auto initcpio = detail::Initcpio{initcpio_filename}; + // NOTE: make sure that we have valid initcpio config, + // overwise we will end up here with unbootable system. + initcpio.append_hooks({"base", "udev", "autodetect", "modconf", "block", "filesystems", "keyboard", "fsck"}); + // filter_packages utils::install_from_pkglist(base_pkgs); @@ -760,6 +764,7 @@ void install_base(const std::string_view& packages) noexcept { std::int32_t zfs_root = 0; const auto& filesystem_type = fmt::format(FMT_COMPILE("findmnt -ln -o FSTYPE {}"), mountpoint); + spdlog::info("filesystem type on '{}' := '{}'", mountpoint, filesystem_type); if (filesystem_type == "btrfs") { btrfs_root = 1; initcpio.remove_hook("fsck"); @@ -776,6 +781,7 @@ void install_base(const std::string_view& packages) noexcept { // add luks and lvm hooks as needed const auto& lvm = std::get(config_data["LVM"]); const auto& luks = std::get(config_data["LUKS"]); + spdlog::info("LVM := {}, LUKS := {}", lvm, luks); if (lvm == 1 && luks == 0) { initcpio.insert_hook("filesystems", "lvm2"); @@ -792,7 +798,9 @@ void install_base(const std::string_view& packages) noexcept { // Just explicitly flush the data to file, // if smth really happened between our calls. - initcpio.write(); + if (initcpio.parse_file()) { + initcpio.write(); + } if (lvm + luks + btrfs_root + zfs_root > 0) { utils::arch_chroot("mkinitcpio -P"); diff --git a/tests/unit-initcpio.cpp b/tests/unit-initcpio.cpp index 17d4ca6..e10e095 100644 --- a/tests/unit-initcpio.cpp +++ b/tests/unit-initcpio.cpp @@ -58,7 +58,7 @@ int main() { initcpio.append_module("radeon"); initcpio.append_hook("btrfs"); initcpio.append_module("crc32c-intel"); - initcpio.hooks.insert(initcpio.hooks.end(), {"usr", "lvm2", "zfs"}); + initcpio.append_hooks({"usr", "lvm2", "zfs"}); // Write data. assert(initcpio.write());