FlatImage
A configurable Linux containerization system
Loading...
Searching...
No Matches
/flatimage/src/filesystems/layers.hpp
Layers layers;
layers.push_from_var("FIM_LAYERS"); // Process FIM_LAYERS env var
layers.push("/path/to/layers"); // Add directory or file
auto const& paths = layers.get_layers(); // Retrieve all layer paths
#pragma once
#include <cstdint>
#include <filesystem>
#include <fstream>
#include <vector>
#include <ranges>
#include <algorithm>
#include "../std/expected.hpp"
#include "../std/filesystem.hpp"
#include "../lib/env.hpp"
#include "../macro.hpp"
#include "dwarfs.hpp"
namespace ns_filesystems::ns_layers
{
namespace
{
namespace fs = std::filesystem;
}
class Layers
{
private:
struct Layer
{
fs::path const path;
uint64_t offset;
uint64_t size;
};
std::vector<Layer> layers;
[[nodiscard]] Value<void> append_file(fs::path const& path)
{
return_if(not ns_dwarfs::is_dwarfs(path), Error("W::Skipping invalid dwarfs filesystem '{}'", path));
layers.push_back({path, 0, std::filesystem::file_size(path)});
return {};
}
[[nodiscard]] Value<void> append_directory(fs::path const& path)
{
// Get all regular files from the directory
auto result = Pop(ns_fs::regular_files(path));
// Sort layers files
std::ranges::sort(result);
// Process each file
for(auto&& file : result)
{
append_file(file).discard("W::Failed to append layer from directory");
}
return {};
}
public:
[[nodiscard]] Value<void> push(fs::path const& path)
{
if(Try(fs::is_regular_file(path)))
{
append_file(path).discard("W::Failed to append layer from regular file");
}
else if(Try(fs::is_directory(path)))
{
append_directory(path).discard("W::Failed to append layer from directory");
}
return {};
}
[[nodiscard]] Value<void> push_from_var(std::string_view var)
{
for(fs::path const& path : ns_env::get_expected<"Q">(var)
// Perform word expansions (variables, run subshells...)
.transform([](auto&& e){ return ns_env::expand(e).value_or(std::string{e}); })
// Get value or default to empty
.value_or(std::string{})
// Split values variable on ':'
| std::views::split(':')
// Create a path
| std::views::transform([](auto&& e){ return fs::path(e.begin(), e.end()); })
)
{
Pop(push(path));
}
return {};
}
std::vector<Layer> const& get_layers() const
{
return layers;
}
void push_binary(fs::path const& path_file_binary, uint64_t offset)
{
// Open the binary file
std::ifstream file_binary(path_file_binary, std::ios::binary);
// Advance to starting offset
file_binary.seekg(offset);
// Scan for filesystems concatenated in the binary
while (true)
{
// Read filesystem size
uint64_t size_fs;
break_if(not file_binary.read(reinterpret_cast<char*>(&size_fs), sizeof(size_fs))
, "D::Stopped reading at offset {}", offset
);
logger("D::Filesystem size is '{}'", size_fs);
// Validate filesystem size
break_if(size_fs <= 0, "E::Invalid filesystem size '{}' at offset {}", size_fs, offset);
// Skip size bytes to point to filesystem data
offset += 8;
// Check if filesystem is of type 'DWARFS'
break_if(not ns_dwarfs::is_dwarfs(path_file_binary, offset)
, "E::Invalid dwarfs filesystem appended on the image"
);
// Store the filesystem with its offset
layers.push_back({path_file_binary, offset, size_fs});
// Move to next filesystem position
offset += size_fs;
file_binary.seekg(offset);
}
file_binary.close();
}
};
} // ns_filesystems::ns_layers
std::vector< Layer > const & get_layers() const
Retrieves the collected layer file paths with offsets.
Definition layers.hpp:174
Value< void > push_from_var(std::string_view var)
Loads layers from a colon-separated environment variable.
Definition layers.hpp:148
Value< void > push(fs::path const &path)
Adds a layer from a file or directory path.
Definition layers.hpp:119
void push_binary(fs::path const &path_file_binary, uint64_t offset)
Scans a binary file for embedded DwarFS filesystems.
Definition layers.hpp:195
Manage dwarfs filesystems.
#define logger(fmt,...)
Compile-time log level dispatch macro with automatic location capture.
Definition log.hpp:682
Value< std::string > expand(ns_concept::StringRepresentable auto &&var)
Performs variable expansion analogous to a POSIX shell.
Definition env.hpp:96
Value< std::string > get_expected(std::string_view name)
Get the value of an environment variable.
Definition env.hpp:65
bool is_dwarfs(fs::path const &path_file_dwarfs, uint64_t offset=0)
Checks if the filesystem is a Dwarfs filesystem with a given offset.
Definition dwarfs.hpp:114
Value< std::vector< fs::path > > regular_files(fs::path const &path_dir_src)
List the files in a directory.
Enhanced expected type with integrated logging capabilities.
Definition expected.hpp:44