diff --git a/docs/config.md b/docs/config.md index a6785f6..708ad94 100644 --- a/docs/config.md +++ b/docs/config.md @@ -86,6 +86,34 @@ Example configuration: "device": "/dev/nvme0n1" ``` --- +### `partitions` + +This declares partitions map. +Required in `HEADLESS` mode! + +The `partitions` provide information, which will be used +during the partition and mount steps. + +There is no default for this option. + +Example configuration: +```json +"partitions": [ + { + "name": "/dev/nvme0n1p3", + "mountpoint": "/", + "size": "450G", + "type": "root" + }, + { + "name": "/dev/nvme0n1p1", + "mountpoint": "/boot", + "size": "512M", + "type": "boot" + } +] +``` +--- ### `fs_name` This sets the target device filesystem. diff --git a/settings.json b/settings.json index 61d99d5..0163f01 100644 --- a/settings.json +++ b/settings.json @@ -3,6 +3,20 @@ "headless_mode": false, "device": "/dev/nvme0n1", "fs_name": "btrfs", + "partitions": [ + { + "name": "/dev/nvme0n1p3", + "mountpoint": "/", + "size": "450G", + "type": "root" + }, + { + "name": "/dev/nvme0n1p1", + "mountpoint": "/boot", + "size": "512M", + "type": "boot" + } + ], "hostname": "cachyos", "locale": "en_US", "xkbmap": "us", diff --git a/src/config.cpp b/src/config.cpp index 110449d..498975b 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -35,6 +35,7 @@ bool Config::initialize() noexcept { s_config->m_data["LVM"] = 0; s_config->m_data["LVM_LV_NAME"] = ""; // Name of LV to create or use s_config->m_data["LVM_SEP_BOOT"] = 0; + s_config->m_data["READY_PARTITIONS"] = std::vector{}; // Mounting s_config->m_data["MOUNTPOINT"] = "/mnt"; diff --git a/src/simple_tui.cpp b/src/simple_tui.cpp index 68f8025..6807f48 100644 --- a/src/simple_tui.cpp +++ b/src/simple_tui.cpp @@ -103,6 +103,7 @@ void menu_simple() noexcept { const auto& device_info = std::get(config_data["DEVICE"]); const auto& fs_name = std::get(config_data["FILESYSTEM_NAME"]); const auto& mount_opts_info = std::get(config_data["MOUNT_OPTS"]); + const auto& ready_parts = std::get>(config_data["READY_PARTITIONS"]); const auto& hostname = std::get(config_data["HOSTNAME"]); const auto& locale = std::get(config_data["LOCALE"]); diff --git a/src/utils.cpp b/src/utils.cpp index 086c0ea..2c70aa4 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -1537,7 +1537,7 @@ void install_cachyos_repo() noexcept { spdlog::info("{} is supported", isa_level); const auto& repo_list = detail::pacmanconf::get_repo_list("/etc/pacman.conf"); - if (ranges::contains(repo_list, fmt::format("[{}]", repo_name))) { + if (ranges::contains(repo_list, fmt::format(FMT_COMPILE("[{}]"), repo_name))) { spdlog::info("'{}' is already added!", repo_name); return; } @@ -1775,6 +1775,40 @@ bool parse_config() noexcept { return false; } + if (doc.HasMember("partitions")) { + assert(doc["partitions"].IsArray()); + + std::vector ready_parts{}; + for (const auto& partition_map : doc["partitions"].GetArray()) { + assert(partition_map.IsObject()); + + const auto& part_obj = partition_map.GetObject(); + assert(partition_map["name"].IsString()); + assert(partition_map["mountpoint"].IsString()); + assert(partition_map["size"].IsString()); + assert(partition_map["type"].IsString()); + + // Validate partition type. + const auto& part_type = std::string{partition_map["type"].GetString()}; + + using namespace std::literals; + static constexpr std::array valid_types{"root"sv, "boot"sv, "additional"sv}; + if (!ranges::contains(valid_types, part_type)) { + fmt::print(stderr, "partition type '{}' is invalid! Valid types: {}.\n", part_type, valid_types); + return false; + } + + // Just to save some space push as single string instead of a new type. + auto&& part_data = fmt::format(FMT_COMPILE("{}\t{}\t{}\t{}"), partition_map["name"].GetString(), + partition_map["mountpoint"].GetString(), partition_map["size"].GetString(), part_type); + ready_parts.push_back(std::move(part_data)); + } + config_data["READY_PARTITIONS"] = std::move(ready_parts); + } else if (headless_mode) { + fmt::print(stderr, "\"partitions\" field is required in HEADLESS mode!\n"); + return false; + } + if (doc.HasMember("fs_name")) { assert(doc["fs_name"].IsString()); config_data["FILESYSTEM_NAME"] = std::string{doc["fs_name"].GetString()};