refactor: remove all generators

Signed-off-by: ComixHe <ComixHe1895@outlook.com>
This commit is contained in:
ComixHe
2025-06-11 13:29:00 +08:00
committed by reddevillg
parent d8a3191d2f
commit 2615ac3525
22 changed files with 0 additions and 1550 deletions

View File

@ -2,19 +2,6 @@
#
# SPDX-License-Identifier: LGPL-3.0-or-later
macro(configure_patch_variable source)
get_filename_component(BASE_NAME ${source} NAME_WE)
string(TOUPPER ${BASE_NAME} PATCH_VAR)
string(REPLACE "-" "_" PATCH_VAR ${PATCH_VAR})
string(PREPEND PATCH_VAR "LINGLONG_OCI_CFG_GEN_")
file(READ ${source} ${PATCH_VAR})
endmacro()
configure_patch_variable(${PROJECT_SOURCE_DIR}/misc/lib/linglong/container/config.json)
configure_patch_variable(${PROJECT_SOURCE_DIR}/misc/lib/linglong/container/config.d/10-basics.json)
configure_patch_variable(${PROJECT_SOURCE_DIR}/misc/lib/linglong/container/config.d/25-host-rootfs.json)
configure_patch_variable(${PROJECT_SOURCE_DIR}/misc/lib/linglong/container/config.d/25-host-statics.json)
pfl_add_library(
MERGED_HEADER_PLACEMENT
DISABLE_INSTALL
@ -22,30 +9,8 @@ pfl_add_library(
STATIC
SOURCES
# find -regex '\.\/.+\.[ch]\(pp\)?' -type f -printf '%P\n'| sort
src/linglong/oci-cfg-generators/00_id_mapping.cpp
src/linglong/oci-cfg-generators/00_id_mapping.h
src/linglong/oci-cfg-generators/05_initialize.cpp
src/linglong/oci-cfg-generators/05_initialize.h
src/linglong/oci-cfg-generators/10_basics.cpp
src/linglong/oci-cfg-generators/10_basics.h.in
src/linglong/oci-cfg-generators/20_devices.cpp
src/linglong/oci-cfg-generators/20_devices.h
src/linglong/oci-cfg-generators/25_host_env.cpp
src/linglong/oci-cfg-generators/25_host_env.h
src/linglong/oci-cfg-generators/25_host_rootfs.cpp
src/linglong/oci-cfg-generators/25_host_rootfs.h.in
src/linglong/oci-cfg-generators/25_host_statics.cpp
src/linglong/oci-cfg-generators/25_host_statics.h.in
src/linglong/oci-cfg-generators/30_user_home.cpp
src/linglong/oci-cfg-generators/30_user_home.h
src/linglong/oci-cfg-generators/40_host_ipc.cpp
src/linglong/oci-cfg-generators/40_host_ipc.h
src/linglong/oci-cfg-generators/90_legacy.cpp
src/linglong/oci-cfg-generators/90_legacy.h
src/linglong/oci-cfg-generators/builtins.h.in
src/linglong/oci-cfg-generators/container_cfg_builder.cpp
src/linglong/oci-cfg-generators/container_cfg_builder.h
src/linglong/oci-cfg-generators/generator.h
COMPILE_FEATURES
PUBLIC
cxx_std_17

View File

@ -1,45 +0,0 @@
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
#include "00_id_mapping.h"
#include <iostream>
#include <unistd.h>
namespace linglong::generator {
bool IDMapping::generate(ocppi::runtime::config::types::Config &config) const noexcept
{
if (config.ociVersion != "1.0.1") {
std::cerr << "OCI version mismatched." << std::endl;
return false;
}
auto linux_ = config.linux_.value_or(ocppi::runtime::config::types::Linux{});
auto uidMappings = std::vector<ocppi::runtime::config::types::IdMapping>{
ocppi::runtime::config::types::IdMapping{
.containerID = ::getuid(),
.hostID = ::getuid(),
.size = 1,
}
};
auto gidMappings = std::vector<ocppi::runtime::config::types::IdMapping>{
ocppi::runtime::config::types::IdMapping{
.containerID = ::getgid(),
.hostID = ::getgid(),
.size = 1,
}
};
linux_.uidMappings = std::move(uidMappings);
linux_.gidMappings = std::move(gidMappings);
config.linux_ = std::move(linux_);
return true;
}
} // namespace linglong::generator

View File

@ -1,17 +0,0 @@
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
#pragma once
#include "linglong/oci-cfg-generators/generator.h"
namespace linglong::generator {
struct IDMapping : public Generator
{
[[nodiscard]] std::string_view name() const override { return "00-id-mapping"; }
bool generate(ocppi::runtime::config::types::Config &config) const noexcept override;
};
} // namespace linglong::generator

View File

@ -1,75 +0,0 @@
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
#include "05_initialize.h"
#include <filesystem>
#include <iostream>
namespace linglong::generator {
bool Initialize::generate(ocppi::runtime::config::types::Config &config) const noexcept
{
if (config.ociVersion != "1.0.1") {
std::cerr << "OCI version mismatched." << std::endl;
return false;
}
if (!config.annotations) {
std::cerr << "no annotations." << std::endl;
return false;
}
const auto &annotations = config.annotations.value();
auto appID = config.annotations->find("org.deepin.linglong.appID");
if (appID == config.annotations->end()) {
std::cerr << "appID not found." << std::endl;
return false;
}
if (appID->second.empty()) {
std::cerr << "appID is empty." << std::endl;
return false;
}
auto mounts = config.mounts.value_or(std::vector<ocppi::runtime::config::types::Mount>{});
if (auto runtimeDir = annotations.find("org.deepin.linglong.runtimeDir");
runtimeDir != annotations.end()) {
mounts.push_back(ocppi::runtime::config::types::Mount{
.destination = "/runtime",
.options = string_list{ "rbind", "ro" },
.source = std::filesystem::path(runtimeDir->second) / "files",
.type = "bind" });
}
if (auto appDir = annotations.find("org.deepin.linglong.appDir"); appDir != annotations.end()) {
mounts.push_back(ocppi::runtime::config::types::Mount{
.destination = "/opt",
.options = string_list{ "nodev", "nosuid", "mode=700" },
.source = "tmpfs",
.type = "tmpfs",
});
mounts.push_back(ocppi::runtime::config::types::Mount{
.destination = std::filesystem::path("/opt/apps") / appID->second / "files",
.options = string_list{ "rbind", "rw" },
.source = std::filesystem::path(appDir->second) / "files",
.type = "bind" });
}
std::srand(std::time(0));
auto tmpDir =
std::filesystem::temp_directory_path() / ("linglong_tmp_" + std::to_string(std::rand()));
std::filesystem::create_directory(tmpDir.string());
mounts.push_back(ocppi::runtime::config::types::Mount{ .destination = "/tmp",
.options = string_list{ "rbind", "rw" },
.source = tmpDir,
.type = "bind" });
config.mounts = std::move(mounts);
return true;
}
} // namespace linglong::generator

View File

@ -1,18 +0,0 @@
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
#pragma once
#include "linglong/oci-cfg-generators/generator.h"
namespace linglong::generator {
struct Initialize : public Generator
{
[[nodiscard]] std::string_view name() const override { return "05-initialize"; }
bool generate(ocppi::runtime::config::types::Config &config) const noexcept override;
};
} // namespace linglong::generator

View File

@ -1,50 +0,0 @@
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
#include "10_basics.h"
#include "ocppi/runtime/config/types/Generators.hpp"
#include <iostream>
namespace linglong::generator {
bool Basics::generate(ocppi::runtime::config::types::Config &config) const noexcept
{
nlohmann::json rawPatch;
try {
rawPatch = nlohmann::json::parse(basicsPatch);
} catch (const std::exception &e) {
std::cerr << "parse basicsPatch failed:" << e.what() << std::endl;
return false;
}
if (config.ociVersion != rawPatch["ociVersion"].get<std::string>()) {
std::cerr << "ociVersion mismatched" << std::endl;
return false;
}
if (!config.annotations) {
std::cerr << "no annotations." << std::endl;
return false;
}
auto onlyApp = config.annotations->find("org.deepin.linglong.onlyApp");
if (onlyApp != config.annotations->end() && onlyApp->second == "true") {
return true;
}
try {
auto rawConfig = nlohmann::json(config);
rawConfig = rawConfig.patch(rawPatch["patch"]);
config = rawConfig.get<ocppi::runtime::config::types::Config>();
} catch (const std::exception &e) {
std::cerr << "patch basics failed:" << e.what() << std::endl;
return false;
}
return true;
}
} // namespace linglong::generator

View File

@ -1,21 +0,0 @@
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
#pragma once
#include "linglong/oci-cfg-generators/generator.h"
namespace linglong::generator {
struct Basics : public Generator
{
[[nodiscard]] std::string_view name() const override { return "10-basics"; }
bool generate(ocppi::runtime::config::types::Config &config) const noexcept override;
private:
static constexpr std::string_view basicsPatch{ R"(@LINGLONG_OCI_CFG_GEN_10_BASICS@)" };
};
} // namespace linglong::generator

View File

@ -1,129 +0,0 @@
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
#include "20_devices.h"
#include <filesystem>
#include <iostream>
namespace linglong::generator {
bool Devices::generate(ocppi::runtime::config::types::Config &config) const noexcept
{
if (config.ociVersion != "1.0.1") {
std::cerr << "OCI version mismatched." << std::endl;
return false;
}
if (!config.annotations) {
std::cerr << "no annotations." << std::endl;
return false;
}
auto onlyApp = config.annotations->find("org.deepin.linglong.onlyApp");
if (onlyApp != config.annotations->end() && onlyApp->second == "true") {
return true;
}
auto mounts = config.mounts.value_or(std::vector<ocppi::runtime::config::types::Mount>{});
auto bindIfExist = [&mounts](std::string_view source, std::string_view destination) mutable {
std::error_code ec;
if (!std::filesystem::exists(source, ec)) {
if (ec) {
std::cerr << "Failed to check existence of " << source << ": " << ec.message()
<< std::endl;
return;
}
return;
}
auto realDest = destination.empty() ? source : destination;
mounts.push_back(ocppi::runtime::config::types::Mount{
.destination = std::string{ realDest },
.options = string_list{ "rbind" },
.source = std::string{ source },
.type = "bind",
});
};
bindIfExist("/run/udev", "");
bindIfExist("/dev/snd", "");
bindIfExist("/dev/dri", "");
for (const auto &entry : std::filesystem::directory_iterator{ "/dev" }) {
const auto &devPath = entry.path();
auto devName = devPath.filename().string();
if ((devName.rfind("video", 0) == 0) || (devName.rfind("nvidia", 0) == 0)) {
mounts.emplace_back(ocppi::runtime::config::types::Mount{
.destination = devPath,
.options = string_list{ "rbind" },
.source = devPath,
.type = "bind",
});
}
}
// using FHS media directory and ignore '/run/media' for now
// FIXME: the mount base location of udisks will be affected by the flag
// '--enable-fhs-media', if not set this option, udisks will choose `/run/media` as the
// mount location. some linux distros (e.g. ArchLinux) don't have this flag enabled, perhaps
// we could find a better way to compatible with those distros.
// https://github.com/storaged-project/udisks/commit/ae2a5ff1e49ae924605502ace170eb831e9c38e4
std::error_code ec;
auto mediaDir = std::filesystem::path("/media");
auto status = std::filesystem::symlink_status(mediaDir, ec);
if (ec && ec != std::errc::no_such_file_or_directory) {
std::cerr << "failed to get /media status of "
<< ": " << ec.message() << std::endl;
return false;
}
if (status.type() == std::filesystem::file_type::symlink) {
auto targetDir = std::filesystem::read_symlink(mediaDir, ec);
if (ec) {
std::cerr << "failed to resolve symlink." << std::endl;
return false;
}
auto destinationDir = "/" + targetDir.string();
if (!std::filesystem::exists(destinationDir, ec)) {
if (ec) {
std::cerr << "check destination dir existence." << std::endl;
return false;
}
std::cerr << "destination path not found." << std::endl;
return false;
}
mounts.push_back(ocppi::runtime::config::types::Mount{
.destination = destinationDir,
.options = string_list{ "rbind", "rshared" },
.source = destinationDir,
.type = "bind",
});
mounts.push_back(ocppi::runtime::config::types::Mount{
.destination = "/media",
.options = string_list{ "rbind", "ro", "copy-symlink" },
.source = "/media",
.type = "bind",
});
} else {
mounts.push_back(ocppi::runtime::config::types::Mount{
.destination = "/media",
.options = string_list{ "rbind", "rshared" },
.source = "/media",
.type = "bind",
});
}
config.mounts = std::move(mounts);
return true;
}
} // namespace linglong::generator

View File

@ -1,18 +0,0 @@
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
#pragma once
#include "linglong/oci-cfg-generators/generator.h"
namespace linglong::generator {
struct Devices : public Generator
{
[[nodiscard]] std::string_view name() const override { return "20-devices"; }
bool generate(ocppi::runtime::config::types::Config &config) const noexcept override;
};
} // namespace linglong::generator

View File

@ -1,101 +0,0 @@
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
#include "25_host_env.h"
#include <iostream>
#include <unistd.h>
namespace linglong::generator {
bool HostEnv::generate(ocppi::runtime::config::types::Config &config) const noexcept
{
if (config.ociVersion != "1.0.1") {
std::cerr << "OCI version mismatched." << std::endl;
return false;
}
if (!config.annotations) {
std::cerr << "no annotations." << std::endl;
return false;
}
auto appID = config.annotations->find("org.deepin.linglong.appID");
if (appID == config.annotations->end()) {
std::cerr << "appID not found." << std::endl;
return false;
}
if (appID->second.empty()) {
std::cerr << "appID is empty." << std::endl;
return false;
}
auto process = config.process.value_or(ocppi::runtime::config::types::Process{});
auto env = process.env.value_or(std::vector<std::string>{});
env.push_back("LINGLONG_APPID=" + appID->second);
const std::vector<std::string> envList = {
"DISPLAY",
"LANG",
"LANGUAGE",
"XDG_SESSION_DESKTOP",
"D_DISABLE_RT_SCREEN_SCALE",
"XMODIFIERS",
"XCURSOR_SIZE", // 鼠标尺寸
"DESKTOP_SESSION",
"DEEPIN_WINE_SCALE",
"XDG_CURRENT_DESKTOP",
"XIM",
"XDG_SESSION_TYPE",
"XDG_RUNTIME_DIR",
"CLUTTER_IM_MODULE",
"QT4_IM_MODULE",
"GTK_IM_MODULE",
"auto_proxy", // 网络系统代理自动代理
"http_proxy", // 网络系统代理手动http代理
"https_proxy", // 网络系统代理手动https代理
"ftp_proxy", // 网络系统代理手动ftp代理
"SOCKS_SERVER", // 网络系统代理手动socks代理
"no_proxy", // 网络系统代理手动配置代理
"USER", // wine应用会读取此环境变量
"QT_IM_MODULE", // 输入法
"LINGLONG_ROOT", // 玲珑安装位置
"WAYLAND_DISPLAY", // 导入wayland相关环境变量
"QT_QPA_PLATFORM",
"QT_WAYLAND_SHELL_INTEGRATION",
"GDMSESSION",
"QT_WAYLAND_FORCE_DPI",
"GIO_LAUNCHED_DESKTOP_FILE", // 系统监视器
"GNOME_DESKTOP_SESSION_ID", // gnome 桌面标识有些应用会读取此变量以使用gsettings配置,
// 如chrome
"TERM",
"DSG_APP_ID" // DSG 配置文件环境变量
};
auto onlyApp = config.annotations->find("org.deepin.linglong.onlyApp");
if (onlyApp != config.annotations->end() && onlyApp->second == "true") {
// 如果是 onlyApp 模式,直接追加所有环境变量并返回
for (char **envp = environ; *envp != nullptr; envp++) {
env.emplace_back(*envp);
}
} else {
// get the environment variables of current process
for (const auto &filter : envList) {
auto *host = ::getenv(filter.data());
if (host != nullptr) {
env.emplace_back(std::string{ filter } + "=" + host);
}
}
}
process.env = std::move(env);
config.process = std::move(process);
return true;
}
} // namespace linglong::generator

View File

@ -1,16 +0,0 @@
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
#pragma once
#include "linglong/oci-cfg-generators/generator.h"
namespace linglong::generator {
struct HostEnv : public Generator
{
[[nodiscard]] std::string_view name() const override { return "25-host-env"; }
bool generate(ocppi::runtime::config::types::Config &config) const noexcept override;
};
} // namespace linglong::generator

View File

@ -1,51 +0,0 @@
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
#include "25_host_rootfs.h"
#include "ocppi/runtime/config/types/Generators.hpp"
#include <iostream>
namespace linglong::generator {
bool HostRootfs::generate(ocppi::runtime::config::types::Config &config) const noexcept
{
nlohmann::json rawPatch;
try {
rawPatch = nlohmann::json::parse(hostRootfsPatch);
} catch (const std::exception &e) {
std::cerr << "parse basicsPatch failed:" << e.what() << std::endl;
return false;
}
if (config.ociVersion != rawPatch["ociVersion"].get<std::string>()) {
std::cerr << "ociVersion mismatched" << std::endl;
return false;
}
if (!config.annotations) {
std::cerr << "no annotations." << std::endl;
return false;
}
auto onlyApp = config.annotations->find("org.deepin.linglong.onlyApp");
if (onlyApp != config.annotations->end() && onlyApp->second == "true") {
return true;
}
try {
auto rawConfig = nlohmann::json(config);
rawConfig = rawConfig.patch(rawPatch["patch"]);
config = rawConfig.get<ocppi::runtime::config::types::Config>();
} catch (const std::exception &e) {
std::cerr << "patch basics failed:" << e.what() << std::endl;
return false;
}
return true;
}
} // namespace linglong::generator

View File

@ -1,21 +0,0 @@
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
#pragma once
#include "linglong/oci-cfg-generators/generator.h"
namespace linglong::generator {
struct HostRootfs : public Generator
{
[[nodiscard]] std::string_view name() const override { return "25-host-rootfs"; }
bool generate(ocppi::runtime::config::types::Config &config) const noexcept override;
private:
static constexpr std::string_view hostRootfsPatch{ R"(@LINGLONG_OCI_CFG_GEN_25_HOST_ROOTFS@)" };
};
} // namespace linglong::generator

View File

@ -1,50 +0,0 @@
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
#include "25_host_statics.h"
#include "ocppi/runtime/config/types/Generators.hpp"
#include <iostream>
namespace linglong::generator {
bool HostStatics::generate(ocppi::runtime::config::types::Config &config) const noexcept
{
nlohmann::json rawPatch;
try {
rawPatch = nlohmann::json::parse(hostStaticsPatch);
} catch (const std::exception &e) {
std::cerr << "parse basicsPatch failed:" << e.what() << std::endl;
return false;
}
if (config.ociVersion != rawPatch["ociVersion"].get<std::string>()) {
std::cerr << "ociVersion mismatched" << std::endl;
return false;
}
if (!config.annotations) {
std::cerr << "no annotations." << std::endl;
return false;
}
auto onlyApp = config.annotations->find("org.deepin.linglong.onlyApp");
if (onlyApp != config.annotations->end() && onlyApp->second == "true") {
return true;
}
try {
auto rawConfig = nlohmann::json(config);
rawConfig = rawConfig.patch(rawPatch["patch"]);
config = rawConfig.get<ocppi::runtime::config::types::Config>();
} catch (const std::exception &e) {
std::cerr << "patch basics failed:" << e.what() << std::endl;
return false;
}
return true;
}
} // namespace linglong::generator

View File

@ -1,23 +0,0 @@
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
#pragma once
#include "linglong/oci-cfg-generators/generator.h"
namespace linglong::generator {
struct HostStatics : public Generator
{
[[nodiscard]] std::string_view name() const override { return "25-host-statics"; }
bool generate(ocppi::runtime::config::types::Config &config) const noexcept override;
private:
static constexpr std::string_view hostStaticsPatch{
R"(@LINGLONG_OCI_CFG_GEN_25_HOST_STATICS@)"
};
};
} // namespace linglong::generator

View File

@ -1,360 +0,0 @@
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
#include "30_user_home.h"
#include "linglong/api/types/v1/Generators.hpp"
#include <linux/limits.h>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <pwd.h>
#include <unistd.h>
// TODO: resolve xdg-user-dir config
std::string resolveXDGDir(const std::string &dirType)
{
return dirType;
}
namespace linglong::generator {
bool UserHome::generate(ocppi::runtime::config::types::Config &config) const noexcept
{
if (::getenv("LINGLONG_SKIP_HOME_GENERATE") != nullptr) {
return true;
}
if (config.ociVersion != "1.0.1") {
std::cerr << "OCI version mismatched." << std::endl;
return false;
}
if (!config.annotations) {
std::cerr << "no annotations." << std::endl;
return false;
}
auto onlyApp = config.annotations->find("org.deepin.linglong.onlyApp");
if (onlyApp != config.annotations->end() && onlyApp->second == "true") {
return true;
}
auto appID = config.annotations->find("org.deepin.linglong.appID");
if (appID == config.annotations->end()) {
std::cerr << "appID not found." << std::endl;
return false;
}
if (appID->second.empty()) {
std::cerr << "appID is empty." << std::endl;
return false;
}
auto mounts = config.mounts.value_or(std::vector<ocppi::runtime::config::types::Mount>{});
auto process = config.process.value_or(ocppi::runtime::config::types::Process{});
auto env = process.env.value_or(std::vector<std::string>{});
auto *homeEnv = ::getenv("HOME");
auto *userNameEnv = ::getenv("USER");
if (homeEnv == nullptr || userNameEnv == nullptr) {
std::cerr << "Couldn't get HOME or USER from env." << std::endl;
return false;
}
auto hostHomeDir = std::filesystem::path(homeEnv);
auto cognitiveHomeDir = std::filesystem::path{ "/home" } / userNameEnv;
if (!std::filesystem::exists(hostHomeDir)) {
std::cerr << "Home " << hostHomeDir << "doesn't exists." << std::endl;
return false;
}
mounts.push_back(ocppi::runtime::config::types::Mount{
.destination = "/home",
.options = string_list{ "nodev", "nosuid", "mode=700" },
.source = "tmpfs",
.type = "tmpfs",
});
auto envExist = [&env](const std::string &key) {
auto prefix = key + "=";
auto it = std::find_if(env.cbegin(), env.cend(), [&prefix](const std::string &item) {
return (item.rfind(prefix, 0) == 0);
});
return it != env.cend();
};
auto mountDir = [&mounts](const std::string &hostDir, const std::string &containerDir) {
std::error_code ec;
if (!std::filesystem::exists(hostDir, ec)) {
if (ec) {
std::cerr << "failed to get state of directories " << hostDir << ":" << ec.message()
<< std::endl;
return false;
}
if (!std::filesystem::create_directories(hostDir, ec) && ec) {
std::cerr << "failed to create directories " << hostDir << ":" << ec.message()
<< std::endl;
return false;
}
}
mounts.push_back(ocppi::runtime::config::types::Mount{
.destination = containerDir,
.options = string_list{ "rbind" },
.source = hostDir,
.type = "bind",
});
return true;
};
if (!mountDir(hostHomeDir, cognitiveHomeDir)) {
return false;
}
if (envExist("HOME")) {
std::cerr << "HOME already exist." << std::endl;
return false;
}
env.emplace_back("HOME=" + cognitiveHomeDir.string());
// process XDG_* environment variables.
std::error_code ec;
auto privateAppDir = hostHomeDir / ".linglong" / appID->second;
if (!std::filesystem::create_directories(privateAppDir, ec) && ec) {
std::cerr << "failed to create " << privateAppDir << ": " << ec.message() << std::endl;
return false;
}
// XDG_DATA_HOME
auto *ptr = ::getenv("XDG_DATA_HOME");
std::filesystem::path XDGDataHome = ptr == nullptr ? "" : std::string{ ptr };
if (XDGDataHome.empty()) {
XDGDataHome = hostHomeDir / ".local" / "share";
}
std::filesystem::path cognitiveDataHome = cognitiveHomeDir / ".local" / "share";
if (!mountDir(XDGDataHome, cognitiveDataHome)) {
return false;
}
if (envExist("XDG_DATA_HOME")) {
std::cerr << "XDG_DATA_HOME already exist." << std::endl;
return false;
}
env.emplace_back("XDG_DATA_HOME=" + cognitiveDataHome.string());
// XDG_CONFIG_HOME
ptr = ::getenv("XDG_CONFIG_HOME");
std::filesystem::path XDGConfigHome = ptr == nullptr ? "" : std::string{ ptr };
if (XDGConfigHome.empty()) {
XDGConfigHome = hostHomeDir / ".config";
}
if (auto privateConfigDir = privateAppDir / "config";
std::filesystem::exists(privateConfigDir, ec)) {
XDGConfigHome = privateConfigDir;
}
ec.clear();
auto cognitiveConfigHome = cognitiveHomeDir / ".config";
if (!mountDir(XDGConfigHome, cognitiveConfigHome)) {
return false;
}
if (envExist("XDG_CONFIG_HOME")) {
std::cerr << "XDG_CONFIG_HOME already exist." << std::endl;
return false;
}
env.emplace_back("XDG_CONFIG_HOME=" + cognitiveConfigHome.string());
// XDG_CACHE_HOME
ptr = ::getenv("XDG_CACHE_HOME");
std::filesystem::path XDGCacheHome = ptr == nullptr ? "" : std::string{ ptr };
if (XDGCacheHome.empty()) {
XDGCacheHome = hostHomeDir / ".cache";
}
if (auto privateCacheDir = privateAppDir / "cache";
std::filesystem::exists(privateCacheDir, ec)) {
XDGCacheHome = privateCacheDir;
}
ec.clear();
auto cognitiveCacheHome = cognitiveHomeDir / ".cache";
if (!mountDir(XDGCacheHome, cognitiveCacheHome)) {
return false;
}
if (envExist("XDG_CACHE_HOME")) {
std::cerr << "XDG_CACHE_HOME already exist." << std::endl;
return false;
}
env.emplace_back("XDG_CACHE_HOME=" + cognitiveCacheHome.string());
// XDG_STATE_HOME
ptr = ::getenv("XDG_STATE_HOME");
std::filesystem::path XDGStateHome = ptr == nullptr ? "" : std::string{ ptr };
if (XDGStateHome.empty()) {
XDGStateHome = hostHomeDir / ".local" / "state";
}
if (auto privateStateDir = privateAppDir / "config";
std::filesystem::exists(privateStateDir, ec)) {
XDGStateHome = privateStateDir;
}
ec.clear();
auto cognitiveStateHome = cognitiveHomeDir / ".local" / "state";
if (!mountDir(XDGStateHome, cognitiveStateHome)) {
return false;
}
if (envExist("XDG_STATE_HOME")) {
std::cerr << "XDG_STATE_HOME already exist." << std::endl;
return false;
}
env.emplace_back("XDG_STATE_HOME=" + cognitiveStateHome.string());
// systemd user path
auto hostSystemdUserDir = XDGConfigHome / "systemd" / "user";
if (std::filesystem::exists(hostSystemdUserDir, ec)) {
auto cognitiveSystemdUserDir = cognitiveConfigHome / "systemd" / "user";
if (!mountDir(hostSystemdUserDir, cognitiveSystemdUserDir)) {
return false;
}
}
// FIXME: Many applications get configurations from dconf, so we expose dconf to all
// applications for now. If there is a better solution to fix this issue, please change the
// following codes
auto hostUserDconfPath = XDGConfigHome / "dconf";
if (std::filesystem::exists(hostUserDconfPath, ec)) {
auto cognitiveAppDconfPath = cognitiveConfigHome / "dconf";
if (!mountDir(hostUserDconfPath, cognitiveAppDconfPath)) {
return false;
}
}
// for dde application theme
auto hostDDEApiPath = XDGCacheHome / "deepin" / "dde-api";
if (std::filesystem::exists(hostDDEApiPath, ec)) {
auto cognitiveDDEApiPath = cognitiveCacheHome / "deepin" / "dde-api";
if (!mountDir(hostDDEApiPath, cognitiveDDEApiPath)) {
return false;
}
}
// for xdg-user-dirs
auto XDGUserDirs = XDGConfigHome / "user-dirs.dirs";
if (std::filesystem::exists(XDGUserDirs, ec)) {
mounts.push_back(ocppi::runtime::config::types::Mount{
.destination = cognitiveConfigHome / "user-dirs.dirs",
.options = string_list{ "rbind" },
.source = XDGUserDirs,
.type = "bind",
});
}
auto XDGUserLocale = XDGConfigHome / "user-dirs.locale";
if (std::filesystem::exists(XDGUserLocale, ec)) {
mounts.push_back(ocppi::runtime::config::types::Mount{
.destination = cognitiveConfigHome / "user-dirs" / ".locale",
.options = string_list{ "rbind" },
.source = XDGUserLocale,
.type = "bind",
});
}
// NOTE:
// Running ~/.bashrc from user home is meaningless in linglong container,
// and might cause some issues, so we mask it with the default one.
// https://github.com/linuxdeepin/linglong/issues/459
constexpr auto defaultBashrc = "/etc/skel/.bashrc";
if (std::filesystem::exists(defaultBashrc)) {
mounts.push_back(ocppi::runtime::config::types::Mount{
.destination = hostHomeDir / ".bashrc",
.options = string_list{ "ro", "rbind" },
.source = defaultBashrc,
.type = "bind",
});
} else {
std::cerr << "failed to mask bashrc" << std::endl;
}
// hide self data
auto linglongMaskDataDir = hostHomeDir / ".linglong" / "data";
if (!mountDir(linglongMaskDataDir, cognitiveHomeDir / ".linglong")) {
return false;
}
linglong::api::types::v1::ApplicationConfigurationPermissions permissions;
auto configFile = privateAppDir / "permissions.json";
if (std::filesystem::exists(configFile, ec)) {
auto input = std::ifstream(configFile);
if (!input.is_open()) {
std::cerr << "couldn't open config file " << configFile.c_str() << std::endl;
return false;
}
try {
auto content = nlohmann::json::parse(input);
permissions =
content.get<linglong::api::types::v1::ApplicationConfigurationPermissions>();
} catch (nlohmann::json::parse_error &e) {
std::cerr << "deserialize error:" << e.what() << std::endl;
return false;
} catch (std::exception &e) {
std::cerr << "unknown exception:" << e.what() << std::endl;
return false;
}
}
if (ec) {
std::cerr << "failed to get status of " << configFile.c_str() << ": " << ec.message()
<< std::endl;
return false;
}
auto directories = permissions.xdgDirectories.value_or(
std::vector<linglong::api::types::v1::XdgDirectoryPermission>{});
// FIXME: we should resolve real home through env GNUPGHOME
// FIXME: we should resolve user dirs through ${XDG_CONFIG_HOME}/user-dirs.dirs
std::vector<std::string> blacklist = { ".gnupg", ".ssh" };
for (const auto &[allowed, dirType] : directories) {
if (!allowed) {
blacklist.push_back(resolveXDGDir(dirType));
}
}
auto it =
std::remove_if(blacklist.begin(), blacklist.end(), [&hostHomeDir](const std::string &dir) {
std::error_code ec;
auto ret = !std::filesystem::exists(hostHomeDir / dir, ec);
if (ec) {
std::cerr << "failed to get state of " << hostHomeDir / dir << ": " << ec.message()
<< std::endl;
}
return ret;
});
if (it != blacklist.end()) {
blacklist.erase(it);
}
for (const auto &relative : blacklist) {
if (!mountDir(privateAppDir / relative, cognitiveHomeDir / relative)) {
return false;
}
}
process.env = std::move(env);
config.process = std::move(process);
config.mounts = std::move(mounts);
return true;
}
} // namespace linglong::generator

View File

@ -1,18 +0,0 @@
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
#pragma once
#include "linglong/oci-cfg-generators/generator.h"
namespace linglong::generator {
struct UserHome : public Generator
{
[[nodiscard]] std::string_view name() const override { return "30-user-home"; }
bool generate(ocppi::runtime::config::types::Config &config) const noexcept override;
};
} // namespace linglong::generator

View File

@ -1,383 +0,0 @@
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
#include "40_host_ipc.h"
#include <linux/limits.h>
#include <cstdlib>
#include <filesystem>
#include <iostream>
#include <string>
#include <sys/stat.h>
#include <unistd.h>
namespace linglong::generator {
bool HostIPC::generate(ocppi::runtime::config::types::Config &config) const noexcept
{
if (config.ociVersion != "1.0.1") {
std::cerr << "OCI version mismatched." << std::endl;
return false;
}
if (!config.annotations) {
std::cerr << "no annotations." << std::endl;
return false;
}
auto onlyApp = config.annotations->find("org.deepin.linglong.onlyApp");
if (onlyApp != config.annotations->end() && onlyApp->second == "true") {
return true;
}
auto it = config.annotations->find("org.deepin.linglong.bundleDir");
if (it == config.annotations->end()) {
std::cerr << "bundleDir not found." << std::endl;
return false;
}
if (it->second.empty()) {
std::cerr << "appID is empty." << std::endl;
return false;
}
auto bundleDir = std::filesystem::path{ it->second };
auto mounts = config.mounts.value_or(std::vector<ocppi::runtime::config::types::Mount>{});
auto process = config.process.value_or(ocppi::runtime::config::types::Process{});
auto env = process.env.value_or(std::vector<std::string>{});
auto bindIfExist = [&mounts](std::string_view source, std::string_view destination) mutable {
std::error_code ec;
if (!std::filesystem::exists(source, ec)) {
if (ec) {
std::cerr << "Failed to check existence of " << source << ": " << ec.message()
<< std::endl;
return;
}
return;
}
auto realDest = destination.empty() ? source : destination;
mounts.push_back(ocppi::runtime::config::types::Mount{
.destination = std::string{ realDest },
.options = string_list{ "rbind" },
.source = std::string{ source },
.type = "bind",
});
};
bindIfExist("/tmp/.X11-unix", "");
auto mountTemplate =
ocppi::runtime::config::types::Mount{ .options = string_list{ "rbind" }, .type = "bind" };
// TODO 应该参考规范文档实现更完善的地址解析支持
// https://dbus.freedesktop.org/doc/dbus-specification.html#addresses
[dbusMount = mountTemplate, &mounts, &env]() mutable {
// default value from
// https://dbus.freedesktop.org/doc/dbus-specification.html#message-bus-types-system
std::string systemBusEnv = "unix:path=/var/run/dbus/system_bus_socket";
if (auto cStr = std::getenv("DBUS_SYSTEM_BUS_ADDRESS"); cStr != nullptr) {
systemBusEnv = cStr;
}
// address 可能是 unix:path=/xxxx,giud=xxx 这种格式
// 所以先将options部分提取出来挂载时不需要关心
std::string options;
auto optionsPos = systemBusEnv.find(",");
if (optionsPos != std::string::npos) {
options = systemBusEnv.substr(optionsPos);
systemBusEnv.resize(optionsPos);
}
auto systemBus = std::string_view{ systemBusEnv };
auto suffix = std::string_view{ "unix:path=" };
if (systemBus.rfind(suffix, 0) != 0U) {
std::cerr << "Unexpected DBUS_SYSTEM_BUS_ADDRESS=" << systemBus << std::endl;
return;
}
auto socketPath = std::filesystem::path(systemBus.substr(suffix.size()));
std::error_code ec;
if (!std::filesystem::exists(socketPath, ec)) {
if (ec) {
std::cerr << "Failed to check existence of " << socketPath << ": " << ec.message()
<< std::endl;
return;
}
std::cerr << "D-Bus session bus socket not found at " << socketPath << std::endl;
return;
}
dbusMount.destination = "/run/dbus/system_bus_socket";
dbusMount.source = std::move(socketPath);
mounts.emplace_back(std::move(dbusMount));
// 将提取的options再拼到容器中的环境变量
env.emplace_back("DBUS_SYSTEM_BUS_ADDRESS=unix:path=/run/dbus/system_bus_socket" + options);
}();
mounts.push_back(ocppi::runtime::config::types::Mount{
.destination = "/run/user",
.options = string_list{ "nodev", "nosuid", "mode=700" },
.source = "tmpfs",
.type = "tmpfs",
});
[XDGMount = mountTemplate, &mounts, &env, &bindIfExist]() {
auto *XDGRuntimeDirEnv = getenv("XDG_RUNTIME_DIR"); // NOLINT
if (XDGRuntimeDirEnv == nullptr) {
return;
}
auto hostXDGRuntimeDir = std::filesystem::path{ XDGRuntimeDirEnv };
auto status = std::filesystem::status(hostXDGRuntimeDir);
using perm = std::filesystem::perms;
if (status.permissions() != perm::owner_all) {
std::cerr << "The Unix permission of " << hostXDGRuntimeDir << "must be 0700."
<< std::endl;
return;
}
struct stat64 buf{};
if (::stat64(hostXDGRuntimeDir.string().c_str(), &buf) != 0) {
std::cerr << "Failed to get state of " << hostXDGRuntimeDir << ": " << ::strerror(errno)
<< std::endl;
return;
}
if (buf.st_uid != ::getuid()) {
std::cerr << hostXDGRuntimeDir << " doesn't belong to current user.";
return;
}
auto cognitiveXDGRuntimeDir =
std::filesystem::path{ "/run/user" } / std::to_string(::getuid());
// tmpfs
mounts.push_back(ocppi::runtime::config::types::Mount{
.destination = cognitiveXDGRuntimeDir,
.options = string_list{ "nodev", "nosuid", "mode=700" },
.source = "tmpfs",
.type = "tmpfs",
});
env.emplace_back(std::string{ "XDG_RUNTIME_DIR=" } + cognitiveXDGRuntimeDir.string());
bindIfExist((hostXDGRuntimeDir / "pulse").string(),
(cognitiveXDGRuntimeDir / "pulse").string());
bindIfExist((hostXDGRuntimeDir / "gvfs").string(),
(cognitiveXDGRuntimeDir / "gvfs").string());
[&hostXDGRuntimeDir, &cognitiveXDGRuntimeDir, &mounts]() {
auto *waylandDisplayEnv = getenv("WAYLAND_DISPLAY"); // NOLINT
if (waylandDisplayEnv == nullptr) {
std::cerr << "Couldn't get WAYLAND_DISPLAY." << std::endl;
return;
}
auto socketPath = std::filesystem::path(hostXDGRuntimeDir) / waylandDisplayEnv;
std::error_code ec;
if (!std::filesystem::exists(socketPath, ec)) {
if (ec) {
std::cerr << "Failed to check existence of " << socketPath << ": "
<< ec.message() << std::endl;
return;
}
std::cerr << "Wayland display socket not found at " << socketPath << "."
<< std::endl;
return;
}
mounts.emplace_back(ocppi::runtime::config::types::Mount{
.destination = cognitiveXDGRuntimeDir / waylandDisplayEnv,
.options = string_list{ "rbind" },
.source = socketPath,
.type = "bind",
});
}();
// TODO 应该参考规范文档实现更完善的地址解析支持
// https://dbus.freedesktop.org/doc/dbus-specification.html#addresses
[&cognitiveXDGRuntimeDir, &mounts, &env]() {
std::string sessionBusEnv;
if (auto cStr = std::getenv("DBUS_SESSION_BUS_ADDRESS"); cStr != nullptr) {
sessionBusEnv = cStr;
}
if (sessionBusEnv.empty()) {
std::cerr << "Couldn't get DBUS_SESSION_BUS_ADDRESS" << std::endl;
return;
}
// address 可能是 unix:path=/xxxx,giud=xxx 这种格式
// 所以先将options部分提取出来挂载时不需要关心
std::string options;
auto optionsPos = sessionBusEnv.find(",");
if (optionsPos != std::string::npos) {
options = sessionBusEnv.substr(optionsPos);
sessionBusEnv.resize(optionsPos);
}
auto sessionBus = std::string_view{ sessionBusEnv };
auto suffix = std::string_view{ "unix:path=" };
if (sessionBus.rfind(suffix, 0) != 0U) {
std::cerr << "Unexpected DBUS_SESSION_BUS_ADDRESS=" << sessionBus << std::endl;
return;
}
auto socketPath = std::filesystem::path(sessionBus.substr(suffix.size()));
if (!std::filesystem::exists(socketPath)) {
std::cerr << "D-Bus session bus socket not found at " << socketPath << std::endl;
return;
}
auto cognitiveSessionBus = cognitiveXDGRuntimeDir / "bus";
mounts.emplace_back(ocppi::runtime::config::types::Mount{
.destination = cognitiveSessionBus,
.options = string_list{ "rbind" },
.source = socketPath,
.type = "bind",
});
// 将提取的options再拼到容器中的环境变量
env.emplace_back(std::string{ "DBUS_SESSION_BUS_ADDRESS=" }
+ "unix:path=" + cognitiveSessionBus.string() + options);
}();
[&hostXDGRuntimeDir, &cognitiveXDGRuntimeDir, &mounts]() {
auto dconfPath = std::filesystem::path(hostXDGRuntimeDir) / "dconf";
if (!std::filesystem::exists(dconfPath)) {
std::cerr << "dconf directory not found at " << dconfPath << "." << std::endl;
return;
}
mounts.emplace_back(ocppi::runtime::config::types::Mount{
.destination = cognitiveXDGRuntimeDir / "dconf",
.options = string_list{ "rbind" },
.source = dconfPath.string(),
.type = "bind",
});
}();
}
();
[xauthPatch = mountTemplate, &mounts, &env]() mutable {
if (::getenv("LINGLONG_SKIP_HOME_GENERATE") != nullptr) {
return;
}
auto *homeEnv = ::getenv("HOME"); // NOLINT
if (homeEnv == nullptr) {
std::cerr << "Couldn't get HOME from env." << std::endl;
return;
}
auto *userEnv = ::getenv("USER");
if (userEnv == nullptr) {
std::cerr << "Couldn't get USER from env." << std::endl;
return;
}
auto hostXauthFile = std::string{ homeEnv } + "/.Xauthority";
auto cognitiveXauthFile = std::string{ "/home/" } + userEnv + "/.Xauthority";
auto *xauthFileEnv = ::getenv("XAUTHORITY"); // NOLINT
std::error_code ec;
if (xauthFileEnv != nullptr && std::filesystem::exists(xauthFileEnv, ec)) {
hostXauthFile = xauthFileEnv;
}
if (!std::filesystem::exists(hostXauthFile, ec) && ec) {
std::cerr << "XAUTHORITY file not found at " << hostXauthFile << ":" << ec.message()
<< std::endl;
return;
}
env.emplace_back("XAUTHORITY=" + cognitiveXauthFile);
xauthPatch.destination = std::move(cognitiveXauthFile);
xauthPatch.source = hostXauthFile;
mounts.emplace_back(std::move(xauthPatch));
}();
// 在容器中把易变的文件挂载成软链接,指向/run/host/rootfs实现实时响应
std::array<std::filesystem::path, 3> vec{
"/etc/localtime",
"/etc/resolv.conf",
"/etc/timezone",
};
std::error_code ec;
for (const auto &destination : vec) {
auto target = destination;
auto name = target.filename();
if (!std::filesystem::exists(target, ec)) {
if (ec) {
std::cerr << "Failed to check existence of " << target << ": " << ec.message()
<< std::endl;
return false;
}
continue;
}
auto status = std::filesystem::symlink_status(target, ec);
if (ec) {
std::cerr << "Failed to get status of " << target << ": " << ec.message() << std::endl;
return false;
}
if (status.type() == std::filesystem::file_type::symlink) {
std::array<char, PATH_MAX + 1> buf{};
auto *rpath = ::realpath(target.c_str(), buf.data());
if (rpath == nullptr) {
std::cerr << "Failed to get realpath of " << target << ": " << ::strerror(errno)
<< std::endl;
return false;
}
target.assign(rpath);
}
auto linkfile = bundleDir / name;
target = "/run/host/rootfs" / target.lexically_relative("/");
std::filesystem::create_symlink(target, linkfile, ec);
if (ec) {
std::cerr << "Failed to create symlink from " << target << " to " << linkfile << ": "
<< ec.message() << std::endl;
continue;
};
mounts.push_back(ocppi::runtime::config::types::Mount{
.destination = std::string{ destination },
.options = string_list{ "rbind", "ro", "copy-symlink" },
.source = linkfile,
.type = "bind",
});
}
// process ld.so.cache
auto ldLink = bundleDir / "ld.so.cache";
std::filesystem::create_symlink("/run/linglong/cache/ld.so.cache", ldLink, ec);
if (ec) {
std::cerr << "Failed to create symlink from " << "/run/linglong/cache/ld.so.cache" << " to "
<< ldLink << ": " << ec.message() << std::endl;
return false;
}
mounts.push_back(ocppi::runtime::config::types::Mount{
.destination = "/etc/ld.so.cache",
.options = string_list{ "rbind", "ro", "copy-symlink" },
.source = ldLink,
.type = "bind",
});
process.env = std::move(env);
config.process = std::move(process);
config.mounts = std::move(mounts);
return true;
}
} // namespace linglong::generator

View File

@ -1,16 +0,0 @@
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
#pragma once
#include "linglong/oci-cfg-generators/generator.h"
namespace linglong::generator {
struct HostIPC : public Generator
{
[[nodiscard]] std::string_view name() const override { return "40-host-ipc"; }
bool generate(ocppi::runtime::config::types::Config &config) const noexcept override;
};
} // namespace linglong::generator

View File

@ -1,17 +0,0 @@
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
#pragma once
#include "linglong/oci-cfg-generators/generator.h"
namespace linglong::generator {
class Legacy : public Generator
{
public:
[[nodiscard]] std::string_view name() const override { return "90-legacy"; }
bool generate(ocppi::runtime::config::types::Config &config) const noexcept override;
};
} // namespace linglong::generator

View File

@ -1,65 +0,0 @@
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
#pragma once
#include "linglong/oci-cfg-generators/00_id_mapping.h"
#include "linglong/oci-cfg-generators/05_initialize.h"
#include "linglong/oci-cfg-generators/10_basics.h"
#include "linglong/oci-cfg-generators/20_devices.h"
#include "linglong/oci-cfg-generators/25_host_env.h"
#include "linglong/oci-cfg-generators/25_host_rootfs.h"
#include "linglong/oci-cfg-generators/25_host_statics.h"
#include "linglong/oci-cfg-generators/30_user_home.h"
#include "linglong/oci-cfg-generators/40_host_ipc.h"
#include "linglong/oci-cfg-generators/90_legacy.h"
namespace linglong::generator {
using generators = std::map<std::string_view, std::unique_ptr<linglong::generator::Generator>>;
constexpr auto initConfig = R"(@LINGLONG_OCI_CFG_GEN_CONFIG@)";
inline const generators &builtin_generators() noexcept
{
static std::unique_ptr<generators> gens;
if (gens) {
return *gens;
}
gens = std::make_unique<generators>();
auto *id = new IDMapping{};
gens->emplace(id->name(), id);
auto *init = new Initialize{};
gens->emplace(init->name(), init);
auto *basics = new Basics{};
gens->emplace(basics->name(), basics);
auto *dev = new Devices{};
gens->emplace(dev->name(), dev);
auto *env = new HostEnv{};
gens->emplace(env->name(), env);
auto *rootfs = new HostRootfs{};
gens->emplace(rootfs->name(), rootfs);
auto *statics = new HostStatics{};
gens->emplace(statics->name(), statics);
auto *home = new UserHome{};
gens->emplace(home->name(), home);
auto *ipc = new HostIPC{};
gens->emplace(ipc->name(), ipc);
auto *legacy = new Legacy{};
gens->emplace(legacy->name(), legacy);
return *gens;
}
} // namespace linglong::generator

View File

@ -1,21 +0,0 @@
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
#pragma once
#include "ocppi/runtime/config/types/Config.hpp"
namespace linglong::generator {
using string_list = std::vector<std::string>;
struct Generator
{
Generator() = default;
virtual ~Generator() = default;
virtual bool generate(ocppi::runtime::config::types::Config &config) const noexcept = 0;
[[nodiscard]] virtual std::string_view name() const = 0;
};
} // namespace linglong::generator