FlatImage
A configurable Linux containerization system
Loading...
Searching...
No Matches
utils.hpp
Go to the documentation of this file.
1
8
9#pragma once
10
11#include <string>
12#include <filesystem>
13#include <ranges>
14#include <chrono>
15#include <thread>
16
17#include "../std/expected.hpp"
18#include "../macro.hpp"
19
29{
30
31namespace
32{
33
34namespace fs = std::filesystem;
35
36}
37
50inline bool is_busy(fs::path const& path_dir)
51{
52 [[maybe_unused]] auto __expected_fn = [](auto&&){ return std::nullopt; };
53 // Check all processes in /proc
54 std::vector<std::string> const pids = std::filesystem::directory_iterator("/proc")
55 // Get directories only
56 | std::views::filter([](auto&& e){ return fs::is_directory(e); })
57 // Get string file names
58 | std::views::transform([](auto&& e){ return e.path().filename().string(); })
59 // Drop empty strings
60 | std::views::filter([](auto&& e){ return not e.empty(); })
61 // Filter & transform to pid
62 | std::views::filter([](auto&& e){ return Catch(std::stoi(e)).has_value(); })
63 | std::ranges::to<std::vector<std::string>>();
64
65 for (std::string const& pid : pids)
66 {
67 // Open mountinfo file
68 std::ifstream file_info("/proc/" + pid + "/mountinfo");
69 continue_if(not file_info.is_open());
70 // Iterate through file lines
71 auto lines = std::ranges::istream_view<std::string>(file_info);
72 auto it = std::ranges::find_if(lines, [&](auto const& line)
73 {
74 return line.find(path_dir) != std::string::npos;
75 });
76 return_if(it != lines.end(), true, "D::Busy '{}' due to '{}'", path_dir, *it);
77 }
78 return false;
79}
80
92[[nodiscard]] inline Value<void> wait_busy(fs::path const& path_dir, std::chrono::nanoseconds timeout)
93{
94 using namespace std::chrono;
95
96 auto const start_time = steady_clock::now();
97 constexpr auto poll_interval = milliseconds(100);
98
99 while(true)
100 {
101 if(!is_busy(path_dir))
102 {
103 return {}; // Directory is no longer busy
104 }
105
106 auto const elapsed = steady_clock::now() - start_time;
107 if(elapsed >= timeout)
108 {
109 auto const timeout_ms = duration_cast<milliseconds>(timeout).count();
110 return Error("C::Another instance is running on {} (timeout after {}ms)", path_dir, timeout_ms);
111 }
112
113 std::this_thread::sleep_for(poll_interval);
114 }
115}
116
121{
122 pid_t pid;
123 fs::path path;
124};
125
137[[nodiscard]] inline std::vector<Instance> get_instances(fs::path const& path_dir_instances)
138{
139 // List instances
140 auto f_pid = [&](auto&& e) { return Catch(std::stoi(e.path().filename().string())).value_or(0); };
141 // Get instances
142 auto instances = fs::directory_iterator(path_dir_instances)
143 | std::views::transform([&](auto&& e){ return Instance(f_pid(e), e.path()); })
144 | std::views::filter([&](auto&& e){ return e.pid > 0; })
145 | std::views::filter([&](auto&& e){ return fs::exists(fs::path{"/proc"} / std::to_string(e.pid)); })
146 | std::views::filter([&](auto&& e){ return e.pid != getpid(); })
147 | std::ranges::to<std::vector<Instance>>();
148 // Sort by pid (filename is a directory named as the pid of that instance)
149 std::ranges::sort(instances, {}, [](auto&& e){ return e.pid; });
150 return instances;
151}
152
164[[nodiscard]] inline std::vector<fs::path> get_mounted_layers(fs::path const& path_dir_layers)
165{
166 std::vector<fs::path> vec_path_dir_layer = fs::directory_iterator(path_dir_layers)
167 | std::views::filter([](auto&& e){ return fs::is_directory(e.path()); })
168 | std::views::transform([](auto&& e){ return e.path(); })
169 | std::ranges::to<std::vector<fs::path>>();
170 std::ranges::sort(vec_path_dir_layer);
171 return vec_path_dir_layer;
172}
173
174
175
176} // namespace ns_filesystems::ns_utils
Enhanced error handling framework built on std::expected.
constexpr auto __expected_fn
Lambda helper for Pop macro error returns.
Definition expected.hpp:147
Simplified macros for common control flow patterns with optional logging.
Filesystem utility functions.
std::vector< fs::path > get_mounted_layers(fs::path const &path_dir_layers)
Get a path for each layer directory.
Definition utils.hpp:164
Value< void > wait_busy(fs::path const &path_dir, std::chrono::nanoseconds timeout)
Waits for a filesystem path to become available (not busy).
Definition utils.hpp:92
bool is_busy(fs::path const &path_dir)
Checks if a filesystem path is currently in use by any active process.
Definition utils.hpp:50
std::vector< Instance > get_instances(fs::path const &path_dir_instances)
Get the running FlatImage instances.
Definition utils.hpp:137
Enhanced expected type with integrated logging capabilities.
Definition expected.hpp:44
Represents an instance.
Definition utils.hpp:121
pid_t pid
PID of the running instance.
Definition utils.hpp:122
fs::path path
Path to FIM_DIR_INSTANCE.
Definition utils.hpp:123