Skip to content

Commit 62a3474

Browse files
reddevillgComixHe
authored andcommitted
feat: support build extension
Introduce RunContext to unify runtime layer resolution, requiring changes across the builder, CLI, and PM. Signed-off-by: reddevillg <reddevillg@gmail.com>
1 parent 6ee4e1f commit 62a3474

15 files changed

Lines changed: 959 additions & 723 deletions

File tree

libs/linglong/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ pfl_add_library(
7979
src/linglong/runtime/container_builder.h
8080
src/linglong/runtime/container.cpp
8181
src/linglong/runtime/container.h
82+
src/linglong/runtime/run_context.cpp
83+
src/linglong/runtime/run_context.h
8284
TESTS
8385
ll-tests
8486
COMPILE_FEATURES

libs/linglong/src/linglong/builder/linglong_builder.cpp

Lines changed: 192 additions & 412 deletions
Large diffs are not rendered by default.

libs/linglong/src/linglong/builder/linglong_builder.h

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "linglong/api/types/v1/BuilderProject.hpp"
1111
#include "linglong/repo/ostree_repo.h"
1212
#include "linglong/runtime/container_builder.h"
13+
#include "linglong/runtime/run_context.h"
1314
#include "linglong/utils/error/error.h"
1415
#include "linglong/utils/overlayfs.h"
1516

@@ -110,7 +111,6 @@ class Builder
110111
auto generateBuildDependsScript() noexcept -> utils::error::Result<bool>;
111112
auto generateDependsScript() noexcept -> utils::error::Result<bool>;
112113
void takeTerminalForeground();
113-
void patchBuildPhaseConfig(ocppi::runtime::config::types::Config &config);
114114
void mergeOutput(const QList<QDir> &src, const QDir &dest, const QStringList &target);
115115
void printBasicInfo();
116116
void printRepo();
@@ -128,14 +128,11 @@ class Builder
128128

129129
std::optional<package::Reference> projectRef;
130130
QStringList packageModules;
131-
std::optional<package::Reference> baseRef;
132-
std::optional<package::LayerDir> baseLayerDir;
133-
std::optional<package::Reference> runtimeRef;
134-
std::optional<package::LayerDir> runtimeLayerDir;
135131
std::unique_ptr<utils::OverlayFS> baseOverlay;
136132
std::unique_ptr<utils::OverlayFS> runtimeOverlay;
137133
QDir buildOutput;
138-
QString installPrefix;
134+
std::string installPrefix;
135+
runtime::RunContext buildContext;
139136
};
140137

141138
} // namespace linglong::builder

libs/linglong/src/linglong/cli/cli.cpp

Lines changed: 16 additions & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "linglong/package/layer_file.h"
2727
#include "linglong/package/reference.h"
2828
#include "linglong/runtime/container_builder.h"
29+
#include "linglong/runtime/run_context.h"
2930
#include "linglong/utils/configure.h"
3031
#include "linglong/utils/error/error.h"
3132
#include "linglong/utils/finally/finally.h"
@@ -572,16 +573,15 @@ int Cli::run([[maybe_unused]] CLI::App *subcommand)
572573
this->printer.printErr(curAppRef.error());
573574
return -1;
574575
}
575-
auto appLayerDir = this->repository.getMergedModuleDir(*curAppRef);
576-
if (!appLayerDir) {
577-
this->printer.printErr(appLayerDir.error());
578-
return -1;
576+
577+
runtime::RunContext runContext(this->repository);
578+
auto res = runContext.resolve(*curAppRef);
579+
if (!res) {
580+
this->printer.printErr(res.error());
579581
}
580582

581-
// Note: we should use the info.json which from states.json instead of layer dir
582-
const auto &appLayerItem = this->repository.getLayerItem(*curAppRef);
583+
const auto &appLayerItem = runContext.getCachedAppItem();
583584
if (!appLayerItem) {
584-
this->printer.printErr(appLayerItem.error());
585585
return -1;
586586
}
587587
const auto &info = appLayerItem->info;
@@ -591,78 +591,6 @@ int Cli::run([[maybe_unused]] CLI::App *subcommand)
591591
qWarning() << ret.error().message();
592592
}
593593

594-
std::optional<std::string> runtimeLayerRef;
595-
std::optional<package::LayerDir> runtimeLayerDir;
596-
if (info.runtime) {
597-
auto runtimeFuzzyRef =
598-
package::FuzzyReference::parse(QString::fromStdString(info.runtime.value()));
599-
if (!runtimeFuzzyRef) {
600-
this->printer.printErr(runtimeFuzzyRef.error());
601-
return -1;
602-
}
603-
604-
auto runtimeRefRet = this->repository.clearReference(*runtimeFuzzyRef,
605-
{
606-
.forceRemote = false,
607-
.fallbackToRemote = false,
608-
.semanticMatching = true,
609-
});
610-
if (!runtimeRefRet) {
611-
this->printer.printErr(runtimeRefRet.error());
612-
return -1;
613-
}
614-
const auto &runtimeRef = *runtimeRefRet;
615-
616-
if (!info.uuid.has_value()) {
617-
auto runtimeLayerDirRet = this->repository.getMergedModuleDir(runtimeRef);
618-
if (!runtimeLayerDirRet) {
619-
this->printer.printErr(runtimeLayerDirRet.error());
620-
return -1;
621-
}
622-
runtimeLayerDir = std::move(runtimeLayerDirRet).value();
623-
} else {
624-
auto runtimeLayerDirRet =
625-
this->repository.getLayerDir(*runtimeRefRet, "binary", info.uuid);
626-
if (!runtimeLayerDirRet) {
627-
this->printer.printErr(runtimeLayerDirRet.error());
628-
return -1;
629-
}
630-
runtimeLayerRef = runtimeRefRet->toString().toStdString();
631-
runtimeLayerDir = std::move(runtimeLayerDirRet).value();
632-
}
633-
}
634-
635-
auto baseFuzzyRef = package::FuzzyReference::parse(QString::fromStdString(info.base));
636-
if (!baseFuzzyRef) {
637-
this->printer.printErr(baseFuzzyRef.error());
638-
return -1;
639-
}
640-
641-
auto baseRef = this->repository.clearReference(*baseFuzzyRef,
642-
{
643-
.forceRemote = false,
644-
.fallbackToRemote = false,
645-
.semanticMatching = true,
646-
});
647-
if (!baseRef) {
648-
this->printer.printErr(LINGLONG_ERRV(baseRef));
649-
return -1;
650-
}
651-
652-
utils::error::Result<package::LayerDir> baseLayerDir;
653-
if (!info.uuid.has_value()) {
654-
qDebug() << "getMergedModuleDir base";
655-
baseLayerDir = this->repository.getMergedModuleDir(*baseRef);
656-
} else {
657-
qDebug() << "getLayerDir base" << info.uuid.value().c_str();
658-
baseLayerDir = this->repository.getLayerDir(*baseRef, "binary", info.uuid);
659-
}
660-
661-
if (!baseLayerDir) {
662-
this->printer.printErr(LINGLONG_ERRV(baseLayerDir));
663-
return -1;
664-
}
665-
666594
auto appCache = this->ensureCache(*curAppRef, *appLayerItem);
667595
if (!appCache) {
668596
this->printer.printErr(LINGLONG_ERRV(appCache));
@@ -675,21 +603,9 @@ int Cli::run([[maybe_unused]] CLI::App *subcommand)
675603
}
676604
commands = filePathMapping(commands);
677605

678-
auto newContainerID = runtime::genContainerID(*curAppRef);
679-
auto bundle = runtime::getBundleDir(newContainerID);
680-
if (!bundle) {
681-
this->printer.printErr(LINGLONG_ERRV(bundle));
682-
return -1;
683-
}
684-
685606
// this lambda will dump reference of containerID, app, base and runtime to
686607
// /run/linglong/getuid()/getpid() to store these needed infomation
687-
auto dumpContainerInfo = [app = curAppRef->toString().toStdString(),
688-
base = baseRef->toString().toStdString(),
689-
&newContainerID,
690-
&runtimeLayerRef,
691-
uid,
692-
this]() -> bool {
608+
auto dumpContainerInfo = [uid, &runContext, this]() -> bool {
693609
LINGLONG_TRACE("dump info")
694610
std::error_code ec;
695611
auto pidFile = std::filesystem::path{ "/run/linglong" } / std::to_string(uid)
@@ -711,12 +627,7 @@ int Cli::run([[maybe_unused]] CLI::App *subcommand)
711627
this->printer.printErr(LINGLONG_ERRV(msg));
712628
return false;
713629
}
714-
stream << nlohmann::json(linglong::api::types::v1::ContainerProcessStateInfo{
715-
.app = app,
716-
.base = base,
717-
.containerID = newContainerID,
718-
.runtime = runtimeLayerRef,
719-
});
630+
stream << nlohmann::json(runContext.stateInfo());
720631
stream.close();
721632

722633
return true;
@@ -776,47 +687,6 @@ int Cli::run([[maybe_unused]] CLI::App *subcommand)
776687
return 0;
777688
}
778689

779-
std::vector<ocppi::runtime::config::types::Mount> applicationMounts{};
780-
auto bindMount =
781-
[&applicationMounts](const api::types::v1::ApplicationConfigurationPermissionsBind &bind) {
782-
applicationMounts.push_back(ocppi::runtime::config::types::Mount{
783-
.destination = bind.destination,
784-
.gidMappings = {},
785-
.options = { { "rbind" } },
786-
.source = bind.source,
787-
.type = "bind",
788-
.uidMappings = {},
789-
});
790-
};
791-
792-
auto bindInnerMount =
793-
[&applicationMounts,
794-
&bundle](const api::types::v1::ApplicationConfigurationPermissionsInnerBind &bind) {
795-
applicationMounts.push_back(ocppi::runtime::config::types::Mount{
796-
.destination = bind.destination,
797-
.gidMappings = {},
798-
.options = { { "rbind" } },
799-
.source = bundle->string() + "/rootfs" + bind.source,
800-
.type = "bind",
801-
.uidMappings = {},
802-
});
803-
};
804-
805-
if (info.permissions) {
806-
const auto &perm = info.permissions;
807-
if (perm->binds) {
808-
const auto &binds = perm->binds;
809-
std::for_each(binds->cbegin(), binds->cend(), bindMount);
810-
}
811-
812-
if (perm->innerBinds) {
813-
const auto &innerBinds = perm->innerBinds;
814-
const auto &hostSourceDir =
815-
std::filesystem::path{ appLayerDir->absolutePath().toStdString() };
816-
std::for_each(innerBinds->cbegin(), innerBinds->cend(), bindInnerMount);
817-
}
818-
}
819-
820690
auto *homeEnv = ::getenv("HOME");
821691
auto *userNameEnv = ::getenv("USER");
822692
if (homeEnv == nullptr || userNameEnv == nullptr) {
@@ -825,12 +695,14 @@ int Cli::run([[maybe_unused]] CLI::App *subcommand)
825695
}
826696

827697
linglong::generator::ContainerCfgBuilder cfgBuilder;
698+
res = runContext.fillContextCfg(cfgBuilder);
699+
if (!res) {
700+
this->printer.printErr(res.error());
701+
return -1;
702+
}
828703
cfgBuilder.setAppId(curAppRef->id.toStdString())
829-
.setAppPath(appLayerDir->absoluteFilePath("files").toStdString())
830-
.setBasePath(baseLayerDir->absoluteFilePath("files").toStdString())
831704
.setAppCache(*appCache)
832705
.enableLDCache()
833-
.setBundlePath(std::move(bundle).value())
834706
.addUIdMapping(uid, uid, 1)
835707
.addGIdMapping(gid, gid, 1)
836708
.bindDefault()
@@ -847,11 +719,7 @@ int Cli::run([[maybe_unused]] CLI::App *subcommand)
847719
.mapPrivate(std::string("/home/") + userNameEnv + "/.gnupg", true)
848720
.bindIPC()
849721
.forwordDefaultEnv()
850-
.setExtraMounts(applicationMounts)
851722
.enableSelfAdjustingMount();
852-
if (info.runtime) {
853-
cfgBuilder.setRuntimePath(runtimeLayerDir->absoluteFilePath("files").toStdString());
854-
}
855723
#ifdef LINGLONG_FONT_CACHE_GENERATOR
856724
cfgBuilder.enableFontCache();
857725
#endif
@@ -863,7 +731,8 @@ int Cli::run([[maybe_unused]] CLI::App *subcommand)
863731
}
864732

865733
auto container =
866-
this->containerBuilder.create(cfgBuilder, QString::fromStdString(newContainerID));
734+
this->containerBuilder.create(cfgBuilder,
735+
QString::fromStdString(runContext.getContainerId()));
867736

868737
if (!container) {
869738
this->printer.printErr(container.error());

libs/linglong/src/linglong/package/reference.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,4 +173,36 @@ utils::error::Result<Reference> Reference::fromVariantMap(const QVariantMap &dat
173173
return *reference;
174174
}
175175

176+
utils::error::Result<Reference>
177+
Reference::fromBuilderProject(const api::types::v1::BuilderProject &project) noexcept
178+
{
179+
LINGLONG_TRACE("parse reference from BuilderProject");
180+
181+
auto version = package::Version::parse(QString::fromStdString(project.package.version));
182+
if (!version) {
183+
return LINGLONG_ERR(version);
184+
}
185+
186+
auto architecture = package::Architecture::currentCPUArchitecture();
187+
if (project.package.architecture) {
188+
architecture = package::Architecture::parse(*project.package.architecture);
189+
}
190+
if (!architecture) {
191+
return LINGLONG_ERR(architecture);
192+
}
193+
std::string channel = "main";
194+
if (project.package.channel.has_value()) {
195+
channel = *project.package.channel;
196+
}
197+
auto ref = package::Reference::create(QString::fromStdString(channel),
198+
QString::fromStdString(project.package.id),
199+
*version,
200+
*architecture);
201+
if (!ref) {
202+
return LINGLONG_ERR(ref);
203+
}
204+
205+
return ref;
206+
}
207+
176208
} // namespace linglong::package

libs/linglong/src/linglong/package/reference.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#pragma once
88

9+
#include "linglong/api/types/v1/BuilderProject.hpp"
910
#include "linglong/api/types/v1/PackageInfoV2.hpp"
1011
#include "linglong/api/types/v1/Repo.hpp"
1112
#include "linglong/package/architecture.h"
@@ -28,6 +29,8 @@ class Reference final
2829
fromPackageInfo(const api::types::v1::PackageInfoV2 &info) noexcept;
2930
static QVariantMap toVariantMap(const Reference &ref) noexcept;
3031
static utils::error::Result<Reference> fromVariantMap(const QVariantMap &data) noexcept;
32+
static utils::error::Result<Reference>
33+
fromBuilderProject(const api::types::v1::BuilderProject &project) noexcept;
3134

3235
QString channel;
3336
QString id;

0 commit comments

Comments
 (0)