at master 91 lines 3.7 kB view raw
1diff --git a/libs/oci-cfg-generators/src/linglong/oci-cfg-generators/container_cfg_builder.cpp b/libs/oci-cfg-generators/src/linglong/oci-cfg-generators/container_cfg_builder.cpp 2index 787e70cb..a71df46a 100644 3--- a/libs/oci-cfg-generators/src/linglong/oci-cfg-generators/container_cfg_builder.cpp 4+++ b/libs/oci-cfg-generators/src/linglong/oci-cfg-generators/container_cfg_builder.cpp 5@@ -19,6 +19,8 @@ 6 #include <iomanip> 7 #include <iostream> 8 #include <vector> 9+#include <unordered_map> 10+#include <unordered_set> 11 12 #include <sys/stat.h> 13 #include <sys/types.h> 14@@ -432,19 +434,67 @@ ContainerCfgBuilder &ContainerCfgBuilder::bindHostRoot() noexcept 15 16 ContainerCfgBuilder &ContainerCfgBuilder::bindHostStatics() noexcept 17 { 18- std::vector<std::filesystem::path> statics{ 19- "/etc/machine-id", 20- // FIXME: support for host /etc/ssl, ref https://github.com/p11-glue/p11-kit 21- "/usr/lib/locale", 22- "/usr/share/fonts", 23- "/usr/share/icons", 24- "/usr/share/themes", 25- "/var/cache/fontconfig", 26+ std::unordered_map<std::filesystem::path, std::string> statics{ 27+ { "/etc/machine-id", "" }, 28+ { "/usr/lib/locale", "" }, 29+ { "/var/cache/fontconfig", "" }, 30+ 31+ { "/run/current-system/sw/share/X11/fonts", "/usr/share/fonts" }, 32+ { "/run/current-system/sw/share/icons", "/usr/share/icons" }, 33+ { "/run/current-system/sw/share/themes", "/usr/share/themes" }, 34 }; 35 36 hostStaticsMount = std::vector<Mount>{}; 37- for (const auto &loc : statics) { 38- bindIfExist(*hostStaticsMount, loc); 39+ auto nixStorePaths = std::unordered_set<std::string>{}; 40+ for (const auto &[source, destination] : statics) { 41+ if (!std::filesystem::exists(source)) { 42+ std::cerr << "[bindHostStatics] Skipping non-existent path: " << source << std::endl; 43+ continue; 44+ } 45+ 46+ bindIfExist(*hostStaticsMount, source, destination); 47+ 48+ std::string sourcePathPrefix = "/run/current-system/sw/share/"; 49+ std::string nixStorePrefix = "/nix/store/"; 50+ 51+ if (source.string().rfind(sourcePathPrefix, 0) != 0) 52+ continue; 53+ 54+ std::error_code ec; 55+ for (const std::filesystem::directory_entry &dir_entry : 56+ std::filesystem::recursive_directory_iterator(source, std::filesystem::directory_options::skip_permission_denied, ec)) 57+ { 58+ if (ec) { 59+ std::cerr << "[bindHostStatics] Failed to iterate directory: " << source << ", error: " << ec.message() << std::endl; 60+ break; 61+ } 62+ 63+ if (!dir_entry.is_symlink(ec) || ec) { 64+ if (ec) 65+ std::cerr << "[bindHostStatics] Failed to check symlink: " << dir_entry.path() << ", error: " << ec.message() << std::endl; 66+ continue; 67+ } 68+ 69+ std::filesystem::path targetPath = std::filesystem::canonical(dir_entry.path(), ec); 70+ if (ec) { 71+ std::cerr << "[bindHostStatics] Failed to resolve symlink: " << dir_entry.path() << ", error: " << ec.message() << std::endl; 72+ continue; 73+ } 74+ 75+ std::string target = targetPath.string(); 76+ if (target.rfind(nixStorePrefix, 0) != 0) 77+ continue; 78+ 79+ auto endPos = target.find('/', nixStorePrefix.length()); 80+ if (endPos != std::string::npos) 81+ nixStorePaths.insert(target.substr(0, endPos)); 82+ else 83+ nixStorePaths.insert(target); 84+ } 85+ } 86+ 87+ for (const std::string &path : nixStorePaths) { 88+ bindIfExist(*hostStaticsMount, path); 89 } 90 91 return *this;