mirror of
https://github.com/CachyOS/New-Cli-Installer.git
synced 2025-01-23 14:32:22 +08:00
👷 add btrfs subvolumes
This commit is contained in:
parent
9c6ca2ddf9
commit
5dc58c5745
@ -22,18 +22,12 @@ include(StaticAnalyzers)
|
||||
include(Sanitizers)
|
||||
include(CPM)
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(
|
||||
LIBNM
|
||||
REQUIRED
|
||||
IMPORTED_TARGET
|
||||
libnm>=1.10.6)
|
||||
|
||||
pkg_check_modules(
|
||||
GLIBMM
|
||||
REQUIRED
|
||||
IMPORTED_TARGET
|
||||
glibmm-2.4>=2.56.0)
|
||||
#find_package(PkgConfig REQUIRED)
|
||||
#pkg_check_modules(
|
||||
# GLIBMM
|
||||
# REQUIRED
|
||||
# IMPORTED_TARGET
|
||||
# glibmm-2.4>=2.56.0)
|
||||
|
||||
CPMAddPackage(
|
||||
NAME ftxui
|
||||
@ -80,7 +74,7 @@ endif()
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -flto")
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fwhole-program")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fwhole-program -fuse-linker-plugin")
|
||||
endif()
|
||||
|
||||
# Link this 'library' to set the c++ standard / compile-time options requested
|
||||
@ -138,9 +132,9 @@ enable_sanitizers(project_options)
|
||||
|
||||
include_directories(${CMAKE_SOURCE_DIR}/src)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE project_warnings project_options spdlog::spdlog fmt::fmt ftxui::screen ftxui::dom ftxui::component simdjson::simdjson cpr::cpr PkgConfig::GLIBMM)
|
||||
target_link_libraries(test-exec-interactive PRIVATE project_warnings project_options spdlog::spdlog fmt::fmt ftxui::component simdjson::simdjson cpr::cpr PkgConfig::GLIBMM)
|
||||
target_link_libraries(test-process-tailing PRIVATE project_warnings project_options spdlog::spdlog fmt::fmt ftxui::component simdjson::simdjson cpr::cpr PkgConfig::GLIBMM)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE project_warnings project_options spdlog::spdlog fmt::fmt ftxui::screen ftxui::dom ftxui::component simdjson::simdjson cpr::cpr)
|
||||
target_link_libraries(test-exec-interactive PRIVATE project_warnings project_options spdlog::spdlog fmt::fmt ftxui::component simdjson::simdjson cpr::cpr)
|
||||
target_link_libraries(test-process-tailing PRIVATE project_warnings project_options spdlog::spdlog fmt::fmt ftxui::component simdjson::simdjson cpr::cpr)
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE range-v3::range-v3)
|
||||
|
@ -27,12 +27,16 @@ set(SIMDJSON_DISABLE_DEPRECATED_API ON CACHE INTERNAL "" FORCE)
|
||||
# Generate compile_commands.json to make it easier to work with clang based tools
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -flto")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -flto")
|
||||
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -fwhole-program -fuse-linker-plugin")
|
||||
endif()
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fwhole-program -fuse-linker-plugin")
|
||||
endif()
|
||||
#set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++") #-static")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++")# -static")
|
||||
|
||||
option(ENABLE_IPO "Enable Interprocedural Optimization, aka Link Time Optimization (LTO)" OFF)
|
||||
|
||||
|
@ -38,8 +38,7 @@ fmt = dependency('fmt', version : ['>=8.0.0'], fallback : ['fmt', 'fmt_dep'])
|
||||
ftxui = dependency('ftxui', modules : ['ftxui::screen', 'ftxui::dom', 'ftxui::component'], fallback : ['ftxui', 'ftxui_dep'])
|
||||
simdjson = dependency('simdjson', version : ['>=1.0.2'], fallback : ['simdjson', 'simdjson_dep'])
|
||||
cpr = dependency('cpr', version : ['>=1.7.0'], fallback : ['cpr', 'cpr_dep'])
|
||||
libnm = dependency('libnm', version : ['>=1.10.6'])
|
||||
glibmm = dependency('glibmm-2.4', version : ['>=2.56.0'])
|
||||
#glibmm = dependency('glibmm-2.4', version : ['>=2.56.0'])
|
||||
|
||||
src_files = files(
|
||||
'src/view.hpp',
|
||||
@ -113,13 +112,13 @@ if not is_debug_build
|
||||
endif
|
||||
|
||||
possible_cc_flags += ['-fdata-sections', '-ffunction-sections']
|
||||
possible_link_flags = ['-Wl,--gc-sections']
|
||||
possible_link_flags = ['-Wl,--gc-sections', '-static-libgcc', '-static-libstdc++']
|
||||
add_project_link_arguments(cc.get_supported_link_arguments(possible_link_flags), language : 'cpp')
|
||||
endif
|
||||
|
||||
add_project_arguments(cc.get_supported_arguments(possible_cc_flags), language : 'cpp')
|
||||
|
||||
deps = [fmt, spdlog, ftxui, simdjson, cpr, glibmm]
|
||||
deps = [fmt, spdlog, ftxui, simdjson, cpr]
|
||||
if cc.get_id() == 'clang'
|
||||
ranges = dependency('range-v3', version : ['>=0.11.0'])
|
||||
deps += [ranges]
|
||||
|
@ -75,9 +75,9 @@ bool luks_open() noexcept {
|
||||
utils::find_partitions();
|
||||
|
||||
// Filter out partitions that don't contain crypt device
|
||||
const auto& ignore_part = utils::list_non_crypt();
|
||||
/*const auto& ignore_part = utils::list_non_crypt();
|
||||
|
||||
/* const auto& parts = utils::make_multiline(ignore_part);
|
||||
const auto& parts = utils::make_multiline(ignore_part);
|
||||
for (const auto& part : parts) {
|
||||
utils::delete_partition_in_list(part);
|
||||
}*/
|
||||
|
71
src/disk.cpp
71
src/disk.cpp
@ -16,6 +16,75 @@ namespace fs = std::filesystem;
|
||||
|
||||
namespace utils {
|
||||
|
||||
void btrfs_create_subvols([[maybe_unused]] const disk_part& disk, const std::string_view& mode) noexcept {
|
||||
/* clang-format off */
|
||||
if (mode.empty()) { return; }
|
||||
/* clang-format on */
|
||||
|
||||
#ifdef NDEVENV
|
||||
// save mount options and name of the root partition
|
||||
utils::exec("mount | grep \"on /mnt \" | grep -Po '(?<=\\().*(?=\\))' > /tmp/.root_mount_options");
|
||||
// utils::exec("lsblk -lno MOUNTPOINT,NAME | awk '/^\\/mnt / {print $2}' > /tmp/.root_partition");
|
||||
|
||||
if (mode == "manual") {
|
||||
// Create subvolumes manually
|
||||
std::string subvols{"@ @home @cache"};
|
||||
static constexpr auto subvols_body = "\nInput names of the subvolumes separated by spaces.\nThe first one will be used for mounting /.\n";
|
||||
if (!tui::detail::inputbox_widget(subvols, subvols_body, size(ftxui::HEIGHT, ftxui::GREATER_THAN, 4))) {
|
||||
return;
|
||||
}
|
||||
const auto& saved_path = fs::current_path();
|
||||
fs::current_path("/mnt");
|
||||
auto subvol_list = utils::make_multiline(subvols, false, " ");
|
||||
for (const auto& subvol : subvol_list) {
|
||||
utils::exec(fmt::format(FMT_COMPILE("btrfs subvolume create {}"), subvol), true);
|
||||
}
|
||||
fs::current_path(saved_path);
|
||||
// Mount subvolumes
|
||||
umount("/mnt");
|
||||
// Mount the first subvolume as /
|
||||
utils::exec(fmt::format(FMT_COMPILE("mount -o {},subvol=\"{}\" \"{}\" /mnt"), disk.mount_opts, subvol_list[0], disk.root));
|
||||
// Remove the first subvolume from the subvolume list
|
||||
subvol_list.erase(subvol_list.begin());
|
||||
|
||||
// Loop to mount all created subvolumes
|
||||
for (const auto& subvol : subvol_list) {
|
||||
std::string mountp{"/home"};
|
||||
const auto& mountp_body = fmt::format(FMT_COMPILE("\nInput mountpoint of the subvolume {}\nas it would appear in installed system\n(without prepending /mnt).\n"), subvol);
|
||||
if (!tui::detail::inputbox_widget(mountp, mountp_body, size(ftxui::HEIGHT, ftxui::GREATER_THAN, 4))) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& mountp_formatted = fmt::format(FMT_COMPILE("/mnt{}"), mountp);
|
||||
fs::create_directories(mountp_formatted);
|
||||
utils::exec(fmt::format(FMT_COMPILE("mount -o {},subvol=\"{}\" \"{}\" \"{}\""), disk.mount_opts, subvol, disk.root, mountp_formatted));
|
||||
}
|
||||
return;
|
||||
}
|
||||
static constexpr auto content = "\nThis creates subvolumes:\n@ for /,\n@home for /home,\n@cache for /var/cache.\n";
|
||||
const auto& do_create = tui::detail::yesno_widget(content, size(ftxui::HEIGHT, ftxui::LESS_THAN, 15) | size(ftxui::WIDTH, ftxui::LESS_THAN, 75));
|
||||
/* clang-format off */
|
||||
if (!do_create) { return; }
|
||||
/* clang-format on */
|
||||
|
||||
// Create subvolumes automatically
|
||||
const auto& saved_path = fs::current_path();
|
||||
fs::current_path("/mnt");
|
||||
utils::exec("btrfs subvolume create @", true);
|
||||
utils::exec("btrfs subvolume create @home", true);
|
||||
utils::exec("btrfs subvolume create @cache", true);
|
||||
// utils::exec("btrfs subvolume create @snapshots", true);
|
||||
fs::current_path(saved_path);
|
||||
// Mount subvolumes
|
||||
umount("/mnt");
|
||||
utils::exec(fmt::format(FMT_COMPILE("mount -o {},subvol=@ \"{}\" /mnt"), disk.mount_opts, disk.root));
|
||||
fs::create_directories("/mnt/home");
|
||||
fs::create_directories("/mnt/var/cache");
|
||||
utils::exec(fmt::format(FMT_COMPILE("mount -o {},subvol=@home \"{}\" /mnt/home"), disk.mount_opts, disk.root));
|
||||
utils::exec(fmt::format(FMT_COMPILE("mount -o {},subvol=@cache \"{}\" /mnt/var/cache"), disk.mount_opts, disk.root));
|
||||
#endif
|
||||
}
|
||||
|
||||
void mount_existing_subvols(const disk_part& disk) noexcept {
|
||||
// Set mount options
|
||||
const auto& format_name = utils::exec(fmt::format(FMT_COMPILE("echo {} | rev | cut -d/ -f1 | rev"), disk.part));
|
||||
@ -36,7 +105,7 @@ void mount_existing_subvols(const disk_part& disk) noexcept {
|
||||
// Ask for mountpoint
|
||||
const auto& content = fmt::format(FMT_COMPILE("\nInput mountpoint of the subvolume {}\nas it would appear in installed system\n(without prepending /mnt).\n"), subvol);
|
||||
std::string mountpoint{"/"};
|
||||
if (!tui::detail::inputbox_widget(mountpoint, content, size(ftxui::HEIGHT, ftxui::LESS_THAN, 9) | size(ftxui::WIDTH, ftxui::LESS_THAN, 30))) {
|
||||
if (!tui::tui::detail::inputbox_widget(mountpoint, content, size(ftxui::HEIGHT, ftxui::LESS_THAN, 9) | size(ftxui::WIDTH, ftxui::LESS_THAN, 30))) {
|
||||
return;
|
||||
}
|
||||
const auto& mount_dir{fmt::format(FMT_COMPILE("/mnt/{}"), mountpoint)};
|
||||
|
@ -6,11 +6,14 @@
|
||||
namespace utils {
|
||||
|
||||
struct disk_part {
|
||||
const std::string_view root;
|
||||
const std::string_view part;
|
||||
const std::string_view root{};
|
||||
const std::string_view part{};
|
||||
const std::string_view mount_opts{};
|
||||
};
|
||||
|
||||
void mount_existing_subvols(const disk_part& partition) noexcept;
|
||||
void btrfs_create_subvols(const disk_part& disk, const std::string_view& mode) noexcept;
|
||||
void mount_existing_subvols(const disk_part& disk) noexcept;
|
||||
|
||||
} // namespace utils
|
||||
|
||||
#endif // DISK_HPP
|
||||
|
38
src/tui.cpp
38
src/tui.cpp
@ -133,6 +133,33 @@ bool exit_done() noexcept {
|
||||
#endif
|
||||
}
|
||||
|
||||
void btrfs_subvolumes() noexcept {
|
||||
const std::vector<std::string> menu_entries = {
|
||||
"automatic",
|
||||
"manual",
|
||||
};
|
||||
auto screen = ScreenInteractive::Fullscreen();
|
||||
std::int32_t selected{};
|
||||
std::string btrfsvols_mode{};
|
||||
auto ok_callback = [&] {
|
||||
btrfsvols_mode = menu_entries[static_cast<std::size_t>(selected)];
|
||||
screen.ExitLoopClosure()();
|
||||
};
|
||||
static constexpr auto btrfsvols_body = "\nAutomatic mode\nis designed to allow integration\nwith snapper, non-recursive snapshots,\nseparating system and user data and\nrestoring snapshots without losing data.\n";
|
||||
/* clang-format off */
|
||||
detail::menu_widget(menu_entries, ok_callback, &selected, &screen, btrfsvols_body);
|
||||
|
||||
if (btrfsvols_mode.empty()) { return; }
|
||||
/* clang-format on */
|
||||
|
||||
auto* config_instance = Config::instance();
|
||||
auto& config_data = config_instance->data();
|
||||
|
||||
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"]);
|
||||
utils::btrfs_create_subvols({.root = root_part, .mount_opts = mount_opts_info}, btrfsvols_mode);
|
||||
}
|
||||
|
||||
// Function will not allow incorrect UUID type for installed system.
|
||||
void generate_fstab() noexcept {
|
||||
const std::vector<std::string> menu_entries = {
|
||||
@ -1809,16 +1836,17 @@ void mount_partitions() noexcept {
|
||||
const auto& subvolumes_formated = utils::exec(fmt::format(FMT_COMPILE("{} | cut -d\" \" -f9"), subvolumes));
|
||||
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
|
||||
if (existing_subvolumes) {
|
||||
utils::mount_existing_subvols({root_part, part});
|
||||
}
|
||||
/* clang-format off */
|
||||
if (existing_subvolumes) { utils::mount_existing_subvols({root_part, part}); }
|
||||
/* clang-format on */
|
||||
} else {
|
||||
// No subvolumes present. Make some new ones
|
||||
const auto& create_subvolumes = detail::yesno_widget("\nWould you like to create subvolumes in it? \n", size(HEIGHT, LESS_THAN, 15) | size(WIDTH, LESS_THAN, 75));
|
||||
/* clang-format on */
|
||||
if (create_subvolumes) {
|
||||
spdlog::debug("Implement me!");
|
||||
// utils::btrfs_subvolumes({root_part, part});
|
||||
tui::btrfs_subvolumes();
|
||||
}
|
||||
/* clang-format on */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ namespace utils {
|
||||
bool is_connected() noexcept {
|
||||
#ifdef NDEVENV
|
||||
/* clang-format off */
|
||||
auto r = cpr::Get(cpr::Url{"https://www.google.com"},
|
||||
auto r = cpr::Get(cpr::Url{"https://cachyos.org"},
|
||||
cpr::Timeout{1000});
|
||||
/* clang-format on */
|
||||
return cpr::status::is_success(static_cast<std::int32_t>(r.status_code)) || cpr::status::is_redirect(static_cast<std::int32_t>(r.status_code));
|
||||
|
Loading…
Reference in New Issue
Block a user