Skip to content

Commit 1414c5e

Browse files
authored
Merge branch 'OpenAtomFoundation:master' into master
2 parents 2fceaa1 + 73c1bee commit 1414c5e

File tree

9 files changed

+261
-70
lines changed

9 files changed

+261
-70
lines changed

apps/uab/header/src/main.cpp

+25-14
Original file line numberDiff line numberDiff line change
@@ -617,25 +617,22 @@ void runAppLoader(const nlohmann::json &info, const std::vector<std::string> &lo
617617

618618
void runAppLinglong(const std::string &cliBin,
619619
const nlohmann::json &info,
620-
const std::vector<std::string> &loaderArgs) noexcept
620+
[[maybe_unused]] const std::vector<std::string> &loaderArgs) noexcept
621621
{
622622
if (!info.contains("id") || !info["id"].is_string()) {
623623
std::cerr << "couldn't get appId, stop to delegate runnning operation to linglong"
624624
<< std::endl;
625625
cleanAndExit(-1);
626626
}
627627

628-
const auto &appId = info["id"];
629-
auto argc = loaderArgs.size() + 2;
630-
auto *argv = (const char **)malloc(sizeof(char *) * argc);
628+
const auto &appId = info["id"].get<std::string>();
629+
std::array<const char *, 4> argv{};
631630
argv[0] = cliBin.c_str();
632-
argv[argc - 1] = nullptr;
633-
634-
for (std::size_t i = 0; i < loaderArgs.size(); ++i) {
635-
argv[i + 1] = loaderArgs[i].c_str();
636-
}
631+
argv[1] = "run";
632+
argv[2] = appId.c_str();
633+
argv[3] = nullptr;
637634

638-
cleanAndExit(::execv(cliBin.c_str(), (char *const *)(argv)));
635+
cleanAndExit(::execv(cliBin.c_str(), (char *const *)argv.data()));
639636
}
640637

641638
enum uabOption {
@@ -781,13 +778,27 @@ int main(int argc, char **argv)
781778
return -1;
782779
}
783780

784-
const auto &appLayer = metaInfo["layers"].front();
785-
if (!appLayer.is_object() || !appLayer.contains("info") || !appLayer["info"].is_object()) {
786-
std::cerr << "invalid format of app layer" << std::endl;
781+
const auto &layersRef = metaInfo["layers"].get<std::vector<nlohmann::json>>();
782+
const auto &appLayer =
783+
std::find_if(layersRef.cbegin(), layersRef.cend(), [](const nlohmann::json &layer) {
784+
if (!layer.is_object() || !layer.contains("info") || !layer["info"].is_object()) {
785+
return false;
786+
}
787+
788+
const auto &infoRef = layer["info"];
789+
if (!infoRef.contains("kind")) {
790+
return false;
791+
}
792+
793+
return infoRef["kind"] == "app";
794+
});
795+
796+
if (appLayer == layersRef.cend()) {
797+
std::cerr << "couldn't find application layer" << std::endl;
787798
return -1;
788799
}
789800

790-
auto info = appLayer["info"];
801+
auto info = (*appLayer)["info"];
791802
runAppLinglong(cliPath, info, opts.loaderArgs);
792803
}
793804

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

+6-6
Original file line numberDiff line numberDiff line change
@@ -708,19 +708,19 @@ utils::error::Result<void> Builder::build(const QStringList &args) noexcept
708708
if (!result) {
709709
qWarning() << "remove" << ref->toString() << result.error().message();
710710
}
711-
result = this->repo.importLayerDir(binaryOutputLayerDir);
712-
if (!result) {
713-
return LINGLONG_ERR(result);
711+
auto localLayer = this->repo.importLayerDir(binaryOutputLayerDir);
712+
if (!localLayer) {
713+
return LINGLONG_ERR(localLayer);
714714
}
715715

716716
package::LayerDir developOutputLayerDir = developOutput.absoluteFilePath("..");
717717
result = this->repo.remove(*ref, true);
718718
if (!result) {
719719
qWarning() << "remove" << ref->toString() << result.error().message();
720720
}
721-
result = this->repo.importLayerDir(developOutputLayerDir);
722-
if (!result) {
723-
return LINGLONG_ERR(result);
721+
localLayer = this->repo.importLayerDir(developOutputLayerDir);
722+
if (!localLayer) {
723+
return LINGLONG_ERR(localLayer);
724724
}
725725

726726
printMessage("Successfully build " + this->project.package.id);

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

+69-22
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,48 @@ Cli::Cli(Printer &printer,
143143
{
144144
}
145145

146+
utils::error::Result<package::LayerDir> Cli::getDependLayerDir(
147+
const package::Reference &appRef, const package::Reference &dependRef) const noexcept
148+
{
149+
LINGLONG_TRACE("get layer dir of depends")
150+
151+
auto appLayerDir = this->repository.getLayerDir(appRef);
152+
if (!appLayerDir) {
153+
return LINGLONG_ERR(appLayerDir);
154+
}
155+
156+
auto dependLayerDir = this->repository.getLayerDir(dependRef);
157+
if (!dependLayerDir) {
158+
return LINGLONG_ERR(dependLayerDir);
159+
}
160+
161+
if (!appLayerDir->exists(QString{ ".minified-%1" }.arg(dependRef.id))) {
162+
return dependLayerDir;
163+
}
164+
165+
auto minified = utils::serialize::LoadJSONFile<api::types::v1::MinifiedInfo>(
166+
dependLayerDir->absoluteFilePath("minified.json"));
167+
if (!minified) {
168+
return LINGLONG_ERR(minified);
169+
}
170+
171+
const auto &appRefStr = appRef.toString().toStdString();
172+
QString subRef;
173+
for (const auto &[appRef, uuid] : minified->infos) {
174+
if (appRef == appRefStr) {
175+
subRef = QString{ "minified/%1" }.arg(QString::fromStdString(uuid));
176+
break;
177+
}
178+
}
179+
180+
if (subRef.isEmpty()) {
181+
return LINGLONG_ERR("couldn't find the association between app and depend in minified.json "
182+
"which under the layer directory.");
183+
}
184+
185+
return this->repository.getLayerDir(dependRef, false, subRef);
186+
}
187+
146188
int Cli::run(std::map<std::string, docopt::value> &args)
147189
{
148190
LINGLONG_TRACE("command run");
@@ -156,30 +198,29 @@ int Cli::run(std::map<std::string, docopt::value> &args)
156198
return -1;
157199
}
158200

159-
auto ref = this->repository.clearReference(*fuzzyRef,
160-
{
161-
.forceRemote = false,
162-
.fallbackToRemote = false,
163-
});
164-
if (!ref) {
165-
this->printer.printErr(ref.error());
201+
auto curAppRef = this->repository.clearReference(*fuzzyRef,
202+
{
203+
.forceRemote = false,
204+
.fallbackToRemote = false,
205+
});
206+
if (!curAppRef) {
207+
this->printer.printErr(curAppRef.error());
166208
return -1;
167209
}
168210

169-
auto layerDir = this->repository.getLayerDir(*ref, false);
170-
if (!layerDir) {
171-
this->printer.printErr(layerDir.error());
211+
auto appLayerDir = this->repository.getLayerDir(*curAppRef, false);
212+
if (!appLayerDir) {
213+
this->printer.printErr(appLayerDir.error());
172214
return -1;
173215
}
174216

175-
auto info = layerDir->info();
217+
auto info = appLayerDir->info();
176218
if (!info) {
177219
this->printer.printErr(info.error());
178220
return -1;
179221
}
180222

181223
std::optional<package::LayerDir> runtimeLayerDir;
182-
183224
if (info->runtime) {
184225
auto runtimeFuzzyRef =
185226
package::FuzzyReference::parse(QString::fromStdString(*info->runtime));
@@ -198,13 +239,13 @@ int Cli::run(std::map<std::string, docopt::value> &args)
198239
return -1;
199240
}
200241

201-
auto layerDir = this->repository.getLayerDir(*runtimeRef);
202-
if (!layerDir) {
203-
this->printer.printErr(layerDir.error());
242+
auto dependRet = getDependLayerDir(*curAppRef, *runtimeRef);
243+
if (!dependRet) {
244+
this->printer.printErr(dependRet.error());
204245
return -1;
205246
}
206247

207-
runtimeLayerDir = *layerDir;
248+
runtimeLayerDir = *dependRet;
208249
}
209250

210251
auto baseFuzzyRef = package::FuzzyReference::parse(QString::fromStdString(info->base));
@@ -223,7 +264,7 @@ int Cli::run(std::map<std::string, docopt::value> &args)
223264
return -1;
224265
}
225266

226-
auto baseLayerDir = this->repository.getLayerDir(*baseRef);
267+
auto baseLayerDir = getDependLayerDir(*curAppRef, *baseRef);
227268
if (!baseLayerDir) {
228269
this->printer.printErr(LINGLONG_ERRV(baseLayerDir));
229270
return -1;
@@ -242,7 +283,7 @@ int Cli::run(std::map<std::string, docopt::value> &args)
242283
auto containers = this->ociCLI.list().value_or(std::vector<ocppi::types::ContainerListItem>{});
243284
for (const auto &container : containers) {
244285
const auto &decodedID = QString(QByteArray::fromBase64(container.id.c_str()));
245-
if (!decodedID.startsWith(ref->toString())) {
286+
if (!decodedID.startsWith(curAppRef->toString())) {
246287
continue;
247288
}
248289

@@ -310,17 +351,18 @@ int Cli::run(std::map<std::string, docopt::value> &args)
310351
if (perm->innerBinds) {
311352
const auto &innerBinds = perm->innerBinds;
312353
const auto &hostSourceDir =
313-
std::filesystem::path{ layerDir->absolutePath().toStdString() };
354+
std::filesystem::path{ appLayerDir->absolutePath().toStdString() };
314355
std::for_each(innerBinds->cbegin(), innerBinds->cend(), bindInnerMount);
315356
}
316357
}
317358

318359
auto container = this->containerBuilder.create({
319-
.appID = ref->id,
320-
.containerID = (ref->toString() + "-" + QUuid::createUuid().toString()).toUtf8().toBase64(),
360+
.appID = curAppRef->id,
361+
.containerID =
362+
(curAppRef->toString() + "-" + QUuid::createUuid().toString()).toUtf8().toBase64(),
321363
.runtimeDir = runtimeLayerDir,
322364
.baseDir = *baseLayerDir,
323-
.appDir = *layerDir,
365+
.appDir = *appLayerDir,
324366
.patches = {},
325367
.mounts = std::move(applicationMounts),
326368
});
@@ -589,6 +631,11 @@ int Cli::install(std::map<std::string, docopt::value> &args)
589631

590632
api::types::v1::PackageManager1InstallParameters params;
591633
auto fuzzyRef = package::FuzzyReference::parse(QString::fromStdString(tier));
634+
if (!fuzzyRef) {
635+
this->printer.printErr(fuzzyRef.error());
636+
return -1;
637+
}
638+
592639
params.package.id = fuzzyRef->id.toStdString();
593640
if (fuzzyRef->channel) {
594641
params.package.channel = fuzzyRef->channel->toStdString();

libs/linglong/src/linglong/cli/cli.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ class Cli : public QObject
5555
static void filterPackageInfosFromType(std::vector<api::types::v1::PackageInfoV2> &list,
5656
const QString &type) noexcept;
5757
void updateAM() noexcept;
58+
[[nodiscard]] utils::error::Result<package::LayerDir> getDependLayerDir(
59+
const package::Reference &appRef, const package::Reference &ref) const noexcept;
5860

5961
public:
6062
int run(std::map<std::string, docopt::value> &args);
@@ -74,7 +76,7 @@ class Cli : public QObject
7476
void cancelCurrentTask();
7577

7678
private Q_SLOTS:
77-
int installFromFile(const QFileInfo& fileInfo);
79+
int installFromFile(const QFileInfo &fileInfo);
7880
void processDownloadStatus(const QString &recTaskID,
7981
const QString &percentage,
8082
const QString &message,

libs/linglong/src/linglong/package_manager/package_manager.cpp

+44-6
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,8 @@ QVariantMap PackageManager::installFromUAB(const QDBusUnixFileDescriptor &fd) no
315315
}
316316

317317
layerInfos.erase(appLayerIt);
318-
layerInfos.insert(layerInfos.begin(), std::move(appLayer));
318+
layerInfos.insert(layerInfos.begin(),
319+
std::move(appLayer)); // app layer should place to the first of vector
319320
auto &taskRef = this->taskList.emplace_back(std::move(task));
320321
connect(&taskRef, &InstallTask::TaskChanged, this, &PackageManager::TaskChanged);
321322

@@ -335,6 +336,13 @@ QVariantMap PackageManager::installFromUAB(const QDBusUnixFileDescriptor &fd) no
335336
}
336337
this->taskList.erase(elem);
337338
});
339+
340+
if (taskRef.currentStatus() == InstallTask::Canceled) {
341+
qInfo() << "task" << taskRef.taskID() << "has been canceled by user, layer"
342+
<< taskRef.layer();
343+
return;
344+
}
345+
338346
taskRef.updateStatus(InstallTask::preInstall, "prepare for installing uab");
339347
auto verifyRet = uab->verify();
340348
if (!verifyRet) {
@@ -347,12 +355,24 @@ QVariantMap PackageManager::installFromUAB(const QDBusUnixFileDescriptor &fd) no
347355
return;
348356
}
349357

358+
if (taskRef.currentStatus() == InstallTask::Canceled) {
359+
qInfo() << "task" << taskRef.taskID() << "has been canceled by user, layer"
360+
<< taskRef.layer();
361+
return;
362+
}
363+
350364
auto mountPoint = uab->mountUab();
351365
if (!mountPoint) {
352366
taskRef.updateStatus(InstallTask::Failed, std::move(mountPoint).error());
353367
return;
354368
}
355369

370+
if (taskRef.currentStatus() == InstallTask::Canceled) {
371+
qInfo() << "task" << taskRef.taskID() << "has been canceled by user, layer"
372+
<< taskRef.layer();
373+
return;
374+
}
375+
356376
const auto &uabLayersDirInfo = QFileInfo{ mountPoint->absoluteFilePath("layers") };
357377
if (!uabLayersDirInfo.exists() || !uabLayersDirInfo.isDir()) {
358378
taskRef.updateStatus(InstallTask::Failed,
@@ -362,7 +382,14 @@ QVariantMap PackageManager::installFromUAB(const QDBusUnixFileDescriptor &fd) no
362382

363383
utils::Transaction transaction;
364384
const auto &uabLayersDir = QDir{ uabLayersDirInfo.absoluteFilePath() };
385+
package::LayerDir appLayerDir;
365386
for (const auto &layer : layerInfos) {
387+
if (taskRef.currentStatus() == InstallTask::Canceled) {
388+
qInfo() << "task" << taskRef.taskID() << "has been canceled by user, layer"
389+
<< taskRef.layer();
390+
return;
391+
}
392+
366393
QDir layerDirPath = uabLayersDir.absoluteFilePath(
367394
QString::fromStdString(layer.info.id) % QDir::separator()
368395
% QString::fromStdString(layer.info.packageInfoV2Module));
@@ -380,11 +407,6 @@ QVariantMap PackageManager::installFromUAB(const QDBusUnixFileDescriptor &fd) no
380407
subRef = "minified/" + QString::fromStdString(metaInfo.get().uuid);
381408
}
382409

383-
bool isAppLayer = layer.info.kind == "app";
384-
if (isAppLayer) { // it's meaningless for app layer that declare minified is true
385-
subRef.clear();
386-
}
387-
388410
auto infoRet = layerDir.info();
389411
if (!infoRet) {
390412
taskRef.updateStatus(InstallTask::Failed, std::move(infoRet).error());
@@ -399,6 +421,11 @@ QVariantMap PackageManager::installFromUAB(const QDBusUnixFileDescriptor &fd) no
399421
}
400422
auto &ref = *refRet;
401423

424+
bool isAppLayer = layer.info.kind == "app";
425+
if (isAppLayer) { // it's meaningless for app layer that declare minified is true
426+
subRef.clear();
427+
}
428+
402429
auto ret = this->repo.importLayerDir(layerDir, subRef);
403430
if (!ret) {
404431
if (ret.error().code() == 0
@@ -419,7 +446,18 @@ QVariantMap PackageManager::installFromUAB(const QDBusUnixFileDescriptor &fd) no
419446
}
420447
});
421448

449+
if (isAppLayer) {
450+
appLayerDir = *ret;
451+
}
452+
422453
if (!subRef.isEmpty()) {
454+
QFile tagFile =
455+
appLayerDir.absoluteFilePath(QString{ ".minified-%1" }.arg(ref.id));
456+
if (!tagFile.open(QIODevice::NewOnly | QIODevice::WriteOnly)) {
457+
taskRef.updateStatus(InstallTask::Failed, tagFile.errorString());
458+
return;
459+
}
460+
423461
const auto &completedLayer = this->repo.getLayerDir(ref);
424462
if (!completedLayer) {
425463
taskRef.updateStatus(InstallTask::Failed, std::move(ret).error());

0 commit comments

Comments
 (0)