From 38d6a8dedc45e0d38ce2a29f8b2e5f250d5f3172 Mon Sep 17 00:00:00 2001 From: ComixHe Date: Thu, 9 Jan 2025 11:05:49 +0800 Subject: [PATCH] fix: add runtimeCheck method for builder all checkers should execute at the container which based on binary layer Signed-off-by: ComixHe --- apps/ll-builder/src/main.cpp | 2 +- .../src/linglong/builder/linglong_builder.cpp | 191 +++++++++++------- .../src/linglong/builder/linglong_builder.h | 23 ++- 3 files changed, 133 insertions(+), 83 deletions(-) diff --git a/apps/ll-builder/src/main.cpp b/apps/ll-builder/src/main.cpp index 9585735da..4db9fe9c6 100644 --- a/apps/ll-builder/src/main.cpp +++ b/apps/ll-builder/src/main.cpp @@ -727,7 +727,7 @@ You can report bugs to the linyaps team under this project: https://github.com/O builder.setBuildOptions(options); - auto result = builder.run(modules, exec, debug); + auto result = builder.run(modules, exec, std::nullopt, debug); if (!result) { qCritical() << result.error(); return -1; diff --git a/libs/linglong/src/linglong/builder/linglong_builder.cpp b/libs/linglong/src/linglong/builder/linglong_builder.cpp index 1b9150ef5..b99418efc 100644 --- a/libs/linglong/src/linglong/builder/linglong_builder.cpp +++ b/libs/linglong/src/linglong/builder/linglong_builder.cpp @@ -453,6 +453,11 @@ utils::error::Result Builder::build(const QStringList &args) noexcept if (!arch) { return LINGLONG_ERR(arch); } + + if (!QFileInfo::exists(LINGLONG_BUILDER_HELPER)) { + return LINGLONG_ERR("builder helper doesn't exists"); + } + printMessage("[Build Target]"); printMessage(this->project.package.id, 2); printMessage("[Project Info]"); @@ -614,12 +619,8 @@ set -e } scriptContent.append(project.build); scriptContent.push_back('\n'); - // Do some checks after run container - if (!this->buildOptions.skipCheckOutput && this->project.package.kind == "app") { - scriptContent.append("# POST BUILD PROCESS\n"); - scriptContent.append(LINGLONG_BUILDER_HELPER "/main-check.sh\n"); - } if (!this->buildOptions.skipStripSymbols) { + scriptContent.append("# POST BUILD PROCESS\n"); scriptContent.append(LINGLONG_BUILDER_HELPER "/symbols-strip.sh\n"); } @@ -683,16 +684,14 @@ set -e .type = "bind", .uidMappings = {}, }); - if (QDir(LINGLONG_BUILDER_HELPER).exists()) { - opts.mounts.push_back({ - .destination = LINGLONG_BUILDER_HELPER, - .gidMappings = {}, - .options = { { "rbind", "ro" } }, - .source = LINGLONG_BUILDER_HELPER, - .type = "bind", - .uidMappings = {}, - }); - } + opts.mounts.push_back({ + .destination = LINGLONG_BUILDER_HELPER, + .gidMappings = {}, + .options = { { "rbind", "ro" } }, + .source = LINGLONG_BUILDER_HELPER, + .type = "bind", + .uidMappings = {}, + }); opts.mounts.push_back({ .destination = "/project", .gidMappings = {}, @@ -707,16 +706,7 @@ set -e if (!appCache.mkpath(".")) { return LINGLONG_ERR("make path " + appCache.absolutePath() + ": failed."); } -#ifdef LINGLONG_FONT_CACHE_GENERATOR - QDir appFontCache = appCache.absoluteFilePath("fontconfig"); - if (!appFontCache.mkpath(".")) { - return LINGLONG_ERR("make path " + appFontCache.absolutePath() + ": failed."); - } - QDir appFonts = appCache.absoluteFilePath("fonts"); - if (!appFonts.mkpath(".")) { - return LINGLONG_ERR("make path " + appFonts.absolutePath() + ": failed."); - } -#endif + // write ld.so.conf QFile ldsoconf = appCache.absoluteFilePath("ld.so.conf"); if (!ldsoconf.open(QIODevice::WriteOnly)) { @@ -733,21 +723,6 @@ include /opt/apps/@id@/files/etc/ld.so.conf)"; ldsoconf.write(ldRawConf.toUtf8()); // must be closed here, this conf will be used later. ldsoconf.close(); -#ifdef LINGLONG_FONT_CACHE_GENERATOR - // write fonts.conf - QFile fontsConf = appFonts.absoluteFilePath("fonts.conf"); - if (!fontsConf.open(QIODevice::WriteOnly)) { - return LINGLONG_ERR(fontsConf); - } - QString fontsRawConf = R"( - - - /run/linglong/fonts - /opt/apps/@id@/files/etc/fonts/fonts.conf -)"; - fontsRawConf.replace("@id@", QString::fromStdString(this->project.package.id)); - fontsConf.write(fontsRawConf.toUtf8()); -#endif opts.mounts.push_back({ .destination = "/run/linglong/cache", @@ -1159,6 +1134,12 @@ include /opt/apps/@id@/files/etc/ld.so.conf)"; return mergeRet; } printMessage("Successfully build " + this->project.package.id); + + ret = runtimeCheck(modules); + if (!ret) { + return LINGLONG_ERR(ret); + } + return LINGLONG_OK; } @@ -1389,7 +1370,8 @@ utils::error::Result Builder::importLayer(repo::OSTreeRepo &ostree, const utils::error::Result Builder::run(const QStringList &modules, const QStringList &args, - const bool &debug) + std::optional init, + bool debug) { LINGLONG_TRACE("run application"); @@ -1398,16 +1380,9 @@ utils::error::Result Builder::run(const QStringList &modules, return LINGLONG_ERR(curRef); } - auto options = runtime::ContainerOptions{ - .appID = curRef->id, - .containerID = genContainerID(*curRef), - .runtimeDir = {}, - .baseDir = {}, - .appDir = {}, - .patches = {}, - .mounts = {}, - .hooks = {}, - }; + auto options = init.value_or(runtime::ContainerOptions{}); + options.appID = curRef->id; + options.containerID = genContainerID(*curRef); auto fuzzyBase = package::FuzzyReference::parse(QString::fromStdString(this->project.base)); if (!fuzzyBase) { @@ -1549,44 +1524,77 @@ utils::error::Result Builder::run(const QStringList &modules, .type = "bind", }); } + // mount app cache + QDir appCache = this->workingDir.absoluteFilePath("linglong/cache"); applicationMounts.push_back(ocppi::runtime::config::types::Mount{ .destination = "/run/linglong/cache", .options = { { "rbind", "rw" } }, - .source = this->workingDir.absoluteFilePath("linglong/cache").toStdString(), + .source = appCache.absolutePath().toStdString(), .type = "bind", }); + + // write fonts.conf + QDir appFontCache = appCache.absoluteFilePath("fontconfig"); + if (!appFontCache.mkpath(".")) { + return LINGLONG_ERR("make path " + appFontCache.absolutePath() + ": failed."); + } + + QDir appFonts = appCache.absoluteFilePath("fonts"); + if (!appFonts.mkpath(".")) { + return LINGLONG_ERR("make path " + appFonts.absolutePath() + ": failed."); + } + + QFile fontsConf = appFonts.absoluteFilePath("fonts.conf"); + if (!fontsConf.open(QIODevice::WriteOnly)) { + return LINGLONG_ERR(fontsConf); + } + QString fontsRawConf = R"( + + + /run/linglong/fonts + /opt/apps/@id@/files/etc/fonts/fonts.conf +)"; + fontsRawConf.replace("@id@", QString::fromStdString(this->project.package.id)); + fontsConf.write(fontsRawConf.toUtf8()); + fontsConf.close(); + #ifdef LINGLONG_FONT_CACHE_GENERATOR // mount font cache applicationMounts.push_back(ocppi::runtime::config::types::Mount{ .destination = "/var/cache/fontconfig", .options = { { "rbind", "rw" } }, - .source = this->workingDir.absoluteFilePath("linglong/cache/fontconfig").toStdString(), + .source = appFontCache.absolutePath().toStdString(), .type = "bind", }); #endif - std::vector generateCache{}; - std::vector ldconfigCmd = { "/sbin/ldconfig", - "-C", - "/run/linglong/cache/ld.so.cache" }; - generateCache.push_back(ocppi::runtime::config::types::Hook{ - .args = std::move(ldconfigCmd), - .env = {}, - .path = "/sbin/ldconfig", - .timeout = {}, - }); + std::vector generateCache{ + { + .args = + std::vector{ "/sbin/ldconfig", "-C", "/run/linglong/cache/ld.so.cache" }, + .env = {}, + .path = "/sbin/ldconfig", + .timeout = {}, + }, #ifdef LINGLONG_FONT_CACHE_GENERATOR - std::vector fontconfiCmd = { "fc-cache", "-f" }; - generateCache.push_back(ocppi::runtime::config::types::Hook{ - .args = std::move(fontconfiCmd), - .env = {}, - .path = "/bin/fc-cache", - .timeout = {}, - }); + { + .args = std::vector{ "/bin/fc-cache", "-f" }, + .env = {}, + .path = "/bin/fc-cache", + .timeout = {}, + } #endif - options.hooks.startContainer = std::move(generateCache); - options.mounts = std::move(applicationMounts); + }; + + auto startHooks = + options.hooks.startContainer.value_or(std::vector{}); + startHooks.insert(startHooks.begin(), generateCache.begin(), generateCache.end()); + options.hooks.startContainer = std::move(startHooks); + + options.mounts.insert(options.mounts.begin(), + applicationMounts.begin(), + applicationMounts.end()); auto container = this->containerBuilder.create(options); if (!container) { @@ -1616,4 +1624,43 @@ utils::error::Result Builder::run(const QStringList &modules, return LINGLONG_OK; } +utils::error::Result Builder::runtimeCheck(const QStringList &modules) +{ + LINGLONG_TRACE("runtime check"); + printMessage("[Runtime Check]"); + // Do some checks after run container + if (!this->buildOptions.skipCheckOutput && this->project.package.kind == "app") { + printMessage("Start runtime check", 2); + runtime::ContainerOptions opts{ .mounts = { + ocppi::runtime::config::types::Mount{ + .destination = LINGLONG_BUILDER_HELPER, + .gidMappings = {}, + .options = { { "rbind", "ro" } }, + .source = LINGLONG_BUILDER_HELPER, + .type = "bind", + .uidMappings = {}, + }, + { + .destination = "/project", + .gidMappings = {}, + .options = { { "rbind", "rw" } }, + .source = this->workingDir.absolutePath().toStdString(), + .type = "bind", + .uidMappings = {}, + } } }; + + auto ret = + this->run(modules, { { QString{ LINGLONG_BUILDER_HELPER } + "/main-check.sh" } }, opts); + if (!ret) { + printMessage("Runtime check failed", 2); + return LINGLONG_ERR(ret); + } + } else { + printMessage("Skip runtime check", 2); + } + + printMessage("Runtime check done", 2); + return LINGLONG_OK; +} + } // namespace linglong::builder diff --git a/libs/linglong/src/linglong/builder/linglong_builder.h b/libs/linglong/src/linglong/builder/linglong_builder.h index 787e1b259..2ae5aec17 100644 --- a/libs/linglong/src/linglong/builder/linglong_builder.h +++ b/libs/linglong/src/linglong/builder/linglong_builder.h @@ -56,15 +56,15 @@ class Builder auto create(const QString &projectName) -> utils::error::Result; - auto build(const QStringList &args = { "/project/linglong/entry.sh" }) noexcept - -> utils::error::Result; + auto build(const QStringList &args = { + "/project/linglong/entry.sh" }) noexcept -> utils::error::Result; - auto exportUAB(const QString &destination, const UABOption &option) - -> utils::error::Result; + auto exportUAB(const QString &destination, + const UABOption &option) -> utils::error::Result; auto exportLayer(const QString &destination) -> utils::error::Result; - static auto extractLayer(const QString &layerPath, const QString &destination) - -> utils::error::Result; + static auto extractLayer(const QString &layerPath, + const QString &destination) -> utils::error::Result; auto push(const std::string &module, const std::string &repoUrl = "", @@ -72,11 +72,14 @@ class Builder auto import() -> utils::error::Result; - static auto importLayer(repo::OSTreeRepo &repo, const QString &path) - -> utils::error::Result; + static auto importLayer(repo::OSTreeRepo &repo, + const QString &path) -> utils::error::Result; - auto run(const QStringList &modules, const QStringList &args, const bool &debug) - -> utils::error::Result; + auto run(const QStringList &modules, + const QStringList &args, + std::optional init = std::nullopt, + bool debug = false) -> utils::error::Result; + auto runtimeCheck(const QStringList &modules) -> utils::error::Result; void setBuildOptions(const BuilderBuildOptions &options) noexcept { buildOptions = options; }