mirror of
https://github.com/CachyOS/New-Cli-Installer.git
synced 2025-01-23 05:52:23 +08:00
👷 gucc: add block devices parser
Some checks failed
Build / Build with CMake (push) Has been cancelled
Build / Build with CMake (DEVENV OFF) (push) Has been cancelled
Build / Build with Meson (push) Has been cancelled
Build / Build with Meson (DEVENV OFF) (push) Has been cancelled
Checks / cpp-linter (push) Has been cancelled
Checks / Check C++ style (push) Has been cancelled
Some checks failed
Build / Build with CMake (push) Has been cancelled
Build / Build with CMake (DEVENV OFF) (push) Has been cancelled
Build / Build with Meson (push) Has been cancelled
Build / Build with Meson (DEVENV OFF) (push) Has been cancelled
Checks / cpp-linter (push) Has been cancelled
Checks / Check C++ style (push) Has been cancelled
This commit is contained in:
parent
ccaa6fdbe4
commit
a3ece6c01d
@ -23,6 +23,7 @@ add_library(${PROJECT_NAME} #SHARED
|
||||
src/cpu.cpp include/gucc/cpu.hpp
|
||||
src/pacmanconf_repo.cpp include/gucc/pacmanconf_repo.hpp
|
||||
src/initcpio.cpp include/gucc/initcpio.hpp
|
||||
src/block_devices.cpp include/gucc/block_devices.hpp
|
||||
src/luks.cpp include/gucc/luks.hpp
|
||||
src/zfs.cpp include/gucc/zfs.hpp
|
||||
src/btrfs.cpp include/gucc/btrfs.hpp
|
||||
|
51
gucc/include/gucc/block_devices.hpp
Normal file
51
gucc/include/gucc/block_devices.hpp
Normal file
@ -0,0 +1,51 @@
|
||||
#ifndef BLOCK_DEVICES_HPP
|
||||
#define BLOCK_DEVICES_HPP
|
||||
|
||||
#include <cstdint> // for uint64_t
|
||||
#include <optional> // for optional
|
||||
#include <string> // for string
|
||||
#include <string_view> // for string_view
|
||||
#include <vector> // for vector
|
||||
|
||||
namespace gucc::disk {
|
||||
|
||||
/// @brief Represents a block device with its properties.
|
||||
struct BlockDevice {
|
||||
/// Device name (e.g., /dev/nvme0n1).
|
||||
std::string name;
|
||||
/// Device type (e.g., part, crypt, disk).
|
||||
std::string type;
|
||||
/// Filesystem type (e.g., ext4, btrfs).
|
||||
std::string fstype;
|
||||
/// Device UUID.
|
||||
std::string uuid;
|
||||
/// Device model.
|
||||
std::optional<std::string> model;
|
||||
/// Mount point.
|
||||
std::optional<std::string> mountpoint;
|
||||
/// Parent device name.
|
||||
std::optional<std::string> pkname;
|
||||
/// Filesystem label.
|
||||
std::optional<std::string> label;
|
||||
/// Partition UUID.
|
||||
std::optional<std::string> partuuid;
|
||||
/// Size of the device in bytes.
|
||||
std::optional<std::uint64_t> size;
|
||||
|
||||
/// @brief Default constructor for BlockDevice.
|
||||
BlockDevice() = default;
|
||||
};
|
||||
|
||||
/// @brief Executes lsblk command and returns a list of block devices.
|
||||
/// @return An optional vector of BlockDevice objects, std::nullopt otherwise.
|
||||
auto list_block_devices() -> std::optional<std::vector<BlockDevice>>;
|
||||
|
||||
/// @brief Finds a block device by its name.
|
||||
/// @param devices A vector of BlockDevice objects.
|
||||
/// @param device_name A string view containing the name of the device to find.
|
||||
/// @return An optional BlockDevice object if found, std::nullopt otherwise.
|
||||
auto find_device_by_name(const std::vector<BlockDevice>& devices, std::string_view device_name) -> std::optional<BlockDevice>;
|
||||
|
||||
} // namespace gucc::disk
|
||||
|
||||
#endif // BLOCK_DEVICES_HPP
|
@ -7,6 +7,7 @@ gucc_lib = library('gucc',
|
||||
'src/cpu.cpp',
|
||||
'src/pacmanconf_repo.cpp',
|
||||
'src/initcpio.cpp',
|
||||
'src/block_devices.cpp',
|
||||
'src/luks.cpp',
|
||||
'src/zfs.cpp',
|
||||
'src/btrfs.cpp',
|
||||
|
99
gucc/src/block_devices.cpp
Normal file
99
gucc/src/block_devices.cpp
Normal file
@ -0,0 +1,99 @@
|
||||
#include "gucc/block_devices.hpp"
|
||||
#include "gucc/io_utils.hpp"
|
||||
|
||||
#include <algorithm> // for find_if
|
||||
#include <ranges> // for ranges::*
|
||||
#include <utility> // for make_optional, move
|
||||
|
||||
#include <rapidjson/document.h>
|
||||
#include <rapidjson/error/en.h>
|
||||
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
using namespace std::string_view_literals;
|
||||
|
||||
namespace {
|
||||
|
||||
using BlockDevice = gucc::disk::BlockDevice;
|
||||
|
||||
/// Constructs a BlockDevice from a RapidJSON object.
|
||||
auto get_blockdevice_from_json(const rapidjson::Value& doc) -> BlockDevice {
|
||||
auto device = BlockDevice{};
|
||||
if (doc.HasMember("name") && doc["name"].IsString()) {
|
||||
device.name = doc["name"].GetString();
|
||||
}
|
||||
if (doc.HasMember("type") && doc["type"].IsString()) {
|
||||
device.type = doc["type"].GetString();
|
||||
}
|
||||
if (doc.HasMember("fstype") && doc["fstype"].IsString()) {
|
||||
device.fstype = doc["fstype"].GetString();
|
||||
}
|
||||
if (doc.HasMember("uuid") && doc["uuid"].IsString()) {
|
||||
device.uuid = doc["uuid"].GetString();
|
||||
}
|
||||
|
||||
if (doc.HasMember("model") && doc["model"].IsString()) {
|
||||
device.model = doc["model"].GetString();
|
||||
}
|
||||
if (doc.HasMember("mountpoint") && doc["mountpoint"].IsString()) {
|
||||
device.mountpoint = doc["mountpoint"].GetString();
|
||||
}
|
||||
if (doc.HasMember("pkname") && doc["pkname"].IsString()) {
|
||||
device.pkname = doc["pkname"].GetString();
|
||||
}
|
||||
if (doc.HasMember("label") && doc["label"].IsString()) {
|
||||
device.label = doc["label"].GetString();
|
||||
}
|
||||
if (doc.HasMember("partuuid") && doc["partuuid"].IsString()) {
|
||||
device.partuuid = doc["partuuid"].GetString();
|
||||
}
|
||||
if (doc.HasMember("size") && doc["size"].IsInt64()) {
|
||||
device.size = doc["size"].GetInt64();
|
||||
}
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
auto parse_lsblk_json(std::string_view json_output) -> std::vector<BlockDevice> {
|
||||
rapidjson::Document document;
|
||||
|
||||
document.Parse(json_output.data(), json_output.size());
|
||||
if (document.HasParseError()) {
|
||||
spdlog::error("Failed to parse lsblk output: {}", rapidjson::GetParseError_En(document.GetParseError()));
|
||||
return {};
|
||||
}
|
||||
|
||||
// Extract data from JSON
|
||||
std::vector<BlockDevice> block_devices{};
|
||||
if (document.HasMember("blockdevices") && document["blockdevices"].IsArray()) {
|
||||
for (const auto& device_json : document["blockdevices"].GetArray()) {
|
||||
auto block_device = get_blockdevice_from_json(device_json);
|
||||
block_devices.emplace_back(std::move(block_device));
|
||||
}
|
||||
}
|
||||
return block_devices;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace gucc::disk {
|
||||
|
||||
auto find_device_by_name(const std::vector<BlockDevice>& devices, std::string_view device_name) -> std::optional<BlockDevice> {
|
||||
auto it = std::ranges::find_if(devices, [device_name](auto&& dev) {
|
||||
return dev.name == device_name;
|
||||
});
|
||||
if (it != std::ranges::end(devices)) {
|
||||
return std::make_optional<BlockDevice>(std::move(*it));
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
auto list_block_devices() -> std::optional<std::vector<BlockDevice>> {
|
||||
const auto& lsblk_output = utils::exec(R"(lsblk -f -o NAME,TYPE,FSTYPE,UUID,PARTUUID,PKNAME,LABEL,SIZE,MOUNTPOINT,MODEL -b -p -a -J -Q "type=='part' || type=='crypt' && fstype")");
|
||||
if (lsblk_output.empty()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return std::make_optional<std::vector<BlockDevice>>(parse_lsblk_json(lsblk_output));
|
||||
}
|
||||
|
||||
} // namespace gucc::disk
|
Loading…
Reference in New Issue
Block a user