mirror of
https://github.com/CachyOS/New-Cli-Installer.git
synced 2025-01-23 14:32:22 +08:00
🧹 move btrfs subvolumes creation into gucc
This commit is contained in:
parent
d4f67e11dd
commit
9e011fc276
@ -18,6 +18,7 @@ add_library(${PROJECT_NAME} SHARED
|
||||
src/initcpio.cpp include/gucc/initcpio.hpp
|
||||
src/luks.cpp include/gucc/luks.hpp
|
||||
src/zfs.cpp include/gucc/zfs.hpp
|
||||
src/btrfs.cpp include/gucc/btrfs.hpp
|
||||
#src/chwd_profiles.cpp src/chwd_profiles.hpp
|
||||
#src/disk.cpp src/disk.hpp
|
||||
)
|
||||
|
22
gucc/include/gucc/btrfs.hpp
Normal file
22
gucc/include/gucc/btrfs.hpp
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef BTRFS_HPP
|
||||
#define BTRFS_HPP
|
||||
|
||||
#include <string_view> // for string_view
|
||||
#include <vector> // for vector
|
||||
|
||||
namespace gucc::fs {
|
||||
|
||||
struct BtrfsSubvolume final {
|
||||
std::string_view subvolume;
|
||||
std::string_view mountpoint;
|
||||
};
|
||||
|
||||
// Creates btrfs subvolume
|
||||
auto btrfs_create_subvol(std::string_view subvolume, std::string_view root_mountpoint) noexcept -> bool;
|
||||
|
||||
// Creates btrfs subvolumes and mounts them
|
||||
auto btrfs_create_subvols(const std::vector<BtrfsSubvolume>& subvols, std::string_view device, std::string_view root_mountpoint, std::string_view mount_opts) noexcept -> bool;
|
||||
|
||||
} // namespace gucc::fs
|
||||
|
||||
#endif // BTRFS_HPP
|
@ -8,6 +8,7 @@ gucc_lib = library('gucc',
|
||||
'src/initcpio.cpp',
|
||||
'src/luks.cpp',
|
||||
'src/zfs.cpp',
|
||||
'src/btrfs.cpp',
|
||||
],
|
||||
include_directories : [include_directories('include')],
|
||||
dependencies: deps
|
||||
|
79
gucc/src/btrfs.cpp
Normal file
79
gucc/src/btrfs.cpp
Normal file
@ -0,0 +1,79 @@
|
||||
#include "gucc/btrfs.hpp"
|
||||
#include "gucc/io_utils.hpp"
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
#include <fmt/compile.h>
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
namespace {
|
||||
|
||||
// same behaviour as os.path.dirname from python
|
||||
constexpr auto get_dirname(std::string_view full_path) noexcept -> std::string_view {
|
||||
if (full_path == "/") {
|
||||
return full_path;
|
||||
}
|
||||
auto pos = full_path.find_last_of('/');
|
||||
if (pos == std::string_view::npos) {
|
||||
return {};
|
||||
}
|
||||
return full_path.substr(0, pos);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace gucc::fs {
|
||||
|
||||
auto btrfs_create_subvol(std::string_view subvolume, std::string_view root_mountpoint) noexcept -> bool {
|
||||
const auto& subvol_dirs_path = fmt::format(FMT_COMPILE("{}{}"), root_mountpoint, get_dirname(subvolume));
|
||||
std::error_code err{};
|
||||
::fs::create_directories(subvol_dirs_path, err);
|
||||
if (err) {
|
||||
spdlog::error("Failed to create directories for btrfs subvolume {}: {}", subvol_dirs_path, err.message());
|
||||
return false;
|
||||
}
|
||||
auto cmd = fmt::format(FMT_COMPILE("btrfs subvolume create {}{} 2>>/tmp/cachyos-install.log"), root_mountpoint, subvolume);
|
||||
return utils::exec(cmd, true) == "0";
|
||||
}
|
||||
|
||||
auto btrfs_create_subvols(const std::vector<BtrfsSubvolume>& subvols, std::string_view device, std::string_view root_mountpoint, std::string_view mount_opts) noexcept -> bool {
|
||||
// Create subvolumes
|
||||
for (const auto& subvol : subvols) {
|
||||
if (subvol.subvolume.empty()) {
|
||||
continue;
|
||||
}
|
||||
if (!fs::btrfs_create_subvol(subvol.subvolume, root_mountpoint)) {
|
||||
spdlog::error("Failed to create btrfs subvolume {} on root mountpoint {}", subvol.subvolume, root_mountpoint);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// TODO(vnepogodin): handle exit code
|
||||
utils::exec(fmt::format(FMT_COMPILE("umount -v {} &>>/tmp/cachyos-install.log"), root_mountpoint));
|
||||
|
||||
// Mount subvolumes
|
||||
for (const auto& subvol : subvols) {
|
||||
auto mount_option = fmt::format(FMT_COMPILE("subvol={},{}"), subvol.subvolume, mount_opts);
|
||||
if (subvol.subvolume.empty()) {
|
||||
mount_option = mount_opts;
|
||||
}
|
||||
|
||||
const auto& subvolume_mountpoint = fmt::format(FMT_COMPILE("{}{}"), root_mountpoint, subvol.subvolume);
|
||||
|
||||
// TODO(vnepogodin): refactor create dir and mount into own function
|
||||
std::error_code err{};
|
||||
::fs::create_directories(subvolume_mountpoint, err);
|
||||
if (err) {
|
||||
spdlog::error("Failed to create directories for btrfs subvols mountpoint {}: {}", subvolume_mountpoint, err.message());
|
||||
return false;
|
||||
}
|
||||
// TODO(vnepogodin): handle exit code
|
||||
utils::exec(fmt::format(FMT_COMPILE("mount -o {} \"{}\" {}"), mount_option, device, subvolume_mountpoint));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace gucc::fs
|
36
src/disk.cpp
36
src/disk.cpp
@ -4,6 +4,7 @@
|
||||
#include "widgets.hpp"
|
||||
|
||||
// import gucc
|
||||
#include "gucc/btrfs.hpp"
|
||||
#include "gucc/io_utils.hpp"
|
||||
#include "gucc/string_utils.hpp"
|
||||
#include "gucc/zfs.hpp"
|
||||
@ -29,26 +30,28 @@ void btrfs_create_subvols([[maybe_unused]] const disk_part& disk, const std::str
|
||||
/* clang-format on */
|
||||
|
||||
#ifdef NDEVENV
|
||||
const auto root_mountpoint = "/mnt"sv;
|
||||
|
||||
// save mount options and name of the root partition
|
||||
gucc::utils::exec(R"(mount | grep 'on /mnt ' | grep -Po '(?<=\().*(?=\))' > /tmp/.root_mount_options)"sv);
|
||||
// gucc::utils::exec("lsblk -lno MOUNTPOINT,NAME | awk '/^\\/mnt / {print $2}' > /tmp/.root_partition"sv);
|
||||
|
||||
if (mode == "manual"sv) {
|
||||
// Create subvolumes manually
|
||||
std::string subvols{"@ @home @cache"};
|
||||
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"sv;
|
||||
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");
|
||||
fs::current_path(root_mountpoint);
|
||||
auto subvol_list = gucc::utils::make_multiline(subvols, false, ' ');
|
||||
for (const auto& subvol : subvol_list) {
|
||||
gucc::utils::exec(fmt::format(FMT_COMPILE("btrfs subvolume create {} 2>>/tmp/cachyos-install.log"), subvol), true);
|
||||
}
|
||||
fs::current_path(saved_path);
|
||||
// Mount subvolumes
|
||||
umount("/mnt");
|
||||
umount(root_mountpoint.data());
|
||||
// Mount the first subvolume as /
|
||||
gucc::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
|
||||
@ -62,14 +65,14 @@ void btrfs_create_subvols([[maybe_unused]] const disk_part& disk, const std::str
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& mountp_formatted = fmt::format(FMT_COMPILE("/mnt{}"), mountp);
|
||||
const auto& mountp_formatted = fmt::format(FMT_COMPILE("{}{}"), root_mountpoint, mountp);
|
||||
fs::create_directories(mountp_formatted);
|
||||
gucc::utils::exec(fmt::format(FMT_COMPILE("mount -o {},subvol=\"{}\" \"{}\" \"{}\""), disk.mount_opts, subvol, disk.root, mountp_formatted));
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!ignore_note) {
|
||||
static constexpr auto content = "\nThis creates subvolumes:\n@ for /,\n@home for /home,\n@cache for /var/cache.\n"sv;
|
||||
static constexpr auto content = "\nThis creates subvolumes:\n/@ for /,\n/@home for /home,\n/@cache for /var/cache.\n"sv;
|
||||
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; }
|
||||
@ -77,20 +80,15 @@ void btrfs_create_subvols([[maybe_unused]] const disk_part& disk, const std::str
|
||||
}
|
||||
|
||||
// Create subvolumes automatically
|
||||
const auto& saved_path = fs::current_path();
|
||||
fs::current_path("/mnt");
|
||||
gucc::utils::exec("btrfs subvolume create @ 2>>/tmp/cachyos-install.log"sv, true);
|
||||
gucc::utils::exec("btrfs subvolume create @home 2>>/tmp/cachyos-install.log"sv, true);
|
||||
gucc::utils::exec("btrfs subvolume create @cache 2>>/tmp/cachyos-install.log"sv, true);
|
||||
// gucc::utils::exec("btrfs subvolume create @snapshots 2>>/tmp/cachyos-install.log"sv, true);
|
||||
fs::current_path(saved_path);
|
||||
// Mount subvolumes
|
||||
umount("/mnt");
|
||||
gucc::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");
|
||||
gucc::utils::exec(fmt::format(FMT_COMPILE("mount -o {},subvol=@home \"{}\" /mnt/home"), disk.mount_opts, disk.root));
|
||||
gucc::utils::exec(fmt::format(FMT_COMPILE("mount -o {},subvol=@cache \"{}\" /mnt/var/cache"), disk.mount_opts, disk.root));
|
||||
const std::vector<gucc::fs::BtrfsSubvolume> subvolumes{
|
||||
gucc::fs::BtrfsSubvolume{.subvolume = "/@"sv, .mountpoint = "/"sv},
|
||||
gucc::fs::BtrfsSubvolume{.subvolume = "/@home"sv, .mountpoint = "/home"sv},
|
||||
gucc::fs::BtrfsSubvolume{.subvolume = "/@cache"sv, .mountpoint = "/var/cache"sv},
|
||||
// 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");
|
||||
}
|
||||
#else
|
||||
spdlog::info("Do we ignore note? {}", ignore_note);
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user