fix: uab support

* Bring back bundle support
  * Check reader ptr before use it as when working in uab mode, ll-box
    might not have reader at all.
  * More config.json generate handling code.
  * Install ll-box-static to /usr/libexec

Change-Id: Iafc2f5a684cecbce2aeb8aed90f1eed451c165f2
This commit is contained in:
chenlinxuan 2022-07-21 09:51:11 +08:00 committed by Chen Linxuan
parent f47eb4ae85
commit 3e83ef0491
6 changed files with 654 additions and 46 deletions

View File

@ -8,7 +8,7 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(VERSION "1.0")
option(BUILD_STATIC "Build the static binary" OFF)
option(BUILD_STATIC "Build the static binary" ON)
# configure debug mode and asan
if (NOT CMAKE_BUILD_TYPE)

View File

@ -26,6 +26,7 @@ target_link_libraries(ll-box ${LINK_LIBS})
if (BUILD_STATIC)
add_executable(ll-box-static ${LL_BOX_SOURCES})
target_link_libraries(ll-box-static -static ${LINK_LIBS})
install(TARGETS ll-box-static RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/libexec)
endif (BUILD_STATIC)
install(TARGETS ll-box RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})

View File

@ -370,7 +370,8 @@ public:
auto epfd = epoll_create(1);
epoll_ctl_add(epfd, sfd);
epoll_ctl_add(epfd, reader->fd);
if (reader.get() != nullptr)
epoll_ctl_add(epfd, reader->fd);
for (;;) {
struct epoll_event events[10];
@ -399,7 +400,8 @@ public:
}
auto it = pidMap.find(child);
if (it != pidMap.end()) {
reader->writeChildExit(child, it->second, wstatus, info);
if (reader.get() != nullptr)
reader->writeChildExit(child, it->second, wstatus, info);
pidMap.erase(it);
}
} else if (child < 0) {
@ -420,7 +422,7 @@ public:
} else {
logWan() << util::format("Read unexpected signal [%d]\n", fdsi.ssi_signo);
}
} else if (event.data.fd == reader->fd) {
} else if (reader.get() != nullptr && event.data.fd == reader->fd) {
auto json = reader->read();
if (json.empty()) {
break;
@ -598,7 +600,8 @@ public:
return PrepareOverlayfsRootfs(r.annotations->overlayfs.value());
}
} else {
return PrepareNativeRootfs(r.annotations->native.value());
return PrepareNativeRootfs(r.annotations->native.has_value() ? r.annotations->native.value()
: AnnotationsNativeRootfs());
}
return -1;

View File

@ -7,40 +7,566 @@
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include <wordexp.h>
#include <regex>
#include <list>
#include <sys/stat.h>
#include "util/logger.h"
#include "util/oci_runtime.h"
#include "container/container_option.h"
// "lowerParent": "/run/user/<<user_uid>>/linglong/375f5681145f4f4f9ffeb3a67aebd422/.overlayfs/lower_parent",
// "upper": "/run/user/<<user_uid>>/linglong/375f5681145f4f4f9ffeb3a67aebd422/.overlayfs/upper",
// "workdir": "/run/user/<<user_uid>>/linglong/375f5681145f4f4f9ffeb3a67aebd422/.overlayfs/workdir",
const std::string kLoadTemplate = R"KLT00(
{
"annotations": {
"containerRootPath": "",
"native": {
"mounts": [
{
"destination": "/usr",
"options": [
"ro",
"rbind"
],
"source": "/usr",
"type": "bind"
},
{
"destination": "/etc",
"options": [
"ro",
"rbind"
],
"source": "/etc",
"type": "bind"
},
{
"destination": "/usr/share/locale/",
"options": [
"ro",
"rbind"
],
"source": "/usr/share/locale/",
"type": "bind"
}
]
}
},
"hooks": null,
"hostname": "linglong",
"linux": {
"gidMappings": [{
"containerID": 0,
"hostID": 1000,
"hostID": <<user_uid>>,
"size": 1
}],
"uidMappings": [{
"containerID": 0,
"hostID": 1000,
"hostID": <<user_uid>>,
"size": 1
}],
"namespaces": [{
"type": "mount"
},
{
"type": "pid"
}
"namespaces": [
{
"type": "pid"
},
{
"type": "mount"
},
{
"type": "uts"
},
{
"type": "user"
}
]
},
"mounts": [{
"destination": "/proc",
"options": [],
"source": "proc",
"type": "proc"
}],
"mounts": [
{
"destination": "/sys",
"options": [
"nosuid",
"noexec",
"nodev"
],
"source": "sysfs",
"type": "sysfs"
},
{
"destination": "/proc",
"options": [],
"source": "proc",
"type": "proc"
},
{
"destination": "/dev",
"options": [
"nosuid",
"strictatime",
"mode=0755",
"size=65536k"
],
"source": "tmpfs",
"type": "tmpfs"
},
{
"destination": "/dev/pts",
"options": [
"nosuid",
"noexec",
"newinstance",
"ptmxmode=0666",
"mode=0620"
],
"source": "devpts",
"type": "devpts"
},
{
"destination": "/dev/shm",
"options": [
"nosuid",
"noexec",
"nodev",
"mode=1777"
],
"source": "shm",
"type": "tmpfs"
},
{
"destination": "/dev/mqueue",
"options": [
"nosuid",
"noexec",
"nodev"
],
"source": "mqueue",
"type": "mqueue"
},
{
"destination": "/sys/fs/cgroup",
"options": [
"nosuid",
"noexec",
"nodev",
"relatime",
"ro"
],
"source": "cgroup",
"type": "cgroup"
},
{
"destination": "/dev/dri",
"options": [
"rbind"
],
"source": "/dev/dri",
"type": "bind"
},
{
"destination": "/dev/snd",
"options": [
"rbind"
],
"source": "/dev/snd",
"type": "bind"
},
{
"destination": "/run/user/<<user_uid>>",
"options": [
"nodev",
"nosuid",
"mode=700"
],
"source": "tmpfs",
"type": "tmpfs"
},
{
"destination": "/run/user/<<user_uid>>/pulse",
"options": [
"rbind"
],
"source": "/run/user/<<user_uid>>/pulse",
"type": "bind"
},
{
"destination": "/run/udev",
"options": [
"rbind"
],
"source": "/run/udev",
"type": "bind"
},
{
"destination": "<<home_dir>>",
"options": [
"rbind"
],
"source": "<<home_dir>>/.linglong/<<appid>>/home",
"type": "bind"
},
{
"destination": "<<home_dir>>/.linglong/<<appid>>",
"options": [
"rbind"
],
"source": "<<home_dir>>/.linglong/<<appid>>",
"type": "bind"
},
{
"destination": "<<home_dir>>/.local/share",
"options": [
"rbind"
],
"source": "<<home_dir>>/.linglong/<<appid>>/share",
"type": "bind"
},
{
"destination": "<<home_dir>>/.config",
"options": [
"rbind"
],
"source": "<<home_dir>>/.linglong/<<appid>>/config",
"type": "bind"
},
{
"destination": "<<home_dir>>/.cache",
"options": [
"rbind"
],
"source": "<<home_dir>>/.linglong/<<appid>>/cache",
"type": "bind"
},
{
"destination": "<<home_dir>>/.deepinwine",
"options": [
"rbind"
],
"source": "<<home_dir>>/.deepinwine",
"type": "bind"
},
{
"destination": "/run/user/<<user_uid>>/dconf",
"options": [
"rbind"
],
"source": "/run/user/<<user_uid>>/dconf",
"type": "bind"
},
{
"destination": "<<home_dir>>/.linglong/<<appid>>/config/systemd/user",
"options": [
"rbind"
],
"source": "<<home_dir>>/.config/systemd/user",
"type": "bind"
},
{
"destination": "<<home_dir>>/.config/user-dirs.dirs",
"options": [
"rbind"
],
"source": "<<home_dir>>/.config/user-dirs.dirs",
"type": "bind"
},
{
"destination": "<<home_dir>>/.linglong/<<appid>>/config/user-dirs.dirs",
"options": [
"rbind"
],
"source": "<<home_dir>>/.config/user-dirs.dirs",
"type": "bind"
},
{
"destination": "<<home_dir>>/.linglong/<<appid>>/share/fonts",
"options": [
"ro",
"rbind"
],
"source": "<<home_dir>>/.local/share/fonts",
"type": "bind"
},
{
"destination": "<<home_dir>>/.linglong/<<appid>>/config/fontconfig",
"options": [
"ro",
"rbind"
],
"source": "<<home_dir>>/.config/fontconfig",
"type": "bind"
},
{
"destination": "/run/host/appearance/user-fonts",
"options": [
"ro",
"rbind"
],
"source": "<<home_dir>>/.local/share/fonts",
"type": "bind"
},
{
"destination": "/run/host/appearance/user-fonts-cache",
"options": [
"ro",
"rbind"
],
"source": "<<home_dir>>/.cache/fontconfig",
"type": "bind"
},
{
"destination": "<<home_dir>>/.cache/deepin/dde-api",
"options": [
"ro",
"rbind"
],
"source": "<<home_dir>>/.cache/deepin/dde-api",
"type": "bind"
},
{
"destination": "<<home_dir>>/.linglong/<<appid>>/cache/deepin/dde-api",
"options": [
"ro",
"rbind"
],
"source": "<<home_dir>>/.cache/deepin/dde-api",
"type": "bind"
},
{
"destination": "<<home_dir>>/.linglong/<<appid>>/config/dconf",
"options": [
"ro",
"rbind"
],
"source": "<<home_dir>>/.config/dconf",
"type": "bind"
},
{
"destination": "<<home_dir>>/.Xauthority",
"options": [
"ro",
"rbind"
],
"source": "<<home_dir>>/.Xauthority",
"type": "bind"
},
{
"destination": "/tmp",
"options": [
"rbind"
],
"source": "/tmp/linglong/573992118ad045e1a42bb03af87f7984",
"type": "bind"
},
{
"destination": "/run/host/network/etc/resolv.conf",
"options": [
"ro",
"rbind"
],
"source": "/etc/resolv.conf",
"type": "bind"
},
{
"destination": "/run/resolvconf",
"options": [
"ro",
"rbind"
],
"source": "/run/resolvconf",
"type": "bind"
},
{
"destination": "/run/host/appearance/fonts",
"options": [
"ro",
"rbind"
],
"source": "/usr/share/fonts",
"type": "bind"
},
{
"destination": "/usr/lib/locale/",
"options": [
"ro",
"rbind"
],
"source": "/usr/lib/locale/",
"type": "bind"
},
{
"destination": "/usr/share/themes",
"options": [
"ro",
"rbind"
],
"source": "/usr/share/themes",
"type": "bind"
},
{
"destination": "/usr/share/icons",
"options": [
"ro",
"rbind"
],
"source": "/usr/share/icons",
"type": "bind"
},
{
"destination": "/usr/share/zoneinfo",
"options": [
"ro",
"rbind"
],
"source": "/usr/share/zoneinfo",
"type": "bind"
},
{
"destination": "/run/host/etc/localtime",
"options": [
"ro",
"rbind"
],
"source": "/etc/localtime",
"type": "bind"
},
{
"destination": "/run/host/etc/machine-id",
"options": [
"ro",
"rbind"
],
"source": "/etc/machine-id",
"type": "bind"
},
{
"destination": "/etc/machine-id",
"options": [
"ro",
"rbind"
],
"source": "/etc/machine-id",
"type": "bind"
},
{
"destination": "/var",
"options": [
"ro",
"rbind"
],
"source": "/var",
"type": "bind"
},
{
"destination": "/run/host/appearance/fonts-cache",
"options": [
"ro",
"rbind"
],
"source": "/var/cache/fontconfig",
"type": "bind"
},
{
"destination": "/tmp/.X11-unix",
"options": [
"rbind"
],
"source": "/tmp/.X11-unix",
"type": "bind"
},
{
"destination": "<<home_dir>>/Desktop",
"options": [
"rw",
"rbind"
],
"source": "<<home_dir>>/Desktop",
"type": "bind"
},
{
"destination": "<<home_dir>>/Documents",
"options": [
"rw",
"rbind"
],
"source": "<<home_dir>>/Documents",
"type": "bind"
},
{
"destination": "<<home_dir>>/Downloads",
"options": [
"rw",
"rbind"
],
"source": "<<home_dir>>/Downloads",
"type": "bind"
},
{
"destination": "<<home_dir>>/Music",
"options": [
"rw",
"rbind"
],
"source": "<<home_dir>>/Music",
"type": "bind"
},
{
"destination": "<<home_dir>>/Pictures",
"options": [
"rw",
"rbind"
],
"source": "<<home_dir>>/Pictures",
"type": "bind"
},
{
"destination": "<<home_dir>>/Videos",
"options": [
"rw",
"rbind"
],
"source": "<<home_dir>>/Videos",
"type": "bind"
},
{
"destination": "<<home_dir>>/.Public",
"options": [
"rw",
"rbind"
],
"source": "<<home_dir>>/.Public",
"type": "bind"
},
{
"destination": "<<home_dir>>/.Templates",
"options": [
"rw",
"rbind"
],
"source": "<<home_dir>>/.Templates",
"type": "bind"
},
{
"destination": "/run/app/env",
"options": [
"rbind"
],
"source": "/run/user/<<user_uid>>/linglong/375f5681145f4f4f9ffeb3a67aebd422/env",
"type": "bind"
},
{
"destination": "/run/user/<<user_uid>>//bus",
"options": [],
"source": "/run/user/<<user_uid>>//bus",
"type": "bind"
},
{
"destination": "/run/dbus/system_bus_socket",
"options": [],
"source": "/run/dbus/system_bus_socket",
"type": "bind"
}
],
"ociVersion": "1.0.1",
"process": {
"args": [
@ -54,24 +580,27 @@ const std::string kLoadTemplate = R"KLT00(
"PS1=\\033[48;5;214;38;5;26m${debian_chroot:+($debian_chroot)}\\h ⚛ \\w\\033[0m",
"QT_PLUGIN_PATH=/usr/lib/plugins",
"QT_QPA_PLATFORM_PLUGIN_PATH=/usr/lib/plugins/platforms",
"DISPLAY=:0",
"DISPLAY=<<x_display>>",
"LANG=zh_CN.UTF-8",
"LANGUAGE=zh_CN",
"XDG_SESSION_DESKTOP=deepin",
"D_DISABLE_RT_SCREEN_SCALE=",
"XMODIFIERS=@im=fcitx",
"XMODIFIERS=@im=<<im_mothod>>",
"DESKTOP_SESSION=deepin",
"DEEPIN_WINE_SCALE=2.00",
"XDG_CURRENT_DESKTOP=Deepin",
"XIM=fcitx",
"XDG_SESSION_TYPE=x11=",
"CLUTTER_IM_MODULE=fcitx",
"QT4_IM_MODULE=",
"GTK_IM_MODULE=fcitx"
"XIM=<<im_mothod>>",
"XDG_SESSION_TYPE=tty",
"XDG_RUNTIME_DIR=/run/user/<<user_uid>>",
"DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/<<user_uid>>/bus",
"CLUTTER_IM_MODULE=<<im_mothod>>",
"QT4_IM_MODULE=<<im_mothod>>",
"QT_IM_MODULE=<<im_mothod>>",
"GTK_IM_MODULE=<<im_mothod>>"
]
},
"root": {
"path": "/run/user/1000/linglong/375f5681145f4f4f9ffeb3a67aebd422/root",
"path": "/run/user/<<user_uid>>/linglong/375f5681145f4f4f9ffeb3a67aebd422/root",
"readonly": false
}
}
@ -88,11 +617,53 @@ linglong::Runtime loadBundle(int argc, char **argv)
throw std::runtime_error("invalid load args count");
}
auto r = linglong::fromString(kLoadTemplate);
auto getenv = [](const char *var) -> const char *const {
auto env = ::getenv(var);
return env ? env : "";
};
// fix json template string with home dir & im mothod & user uid & appid
std::string getHomeDir = getenv("HOME");
if (getHomeDir == "") {
// set default home dir with deepin user
getHomeDir = "/home/deepin";
}
std::string getCurrentImMethod = getenv("QT_IM_MODULE");
if (getCurrentImMethod == "") {
getCurrentImMethod = "fcitx";
}
std::string getCurrentUid = std::to_string(getuid());
if (getCurrentUid == "") {
getCurrentUid = "1000";
}
std::string xDisplay = getenv("DISPLAY");
auto fixTemplateWithHomeDir = std::regex_replace(kLoadTemplate, std::regex("<<home_dir>>"), getHomeDir);
auto fixTemplateWithImMethod =
std::regex_replace(fixTemplateWithHomeDir, std::regex("<<im_mothod>>"), getCurrentImMethod);
auto fixTemplateWithUid = std::regex_replace(fixTemplateWithImMethod, std::regex("<<user_uid>>"), getCurrentUid);
auto fixTemplateWithXDisplay = std::regex_replace(fixTemplateWithUid, std::regex("<<x_display>>"), xDisplay);
auto fixTemplateWithAppid = std::regex_replace(fixTemplateWithXDisplay, std::regex("<<appid>>"), argv[1]);
auto r = linglong::fromString(fixTemplateWithAppid);
std::string id = argv[1];
std::string bundleRoot = argv[2];
std::string exec = argv[3];
// fix appid with user home dir
std::list<std::string> userHomeDirectorys = {
"home/Documents", "home/Downloads", "home/Music", "home/Pictures", "home/Videos",
"home/Public", "home/Templates", "home/Desktop", "cache/deepin/dde-api", "config/systemd/user"};
if (!util::fs::exists(getHomeDir + "/.linglong/" + id)) {
for (const auto &dir : userHomeDirectorys) {
util::fs::create_directories(util::fs::path(getHomeDir + "/.linglong/" + id + "/" + dir).parent_path(),
0755);
}
}
{
Mount m;
m.source = "tmpfs";
@ -164,6 +735,15 @@ linglong::Runtime loadBundle(int argc, char **argv)
r.process.env.push_back(util::format("DBUS_SESSION_BUS_ADDRESS=%s", getenv("DBUS_SESSION_BUS_ADDRESS")));
r.process.env.push_back(util::format("HOME=%s", getenv("HOME")));
// extra env
r.process.env.push_back(util::format("PATH=%s", getenv("PATH")));
r.process.env.push_back(util::format("LD_LIBRARY_PATH=%s", getenv("LD_LIBRARY_PATH")));
r.process.env.push_back(util::format("PYTHONPATH=%s", getenv("PYTHONPATH")));
r.process.env.push_back(util::format("PYTHONHOME=%s", getenv("PYTHONHOME")));
r.process.env.push_back(util::format("XDG_DATA_DIRS=%s", getenv("XDG_DATA_DIRS")));
r.process.env.push_back(util::format("PERLLIB=%s", getenv("PERLLIB")));
r.process.env.push_back(util::format("GSETTINGS_SCHEMA_DIR=%s", getenv("GSETTINGS_SCHEMA_DIR")));
util::str_vec ldLibraryPath;
if (getenv("LD_LIBRARY_PATH")) {
@ -175,10 +755,30 @@ linglong::Runtime loadBundle(int argc, char **argv)
r.process.env.push_back(util::format("LD_LIBRARY_PATH=%s", util::str_vec_join(ldLibraryPath, ':').c_str()));
r.process.cwd = getenv("HOME");
r.process.args = util::str_vec {exec};
// r.process.args = util::str_vec {exec,"sh"};
auto split = [](std::string words) -> util::str_vec {
wordexp_t p;
auto ret = wordexp(words.c_str(), &p, WRDE_SHOWERR);
if (ret != 0) {
std::cerr << "wordexp" << strerror(errno);
wordfree(&p);
return {};
}
util::str_vec res;
for (int i = 0; i < (int)p.we_wordc; i++) {
res.push_back(p.we_wordv[i]);
}
wordfree(&p);
return res;
};
r.process.args = split(exec);
/// run/user/1000/linglong/375f5681145f4f4f9ffeb3a67aebd422/root
char dirTemplate[] = "/run/user/1000/linglong/XXXXXX";
char dirTemplate[255] = {
0,
};
sprintf(dirTemplate, "/run/user/%d/linglong/XXXXXX", getuid());
util::fs::create_directories(util::fs::path(dirTemplate).parent_path(), 0755);
char *dirName = mkdtemp(dirTemplate);
@ -190,6 +790,7 @@ linglong::Runtime loadBundle(int argc, char **argv)
util::fs::create_directories(rootPath, 0755);
r.root.path = rootPath.string();
r.annotations->container_root_path = dirName;
// FIXME: workaround id map
r.linux.uidMappings[0].hostID = getuid();

View File

@ -26,8 +26,7 @@ extern linglong::Runtime loadBundle(int argc, char **argv);
int main(int argc, char **argv)
{
// TODO(iceyer): move loader to ll-loader?
// NOTE(clx): just comment out loadBundle source for now, as currently unused.
// bool is_load_bundle = (argc == 4);
bool is_load_bundle = (argc == 4);
linglong::Option opt;
// TODO(iceyer): default in rootless
@ -37,23 +36,25 @@ int main(int argc, char **argv)
try {
linglong::Runtime r;
nlohmann::json json;
std::unique_ptr<linglong::util::MessageReader> reader = nullptr;
// if (is_load_bundle) {
// r = loadBundle(argc, argv);
// } else {
if (is_load_bundle) {
r = loadBundle(argc, argv);
linglong::to_json(json, r);
} else {
int socket = atoi(argv[1]);
if (socket <= 0) {
socket = open(argv[1], O_RDONLY | O_CLOEXEC);
}
int socket = atoi(argv[1]);
if (socket <= 0) {
socket = open(argv[1], O_RDONLY | O_CLOEXEC);
reader.reset(new linglong::util::MessageReader(socket));
json = reader->read();
r = json.get<linglong::Runtime>();
}
std::unique_ptr<linglong::util::MessageReader> reader(new linglong::util::MessageReader(socket));
auto json = reader->read();
r = json.get<linglong::Runtime>();
// }
if (linglong::util::fs::exists("/tmp/ll-debug")) {
std::ofstream origin(linglong::util::format("/tmp/ll-debug/%d.json", getpid()));
origin << json.dump(4);

View File

@ -18,7 +18,9 @@ std::string GetPidnsPid()
{
char buf[30];
memset(buf, 0, sizeof(buf));
readlink("/proc/self/ns/pid", buf, sizeof(buf) - 1);
if (readlink("/proc/self/ns/pid", buf, sizeof(buf) - 1) == -1) {
return "";
};
std::string str = buf;
return str.substr(5, str.length() - 6) + ":" + std::to_string(getpid()); // 6 = strlen("pid:[]")
}