🧹 gucc: move IO into gucc

This commit is contained in:
Vladislav Nepogodin 2024-06-26 16:54:04 +04:00
parent 795b8b183e
commit 62312c02e7
No known key found for this signature in database
GPG Key ID: B62C3D10C54D5DA9
13 changed files with 433 additions and 387 deletions

View File

@ -10,6 +10,7 @@ project(gucc
add_library(${PROJECT_NAME} SHARED
#src/utils.cpp src/utils.hpp
src/io_utils.cpp include/gucc/io_utils.hpp
src/string_utils.cpp include/gucc/string_utils.hpp
src/file_utils.cpp include/gucc/file_utils.hpp
src/cpu.cpp include/gucc/cpu.hpp

View File

@ -0,0 +1,16 @@
#ifndef IO_UTILS_HPP
#define IO_UTILS_HPP
#include <string> // for string
#include <string_view> // for string_view
#include <vector> // for vector
namespace gucc::utils {
auto safe_getenv(const char* env_name) noexcept -> std::string_view;
void exec(const std::vector<std::string>& vec) noexcept;
auto exec(std::string_view command, bool interactive = false) noexcept -> std::string;
} // namespace gucc::utils
#endif // IO_UTILS_HPP

91
gucc/src/io_utils.cpp Normal file
View File

@ -0,0 +1,91 @@
#include "gucc/io_utils.hpp"
#include <sys/wait.h> // for waitpid
#include <unistd.h> // for execvp, fork
#include <cstdint> // for int32_t
#include <cstdio> // for feof, fgets, pclose, popen
#include <cstdlib> // for WIFEXITED, WIFSIGNALED
#include <algorithm> // for transform
#include <fstream> // for ofstream
#include <fmt/ranges.h>
#include <spdlog/spdlog.h>
using namespace std::string_view_literals;
namespace gucc::utils {
auto safe_getenv(const char* env_name) noexcept -> std::string_view {
const char* const raw_val = getenv(env_name);
return raw_val != nullptr ? std::string_view{raw_val} : std::string_view{};
}
void exec(const std::vector<std::string>& vec) noexcept {
const bool log_exec_cmds = utils::safe_getenv("LOG_EXEC_CMDS") == "1"sv;
const bool dirty_cmd_run = utils::safe_getenv("DIRTY_CMD_RUN") == "1"sv;
if (log_exec_cmds && spdlog::default_logger_raw() != nullptr) {
spdlog::debug("[exec] cmd := {}", vec);
}
if (dirty_cmd_run) {
return;
}
std::int32_t status{};
auto pid = fork();
if (pid == 0) {
std::vector<char*> args;
std::transform(vec.cbegin(), vec.cend(), std::back_inserter(args),
[=](const std::string& arg) -> char* { return const_cast<char*>(arg.data()); });
args.push_back(nullptr);
char** command = args.data();
execvp(command[0], command);
} else {
do {
waitpid(pid, &status, 0);
} while ((!WIFEXITED(status)) && (!WIFSIGNALED(status)));
}
}
// https://github.com/sheredom/subprocess.h
// https://gist.github.com/konstantint/d49ab683b978b3d74172
// https://github.com/arun11299/cpp-subprocess/blob/master/subprocess.hpp#L1218
// https://stackoverflow.com/questions/11342868/c-interface-for-interactive-bash
// https://github.com/hniksic/rust-subprocess
auto exec(std::string_view command, bool interactive) noexcept -> std::string {
const bool log_exec_cmds = utils::safe_getenv("LOG_EXEC_CMDS") == "1"sv;
if (log_exec_cmds && spdlog::default_logger_raw() != nullptr) {
spdlog::debug("[exec] cmd := '{}'", command);
}
if (interactive) {
const auto& ret_code = system(command.data());
return std::to_string(ret_code);
}
const std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(command.data(), "r"), pclose);
if (!pipe) {
spdlog::error("popen failed! '{}'", command);
return "-1";
}
std::string result{};
std::array<char, 128> buffer{};
while (!feof(pipe.get())) {
if (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
result += buffer.data();
}
}
if (result.ends_with('\n')) {
result.pop_back();
}
return result;
}
} // namespace gucc::utils

View File

@ -2,6 +2,7 @@
#include "utils.hpp"
// import gucc
#include "gucc/io_utils.hpp"
#include "gucc/string_utils.hpp"
#include <algorithm> // for any_of, sort, for_each
@ -64,7 +65,7 @@ auto get_available_profile_names(std::string_view profile_type) noexcept -> std:
if (!all_profile_names.has_value()) { return {}; }
/* clang-format on */
const auto& available_profile_names = gucc::utils::make_multiline(utils::exec("chwd --list -d | grep Name | awk '{print $4}'"));
const auto& available_profile_names = gucc::utils::make_multiline(gucc::utils::exec("chwd --list -d | grep Name | awk '{print $4}'"));
std::vector<std::string> filtered_profile_names{};
const auto& functor = [available_profile_names](auto&& profile_name) { return ranges::any_of(available_profile_names, [profile_name](auto&& available_profile) { return available_profile == profile_name; }); };

View File

@ -4,6 +4,7 @@
#include "widgets.hpp"
// import gucc
#include "gucc/io_utils.hpp"
#include "gucc/string_utils.hpp"
#include <fmt/compile.h>
@ -114,7 +115,7 @@ bool luks_open() noexcept {
detail::follow_process_log_widget({"/bin/sh", "-c", fmt::format(FMT_COMPILE("echo \"{}\" | cryptsetup open --type luks {} {}"), luks_password, partition, luks_root_name)});
#endif
const auto& devlist = utils::exec(fmt::format(FMT_COMPILE("lsblk -o NAME,TYPE,FSTYPE,SIZE,MOUNTPOINT {} | grep \"crypt\\|NAME\\|MODEL\\|TYPE\\|FSTYPE\\|SIZE\""), partition));
const auto& devlist = gucc::utils::exec(fmt::format(FMT_COMPILE("lsblk -o NAME,TYPE,FSTYPE,SIZE,MOUNTPOINT {} | grep \"crypt\\|NAME\\|MODEL\\|TYPE\\|FSTYPE\\|SIZE\""), partition));
detail::msgbox_widget(devlist);
return true;
@ -125,7 +126,7 @@ bool luks_setup() noexcept {
auto& config_data = config_instance->data();
#ifdef NDEVENV
utils::exec("modprobe -a dm-mod dm_crypt");
gucc::utils::exec("modprobe -a dm-mod dm_crypt");
#endif
config_data["INCLUDE_PART"] = "part\\|lvm";
utils::umount_partitions();
@ -187,7 +188,7 @@ void luks_express() noexcept {
void luks_show() noexcept {
static constexpr auto luks_success = "Done!";
const auto& lsblk = utils::exec(R"(lsblk -o NAME,TYPE,FSTYPE,SIZE | grep "part\|crypt\|NAME\|TYPE\|FSTYPE\|SIZE")");
const auto& lsblk = gucc::utils::exec(R"(lsblk -o NAME,TYPE,FSTYPE,SIZE | grep "part\|crypt\|NAME\|TYPE\|FSTYPE\|SIZE")");
const auto& content = fmt::format(FMT_COMPILE("\n{}\n \n{}"), luks_success, lsblk);
detail::msgbox_widget(content, size(HEIGHT, GREATER_THAN, 5));
}

View File

@ -4,6 +4,7 @@
#include "widgets.hpp"
// import gucc
#include "gucc/io_utils.hpp"
#include "gucc/string_utils.hpp"
#include <filesystem> // for exists, is_directory
@ -28,8 +29,8 @@ void btrfs_create_subvols([[maybe_unused]] const disk_part& disk, const std::str
#ifdef NDEVENV
// save mount options and name of the root partition
utils::exec("mount | grep \"on /mnt \" | grep -Po '(?<=\\().*(?=\\))' > /tmp/.root_mount_options"sv);
// utils::exec("lsblk -lno MOUNTPOINT,NAME | awk '/^\\/mnt / {print $2}' > /tmp/.root_partition"sv);
gucc::utils::exec("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
@ -42,13 +43,13 @@ void btrfs_create_subvols([[maybe_unused]] const disk_part& disk, const std::str
fs::current_path("/mnt");
auto subvol_list = gucc::utils::make_multiline(subvols, false, ' ');
for (const auto& subvol : subvol_list) {
utils::exec(fmt::format(FMT_COMPILE("btrfs subvolume create {} 2>>/tmp/cachyos-install.log"), subvol), true);
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");
// Mount the first subvolume as /
utils::exec(fmt::format(FMT_COMPILE("mount -o {},subvol=\"{}\" \"{}\" /mnt"), disk.mount_opts, subvol_list[0], disk.root));
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
subvol_list.erase(subvol_list.begin());
@ -62,7 +63,7 @@ void btrfs_create_subvols([[maybe_unused]] const disk_part& disk, const std::str
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));
gucc::utils::exec(fmt::format(FMT_COMPILE("mount -o {},subvol=\"{}\" \"{}\" \"{}\""), disk.mount_opts, subvol, disk.root, mountp_formatted));
}
return;
}
@ -77,18 +78,18 @@ 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");
utils::exec("btrfs subvolume create @ 2>>/tmp/cachyos-install.log"sv, true);
utils::exec("btrfs subvolume create @home 2>>/tmp/cachyos-install.log"sv, true);
utils::exec("btrfs subvolume create @cache 2>>/tmp/cachyos-install.log"sv, true);
// utils::exec("btrfs subvolume create @snapshots 2>>/tmp/cachyos-install.log"sv, true);
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");
utils::exec(fmt::format(FMT_COMPILE("mount -o {},subvol=@ \"{}\" /mnt"), disk.mount_opts, disk.root));
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");
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));
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));
#else
spdlog::info("Do we ignore note? {}", ignore_note);
#endif
@ -96,21 +97,21 @@ void btrfs_create_subvols([[maybe_unused]] const disk_part& disk, const std::str
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));
const auto& format_device = 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& format_name = gucc::utils::exec(fmt::format(FMT_COMPILE("echo {} | rev | cut -d/ -f1 | rev"), disk.part));
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));
std::string fs_opts{};
if (utils::exec(fmt::format(FMT_COMPILE("cat /sys/block/{}/queue/rotational)"), format_device), true) == "1"sv) {
if (gucc::utils::exec(fmt::format(FMT_COMPILE("cat /sys/block/{}/queue/rotational)"), format_device), true) == "1"sv) {
fs_opts = "autodefrag,compress=zlib,noatime,nossd,commit=120"sv;
} else {
fs_opts = "compress=lzo,noatime,space_cache,ssd,commit=120"sv;
}
#ifdef NDEVENV
utils::exec("btrfs subvolume list /mnt 2>/dev/null | cut -d\" \" -f9 > /tmp/.subvols"sv, true);
gucc::utils::exec("btrfs subvolume list /mnt 2>/dev/null | cut -d\" \" -f9 > /tmp/.subvols"sv, true);
umount("/mnt");
// Mount subvolumes one by one
for (const auto& subvol : gucc::utils::make_multiline(utils::exec("cat /tmp/.subvols"sv))) {
for (const auto& subvol : gucc::utils::make_multiline(gucc::utils::exec("cat /tmp/.subvols"sv))) {
// Ask for mountpoint
const auto& content = fmt::format(FMT_COMPILE("\nInput mountpoint of\nthe subvolume {}\nas it would appear\nin installed system\n(without prepending /mnt).\n"), subvol);
std::string mountpoint{"/"};
@ -122,18 +123,18 @@ void mount_existing_subvols(const disk_part& disk) noexcept {
fs::create_directories(mount_dir);
}
// Mount the subvolume
utils::exec(fmt::format(FMT_COMPILE("mount -o \"{},subvol={}\" \"{}\" \"{}\""), fs_opts, subvol, disk.root, mount_dir));
gucc::utils::exec(fmt::format(FMT_COMPILE("mount -o \"{},subvol={}\" \"{}\" \"{}\""), fs_opts, subvol, disk.root, mount_dir));
}
#endif
}
std::vector<std::string> lvm_show_vg() noexcept {
const auto& vg_list = gucc::utils::make_multiline(utils::exec("lvs --noheadings | awk '{print $2}' | uniq"sv));
const auto& vg_list = gucc::utils::make_multiline(gucc::utils::exec("lvs --noheadings | awk '{print $2}' | uniq"sv));
std::vector<std::string> res{};
res.reserve(vg_list.size());
for (const auto& vg : vg_list) {
const auto& temp = utils::exec(fmt::format(FMT_COMPILE("vgdisplay {} | grep -i \"vg size\" | {}"), vg, "awk '{print $3$4}'"sv));
const auto& temp = gucc::utils::exec(fmt::format(FMT_COMPILE("vgdisplay {} | grep -i \"vg size\" | {}"), vg, "awk '{print $3$4}'"sv));
res.push_back(temp);
}
@ -157,7 +158,7 @@ bool zfs_auto_pres(const std::string_view& partition, const std::string_view& zf
#ifdef NDEVENV
// set the rootfs
utils::exec(fmt::format(FMT_COMPILE("zpool set bootfs={0}/ROOT/cos/root {0} 2>>/tmp/cachyos-install.log"), zfs_zpool_name), true);
gucc::utils::exec(fmt::format(FMT_COMPILE("zpool set bootfs={0}/ROOT/cos/root {0} 2>>/tmp/cachyos-install.log"), zfs_zpool_name), true);
#endif
return true;
}
@ -175,15 +176,15 @@ bool zfs_create_zpool(const std::string_view& partition, const std::string_view&
std::int32_t ret_code{};
// Find the UUID of the partition
const auto& partuuid = utils::exec(fmt::format(FMT_COMPILE("lsblk -lno PATH,PARTUUID | grep \"^{}\" | {}"), partition, "awk '{print $2}'"sv), false);
const auto& partuuid = gucc::utils::exec(fmt::format(FMT_COMPILE("lsblk -lno PATH,PARTUUID | grep \"^{}\" | {}"), partition, "awk '{print $2}'"sv), false);
// See if the partition has a partuuid, if not use the device name
const auto& zfs_zpool_cmd = fmt::format(FMT_COMPILE("zpool create {} {}"), zpool_options, pool_name);
if (!partuuid.empty()) {
ret_code = utils::to_int(utils::exec(fmt::format(FMT_COMPILE("{} {} 2>>/tmp/cachyos-install.log"), zfs_zpool_cmd, partuuid), true));
ret_code = utils::to_int(gucc::utils::exec(fmt::format(FMT_COMPILE("{} {} 2>>/tmp/cachyos-install.log"), zfs_zpool_cmd, partuuid), true));
spdlog::info("Creating zpool {} on device {} using partuuid {}", pool_name, partition, partuuid);
} else {
ret_code = utils::to_int(utils::exec(fmt::format(FMT_COMPILE("{} {} 2>>/tmp/cachyos-install.log"), zfs_zpool_cmd, partition), true));
ret_code = utils::to_int(gucc::utils::exec(fmt::format(FMT_COMPILE("{} {} 2>>/tmp/cachyos-install.log"), zfs_zpool_cmd, partition), true));
spdlog::info("Creating zpool {} on device {}", pool_name, partition);
}
@ -200,8 +201,8 @@ bool zfs_create_zpool(const std::string_view& partition, const std::string_view&
#ifdef NDEVENV
// Since zfs manages mountpoints, we export it and then import with a root of MOUNTPOINT
const auto& mountpoint = std::get<std::string>(config_data["MOUNTPOINT"]);
utils::exec(fmt::format(FMT_COMPILE("zpool export {} 2>>/tmp/cachyos-install.log"), pool_name), true);
utils::exec(fmt::format(FMT_COMPILE("zpool import -R {} {} 2>>/tmp/cachyos-install.log"), mountpoint, pool_name), true);
gucc::utils::exec(fmt::format(FMT_COMPILE("zpool export {} 2>>/tmp/cachyos-install.log"), pool_name), true);
gucc::utils::exec(fmt::format(FMT_COMPILE("zpool import -R {} {} 2>>/tmp/cachyos-install.log"), mountpoint, pool_name), true);
#endif
return true;
@ -210,7 +211,7 @@ bool zfs_create_zpool(const std::string_view& partition, const std::string_view&
// Creates a zfs volume
void zfs_create_zvol(const std::string_view& zsize, const std::string_view& zpath) noexcept {
#ifdef NDEVENV
utils::exec(fmt::format(FMT_COMPILE("zfs create -V {}M {} 2>>/tmp/cachyos-install.log"), zsize, zpath), true);
gucc::utils::exec(fmt::format(FMT_COMPILE("zfs create -V {}M {} 2>>/tmp/cachyos-install.log"), zsize, zpath), true);
#else
spdlog::debug("zfs create -V {}M {}", zsize, zpath);
#endif
@ -219,7 +220,7 @@ void zfs_create_zvol(const std::string_view& zsize, const std::string_view& zpat
// Creates a zfs filesystem, the first parameter is the ZFS path and the second is the mount path
void zfs_create_dataset(const std::string_view& zpath, const std::string_view& zmount) noexcept {
#ifdef NDEVENV
utils::exec(fmt::format(FMT_COMPILE("zfs create -o mountpoint={} {} 2>>/tmp/cachyos-install.log"), zmount, zpath), true);
gucc::utils::exec(fmt::format(FMT_COMPILE("zfs create -o mountpoint={} {} 2>>/tmp/cachyos-install.log"), zmount, zpath), true);
#else
spdlog::debug("zfs create -o mountpoint={} {}", zmount, zpath);
#endif
@ -227,7 +228,7 @@ void zfs_create_dataset(const std::string_view& zpath, const std::string_view& z
void zfs_destroy_dataset(const std::string_view& zdataset) noexcept {
#ifdef NDEVENV
utils::exec(fmt::format(FMT_COMPILE("zfs destroy -r {} 2>>/tmp/cachyos-install.log"), zdataset), true);
gucc::utils::exec(fmt::format(FMT_COMPILE("zfs destroy -r {} 2>>/tmp/cachyos-install.log"), zdataset), true);
#else
spdlog::debug("zfs destroy -r {}", zdataset);
#endif
@ -236,7 +237,7 @@ void zfs_destroy_dataset(const std::string_view& zdataset) noexcept {
// returns a list of imported zpools
std::string zfs_list_pools() noexcept {
#ifdef NDEVENV
return utils::exec("zfs list -H -o name 2>/dev/null | grep \"/\""sv);
return gucc::utils::exec("zfs list -H -o name 2>/dev/null | grep \"/\""sv);
#else
return "vol0\nvol1\n";
#endif
@ -246,12 +247,12 @@ std::string zfs_list_pools() noexcept {
std::string zfs_list_devs() noexcept {
std::string list_of_devices{};
// get a list of devices with zpools on them
const auto& devices = gucc::utils::make_multiline(utils::exec("zpool status -PL 2>/dev/null | awk '{print $1}' | grep \"^/\""sv));
const auto& devices = gucc::utils::make_multiline(gucc::utils::exec("zpool status -PL 2>/dev/null | awk '{print $1}' | grep \"^/\""sv));
for (const auto& device : devices) {
// add the device
list_of_devices += fmt::format(FMT_COMPILE("{}\n"), device);
// now let's add any other forms of those devices
list_of_devices += utils::exec(fmt::format(FMT_COMPILE("find -L /dev/ -xtype l -samefile {} 2>/dev/null"), device));
list_of_devices += gucc::utils::exec(fmt::format(FMT_COMPILE("find -L /dev/ -xtype l -samefile {} 2>/dev/null"), device));
}
return list_of_devices;
}
@ -259,12 +260,12 @@ std::string zfs_list_devs() noexcept {
std::string zfs_list_datasets(const std::string_view& type) noexcept {
#ifdef NDEVENV
if (type == "zvol"sv) {
return utils::exec("zfs list -Ht volume -o name,volsize 2>/dev/null"sv);
return gucc::utils::exec("zfs list -Ht volume -o name,volsize 2>/dev/null"sv);
} else if (type == "legacy"sv) {
return utils::exec("zfs list -Ht filesystem -o name,mountpoint 2>/dev/null | grep \"^.*/.*legacy$\" | awk '{print $1}'"sv);
return gucc::utils::exec("zfs list -Ht filesystem -o name,mountpoint 2>/dev/null | grep \"^.*/.*legacy$\" | awk '{print $1}'"sv);
}
return utils::exec("zfs list -H -o name 2>/dev/null | grep \"/\""sv);
return gucc::utils::exec("zfs list -H -o name 2>/dev/null | grep \"/\""sv);
#else
spdlog::debug("type := {}", type);
return "zpcachyos";
@ -273,7 +274,7 @@ std::string zfs_list_datasets(const std::string_view& type) noexcept {
void zfs_set_property(const std::string_view& property, const std::string_view& dataset) noexcept {
#ifdef NDEVENV
utils::exec(fmt::format(FMT_COMPILE("zfs set {} {} 2>>/tmp/cachyos-install.log"), property, dataset), true);
gucc::utils::exec(fmt::format(FMT_COMPILE("zfs set {} {} 2>>/tmp/cachyos-install.log"), property, dataset), true);
#else
spdlog::debug("zfs set {} {}", property, dataset);
#endif
@ -290,7 +291,7 @@ void select_filesystem(const std::string_view& file_sys) noexcept {
config_data["FILESYSTEM"] = "mkfs.btrfs -f";
config_data["fs_opts"] = std::vector<std::string>{"autodefrag", "compress=zlib", "compress=lzo", "compress=zstd", "compress=no", "compress-force=zlib", "compress-force=lzo", "compress-force=zstd", "discard", "noacl", "noatime", "nodatasum", "nospace_cache", "recovery", "skip_balance", "space_cache", "nossd", "ssd", "ssd_spread", "commit=120"};
#ifdef NDEVENV
utils::exec("modprobe btrfs"sv);
gucc::utils::exec("modprobe btrfs"sv);
#endif
} else if (file_sys == "ext4"sv) {
config_data["FILESYSTEM"] = "mkfs.ext4 -q";
@ -299,7 +300,7 @@ void select_filesystem(const std::string_view& file_sys) noexcept {
config_data["FILESYSTEM"] = "mkfs.f2fs -q";
config_data["fs_opts"] = std::vector<std::string>{"data_flush", "disable_roll_forward", "disable_ext_identify", "discard", "fastboot", "flush_merge", "inline_xattr", "inline_data", "inline_dentry", "no_heap", "noacl", "nobarrier", "noextent_cache", "noinline_data", "norecovery"};
#ifdef NDEVENV
utils::exec("modprobe f2fs"sv);
gucc::utils::exec("modprobe f2fs"sv);
#endif
} else if (file_sys == "xfs"sv) {
config_data["FILESYSTEM"] = "mkfs.xfs -f";

View File

@ -3,6 +3,9 @@
#include "tui.hpp" // for init
#include "utils.hpp" // for exec, check_root, clear_sc...
// import gucc
#include "gucc/io_utils.hpp"
#include <chrono> // for seconds
#include <regex> // for regex_search, match_result...
#include <thread> // for sleep_for
@ -13,10 +16,10 @@
#include <spdlog/spdlog.h> // for set_default_logger, set_level
int main() {
const auto& tty = utils::exec("tty");
const auto& tty = gucc::utils::exec("tty");
const std::regex tty_regex("/dev/tty[0-9]*");
if (std::regex_search(tty, tty_regex)) {
utils::exec("setterm -blank 0 -powersave off");
gucc::utils::exec("setterm -blank 0 -powersave off");
}
// Check if installer has enough permissions.

View File

@ -3,6 +3,9 @@
#include "utils.hpp"
#include "widgets.hpp"
// import gucc
#include "gucc/io_utils.hpp"
/* clang-format off */
#include <filesystem> // for exists, is_directory
#include <ftxui/component/component.hpp> // for Renderer, Button
@ -37,7 +40,7 @@ void edit_mkinitcpio(ScreenInteractive& screen) noexcept {
const std::string& mountpoint = "/";
#endif
utils::exec(fmt::format(FMT_COMPILE("vim \"{}/etc/mkinitcpio.conf\""), mountpoint), true);
gucc::utils::exec(fmt::format(FMT_COMPILE("vim \"{}/etc/mkinitcpio.conf\""), mountpoint), true);
screen.Resume();
static constexpr auto content = "\nRun mkinitcpio?\n"sv;
@ -57,7 +60,7 @@ void edit_grub(ScreenInteractive& screen) noexcept {
const std::string& mountpoint = "/";
#endif
utils::exec(fmt::format(FMT_COMPILE("vim \"{}/etc/default/grub\""), mountpoint), true);
gucc::utils::exec(fmt::format(FMT_COMPILE("vim \"{}/etc/default/grub\""), mountpoint), true);
screen.Resume();
static constexpr auto content = "\nUpdate GRUB?\n"sv;
@ -74,7 +77,7 @@ namespace tui {
// Revised to deal with partition sizes now being displayed to the user
bool confirm_mount([[maybe_unused]] const std::string_view& part_user, bool quite) {
#ifdef NDEVENV
const auto& ret_status = utils::exec(fmt::format(FMT_COMPILE("mount | grep {}"), part_user), true);
const auto& ret_status = gucc::utils::exec(fmt::format(FMT_COMPILE("mount | grep {}"), part_user), true);
if (!quite && (ret_status != "0"sv)) {
detail::infobox_widget("\nMount Failed!\n"sv);
std::this_thread::sleep_for(std::chrono::seconds(2));
@ -142,7 +145,7 @@ void edit_configs() noexcept {
bool is_custom = false, std::function<void()>&& cust_func = []() {}) {
const auto& append_function = [&functions](const std::string& filename) {
/* clang-format off */
functions.emplace_back([filename]{ utils::exec(fmt::format(FMT_COMPILE("vim {}"), filename), true); });
functions.emplace_back([filename]{ gucc::utils::exec(fmt::format(FMT_COMPILE("vim {}"), filename), true); });
/* clang-format on */
};
/* clang-format off */
@ -215,12 +218,12 @@ void edit_configs() noexcept {
}
void edit_pacman_conf() noexcept {
utils::exec("vim /etc/pacman.conf"sv, true);
gucc::utils::exec("vim /etc/pacman.conf"sv, true);
#ifdef NDEVENV
// NOTE: don't care now, Will change in future..
detail::infobox_widget("\nUpdating database ...\n"sv);
utils::exec("pacman -Syy"sv, true);
gucc::utils::exec("pacman -Syy"sv, true);
#endif
}
@ -247,16 +250,16 @@ void logs_menu() noexcept {
screen.Suspend();
switch (selected) {
case 0:
utils::exec(fmt::format(FMT_COMPILE("arch-chroot {} dmesg | fzf --reverse --header=\"Exit by pressing esc\" --prompt=\"Type to filter log entries > \""), mountpoint), true);
gucc::utils::exec(fmt::format(FMT_COMPILE("arch-chroot {} dmesg | fzf --reverse --header=\"Exit by pressing esc\" --prompt=\"Type to filter log entries > \""), mountpoint), true);
break;
case 1:
utils::exec(fmt::format(FMT_COMPILE("fzf --reverse --header=\"Exit by pressing esc\" --prompt=\"Type to filter log entries > \" < {}/var/log/pacman.log"), mountpoint), true);
gucc::utils::exec(fmt::format(FMT_COMPILE("fzf --reverse --header=\"Exit by pressing esc\" --prompt=\"Type to filter log entries > \" < {}/var/log/pacman.log"), mountpoint), true);
break;
case 2:
utils::exec(fmt::format(FMT_COMPILE("fzf --reverse --header=\"Exit by pressing esc\" --prompt=\"Type to filter log entries > \" < {}/var/log/Xorg.0.log"), mountpoint), true);
gucc::utils::exec(fmt::format(FMT_COMPILE("fzf --reverse --header=\"Exit by pressing esc\" --prompt=\"Type to filter log entries > \" < {}/var/log/Xorg.0.log"), mountpoint), true);
break;
case 3:
utils::exec(fmt::format(FMT_COMPILE("arch-chroot {} journalctl | fzf --reverse --header=\"Exit by pressing esc\" --prompt=\"Type to filter log entries > \""), mountpoint), true);
gucc::utils::exec(fmt::format(FMT_COMPILE("arch-chroot {} journalctl | fzf --reverse --header=\"Exit by pressing esc\" --prompt=\"Type to filter log entries > \""), mountpoint), true);
break;
default:
screen.Resume();

View File

@ -6,6 +6,7 @@
#include "widgets.hpp"
// import gucc
#include "gucc/io_utils.hpp"
#include "gucc/string_utils.hpp"
/* clang-format off */
@ -128,10 +129,10 @@ void make_esp(const std::string& part_name, std::string_view bootloader_name, bo
config_data["UEFI_PART"] = partition;
// If it is already a fat/vfat partition...
const auto& ret_status = utils::exec(fmt::format(FMT_COMPILE("fsck -N {} | grep fat &>/dev/null"), partition), true);
const auto& ret_status = gucc::utils::exec(fmt::format(FMT_COMPILE("fsck -N {} | grep fat &>/dev/null"), partition), true);
if (ret_status != "0" && reformat_part) {
#ifdef NDEVENV
utils::exec(fmt::format(FMT_COMPILE("mkfs.vfat -F32 {} &>/dev/null"), partition));
gucc::utils::exec(fmt::format(FMT_COMPILE("mkfs.vfat -F32 {} &>/dev/null"), partition));
#endif
spdlog::debug("Formating boot partition with fat/vfat!");
}
@ -140,8 +141,8 @@ void make_esp(const std::string& part_name, std::string_view bootloader_name, bo
const auto& mountpoint_info = std::get<std::string>(config_data["MOUNTPOINT"]);
const auto& path_formatted = fmt::format(FMT_COMPILE("{}{}"), mountpoint_info, uefi_mount);
utils::exec(fmt::format(FMT_COMPILE("mkdir -p {}"), path_formatted));
utils::exec(fmt::format(FMT_COMPILE("mount {} {}"), partition, path_formatted));
gucc::utils::exec(fmt::format(FMT_COMPILE("mkdir -p {}"), path_formatted));
gucc::utils::exec(fmt::format(FMT_COMPILE("mount {} {}"), partition, path_formatted));
#endif
}
@ -188,7 +189,7 @@ auto make_partitions_prepared(std::string_view bootloader, std::string_view root
if (root_fs == "btrfs"sv) {
// Check if there are subvolumes already on the btrfs partition
const auto& subvolumes = fmt::format(FMT_COMPILE("btrfs subvolume list \"{}\" 2>/dev/null"), part_mountpoint);
const auto& subvolumes_count = 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.data());
if (lines_count > 1) {
// Pre-existing subvolumes and user wants to mount them
@ -212,7 +213,7 @@ auto make_partitions_prepared(std::string_view bootloader, std::string_view root
// 2 = separate lvm boot. For Grub configuration
if (part_mountpoint == "/boot"sv) {
const auto& cmd = fmt::format(FMT_COMPILE("lsblk -lno TYPE {} | grep \"lvm\""), part_name);
const auto& cmd_out = utils::exec(cmd);
const auto& cmd_out = gucc::utils::exec(cmd);
config_data["LVM_SEP_BOOT"] = 1;
if (!cmd_out.empty()) {
config_data["LVM_SEP_BOOT"] = 2;
@ -342,7 +343,7 @@ void menu_simple() noexcept {
utils::umount_partitions();
// We need to remount the zfs filesystems that have defined mountpoints already
utils::exec("zfs mount -aO &>/dev/null");
gucc::utils::exec("zfs mount -aO &>/dev/null");
// Get list of available partitions
utils::find_partitions();
@ -388,7 +389,7 @@ void menu_simple() noexcept {
/*if (utils::get_mountpoint_fs(mountpoint) == "btrfs") {
// Check if there are subvolumes already on the btrfs partition
const auto& subvolumes = fmt::format(FMT_COMPILE("btrfs subvolume list \"{}\" 2>/dev/null"), mountpoint);
const auto& subvolumes_count = 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.data());
if (lines_count > 1) {
// Pre-existing subvolumes and user wants to mount them
@ -473,7 +474,7 @@ void menu_simple() noexcept {
// so that output will be synchronized.
auto logger = spdlog::get("cachyos_logger");
logger->flush();
utils::exec(fmt::format(FMT_COMPILE("{} &>>/tmp/cachyos-install.log"), post_install), true);
gucc::utils::exec(fmt::format(FMT_COMPILE("{} &>>/tmp/cachyos-install.log"), post_install), true);
}
tui::exit_done();

View File

@ -10,6 +10,7 @@
#include "widgets.hpp"
// import gucc
#include "gucc/io_utils.hpp"
#include "gucc/string_utils.hpp"
#include <fmt/compile.h>
@ -175,7 +176,7 @@ void set_hostname() noexcept {
// Set system language
void set_locale() noexcept {
const auto& locales = gucc::utils::make_multiline(utils::exec("cat /etc/locale.gen | grep -v \"# \" | sed 's/#//g' | awk '/UTF-8/ {print $1}'"));
const auto& locales = gucc::utils::make_multiline(gucc::utils::exec("cat /etc/locale.gen | grep -v \"# \" | sed 's/#//g' | awk '/UTF-8/ {print $1}'"));
// System language
std::string locale{};
@ -209,7 +210,7 @@ void set_xkbmap() noexcept {
std::string xkbmap_choice{};
auto ok_callback = [&] {
const auto& keymap = xkbmap_list[static_cast<std::size_t>(selected)];
xkbmap_choice = utils::exec(fmt::format(FMT_COMPILE("echo \"{}\" | sed 's/_.*//'"), keymap));
xkbmap_choice = gucc::utils::exec(fmt::format(FMT_COMPILE("echo \"{}\" | sed 's/_.*//'"), keymap));
success = true;
screen.ExitLoopClosure()();
};
@ -238,7 +239,7 @@ void select_keymap() noexcept {
if (!keep_default) { return; }
/* clang-format on */
const auto& keymaps = gucc::utils::make_multiline(utils::exec(R"(ls -R /usr/share/kbd/keymaps | grep "map.gz" | sed 's/\.map\.gz//g' | sort)"));
const auto& keymaps = gucc::utils::make_multiline(gucc::utils::exec(R"(ls -R /usr/share/kbd/keymaps | grep "map.gz" | sed 's/\.map\.gz//g' | sort)"));
auto screen = ScreenInteractive::Fullscreen();
std::int32_t selected{226};
@ -257,7 +258,7 @@ bool set_timezone() noexcept {
std::string zone{};
{
auto screen = ScreenInteractive::Fullscreen();
const auto& cmd = utils::exec(R"(cat /usr/share/zoneinfo/zone.tab | awk '{print $3}' | grep "/" | sed "s/\/.*//g" | sort -ud)");
const auto& cmd = gucc::utils::exec(R"(cat /usr/share/zoneinfo/zone.tab | awk '{print $3}' | grep "/" | sed "s/\/.*//g" | sort -ud)");
const auto& zone_list = gucc::utils::make_multiline(cmd);
std::int32_t selected{};
@ -277,7 +278,7 @@ bool set_timezone() noexcept {
std::string subzone{};
{
auto screen = ScreenInteractive::Fullscreen();
const auto& cmd = utils::exec(fmt::format(FMT_COMPILE("cat /usr/share/zoneinfo/zone.tab | {1} | grep \"{0}/\" | sed \"s/{0}\\///g\" | sort -ud"), zone, "awk '{print $3}'"));
const auto& cmd = gucc::utils::exec(fmt::format(FMT_COMPILE("cat /usr/share/zoneinfo/zone.tab | {1} | grep \"{0}/\" | sed \"s/{0}\\///g\" | sort -ud"), zone, "awk '{print $3}'"));
const auto& city_list = gucc::utils::make_multiline(cmd);
std::int32_t selected{};
@ -465,9 +466,9 @@ void chroot_interactive() noexcept {
const auto& mountpoint = std::get<std::string>(config_data["MOUNTPOINT"]);
const auto& cmd_formatted = fmt::format(FMT_COMPILE("arch-chroot {} bash"), mountpoint);
utils::exec(cmd_formatted, true);
gucc::utils::exec(cmd_formatted, true);
#else
utils::exec("bash", true);
gucc::utils::exec("bash", true);
#endif
}
@ -479,7 +480,7 @@ void install_grub_uefi() noexcept {
/* clang-format on */
std::string bootid{"cachyos"};
auto ret_status = utils::exec("efibootmgr | cut -d\\ -f2 | grep -q -o cachyos", true);
auto ret_status = gucc::utils::exec("efibootmgr | cut -d\\ -f2 | grep -q -o cachyos", true);
if (ret_status == "0"sv) {
static constexpr auto bootid_content = "\nInput the name identify your grub installation. Choosing an existing name overwrites it.\n"sv;
if (!detail::inputbox_widget(bootid, bootid_content, size(ftxui::HEIGHT, ftxui::LESS_THAN, 9) | size(ftxui::WIDTH, ftxui::LESS_THAN, 30))) {
@ -544,7 +545,7 @@ void uefi_bootloader() noexcept {
static constexpr auto efi_path = "/sys/firmware/efi/"sv;
if (fs::exists(efi_path) && fs::is_directory(efi_path)) {
// Mount efivarfs if it is not already mounted
const auto& mount_out = utils::exec("mount | grep /sys/firmware/efi/efivars");
const auto& mount_out = gucc::utils::exec("mount | grep /sys/firmware/efi/efivars");
if (mount_out.empty() && (mount("efivarfs", "/sys/firmware/efi/efivars", "efivarfs", 0, "") != 0)) {
perror("utils::uefi_bootloader");
exit(1);
@ -608,16 +609,16 @@ void install_base() noexcept {
std::string packages{};
auto ok_callback = [&] {
packages = detail::from_checklist_string(available_kernels, kernels_state.get());
auto ret_status = utils::exec(fmt::format(FMT_COMPILE("echo \"{}\" | grep \"linux\""), packages), true);
auto ret_status = gucc::utils::exec(fmt::format(FMT_COMPILE("echo \"{}\" | grep \"linux\""), packages), true);
if (ret_status != "0") {
// Check if a kernel is already installed
ret_status = utils::exec(fmt::format(FMT_COMPILE("ls {}/boot/*.img >/dev/null 2>&1"), mountpoint), true);
ret_status = gucc::utils::exec(fmt::format(FMT_COMPILE("ls {}/boot/*.img >/dev/null 2>&1"), mountpoint), true);
if (ret_status != "0") {
static constexpr auto ErrNoKernel = "\nAt least one kernel must be selected.\n"sv;
detail::msgbox_widget(ErrNoKernel);
return;
}
const auto& cmd = utils::exec(fmt::format(FMT_COMPILE("ls {}/boot/*.img | cut -d'-' -f2 | grep -v ucode.img | sort -u"), mountpoint));
const auto& cmd = gucc::utils::exec(fmt::format(FMT_COMPILE("ls {}/boot/*.img | cut -d'-' -f2 | grep -v ucode.img | sort -u"), mountpoint));
detail::msgbox_widget(fmt::format(FMT_COMPILE("\nlinux-{} detected\n"), cmd));
screen.ExitLoopClosure()();
}
@ -766,14 +767,14 @@ void bios_bootloader() {
void enable_autologin() {
// Detect display manager
const auto& dm = utils::exec("file /mnt/etc/systemd/system/display-manager.service 2>/dev/null | awk -F'/' '{print $NF}' | cut -d. -f1");
const auto& dm = gucc::utils::exec("file /mnt/etc/systemd/system/display-manager.service 2>/dev/null | awk -F'/' '{print $NF}' | cut -d. -f1");
const auto& content = fmt::format(FMT_COMPILE("\nThis option enables autologin using {}.\n\nProceed?\n"), dm);
/* clang-format off */
if (!detail::yesno_widget(content, size(HEIGHT, LESS_THAN, 15) | size(WIDTH, LESS_THAN, 75))) { return; }
if (utils::exec("echo /mnt/home/* | xargs -n1 | wc -l") != "1") { return; }
if (gucc::utils::exec("echo /mnt/home/* | xargs -n1 | wc -l") != "1") { return; }
/* clang-format on */
const auto& autologin_user = utils::exec("echo /mnt/home/* | cut -d/ -f4");
const auto& autologin_user = gucc::utils::exec("echo /mnt/home/* | cut -d/ -f4");
utils::enable_autologin(dm, autologin_user);
}
@ -859,13 +860,13 @@ void auto_partition() noexcept {
utils::auto_partition();
// Show created partitions
const auto& disk_list = utils::exec(fmt::format(FMT_COMPILE("lsblk {} -o NAME,TYPE,FSTYPE,SIZE"), device_info));
const auto& disk_list = gucc::utils::exec(fmt::format(FMT_COMPILE("lsblk {} -o NAME,TYPE,FSTYPE,SIZE"), device_info));
detail::msgbox_widget(disk_list, size(HEIGHT, GREATER_THAN, 5));
}
// Simple code to show devices / partitions.
void show_devices() noexcept {
const auto& lsblk = utils::exec(R"(lsblk -o NAME,MODEL,TYPE,FSTYPE,SIZE,MOUNTPOINT | grep "disk\|part\|lvm\|crypt\|NAME\|MODEL\|TYPE\|FSTYPE\|SIZE\|MOUNTPOINT")");
const auto& lsblk = gucc::utils::exec(R"(lsblk -o NAME,MODEL,TYPE,FSTYPE,SIZE,MOUNTPOINT | grep "disk\|part\|lvm\|crypt\|NAME\|MODEL\|TYPE\|FSTYPE\|SIZE\|MOUNTPOINT")");
detail::msgbox_widget(lsblk, size(HEIGHT, GREATER_THAN, 5));
}
@ -883,7 +884,7 @@ void refresh_pacman_keys() noexcept {
bool select_device() noexcept {
auto* config_instance = Config::instance();
auto& config_data = config_instance->data();
auto devices = utils::exec(R"(lsblk -lno NAME,SIZE,TYPE | grep 'disk' | awk '{print "/dev/" $1 " " $2}' | sort -u)");
auto devices = gucc::utils::exec(R"(lsblk -lno NAME,SIZE,TYPE | grep 'disk' | awk '{print "/dev/" $1 " " $2}' | sort -u)");
const auto& devices_list = gucc::utils::make_multiline(devices);
auto screen = ScreenInteractive::Fullscreen();
@ -942,7 +943,7 @@ bool select_filesystem() noexcept {
const auto& do_mount = detail::yesno_widget(content, size(HEIGHT, LESS_THAN, 15) | size(WIDTH, LESS_THAN, 75));
if (do_mount) {
#ifdef NDEVENV
utils::exec(fmt::format(FMT_COMPILE("{} {}"), file_sys, partition));
gucc::utils::exec(fmt::format(FMT_COMPILE("{} {}"), file_sys, partition));
#endif
spdlog::info("mount.{} {}", partition, file_sys);
}
@ -959,10 +960,10 @@ void mount_opts(bool force) noexcept {
const auto& file_sys = std::get<std::string>(config_data["FILESYSTEM"]);
const auto& fs_opts = std::get<std::vector<std::string>>(config_data["fs_opts"]);
const auto& partition = std::get<std::string>(config_data["PARTITION"]);
const auto& format_name = utils::exec(fmt::format(FMT_COMPILE("echo {} | rev | cut -d/ -f1 | rev"), partition));
const auto& format_device = utils::exec(fmt::format(FMT_COMPILE("lsblk -i | tac | sed -r 's/^[^[:alnum:]]+//' | sed -n -e \"/{}/,/disk/p\" | {}"), format_name, "awk '/disk/ {print $1}'"));
const auto& format_name = gucc::utils::exec(fmt::format(FMT_COMPILE("echo {} | rev | cut -d/ -f1 | rev"), partition));
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}'"));
const auto& rotational_queue = (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"), format_device)) == "1"sv);
std::unique_ptr<bool[]> fs_opts_state{new bool[fs_opts.size()]{false}};
for (size_t i = 0; i < fs_opts.size(); ++i) {
@ -988,8 +989,8 @@ void mount_opts(bool force) noexcept {
// Now clean up the file
auto cleaup_mount_opts = [](auto& opts_info) {
opts_info = utils::exec(fmt::format(FMT_COMPILE("echo \"{}\" | sed 's/ /,/g'"), opts_info));
opts_info = utils::exec(fmt::format(FMT_COMPILE("echo \"{}\" | sed '$s/,$//'"), opts_info));
opts_info = gucc::utils::exec(fmt::format(FMT_COMPILE("echo \"{}\" | sed 's/ /,/g'"), opts_info));
opts_info = gucc::utils::exec(fmt::format(FMT_COMPILE("echo \"{}\" | sed '$s/,$//'"), opts_info));
};
if (force) {
@ -1004,7 +1005,7 @@ void mount_opts(bool force) noexcept {
screen.ExitLoopClosure()();
};
const auto& file_sys_formatted = utils::exec(fmt::format(FMT_COMPILE("echo {} | sed \"s/.*\\.//g;s/-.*//g\""), file_sys));
const auto& file_sys_formatted = gucc::utils::exec(fmt::format(FMT_COMPILE("echo {} | sed \"s/.*\\.//g;s/-.*//g\""), file_sys));
const auto& fs_title = fmt::format(FMT_COMPILE("New CLI Installer | {}"), file_sys_formatted);
auto content_size = size(HEIGHT, GREATER_THAN, 10) | size(WIDTH, GREATER_THAN, 40) | vscroll_indicator | yframe | flex;
@ -1052,11 +1053,11 @@ bool mount_current_partition(bool force) noexcept {
const auto& mount_opts_info = std::get<std::string>(config_data["MOUNT_OPTS"]);
if (!mount_opts_info.empty()) {
// check_for_error "mount ${PARTITION} $(cat ${MOUNT_OPTS})"
const auto& mount_status = utils::exec(fmt::format(FMT_COMPILE("mount -o {} {} {}{}"), mount_opts_info, partition, mountpoint, mount_dev));
const auto& mount_status = gucc::utils::exec(fmt::format(FMT_COMPILE("mount -o {} {} {}{}"), mount_opts_info, partition, mountpoint, mount_dev));
spdlog::info("{}", mount_status);
} else {
// check_for_error "mount ${PARTITION}"
const auto& mount_status = utils::exec(fmt::format(FMT_COMPILE("mount {} {}{}"), partition, mountpoint, mount_dev));
const auto& mount_status = gucc::utils::exec(fmt::format(FMT_COMPILE("mount {} {}{}"), partition, mountpoint, mount_dev));
spdlog::info("{}", mount_status);
}
#endif
@ -1066,15 +1067,15 @@ bool mount_current_partition(bool force) noexcept {
/* clang-format on */
// Identify if mounted partition is type "crypt" (LUKS on LVM, or LUKS alone)
if (!utils::exec(fmt::format(FMT_COMPILE("lsblk -lno TYPE {} | grep \"crypt\""), partition)).empty()) {
if (!gucc::utils::exec(fmt::format(FMT_COMPILE("lsblk -lno TYPE {} | grep \"crypt\""), partition)).empty()) {
// cryptname for bootloader configuration either way
config_data["LUKS"] = 1;
auto& luks_name = std::get<std::string>(config_data["LUKS_NAME"]);
const auto& luks_dev = std::get<std::string>(config_data["LUKS_DEV"]);
luks_name = utils::exec(fmt::format(FMT_COMPILE("echo {} | sed \"s~^/dev/mapper/~~g\""), partition));
luks_name = gucc::utils::exec(fmt::format(FMT_COMPILE("echo {} | sed \"s~^/dev/mapper/~~g\""), partition));
const auto& check_cryptparts = [&](const auto cryptparts, auto functor) {
for (const auto& cryptpart : cryptparts) {
if (!utils::exec(fmt::format(FMT_COMPILE("lsblk -lno NAME {} | grep \"{}\""), cryptpart, luks_name)).empty()) {
if (!gucc::utils::exec(fmt::format(FMT_COMPILE("lsblk -lno NAME {} | grep \"{}\""), cryptpart, luks_name)).empty()) {
functor(cryptpart);
return true;
}
@ -1083,7 +1084,7 @@ bool mount_current_partition(bool force) noexcept {
};
// Check if LUKS on LVM (parent = lvm /dev/mapper/...)
auto cryptparts = gucc::utils::make_multiline(utils::exec(R"(lsblk -lno NAME,FSTYPE,TYPE | grep "lvm" | grep -i "crypto_luks" | uniq | awk '{print "/dev/mapper/"$1}')"));
auto cryptparts = gucc::utils::make_multiline(gucc::utils::exec(R"(lsblk -lno NAME,FSTYPE,TYPE | grep "lvm" | grep -i "crypto_luks" | uniq | awk '{print "/dev/mapper/"$1}')"));
auto check_functor = [&](const auto cryptpart) {
config_data["LUKS_DEV"] = fmt::format(FMT_COMPILE("{} cryptdevice={}:{}"), luks_dev, cryptpart, luks_name);
config_data["LVM"] = 1;
@ -1093,16 +1094,16 @@ bool mount_current_partition(bool force) noexcept {
}
// Check if LVM on LUKS
cryptparts = gucc::utils::make_multiline(utils::exec(R"(lsblk -lno NAME,FSTYPE,TYPE | grep " crypt$" | grep -i "LVM2_member" | uniq | awk '{print "/dev/mapper/"$1}')"));
cryptparts = gucc::utils::make_multiline(gucc::utils::exec(R"(lsblk -lno NAME,FSTYPE,TYPE | grep " crypt$" | grep -i "LVM2_member" | uniq | awk '{print "/dev/mapper/"$1}')"));
if (check_cryptparts(cryptparts, check_functor)) {
return true;
}
// Check if LUKS alone (parent = part /dev/...)
cryptparts = gucc::utils::make_multiline(utils::exec(R"(lsblk -lno NAME,FSTYPE,TYPE | grep "part" | grep -i "crypto_luks" | uniq | awk '{print "/dev/"$1}')"));
cryptparts = gucc::utils::make_multiline(gucc::utils::exec(R"(lsblk -lno NAME,FSTYPE,TYPE | grep "part" | grep -i "crypto_luks" | uniq | awk '{print "/dev/"$1}')"));
const auto& check_func_dev = [&](const auto cryptpart) {
auto& luks_uuid = std::get<std::string>(config_data["LUKS_UUID"]);
luks_uuid = utils::exec(fmt::format(FMT_COMPILE("lsblk -lno UUID,TYPE,FSTYPE {} | grep \"part\" | grep -i \"crypto_luks\" | {}"), cryptpart, "awk '{print $1}'"));
luks_uuid = gucc::utils::exec(fmt::format(FMT_COMPILE("lsblk -lno UUID,TYPE,FSTYPE {} | grep \"part\" | grep -i \"crypto_luks\" | {}"), cryptpart, "awk '{print $1}'"));
config_data["LUKS_DEV"] = fmt::format(FMT_COMPILE("{} cryptdevice=UUID={}:{}"), luks_dev, luks_uuid, luks_name);
};
if (check_cryptparts(cryptparts, check_func_dev)) {
@ -1186,13 +1187,13 @@ void make_swap() noexcept {
/* clang-format on */
if (partition == sel_swap_file) {
const auto& total_memory = utils::exec("grep MemTotal /proc/meminfo | awk '{print $2/1024}' | sed 's/\\..*//'");
const auto& total_memory = gucc::utils::exec("grep MemTotal /proc/meminfo | awk '{print $2/1024}' | sed 's/\\..*//'");
std::string value{fmt::format(FMT_COMPILE("{}M"), total_memory)};
if (!detail::inputbox_widget(value, "\nM = MB, G = GB\n", size(ftxui::HEIGHT, ftxui::LESS_THAN, 9) | size(ftxui::WIDTH, ftxui::LESS_THAN, 30))) {
return;
}
while (utils::exec(fmt::format(FMT_COMPILE("echo \"{}\" | grep \"M\\|G\""), value)).empty()) {
while (gucc::utils::exec(fmt::format(FMT_COMPILE("echo \"{}\" | grep \"M\\|G\""), value)).empty()) {
detail::msgbox_widget(fmt::format(FMT_COMPILE("\n{} Error: M = MB, G = GB\n"), sel_swap_file));
value = fmt::format(FMT_COMPILE("{}M"), total_memory);
if (!detail::inputbox_widget(value, "\nM = MB, G = GB\n", size(ftxui::HEIGHT, ftxui::LESS_THAN, 9) | size(ftxui::WIDTH, ftxui::LESS_THAN, 30))) {
@ -1202,10 +1203,10 @@ void make_swap() noexcept {
#ifdef NDEVENV
const auto& swapfile_path = fmt::format(FMT_COMPILE("{}/swapfile"), mountpoint_info);
utils::exec(fmt::format(FMT_COMPILE("fallocate -l {} {} 2>>/tmp/cachyos-install.log &>/dev/null"), value, swapfile_path));
utils::exec(fmt::format(FMT_COMPILE("chmod 600 {} 2>>/tmp/cachyos-install.log"), swapfile_path));
utils::exec(fmt::format(FMT_COMPILE("mkswap {} 2>>/tmp/cachyos-install.log &>/dev/null"), swapfile_path));
utils::exec(fmt::format(FMT_COMPILE("swapon {} 2>>/tmp/cachyos-install.log &>/dev/null"), swapfile_path));
gucc::utils::exec(fmt::format(FMT_COMPILE("fallocate -l {} {} 2>>/tmp/cachyos-install.log &>/dev/null"), value, swapfile_path));
gucc::utils::exec(fmt::format(FMT_COMPILE("chmod 600 {} 2>>/tmp/cachyos-install.log"), swapfile_path));
gucc::utils::exec(fmt::format(FMT_COMPILE("mkswap {} 2>>/tmp/cachyos-install.log &>/dev/null"), swapfile_path));
gucc::utils::exec(fmt::format(FMT_COMPILE("swapon {} 2>>/tmp/cachyos-install.log &>/dev/null"), swapfile_path));
#endif
return;
}
@ -1214,7 +1215,7 @@ void make_swap() noexcept {
auto& number_partitions = std::get<std::int32_t>(config_data["NUMBER_PARTITIONS"]);
// Warn user if creating a new swap
const auto& swap_part = utils::exec(fmt::format(FMT_COMPILE("lsblk -o FSTYPE \"{}\" | grep -i \"swap\""), partition));
const auto& swap_part = gucc::utils::exec(fmt::format(FMT_COMPILE("lsblk -o FSTYPE \"{}\" | grep -i \"swap\""), partition));
if (swap_part != "swap") {
const auto& do_swap = detail::yesno_widget(fmt::format(FMT_COMPILE("\nmkswap {}\n"), partition), size(HEIGHT, LESS_THAN, 15) | size(WIDTH, LESS_THAN, 75));
/* clang-format off */
@ -1222,14 +1223,14 @@ void make_swap() noexcept {
/* clang-format on */
#ifdef NDEVENV
utils::exec(fmt::format(FMT_COMPILE("mkswap {} &>/dev/null"), partition));
gucc::utils::exec(fmt::format(FMT_COMPILE("mkswap {} &>/dev/null"), partition));
#endif
spdlog::info("mkswap.{}", partition);
}
#ifdef NDEVENV
// Whether existing to newly created, activate swap
utils::exec(fmt::format(FMT_COMPILE("swapon {} &>/dev/null"), partition));
gucc::utils::exec(fmt::format(FMT_COMPILE("swapon {} &>/dev/null"), partition));
#endif
// Since a partition was used, remove that partition from the list
@ -1276,7 +1277,7 @@ void lvm_del_vg() noexcept {
#ifdef NDEVENV
// if confirmation given, delete
utils::exec(fmt::format(FMT_COMPILE("vgremove -f {} 2>/dev/null"), sel_vg), true);
gucc::utils::exec(fmt::format(FMT_COMPILE("vgremove -f {} 2>/dev/null"), sel_vg), true);
#endif
}
@ -1397,7 +1398,7 @@ bool zfs_create_zpool(bool do_create_zpool = true) noexcept {
}
bool zfs_import_pool() noexcept {
const auto& zlist = gucc::utils::make_multiline(utils::exec("zpool import 2>/dev/null | grep \"^[[:space:]]*pool\" | awk -F : '{print $2}' | awk '{$1=$1};1'"));
const auto& zlist = gucc::utils::make_multiline(gucc::utils::exec("zpool import 2>/dev/null | grep \"^[[:space:]]*pool\" | awk -F : '{print $2}' | awk '{$1=$1};1'"));
if (zlist.empty()) {
// no available datasets
detail::infobox_widget("\nNo pools available\"\n"sv);
@ -1428,7 +1429,7 @@ bool zfs_import_pool() noexcept {
#ifdef NDEVENV
const auto& mountpoint = std::get<std::string>(config_data["MOUNTPOINT"]);
utils::exec(fmt::format(FMT_COMPILE("zpool import -R {} {} 2>>/tmp/cachyos-install.log"), mountpoint, zfs_zpool_name), true);
gucc::utils::exec(fmt::format(FMT_COMPILE("zpool import -R {} {} 2>>/tmp/cachyos-install.log"), mountpoint, zfs_zpool_name), true);
#endif
config_data["ZFS"] = 1;
@ -1691,7 +1692,7 @@ void zfs_menu_manual() noexcept {
void zfs_menu() noexcept {
#ifdef NDEVENV
// check for zfs support
if (utils::exec("modprobe zfs 2>>/tmp/cachyos-install.log &>/dev/null", true) != "0"sv) {
if (gucc::utils::exec("modprobe zfs 2>>/tmp/cachyos-install.log &>/dev/null", true) != "0"sv) {
detail::infobox_widget("\nThe kernel modules to support ZFS could not be found\n"sv);
std::this_thread::sleep_for(std::chrono::seconds(3));
return;
@ -1763,7 +1764,7 @@ void make_esp() noexcept {
config_data["UEFI_PART"] = partition;
// If it is already a fat/vfat partition...
const auto& ret_status = utils::exec(fmt::format(FMT_COMPILE("fsck -N {} | grep fat"), partition), true);
const auto& ret_status = gucc::utils::exec(fmt::format(FMT_COMPILE("fsck -N {} | grep fat"), partition), true);
bool do_boot_partition{};
if (ret_status != "0") {
const auto& content = fmt::format(FMT_COMPILE("\nThe UEFI partition {} has already been formatted.\n \nReformat? Doing so will erase ALL data already on that partition.\n"), partition);
@ -1771,7 +1772,7 @@ void make_esp() noexcept {
}
if (do_boot_partition) {
#ifdef NDEVENV
utils::exec(fmt::format(FMT_COMPILE("mkfs.vfat -F32 {} &>/dev/null"), partition));
gucc::utils::exec(fmt::format(FMT_COMPILE("mkfs.vfat -F32 {} &>/dev/null"), partition));
#endif
spdlog::debug("Formating boot partition with fat/vfat!");
}
@ -1804,8 +1805,8 @@ void make_esp() noexcept {
uefi_mount = answer;
const auto& path_formatted = fmt::format(FMT_COMPILE("{}{}"), mountpoint_info, uefi_mount);
#ifdef NDEVENV
utils::exec(fmt::format(FMT_COMPILE("mkdir -p {}"), path_formatted));
utils::exec(fmt::format(FMT_COMPILE("mount {} {}"), partition, path_formatted));
gucc::utils::exec(fmt::format(FMT_COMPILE("mkdir -p {}"), path_formatted));
gucc::utils::exec(fmt::format(FMT_COMPILE("mount {} {}"), partition, path_formatted));
#endif
confirm_mount(path_formatted);
}
@ -1825,7 +1826,7 @@ void mount_partitions() noexcept {
utils::umount_partitions();
// We need to remount the zfs filesystems that have defined mountpoints already
utils::exec("zfs mount -aO &>/dev/null");
gucc::utils::exec("zfs mount -aO &>/dev/null");
// Get list of available partitions
utils::find_partitions();
@ -1896,10 +1897,10 @@ void mount_partitions() noexcept {
if (utils::get_mountpoint_fs(mountpoint_info) == "btrfs") {
// 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_count = 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);
if (lines_count > 1) {
const auto& subvolumes_formated = utils::exec(fmt::format(FMT_COMPILE("{} | cut -d\" \" -f9"), subvolumes));
const auto& subvolumes_formated = gucc::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
/* clang-format off */
@ -2008,7 +2009,7 @@ void mount_partitions() noexcept {
// 2 = separate lvm boot. For Grub configuration
if (mount_dev == "/boot") {
const auto& cmd = fmt::format(FMT_COMPILE("lsblk -lno TYPE {} | grep \"lvm\""), partition);
const auto& cmd_out = utils::exec(cmd);
const auto& cmd_out = gucc::utils::exec(cmd);
config_data["LVM_SEP_BOOT"] = 1;
if (!cmd_out.empty()) {
config_data["LVM_SEP_BOOT"] = 2;
@ -2035,7 +2036,7 @@ void configure_mirrorlist() noexcept {
break;
case 1:
screen.Suspend();
utils::exec("cachyos-rate-mirrors"sv, true);
gucc::utils::exec("cachyos-rate-mirrors"sv, true);
screen.Resume();
break;
default:
@ -2072,7 +2073,7 @@ void create_partitions() noexcept {
if (selected_entry != optwipe && selected_entry != optauto) {
screen.Suspend();
#ifdef NDEVENV
utils::exec(fmt::format(FMT_COMPILE("{} {}"), selected_entry, std::get<std::string>(config_data["DEVICE"])), true);
gucc::utils::exec(fmt::format(FMT_COMPILE("{} {}"), selected_entry, std::get<std::string>(config_data["DEVICE"])), true);
#else
spdlog::debug("to be executed: {}", fmt::format(FMT_COMPILE("{} {}"), selected_entry, std::get<std::string>(config_data["DEVICE"])));
#endif

File diff suppressed because it is too large Load Diff

View File

@ -59,10 +59,6 @@ void recheck_luks() noexcept;
void arch_chroot(const std::string_view& command, bool follow = true) noexcept;
void exec_follow(const std::vector<std::string>& vec, std::string& process_log, bool& running, subprocess_s& child, bool async = true) noexcept;
void exec(const std::vector<std::string>& vec) noexcept;
auto exec(const std::string_view& command, const bool& interactive = false) noexcept -> std::string;
[[nodiscard]] auto read_whole_file(const std::string_view& filepath) noexcept -> std::string;
bool write_to_file(const std::string_view& data, const std::string_view& filepath) noexcept;
void dump_to_log(const std::string& data) noexcept;
void dump_settings_to_log() noexcept;
[[nodiscard]] bool check_root() noexcept;

View File

@ -1,8 +1,11 @@
#include "definitions.hpp"
#include "utils.hpp"
// import gucc
#include "gucc/io_utils.hpp"
int main() {
output_inter("\n\n------ TEST BASH LAUNCH BEGIN ------\n\n");
utils::exec("bash", true);
gucc::utils::exec("bash", true);
output_inter("\n\n------ TEST BASH LAUNCH END ------\n\n");
}