mirror of
https://github.com/CachyOS/New-Cli-Installer.git
synced 2025-01-23 14:32:22 +08:00
👷 disk: refactor handling of btrfs information
cache partition information into partition scheme
This commit is contained in:
parent
756d87610f
commit
1ca45defa7
91
src/disk.cpp
91
src/disk.cpp
@ -10,7 +10,10 @@
|
|||||||
#include "gucc/string_utils.hpp"
|
#include "gucc/string_utils.hpp"
|
||||||
#include "gucc/zfs.hpp"
|
#include "gucc/zfs.hpp"
|
||||||
|
|
||||||
#include <filesystem> // for exists, is_directory
|
#include <algorithm> // for find_if
|
||||||
|
#include <filesystem> // for exists, is_directory
|
||||||
|
#include <ranges> // for ranges::*
|
||||||
|
|
||||||
#include <ftxui/component/component.hpp> // for Renderer, Button
|
#include <ftxui/component/component.hpp> // for Renderer, Button
|
||||||
#include <ftxui/component/component_options.hpp> // for ButtonOption
|
#include <ftxui/component/component_options.hpp> // for ButtonOption
|
||||||
#include <ftxui/component/screen_interactive.hpp> // for Component, ScreenI...
|
#include <ftxui/component/screen_interactive.hpp> // for Component, ScreenI...
|
||||||
@ -24,13 +27,40 @@ using namespace std::string_view_literals;
|
|||||||
using namespace std::string_literals;
|
using namespace std::string_literals;
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
constexpr auto is_root_btrfs_part(const gucc::fs::Partition& part) noexcept -> bool {
|
||||||
|
return (part.mountpoint == "/"sv) && (part.fstype == "btrfs"sv);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(vnepogodin): refactor that out of this file
|
||||||
|
constexpr auto find_root_btrfs_part(auto&& parts) noexcept {
|
||||||
|
return std::ranges::find_if(parts,
|
||||||
|
[](auto&& part) { return is_root_btrfs_part(part); });
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
namespace utils {
|
namespace utils {
|
||||||
|
|
||||||
void btrfs_create_subvols([[maybe_unused]] const disk_part& disk, const std::string_view& mode, bool ignore_note) noexcept {
|
void btrfs_create_subvols(std::vector<gucc::fs::Partition>& partitions, const std::string_view& mode, bool ignore_note) noexcept {
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
if (mode.empty()) { return; }
|
if (mode.empty()) { return; }
|
||||||
/* clang-format on */
|
/* clang-format on */
|
||||||
|
|
||||||
|
const std::vector<gucc::fs::BtrfsSubvolume> default_subvolumes{
|
||||||
|
gucc::fs::BtrfsSubvolume{.subvolume = "/@"s, .mountpoint = "/"s},
|
||||||
|
gucc::fs::BtrfsSubvolume{.subvolume = "/@home"s, .mountpoint = "/home"s},
|
||||||
|
gucc::fs::BtrfsSubvolume{.subvolume = "/@cache"s, .mountpoint = "/var/cache"s},
|
||||||
|
// gucc::fs::BtrfsSubvolume{.subvolume = "/@snapshots"sv, .mountpoint = "/.snapshots"sv},
|
||||||
|
};
|
||||||
|
|
||||||
|
auto root_part = find_root_btrfs_part(partitions);
|
||||||
|
if (root_part == std::ranges::end(partitions)) {
|
||||||
|
spdlog::error("btrfs_create_subvols: unable to find btrfs root part");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef NDEVENV
|
#ifdef NDEVENV
|
||||||
const auto root_mountpoint = "/mnt"sv;
|
const auto root_mountpoint = "/mnt"sv;
|
||||||
|
|
||||||
@ -68,9 +98,12 @@ void btrfs_create_subvols([[maybe_unused]] const disk_part& disk, const std::str
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create subvolumes
|
// Create subvolumes
|
||||||
if (!gucc::fs::btrfs_create_subvols(subvolumes, disk.root, root_mountpoint, disk.mount_opts)) {
|
if (!gucc::fs::btrfs_create_subvols(subvolumes, root_part->device, root_mountpoint, root_part->mount_opts)) {
|
||||||
spdlog::error("Failed to create subvolumes");
|
spdlog::error("Failed to create subvolumes");
|
||||||
}
|
}
|
||||||
|
if (!gucc::fs::btrfs_append_subvolumes(partitions, subvolumes)) {
|
||||||
|
spdlog::error("Failed to append btrfs subvolumes into partition scheme");
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!ignore_note) {
|
if (!ignore_note) {
|
||||||
@ -82,35 +115,35 @@ void btrfs_create_subvols([[maybe_unused]] const disk_part& disk, const std::str
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create subvolumes automatically
|
// Create subvolumes automatically
|
||||||
const std::vector<gucc::fs::BtrfsSubvolume> subvolumes{
|
if (!gucc::fs::btrfs_create_subvols(default_subvolumes, root_part->device, root_mountpoint, root_part->mount_opts)) {
|
||||||
gucc::fs::BtrfsSubvolume{.subvolume = "/@"s, .mountpoint = "/"s},
|
|
||||||
gucc::fs::BtrfsSubvolume{.subvolume = "/@home"s, .mountpoint = "/home"s},
|
|
||||||
gucc::fs::BtrfsSubvolume{.subvolume = "/@cache"s, .mountpoint = "/var/cache"s},
|
|
||||||
// gucc::fs::BtrfsSubvolume{.subvolume = "/@snapshots"sv, .mountpoint = "/.snapshots"sv},
|
|
||||||
};
|
|
||||||
if (!gucc::fs::btrfs_create_subvols(subvolumes, disk.root, root_mountpoint, disk.mount_opts)) {
|
|
||||||
spdlog::error("Failed to create subvolumes automatically");
|
spdlog::error("Failed to create subvolumes automatically");
|
||||||
}
|
}
|
||||||
|
|
||||||
gucc::fs::Partition partition{};
|
if (!gucc::fs::btrfs_append_subvolumes(partitions, default_subvolumes)) {
|
||||||
partition.fstype = "btrfs"s;
|
spdlog::error("Failed to append btrfs subvolumes into partition scheme");
|
||||||
partition.mountpoint = subvolumes[0].mountpoint;
|
}
|
||||||
// partition.uuid_str = "";
|
|
||||||
partition.device = disk.root;
|
|
||||||
partition.mount_opts = disk.mount_opts;
|
|
||||||
partition.subvolume = std::make_optional<std::string>(subvolumes[0].subvolume);
|
|
||||||
spdlog::debug("partition: fs='{}';mountpoint='{}';uuid_str='{}';device='{}';mount_opts='{}';subvolume='{}'",
|
|
||||||
partition.fstype, partition.mountpoint, partition.uuid_str, partition.device, partition.mount_opts, *partition.subvolume);
|
|
||||||
#else
|
#else
|
||||||
spdlog::info("Do we ignore note? {}", ignore_note);
|
spdlog::info("Do we ignore note? {}", ignore_note);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// need to find it again, due to modifying the parts
|
||||||
|
root_part = find_root_btrfs_part(partitions);
|
||||||
|
|
||||||
|
spdlog::debug("root partition: fs='{}';mountpoint='{}';uuid_str='{}';device='{}';mount_opts='{}';subvolume='{}'",
|
||||||
|
root_part->fstype, root_part->mountpoint, root_part->uuid_str, root_part->device, root_part->mount_opts, *root_part->subvolume);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mount_existing_subvols(const disk_part& disk) noexcept {
|
void mount_existing_subvols(std::vector<gucc::fs::Partition>& partitions) noexcept {
|
||||||
|
auto root_part = find_root_btrfs_part(partitions);
|
||||||
|
if (root_part == std::ranges::end(partitions)) {
|
||||||
|
spdlog::error("mount_existing_subvols: unable to find btrfs root part");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Set mount options
|
// Set mount options
|
||||||
const auto& format_name = gucc::utils::exec(fmt::format(FMT_COMPILE("echo {} | rev | cut -d/ -f1 | rev"), disk.part));
|
const auto& part_dev_name = gucc::utils::exec(fmt::format(FMT_COMPILE("echo {} | rev | cut -d/ -f1 | rev"), root_part->device));
|
||||||
const auto& format_device = gucc::utils::exec(fmt::format(FMT_COMPILE("lsblk -i | tac | sed -r 's/^[^[:alnum:]]+//' | sed -n -e '/{}/,/disk/p' | {}"), format_name, "awk '/disk/ {print $1}'"sv));
|
const auto& device_name = gucc::utils::exec(fmt::format(FMT_COMPILE("lsblk -i | tac | sed -r 's/^[^[:alnum:]]+//' | sed -n -e '/{}/,/disk/p' | {}"), part_dev_name, "awk '/disk/ {print $1}'"sv));
|
||||||
const auto& rotational_queue = (gucc::utils::exec(fmt::format(FMT_COMPILE("cat /sys/block/{}/queue/rotational"), format_device)) == "1"sv);
|
const auto& rotational_queue = (gucc::utils::exec(fmt::format(FMT_COMPILE("cat /sys/block/{}/queue/rotational"), device_name)) == "1"sv);
|
||||||
|
|
||||||
std::string fs_opts{};
|
std::string fs_opts{};
|
||||||
if (rotational_queue) {
|
if (rotational_queue) {
|
||||||
@ -144,9 +177,19 @@ void mount_existing_subvols(const disk_part& disk) noexcept {
|
|||||||
// TODO(vnepogodin): add confirmation for selected mountpoint for particular subvolume
|
// TODO(vnepogodin): add confirmation for selected mountpoint for particular subvolume
|
||||||
|
|
||||||
// Mount subvolumes
|
// Mount subvolumes
|
||||||
if (!gucc::fs::btrfs_mount_subvols(subvolumes, disk.root, root_mountpoint, fs_opts)) {
|
if (!gucc::fs::btrfs_mount_subvols(subvolumes, root_part->device, root_mountpoint, fs_opts)) {
|
||||||
spdlog::error("Failed to mount btrfs subvolumes");
|
spdlog::error("Failed to mount btrfs subvolumes");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!gucc::fs::btrfs_append_subvolumes(partitions, subvolumes)) {
|
||||||
|
spdlog::error("Failed to append btrfs subvolumes into partition scheme");
|
||||||
|
}
|
||||||
|
|
||||||
|
// need to find it again, due to modifying the parts
|
||||||
|
root_part = find_root_btrfs_part(partitions);
|
||||||
|
|
||||||
|
spdlog::debug("root partition: fs='{}';mountpoint='{}';uuid_str='{}';device='{}';mount_opts='{}';subvolume='{}'",
|
||||||
|
root_part->fstype, root_part->mountpoint, root_part->uuid_str, root_part->device, root_part->mount_opts, *root_part->subvolume);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
12
src/disk.hpp
12
src/disk.hpp
@ -1,20 +1,16 @@
|
|||||||
#ifndef DISK_HPP
|
#ifndef DISK_HPP
|
||||||
#define DISK_HPP
|
#define DISK_HPP
|
||||||
|
|
||||||
|
#include "gucc/partition.hpp"
|
||||||
|
|
||||||
#include <string> // for string
|
#include <string> // for string
|
||||||
#include <string_view> // for string_view
|
#include <string_view> // for string_view
|
||||||
#include <vector> // for vector
|
#include <vector> // for vector
|
||||||
|
|
||||||
namespace utils {
|
namespace utils {
|
||||||
|
|
||||||
struct disk_part {
|
void btrfs_create_subvols(std::vector<gucc::fs::Partition>& partitions, const std::string_view& mode, bool ignore_note = false) noexcept;
|
||||||
const std::string_view root{};
|
void mount_existing_subvols(std::vector<gucc::fs::Partition>& partitions) noexcept;
|
||||||
const std::string_view part{};
|
|
||||||
const std::string_view mount_opts{};
|
|
||||||
};
|
|
||||||
|
|
||||||
void btrfs_create_subvols(const disk_part& disk, const std::string_view& mode, bool ignore_note = false) noexcept;
|
|
||||||
void mount_existing_subvols(const disk_part& disk) noexcept;
|
|
||||||
auto lvm_show_vg() noexcept -> std::vector<std::string>;
|
auto lvm_show_vg() noexcept -> std::vector<std::string>;
|
||||||
|
|
||||||
// ZFS filesystem
|
// ZFS filesystem
|
||||||
|
@ -156,6 +156,8 @@ auto make_partitions_prepared(std::string_view bootloader, std::string_view root
|
|||||||
if (ready_parts.empty()) { spdlog::error("Invalid use! ready parts empty."); return false; }
|
if (ready_parts.empty()) { spdlog::error("Invalid use! ready parts empty."); return false; }
|
||||||
/* clang-format on */
|
/* clang-format on */
|
||||||
|
|
||||||
|
std::vector<gucc::fs::Partition> partitions{};
|
||||||
|
|
||||||
std::string root_part{};
|
std::string root_part{};
|
||||||
for (auto&& ready_part : ready_parts) {
|
for (auto&& ready_part : ready_parts) {
|
||||||
auto part_info = gucc::utils::make_multiline(ready_part, false, '\t');
|
auto part_info = gucc::utils::make_multiline(ready_part, false, '\t');
|
||||||
@ -193,11 +195,14 @@ auto make_partitions_prepared(std::string_view bootloader, std::string_view root
|
|||||||
const auto& subvolumes = fmt::format(FMT_COMPILE("btrfs subvolume list \"{}\" 2>/dev/null"), part_mountpoint);
|
const auto& subvolumes = fmt::format(FMT_COMPILE("btrfs subvolume list \"{}\" 2>/dev/null"), part_mountpoint);
|
||||||
const auto& subvolumes_count = gucc::utils::exec(fmt::format(FMT_COMPILE("{} | wc -l"), subvolumes));
|
const auto& subvolumes_count = gucc::utils::exec(fmt::format(FMT_COMPILE("{} | wc -l"), subvolumes));
|
||||||
const auto& lines_count = utils::to_int(subvolumes_count);
|
const auto& lines_count = utils::to_int(subvolumes_count);
|
||||||
|
|
||||||
|
auto part_struct = gucc::fs::Partition{.fstype = part_fs, .mountpoint = part_mountpoint, .device = root_part, .mount_opts = std::string{mount_opts_info}};
|
||||||
|
partitions.emplace_back(std::move(part_struct));
|
||||||
if (lines_count > 1) {
|
if (lines_count > 1) {
|
||||||
// Pre-existing subvolumes and user wants to mount them
|
// Pre-existing subvolumes and user wants to mount them
|
||||||
utils::mount_existing_subvols({root_part, root_part});
|
utils::mount_existing_subvols(partitions);
|
||||||
} else {
|
} else {
|
||||||
utils::btrfs_create_subvols({.root = part_name, .mount_opts = mount_opts_info}, "automatic"sv, true);
|
utils::btrfs_create_subvols(partitions, "automatic"sv, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
24
src/tui.cpp
24
src/tui.cpp
@ -14,6 +14,7 @@
|
|||||||
#include "gucc/io_utils.hpp"
|
#include "gucc/io_utils.hpp"
|
||||||
#include "gucc/locale.hpp"
|
#include "gucc/locale.hpp"
|
||||||
#include "gucc/mount_partitions.hpp"
|
#include "gucc/mount_partitions.hpp"
|
||||||
|
#include "gucc/partition.hpp"
|
||||||
#include "gucc/string_utils.hpp"
|
#include "gucc/string_utils.hpp"
|
||||||
#include "gucc/zfs.hpp"
|
#include "gucc/zfs.hpp"
|
||||||
|
|
||||||
@ -42,6 +43,7 @@ namespace fs = std::filesystem;
|
|||||||
#include "follow_process_log.hpp"
|
#include "follow_process_log.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
using namespace std::string_literals;
|
||||||
using namespace std::string_view_literals;
|
using namespace std::string_view_literals;
|
||||||
|
|
||||||
namespace tui {
|
namespace tui {
|
||||||
@ -108,7 +110,12 @@ void btrfs_subvolumes() noexcept {
|
|||||||
|
|
||||||
const auto& mount_opts_info = std::get<std::string>(config_data["MOUNT_OPTS"]);
|
const auto& mount_opts_info = std::get<std::string>(config_data["MOUNT_OPTS"]);
|
||||||
const auto& root_part = std::get<std::string>(config_data["ROOT_PART"]);
|
const auto& root_part = std::get<std::string>(config_data["ROOT_PART"]);
|
||||||
utils::btrfs_create_subvols({.root = root_part, .mount_opts = mount_opts_info}, btrfsvols_mode);
|
|
||||||
|
std::vector<gucc::fs::Partition> partitions{
|
||||||
|
gucc::fs::Partition{.fstype = "btrfs"s, .mountpoint = "/"s, .device = root_part, .mount_opts = mount_opts_info},
|
||||||
|
};
|
||||||
|
|
||||||
|
utils::btrfs_create_subvols(partitions, btrfsvols_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function will not allow incorrect UUID type for installed system.
|
// Function will not allow incorrect UUID type for installed system.
|
||||||
@ -1710,6 +1717,8 @@ void mount_partitions() noexcept {
|
|||||||
utils::delete_partition_in_list(part);
|
utils::delete_partition_in_list(part);
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
std::vector<gucc::fs::Partition> partitions{};
|
||||||
|
|
||||||
// check to see if we already have a zfs root mounted
|
// check to see if we already have a zfs root mounted
|
||||||
const auto& mountpoint_info = std::get<std::string>(config_data["MOUNTPOINT"]);
|
const auto& mountpoint_info = std::get<std::string>(config_data["MOUNTPOINT"]);
|
||||||
if (gucc::fs::utils::get_mountpoint_fs(mountpoint_info) == "zfs"sv) {
|
if (gucc::fs::utils::get_mountpoint_fs(mountpoint_info) == "zfs"sv) {
|
||||||
@ -1752,11 +1761,20 @@ void mount_partitions() noexcept {
|
|||||||
|
|
||||||
// utils::delete_partition_in_list(std::get<std::string>(config_data["ROOT_PART"]));
|
// utils::delete_partition_in_list(std::get<std::string>(config_data["ROOT_PART"]));
|
||||||
|
|
||||||
|
// TODO(vnepogodin): parse luks information
|
||||||
|
const auto& mount_opts_info = std::get<std::string>(config_data["MOUNT_OPTS"]);
|
||||||
|
|
||||||
|
const auto& part_fs = gucc::fs::utils::get_mountpoint_fs(mountpoint_info);
|
||||||
|
auto root_part_struct = gucc::fs::Partition{.fstype = part_fs, .mountpoint = "/"s, .device = root_part, .mount_opts = mount_opts_info};
|
||||||
|
|
||||||
|
// insert root partition
|
||||||
|
partitions.emplace_back(std::move(root_part_struct));
|
||||||
|
|
||||||
// Extra check if root is on LUKS or lvm
|
// Extra check if root is on LUKS or lvm
|
||||||
// get_cryptroot
|
// get_cryptroot
|
||||||
// echo "$LUKS_DEV" > /tmp/.luks_dev
|
// echo "$LUKS_DEV" > /tmp/.luks_dev
|
||||||
// If the root partition is btrfs, offer to create subvolumes
|
// If the root partition is btrfs, offer to create subvolumes
|
||||||
if (gucc::fs::utils::get_mountpoint_fs(mountpoint_info) == "btrfs"sv) {
|
if (part_fs == "btrfs"sv) {
|
||||||
// Check if there are subvolumes already on the btrfs partition
|
// Check if there are subvolumes already on the btrfs partition
|
||||||
const auto& subvolumes = fmt::format(FMT_COMPILE("btrfs subvolume list '{}' 2>/dev/null"), mountpoint_info);
|
const auto& subvolumes = fmt::format(FMT_COMPILE("btrfs subvolume list '{}' 2>/dev/null"), mountpoint_info);
|
||||||
const auto& subvolumes_count = gucc::utils::exec(fmt::format(FMT_COMPILE("{} | wc -l"), subvolumes));
|
const auto& subvolumes_count = gucc::utils::exec(fmt::format(FMT_COMPILE("{} | wc -l"), subvolumes));
|
||||||
@ -1766,7 +1784,7 @@ void mount_partitions() noexcept {
|
|||||||
const auto& existing_subvolumes = detail::yesno_widget(fmt::format(FMT_COMPILE("\nFound subvolumes {}\n \nWould you like to mount them?\n "), subvolumes_formated), size(HEIGHT, LESS_THAN, 15) | size(WIDTH, LESS_THAN, 75));
|
const auto& existing_subvolumes = detail::yesno_widget(fmt::format(FMT_COMPILE("\nFound subvolumes {}\n \nWould you like to mount them?\n "), subvolumes_formated), size(HEIGHT, LESS_THAN, 15) | size(WIDTH, LESS_THAN, 75));
|
||||||
// Pre-existing subvolumes and user wants to mount them
|
// Pre-existing subvolumes and user wants to mount them
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
if (existing_subvolumes) { utils::mount_existing_subvols({root_part, part}); }
|
if (existing_subvolumes) { utils::mount_existing_subvols(partitions); }
|
||||||
/* clang-format on */
|
/* clang-format on */
|
||||||
} else {
|
} else {
|
||||||
// No subvolumes present. Make some new ones
|
// No subvolumes present. Make some new ones
|
||||||
|
Loading…
Reference in New Issue
Block a user