FlatImage
A configurable Linux containerization system
Loading...
Searching...
No Matches
layers.hpp
Go to the documentation of this file.
1
8
9#pragma once
10
11#include <cstdint>
12#include <filesystem>
13#include <fstream>
14#include <vector>
15#include <ranges>
16#include <algorithm>
17
18#include "../std/expected.hpp"
19#include "../std/filesystem.hpp"
20#include "../lib/env.hpp"
21#include "../macro.hpp"
22#include "dwarfs.hpp"
23
24namespace ns_filesystems::ns_layers
25{
26
27namespace
28{
29
30namespace fs = std::filesystem;
31
32}
33
59class Layers
60{
61 private:
62 struct Layer
63 {
64 fs::path const path;
65 uint64_t offset;
66 uint64_t size;
67 };
68 std::vector<Layer> layers;
69
78 [[nodiscard]] Value<void> append_file(fs::path const& path)
79 {
80 return_if(not ns_dwarfs::is_dwarfs(path), Error("W::Skipping invalid dwarfs filesystem '{}'", path));
81 layers.push_back({path, 0, std::filesystem::file_size(path)});
82 return {};
83 }
84
94 [[nodiscard]] Value<void> append_directory(fs::path const& path)
95 {
96 // Get all regular files from the directory
97 auto result = Pop(ns_fs::regular_files(path));
98 // Sort layers files
99 std::ranges::sort(result);
100 // Process each file
101 for(auto&& file : result)
102 {
103 append_file(file).discard("W::Failed to append layer from directory");
104 }
105 return {};
106 }
107
108 public:
119 [[nodiscard]] Value<void> push(fs::path const& path)
120 {
121 if(Try(fs::is_regular_file(path)))
122 {
123 append_file(path).discard("W::Failed to append layer from regular file");
124 }
125 else if(Try(fs::is_directory(path)))
126 {
127 append_directory(path).discard("W::Failed to append layer from directory");
128 }
129 return {};
130 }
131
148 [[nodiscard]] Value<void> push_from_var(std::string_view var)
149 {
150 for(fs::path const& path : ns_env::get_expected<"Q">(var)
151 // Perform word expansions (variables, run subshells...)
152 .transform([](auto&& e){ return ns_env::expand(e).value_or(std::string{e}); })
153 // Get value or default to empty
154 .value_or(std::string{})
155 // Split values variable on ':'
156 | std::views::split(':')
157 // Create a path
158 | std::views::transform([](auto&& e){ return fs::path(e.begin(), e.end()); })
159 )
160 {
161 Pop(push(path));
162 }
163 return {};
164 }
165
174 std::vector<Layer> const& get_layers() const
175 {
176 return layers;
177 }
178
195 void push_binary(fs::path const& path_file_binary, uint64_t offset)
196 {
197 // Open the binary file
198 std::ifstream file_binary(path_file_binary, std::ios::binary);
199
200 // Advance to starting offset
201 file_binary.seekg(offset);
202
203 // Scan for filesystems concatenated in the binary
204 while (true)
205 {
206 // Read filesystem size
207 uint64_t size_fs;
208 break_if(not file_binary.read(reinterpret_cast<char*>(&size_fs), sizeof(size_fs))
209 , "D::Stopped reading at offset {}", offset
210 );
211 logger("D::Filesystem size is '{}'", size_fs);
212 // Validate filesystem size
213 break_if(size_fs <= 0, "E::Invalid filesystem size '{}' at offset {}", size_fs, offset);
214 // Skip size bytes to point to filesystem data
215 offset += 8;
216 // Check if filesystem is of type 'DWARFS'
217 break_if(not ns_dwarfs::is_dwarfs(path_file_binary, offset)
218 , "E::Invalid dwarfs filesystem appended on the image"
219 );
220 // Store the filesystem with its offset
221 layers.push_back({path_file_binary, offset, size_fs});
222 // Move to next filesystem position
223 offset += size_fs;
224 file_binary.seekg(offset);
225 }
226
227 file_binary.close();
228 }
229};
230
231} // ns_filesystems::ns_layers
Manages external DwarFS layer files and directories for the filesystem controller.
Definition layers.hpp:60
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.
Enhanced error handling framework built on std::expected.
A library for manipulating environment variables.
#define logger(fmt,...)
Compile-time log level dispatch macro with automatic location capture.
Definition log.hpp:682
Simplified macros for common control flow patterns with optional logging.
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.
Filesystem helpers.
Enhanced expected type with integrated logging capabilities.
Definition expected.hpp:44