diff --git a/api/schema/v1.json b/api/schema/v1.json index 784e645c1..b2f20cc5e 100644 --- a/api/schema/v1.json +++ b/api/schema/v1.json @@ -644,6 +644,27 @@ } } }, + "PackageInfoDisplay": { + "title": "PackageInfoDisplay", + "description": "this is the each item output of ll-cli list --json", + "allOf": [ + { + "$ref": "#/$defs/PackageInfoV2" + }, + { + "type": "object", + "requested": [ + "info" + ], + "properties": { + "install_time": { + "type": "integer", + "description": "package install time" + } + } + } + ] + }, "PackageInfoV2": { "title": "PackageInfoV2", "description": "this is the each item output of ll-cli list --json", @@ -1417,6 +1438,9 @@ "PackageManager1Package": { "$ref": "#/$defs/PackageManager1Package" }, + "PackageInfoDisplay": { + "$ref": "#/$defs/PackageInfoDisplay" + }, "PackageInfoV2": { "$ref": "#/$defs/PackageInfoV2" }, diff --git a/api/schema/v1.yaml b/api/schema/v1.yaml index 4176077aa..60311d8e2 100644 --- a/api/schema/v1.yaml +++ b/api/schema/v1.yaml @@ -508,6 +508,18 @@ $defs: module: type: string description: module of package manager + PackageInfoDisplay: + title: PackageInfoDisplay + description: this is the each item output of ll-cli list --json + allOf: + - $ref: '#/$defs/PackageInfoV2' + - type: object + requested: + - info + properties: + install_time: + type: integer + description: package install time PackageInfoV2: title: PackageInfoV2 description: this is the each item output of ll-cli list --json diff --git a/libs/api/src/linglong/api/types/v1/Generators.hpp b/libs/api/src/linglong/api/types/v1/Generators.hpp index 51c7afb83..f89e9630e 100644 --- a/libs/api/src/linglong/api/types/v1/Generators.hpp +++ b/libs/api/src/linglong/api/types/v1/Generators.hpp @@ -46,6 +46,7 @@ #include "linglong/api/types/v1/PackageManager1GetRepoInfoResult.hpp" #include "linglong/api/types/v1/PackageManager1GetRepoInfoResultRepoInfo.hpp" #include "linglong/api/types/v1/PackageInfoV2.hpp" +#include "linglong/api/types/v1/PackageInfoDisplay.hpp" #include "linglong/api/types/v1/PackageInfo.hpp" #include "linglong/api/types/v1/OciConfigurationPatch.hpp" #include "linglong/api/types/v1/LayerInfo.hpp" @@ -164,6 +165,9 @@ void to_json(json & j, const OciConfigurationPatch & x); void from_json(const json & j, PackageInfo & x); void to_json(json & j, const PackageInfo & x); +void from_json(const json & j, PackageInfoDisplay & x); +void to_json(json & j, const PackageInfoDisplay & x); + void from_json(const json & j, PackageInfoV2 & x); void to_json(json & j, const PackageInfoV2 & x); @@ -730,6 +734,69 @@ j["size"] = x.size; j["version"] = x.version; } +inline void from_json(const json & j, PackageInfoDisplay& x) { +x.arch = j.at("arch").get>(); +x.base = j.at("base").get(); +x.channel = j.at("channel").get(); +x.command = get_stack_optional>(j, "command"); +x.compatibleVersion = get_stack_optional(j, "compatible_version"); +x.description = get_stack_optional(j, "description"); +x.extImpl = get_stack_optional(j, "ext_impl"); +x.extensions = get_stack_optional>(j, "extensions"); +x.id = j.at("id").get(); +x.kind = j.at("kind").get(); +x.packageInfoDisplayModule = j.at("module").get(); +x.name = j.at("name").get(); +x.permissions = get_stack_optional(j, "permissions"); +x.runtime = get_stack_optional(j, "runtime"); +x.schemaVersion = j.at("schema_version").get(); +x.size = j.at("size").get(); +x.uuid = get_stack_optional(j, "uuid"); +x.version = j.at("version").get(); +x.installTime = get_stack_optional(j, "install_time"); +} + +inline void to_json(json & j, const PackageInfoDisplay & x) { +j = json::object(); +j["arch"] = x.arch; +j["base"] = x.base; +j["channel"] = x.channel; +if (x.command) { +j["command"] = x.command; +} +if (x.compatibleVersion) { +j["compatible_version"] = x.compatibleVersion; +} +if (x.description) { +j["description"] = x.description; +} +if (x.extImpl) { +j["ext_impl"] = x.extImpl; +} +if (x.extensions) { +j["extensions"] = x.extensions; +} +j["id"] = x.id; +j["kind"] = x.kind; +j["module"] = x.packageInfoDisplayModule; +j["name"] = x.name; +if (x.permissions) { +j["permissions"] = x.permissions; +} +if (x.runtime) { +j["runtime"] = x.runtime; +} +j["schema_version"] = x.schemaVersion; +j["size"] = x.size; +if (x.uuid) { +j["uuid"] = x.uuid; +} +j["version"] = x.version; +if (x.installTime) { +j["install_time"] = x.installTime; +} +} + inline void from_json(const json & j, PackageInfoV2& x) { x.arch = j.at("arch").get>(); x.base = j.at("base").get(); @@ -1169,6 +1236,7 @@ x.interactionRequest = get_stack_optional(j, "InteractionReq x.layerInfo = get_stack_optional(j, "LayerInfo"); x.ociConfigurationPatch = get_stack_optional(j, "OCIConfigurationPatch"); x.packageInfo = get_stack_optional(j, "PackageInfo"); +x.packageInfoDisplay = get_stack_optional(j, "PackageInfoDisplay"); x.packageInfoV2 = get_stack_optional(j, "PackageInfoV2"); x.packageManager1GetRepoInfoResult = get_stack_optional(j, "PackageManager1GetRepoInfoResult"); x.packageManager1InstallLayerFDResult = get_stack_optional(j, "PackageManager1InstallLayerFDResult"); @@ -1260,6 +1328,9 @@ j["OCIConfigurationPatch"] = x.ociConfigurationPatch; if (x.packageInfo) { j["PackageInfo"] = x.packageInfo; } +if (x.packageInfoDisplay) { +j["PackageInfoDisplay"] = x.packageInfoDisplay; +} if (x.packageInfoV2) { j["PackageInfoV2"] = x.packageInfoV2; } diff --git a/libs/api/src/linglong/api/types/v1/LinglongAPIV1.hpp b/libs/api/src/linglong/api/types/v1/LinglongAPIV1.hpp index c5b26384c..5109370ba 100644 --- a/libs/api/src/linglong/api/types/v1/LinglongAPIV1.hpp +++ b/libs/api/src/linglong/api/types/v1/LinglongAPIV1.hpp @@ -37,6 +37,7 @@ #include "linglong/api/types/v1/LayerInfo.hpp" #include "linglong/api/types/v1/OciConfigurationPatch.hpp" #include "linglong/api/types/v1/PackageInfo.hpp" +#include "linglong/api/types/v1/PackageInfoDisplay.hpp" #include "linglong/api/types/v1/PackageInfoV2.hpp" #include "linglong/api/types/v1/PackageManager1GetRepoInfoResult.hpp" #include "linglong/api/types/v1/PackageManager1InstallParameters.hpp" @@ -107,6 +108,7 @@ std::optional interactionRequest; std::optional layerInfo; std::optional ociConfigurationPatch; std::optional packageInfo; +std::optional packageInfoDisplay; std::optional packageInfoV2; std::optional packageManager1GetRepoInfoResult; std::optional packageManager1InstallLayerFDResult; diff --git a/libs/api/src/linglong/api/types/v1/PackageInfoDisplay.hpp b/libs/api/src/linglong/api/types/v1/PackageInfoDisplay.hpp new file mode 100644 index 000000000..eaa23fcdb --- /dev/null +++ b/libs/api/src/linglong/api/types/v1/PackageInfoDisplay.hpp @@ -0,0 +1,119 @@ +// This file is generated by tools/codegen.sh +// DO NOT EDIT IT. + +// clang-format off + +// To parse this JSON data, first install +// +// json.hpp https://github.com/nlohmann/json +// +// Then include this file, and then do +// +// PackageInfoDisplay.hpp data = nlohmann::json::parse(jsonString); + +#pragma once + +#include +#include +#include "linglong/api/types/v1/helper.hpp" + +#include "linglong/api/types/v1/ExtensionImpl.hpp" +#include "linglong/api/types/v1/ExtensionDefine.hpp" +#include "linglong/api/types/v1/ApplicationConfigurationPermissions.hpp" + +namespace linglong { +namespace api { +namespace types { +namespace v1 { +/** +* this is the each item output of ll-cli list --json +* +* package info of package manager search +*/ + +using nlohmann::json; + +/** +* this is the each item output of ll-cli list --json +* +* package info of package manager search +*/ +struct PackageInfoDisplay { +/** +* arch of package info +*/ +std::vector arch; +/** +* base of package info +*/ +std::string base; +/** +* channel of package info +*/ +std::string channel; +/** +* command of package info +*/ +std::optional> command; +/** +* record linyaps package is compatible with linyaps component version +*/ +std::optional compatibleVersion; +/** +* description of package info +*/ +std::optional description; +std::optional extImpl; +/** +* description of extension +*/ +std::optional> extensions; +/** +* id of package info +*/ +std::string id; +/** +* kind of package info +*/ +std::string kind; +/** +* module of package info +*/ +std::string packageInfoDisplayModule; +/** +* name of package info +*/ +std::string name; +std::optional permissions; +/** +* runtime of package info +*/ +std::optional runtime; +/** +* version of 'PackageInfo' +*/ +std::string schemaVersion; +/** +* Uncompressed package size in bytes +*/ +int64_t size; +/** +* this property is only used for app which instead from UAB and it should be null in other +* conditions. +*/ +std::optional uuid; +/** +* version of package info +*/ +std::string version; +/** +* package install time +*/ +std::optional installTime; +}; +} +} +} +} + +// clang-format on diff --git a/libs/linglong/src/linglong/builder/builder_releases.qrc b/libs/linglong/src/linglong/builder/builder_releases.qrc index f970b59e1..333adedd0 100644 --- a/libs/linglong/src/linglong/builder/builder_releases.qrc +++ b/libs/linglong/src/linglong/builder/builder_releases.qrc @@ -13,6 +13,5 @@ SPDX-License-Identifier: LGPL-3.0-or-later ../../../../../misc/libexec/linglong/fetch-file-source ../../../../../misc/libexec/linglong/fetch-archive-source ../../../../../misc/libexec/linglong/app-conf-generator - ../../../../../misc/lib/linglong/container/config.json diff --git a/libs/linglong/src/linglong/builder/linglong_builder.cpp b/libs/linglong/src/linglong/builder/linglong_builder.cpp index 7672a5d9f..9b5c4a841 100644 --- a/libs/linglong/src/linglong/builder/linglong_builder.cpp +++ b/libs/linglong/src/linglong/builder/linglong_builder.cpp @@ -1854,11 +1854,12 @@ utils::error::Result Builder::run(const QStringList &modules, .type = "bind", }); - QDir appCache = this->workingDir.absoluteFilePath("linglong/cache"); + auto appCache = std::filesystem::path{ workingDir.absolutePath().toStdString() } / "linglong" / "cache"; + std::string ldConfPath = appCache / "ld.so.conf"; applicationMounts.push_back(ocppi::runtime::config::types::Mount{ .destination = "/etc/ld.so.conf.d/zz_deepin-linglong-app.conf", .options = { { "rbind", "ro" } }, - .source = appCache.absoluteFilePath("ld.so.conf").toStdString(), + .source = ldConfPath, .type = "bind", }); @@ -1874,13 +1875,25 @@ utils::error::Result Builder::run(const QStringList &modules, return LINGLONG_ERR(res); } cfgBuilder.setAppId(curRef->id.toStdString()) - .setAppCache(appCache.absolutePath().toStdString(), false) + .setAppCache(appCache, false) .addUIdMapping(uid, uid, 1) .addGIdMapping(gid, gid, 1) .bindDefault() .addExtraMounts(applicationMounts) .enableSelfAdjustingMount(); + // write ld.so.conf + std::string triplet = curRef->arch.getTriplet().toStdString(); + std::string ldRawConf = cfgBuilder.ldConf(triplet); + + QFile ldsoconf{ ldConfPath.c_str() }; + if (!ldsoconf.open(QIODevice::WriteOnly)) { + return LINGLONG_ERR(ldsoconf); + } + ldsoconf.write(ldRawConf.c_str()); + // must be closed here, this conf will be used later. + ldsoconf.close(); + if (!cfgBuilder.build()) { auto err = cfgBuilder.getError(); return LINGLONG_ERR("build cfg error: " + QString::fromStdString(err.reason)); @@ -1911,7 +1924,7 @@ utils::error::Result Builder::run(const QStringList &modules, return LINGLONG_ERR(res); } cfgBuilder.setAppId(curRef->id.toStdString()) - .setAppCache(appCache.absolutePath().toStdString()) + .setAppCache(appCache) .enableLDCache() .addUIdMapping(uid, uid, 1) .addGIdMapping(gid, gid, 1) diff --git a/libs/linglong/src/linglong/cli/cli.cpp b/libs/linglong/src/linglong/cli/cli.cpp index 206b47247..c56123e3f 100644 --- a/libs/linglong/src/linglong/cli/cli.cpp +++ b/libs/linglong/src/linglong/cli/cli.cpp @@ -10,6 +10,8 @@ #include "linglong/api/dbus/v1/dbus_peer.h" #include "linglong/api/types/v1/InteractionReply.hpp" #include "linglong/api/types/v1/InteractionRequest.hpp" +#include "linglong/api/types/v1/LinglongAPIV1.hpp" +#include "linglong/api/types/v1/PackageInfoDisplay.hpp" #include "linglong/api/types/v1/PackageInfoV2.hpp" #include "linglong/api/types/v1/PackageManager1InstallParameters.hpp" #include "linglong/api/types/v1/PackageManager1JobInfo.hpp" @@ -19,6 +21,7 @@ #include "linglong/api/types/v1/PackageManager1SearchParameters.hpp" #include "linglong/api/types/v1/PackageManager1SearchResult.hpp" #include "linglong/api/types/v1/PackageManager1UninstallParameters.hpp" +#include "linglong/api/types/v1/RepositoryCacheLayersItem.hpp" #include "linglong/api/types/v1/State.hpp" #include "linglong/api/types/v1/SubState.hpp" #include "linglong/api/types/v1/UpgradeListResult.hpp" @@ -39,7 +42,10 @@ #include "ocppi/runtime/Signal.hpp" #include "ocppi/types/ContainerListItem.hpp" +#include +#include #include +#include #include #include @@ -48,6 +54,7 @@ #include #include #include +#include #include #include #include @@ -1699,22 +1706,28 @@ int Cli::uninstall([[maybe_unused]] CLI::App *subcommand) } int Cli::list([[maybe_unused]] CLI::App *subcommand) + { if (!options.showUpgradeList) { - auto pkgs = this->repository.listLocal(); - if (!pkgs) { - this->printer.printErr(pkgs.error()); + auto items = this->repository.listLayerItem(); + if (!items) { + this->printer.printErr(items.error()); return -1; } - - auto localPkgs = std::map>{ - { "local", std::move(pkgs).value() } - }; - + std::vector list; + for (const auto &item : *items) { + nlohmann::json json = item.info; + auto m = json.get(); + auto t = this->repository.getLayerCreateTime(item); + if (t.has_value()) { + m.installTime = *t; + } + list.push_back(std::move(m)); + } if (!options.type.empty()) { - filterPackageInfosByType(localPkgs, options.type); + filterPackageInfosByType(list, options.type); } - this->printer.printPackages(localPkgs["local"]); + this->printer.printPackages(list); return 0; } @@ -2251,6 +2264,20 @@ void Cli::filterPackageInfosByType( list = std::move(filtered); } +void Cli::filterPackageInfosByType(std::vector &list, + const std::string &type) +{ + if (type == "all") { + return; + } + list.erase(std::remove_if(list.begin(), + list.end(), + [&type](const api::types::v1::PackageInfoDisplay &pkg) { + return pkg.kind == type; + }), + list.end()); +} + utils::error::Result Cli::filterPackageInfosByVersion( std::map> &list) noexcept { @@ -2390,11 +2417,9 @@ Cli::RequestDirectories(const api::types::v1::PackageInfoV2 &info) noexcept ::close(fd); }); - struct flock lock{ - .l_type = F_WRLCK, - .l_whence = SEEK_SET, - .l_start = 0, - .l_len = 0, + struct flock lock + { + .l_type = F_WRLCK, .l_whence = SEEK_SET, .l_start = 0, .l_len = 0, }; // all later processes should be blocked diff --git a/libs/linglong/src/linglong/cli/cli.h b/libs/linglong/src/linglong/cli/cli.h index c6b92e7de..bb57528e0 100644 --- a/libs/linglong/src/linglong/cli/cli.h +++ b/libs/linglong/src/linglong/cli/cli.h @@ -9,6 +9,8 @@ #include "linglong/api/dbus/v1/package_manager.h" #include "linglong/api/dbus/v1/task.h" #include "linglong/api/types/v1/CommonOptions.hpp" +#include "linglong/api/types/v1/PackageInfoDisplay.hpp" +#include "linglong/api/types/v1/RepositoryCacheLayersItem.hpp" #include "linglong/cli/interactive_notifier.h" #include "linglong/cli/printer.h" #include "linglong/repo/ostree_repo.h" @@ -99,9 +101,12 @@ class Cli : public QObject filePathMapping(const std::vector &command) const noexcept; static std::string mappingFile(const std::filesystem::path &file) noexcept; static std::string mappingUrl(std::string_view url) noexcept; + static void filterPackageInfosByType( std::map> &list, const std::string &type) noexcept; + static void filterPackageInfosByType(std::vector &list, + const std::string &type); static utils::error::Result filterPackageInfosByVersion( std::map> &list) noexcept; void printProgress() noexcept; diff --git a/libs/linglong/src/linglong/cli/cli_printer.cpp b/libs/linglong/src/linglong/cli/cli_printer.cpp index a88b78ac7..33fc44ee6 100644 --- a/libs/linglong/src/linglong/cli/cli_printer.cpp +++ b/libs/linglong/src/linglong/cli/cli_printer.cpp @@ -67,7 +67,7 @@ std::string adjustDisplayWidth(const QString &str, int targetWidth) return (str + QString(targetWidth - currentWidth, QChar(' '))).toStdString(); } -void CLIPrinter::printPackages(const std::vector &list) +void CLIPrinter::printPackages(const std::vector &list) { std::cout << "\033[38;5;214m" << std::left << adjustDisplayWidth(qUtf8Printable(_("ID")), 43) << adjustDisplayWidth(qUtf8Printable(_("Name")), 33) @@ -96,7 +96,7 @@ void CLIPrinter::printPackages(const std::vector auto nameOffset = nameStr.size() - nameWcswidth; std::cout << std::setw(43) << info.id + " " << std::setw(33 + nameOffset) << nameStr + " " << std::setw(16) << info.version + " " << std::setw(16) << info.channel + " " - << std::setw(12) << info.packageInfoV2Module + " " + << std::setw(12) << info.packageInfoDisplayModule + " " << simpleDescription.toStdString() << std::endl; } } diff --git a/libs/linglong/src/linglong/cli/cli_printer.h b/libs/linglong/src/linglong/cli/cli_printer.h index eced97541..b4781be34 100644 --- a/libs/linglong/src/linglong/cli/cli_printer.h +++ b/libs/linglong/src/linglong/cli/cli_printer.h @@ -35,7 +35,7 @@ class CLIPrinter : public Printer void printErr(const utils::error::Error &) override; void printPackage(const api::types::v1::PackageInfoV2 &) override; - void printPackages(const std::vector &) override; + void printPackages(const std::vector &) override; void printSearchResult(std::map>) override; void printPruneResult(const std::vector &list) override; diff --git a/libs/linglong/src/linglong/cli/json_printer.cpp b/libs/linglong/src/linglong/cli/json_printer.cpp index c829cc8fc..4687fba78 100644 --- a/libs/linglong/src/linglong/cli/json_printer.cpp +++ b/libs/linglong/src/linglong/cli/json_printer.cpp @@ -7,6 +7,7 @@ #include "linglong/cli/json_printer.h" #include "linglong/api/types/v1/Generators.hpp" +#include "linglong/cli/cli.h" #include "linglong/package/version.h" #include @@ -28,6 +29,11 @@ void JSONPrinter::printPackage(const api::types::v1::PackageInfoV2 &info) std::cout << nlohmann::json(info).dump() << std::endl; } +void JSONPrinter::printPackages(const std::vector &list) +{ + std::cout << nlohmann::json(list).dump() << std::endl; +} + void JSONPrinter::printPackages(const std::vector &list) { std::cout << nlohmann::json(list).dump() << std::endl; diff --git a/libs/linglong/src/linglong/cli/json_printer.h b/libs/linglong/src/linglong/cli/json_printer.h index cb367a4fb..5998ddc08 100644 --- a/libs/linglong/src/linglong/cli/json_printer.h +++ b/libs/linglong/src/linglong/cli/json_printer.h @@ -6,16 +6,21 @@ #pragma once +#include "linglong/api/types/v1/PackageInfoV2.hpp" +#include "linglong/cli/cli.h" #include "linglong/cli/printer.h" namespace linglong::cli { class JSONPrinter : public Printer { +private: + void printPackages(const std::vector &); + public: void printErr(const utils::error::Error &) override; void printPackage(const api::types::v1::PackageInfoV2 &) override; - void printPackages(const std::vector &) override; + void printPackages(const std::vector &) override; void printSearchResult(std::map>) override; void printPruneResult(const std::vector &) override; diff --git a/libs/linglong/src/linglong/cli/printer.h b/libs/linglong/src/linglong/cli/printer.h index 69828398a..cc9ad6340 100644 --- a/libs/linglong/src/linglong/cli/printer.h +++ b/libs/linglong/src/linglong/cli/printer.h @@ -10,11 +10,13 @@ #include "linglong/api/types/v1/CommonResult.hpp" #include "linglong/api/types/v1/InspectResult.hpp" #include "linglong/api/types/v1/LayerInfo.hpp" +#include "linglong/api/types/v1/PackageInfoDisplay.hpp" #include "linglong/api/types/v1/PackageInfoV2.hpp" #include "linglong/api/types/v1/RepoConfigV2.hpp" #include "linglong/api/types/v1/State.hpp" #include "linglong/api/types/v1/SubState.hpp" #include "linglong/api/types/v1/UpgradeListResult.hpp" +#include "linglong/cli/cli.h" #include "linglong/utils/error/error.h" namespace linglong::cli { @@ -75,7 +77,7 @@ class Printer virtual void printErr(const utils::error::Error &) = 0; virtual void printPackage(const api::types::v1::PackageInfoV2 &) = 0; - virtual void printPackages(const std::vector &) = 0; + virtual void printPackages(const std::vector &) = 0; virtual void printSearchResult(std::map>) = 0; virtual void printPruneResult(const std::vector &) = 0; diff --git a/libs/linglong/src/linglong/repo/ostree_repo.cpp b/libs/linglong/src/linglong/repo/ostree_repo.cpp index bc16f9db7..4c1eee26a 100644 --- a/libs/linglong/src/linglong/repo/ostree_repo.cpp +++ b/libs/linglong/src/linglong/repo/ostree_repo.cpp @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -1548,12 +1549,7 @@ utils::error::Result> OSTreeRepo::listLocal() const noexcept { std::vector pkgInfos; - - QDir layersDir = this->repoDir.absoluteFilePath("layers"); - Q_ASSERT(layersDir.exists()); - auto items = this->cache->queryExistingLayerItem(); - pkgInfos.reserve(items.size()); for (const auto &item : items) { if (item.deleted && item.deleted.value()) { continue; @@ -1565,6 +1561,23 @@ OSTreeRepo::listLocal() const noexcept return pkgInfos; } +utils::error::Result> +OSTreeRepo::listLayerItem() const noexcept +{ + return this->cache->queryExistingLayerItem(); +} + +utils::error::Result +OSTreeRepo::getLayerCreateTime(const api::types::v1::RepositoryCacheLayersItem &item) const noexcept +{ + LINGLONG_TRACE("get install time"); + auto dir = this->getLayerDir(item); + if (!dir.has_value()) { + return LINGLONG_ERR("get layer dir", dir); + } + return QFileInfo(dir->absolutePath()).birthTime().toSecsSinceEpoch(); +} + // Note: Since version 1.7.0, multiple versions are no longer supported, so there will be multiple // versions locally. In some places, we need to list the latest version of each package. utils::error::Result> diff --git a/libs/linglong/src/linglong/repo/ostree_repo.h b/libs/linglong/src/linglong/repo/ostree_repo.h index 337ced2b2..126ab6c1d 100644 --- a/libs/linglong/src/linglong/repo/ostree_repo.h +++ b/libs/linglong/src/linglong/repo/ostree_repo.h @@ -6,6 +6,7 @@ #pragma once +#include "linglong/api/types/v1/PackageInfoV2.hpp" #include "linglong/api/types/v1/Repo.hpp" #include "linglong/api/types/v1/RepoConfigV2.hpp" #include "linglong/package/fuzzy_reference.h" @@ -40,6 +41,7 @@ struct getRemoteReferenceByPriorityOption }; class OSTreeRepo : public QObject + { Q_OBJECT public: @@ -102,9 +104,13 @@ class OSTreeRepo : public QObject utils::error::Result> listRemote(const package::FuzzyReference &fuzzyRef, const std::optional &repo = std::nullopt) const noexcept; + + utils::error::Result> + listLayerItem() const noexcept; [[nodiscard]] utils::error::Result> listLocalBy(const linglong::repo::repoCacheQuery &query) const noexcept; - + utils::error::Result + getLayerCreateTime(const api::types::v1::RepositoryCacheLayersItem &item) const noexcept; utils::error::Result remove(const package::Reference &ref, const std::string &module = "binary", diff --git a/libs/linglong/src/linglong/repo/repo_cache.cpp b/libs/linglong/src/linglong/repo/repo_cache.cpp index 3069a69e4..14f03edc6 100644 --- a/libs/linglong/src/linglong/repo/repo_cache.cpp +++ b/libs/linglong/src/linglong/repo/repo_cache.cpp @@ -60,7 +60,7 @@ RepoCache::create(const std::filesystem::path &cacheFile, repoCache->cache = std::move(result).value(); if (repoCache->cache.version != enableMaker::cacheFileVersion || repoCache->cache.llVersion != LINGLONG_VERSION) { - std::cout << "The existing cache is outdated, rebuild cache..." << std::endl; + std::cerr << "The existing cache is outdated, rebuild cache..." << std::endl; auto ret = repoCache->rebuildCache(repoConfig, repo); if (!ret) { return LINGLONG_ERR(ret); @@ -135,7 +135,7 @@ utils::error::Result RepoCache::rebuildCache(const api::types::v1::RepoCon // FIXME: ll-cli may initialize repo, it can make states.json own by root if (getuid() == 0) { - qWarning() << "Rebuild the cache by root, skip to write data to states.json"; + std::cerr << "Rebuild the cache by root, skip to write data to states.json"; return LINGLONG_OK; } diff --git a/libs/linglong/src/linglong/runtime/container.cpp b/libs/linglong/src/linglong/runtime/container.cpp index 906b9b6fb..c24d4926b 100644 --- a/libs/linglong/src/linglong/runtime/container.cpp +++ b/libs/linglong/src/linglong/runtime/container.cpp @@ -190,13 +190,7 @@ utils::error::Result Container::run(const ocppi::runtime::config::types::P }); auto originalArgs = - this->cfg.process->args.value_or(std::vector{ "echo", "'noting to run'" }); - QStringList appArgs; - std::transform(originalArgs.begin(), - originalArgs.end(), - std::back_inserter(appArgs), - QString::fromStdString); - appArgs.prepend("exec"); + this->cfg.process->args.value_or(std::vector{ "echo", "noting to run" }); auto entrypoint = bundle / "entrypoint.sh"; { @@ -211,7 +205,26 @@ utils::error::Result Container::run(const ocppi::runtime::config::types::P ofs << "#!/run/linglong/container-init /bin/bash\n"; ofs << "source /etc/profile\n"; // we need use /etc/profile to generate all needed // environment variables - ofs << appArgs.join(' ').toStdString(); + ofs << "exec "; + + // quote the argument to avoid the space in the argument and use single quote to avoid the + // shell to expand the argument + // example: + // arg: "let's go" + // quoteArg: "'let'\''s go'" + auto quoteArg = [](std::string arg) { + const std::string quotePrefix = "'\\"; + for (auto it = arg.begin(); it != arg.end(); it++) { + if (*it == '\'') { + it = arg.insert(it, quotePrefix.cbegin(), quotePrefix.cend()); + it = arg.insert(it + quotePrefix.size() + 1, 1, '\''); + } + } + return "'" + arg + "'"; + }; + for (auto arg : originalArgs) { + ofs << quoteArg(arg) << " "; + } } std::filesystem::permissions(entrypoint, std::filesystem::perms::owner_all, ec); diff --git a/misc/CMakeLists.txt b/misc/CMakeLists.txt index 5dc59f991..992880fbc 100644 --- a/misc/CMakeLists.txt +++ b/misc/CMakeLists.txt @@ -25,17 +25,6 @@ configure_files( libexec/linglong/fetch-git-source libexec/linglong/font-cache-generator libexec/linglong/ld-cache-generator - lib/linglong/container/config.d/00-id-mapping - lib/linglong/container/config.d/05-initialize - lib/linglong/container/config.d/10-basics.json - lib/linglong/container/config.d/20-devices - lib/linglong/container/config.d/25-host-env - lib/linglong/container/config.d/25-host-rootfs.json - lib/linglong/container/config.d/25-host-statics.json - lib/linglong/container/config.d/30-user-home - lib/linglong/container/config.d/40-host-ipc - lib/linglong/container/config.d/90-legacy - lib/linglong/container/config.json lib/linglong/container/README.md lib/linglong/generate-xdg-data-dirs.sh lib/systemd/system-environment-generators/61-linglong @@ -108,29 +97,13 @@ install( DESTINATION ${LIBEXEC_LINGLONG_BUILDER_DIR}/helper) # linglong -set(LINGLONG_CONFIG_DIR - ${CMAKE_CURRENT_BINARY_DIR}/lib/linglong/container/config.d) install( PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/lib/linglong/generate-xdg-data-dirs.sh DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/linglong) -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/lib/linglong/container/config.json - ${CMAKE_CURRENT_BINARY_DIR}/lib/linglong/container/README.md +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/lib/linglong/container/README.md DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/linglong/container) -install( - FILES ${LINGLONG_CONFIG_DIR}/10-basics.json - ${LINGLONG_CONFIG_DIR}/25-host-rootfs.json - ${LINGLONG_CONFIG_DIR}/25-host-statics.json - ${LINGLONG_CONFIG_DIR}/00-id-mapping - ${LINGLONG_CONFIG_DIR}/05-initialize - ${LINGLONG_CONFIG_DIR}/20-devices - ${LINGLONG_CONFIG_DIR}/25-host-env - ${LINGLONG_CONFIG_DIR}/30-user-home - ${LINGLONG_CONFIG_DIR}/40-host-ipc - ${LINGLONG_CONFIG_DIR}/90-legacy - DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/linglong/container/config.d) - # linglong default configuration install(FILES ${CMAKE_CURRENT_LIST_DIR}/share/linglong/config.yaml DESTINATION ${CMAKE_INSTALL_PREFIX}/share/linglong) diff --git a/misc/lib/linglong/container/config.d/00-id-mapping b/misc/lib/linglong/container/config.d/00-id-mapping deleted file mode 100644 index 3e575a283..000000000 --- a/misc/lib/linglong/container/config.d/00-id-mapping +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash - -# SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. -# -# SPDX-License-Identifier: LGPL-3.0-or-later - -echo "This is a placeholder file for using builtin oci configuration generator. -If you want to customize the behavior of current generator, -you could replace this file with a same name executable file." 1>&2 - -exit 255 diff --git a/misc/lib/linglong/container/config.d/05-initialize b/misc/lib/linglong/container/config.d/05-initialize deleted file mode 100644 index 3e575a283..000000000 --- a/misc/lib/linglong/container/config.d/05-initialize +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash - -# SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. -# -# SPDX-License-Identifier: LGPL-3.0-or-later - -echo "This is a placeholder file for using builtin oci configuration generator. -If you want to customize the behavior of current generator, -you could replace this file with a same name executable file." 1>&2 - -exit 255 diff --git a/misc/lib/linglong/container/config.d/10-basics.json b/misc/lib/linglong/container/config.d/10-basics.json deleted file mode 100644 index cb18820cb..000000000 --- a/misc/lib/linglong/container/config.d/10-basics.json +++ /dev/null @@ -1,110 +0,0 @@ -{ - "ociVersion": "1.0.1", - "patch": [ - { - "op": "add", - "path": "/mounts/-", - "value": { - "destination": "/sys", - "type": "bind", - "source": "/sys", - "options": ["rbind", "nosuid", "noexec", "nodev"] - } - }, - { - "op": "add", - "path": "/mounts/-", - "value": { - "destination": "/proc", - "type": "proc", - "source": "proc" - } - }, - { - "op": "add", - "path": "/mounts/-", - "value": { - "destination": "/dev", - "type": "tmpfs", - "source": "tmpfs", - "options": ["nosuid", "strictatime", "mode=0755", "size=65536k"] - } - }, - { - "op": "add", - "path": "/mounts/-", - "value": { - "destination": "/dev/pts", - "type": "devpts", - "source": "devpts", - "options": [ - "nosuid", - "noexec", - "newinstance", - "ptmxmode=0666", - "mode=0620" - ] - } - }, - { - "op": "add", - "path": "/mounts/-", - "value": { - "destination": "/dev/shm", - "type": "tmpfs", - "source": "shm", - "options": ["nosuid", "noexec", "nodev", "mode=1777"] - } - }, - { - "op": "add", - "path": "/mounts/-", - "value": { - "destination": "/dev/mqueue", - "type": "bind", - "source": "/dev/mqueue", - "options": ["rbind", "nosuid", "noexec", "nodev"] - } - }, - { - "op": "add", - "path": "/mounts/-", - "value": { - "destination": "/sys/fs/cgroup", - "type": "cgroup", - "source": "cgroup", - "options": ["nosuid", "noexec", "nodev", "relatime", "ro"] - } - }, - { - "op": "add", - "path": "/mounts/-", - "value": { - "destination": "/run", - "type": "tmpfs", - "source": "tmpfs", - "options": ["nosuid", "strictatime", "mode=0755", "size=65536k"] - } - }, - { - "op": "add", - "path": "/mounts/-", - "value": { - "destination": "/run/udev", - "type": "bind", - "source": "/run/udev", - "options": ["rbind"] - } - }, - { - "op": "add", - "path": "/mounts/-", - "value": { - "destination": "/etc/passwd", - "type": "bind", - "source": "/etc/passwd", - "options": ["ro", "rbind"] - } - } - ] -} diff --git a/misc/lib/linglong/container/config.d/20-devices b/misc/lib/linglong/container/config.d/20-devices deleted file mode 100644 index 3e575a283..000000000 --- a/misc/lib/linglong/container/config.d/20-devices +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash - -# SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. -# -# SPDX-License-Identifier: LGPL-3.0-or-later - -echo "This is a placeholder file for using builtin oci configuration generator. -If you want to customize the behavior of current generator, -you could replace this file with a same name executable file." 1>&2 - -exit 255 diff --git a/misc/lib/linglong/container/config.d/25-host-env b/misc/lib/linglong/container/config.d/25-host-env deleted file mode 100644 index 3e575a283..000000000 --- a/misc/lib/linglong/container/config.d/25-host-env +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash - -# SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. -# -# SPDX-License-Identifier: LGPL-3.0-or-later - -echo "This is a placeholder file for using builtin oci configuration generator. -If you want to customize the behavior of current generator, -you could replace this file with a same name executable file." 1>&2 - -exit 255 diff --git a/misc/lib/linglong/container/config.d/25-host-rootfs.json b/misc/lib/linglong/container/config.d/25-host-rootfs.json deleted file mode 100644 index a44f79beb..000000000 --- a/misc/lib/linglong/container/config.d/25-host-rootfs.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "ociVersion": "1.0.1", - "patch": [ - { - "op": "add", - "path": "/mounts/-", - "value": { - "destination": "/run/host", - "type": "tmpfs", - "source": "tmpfs", - "options": ["nodev", "nosuid", "mode=700"] - } - }, - { - "op": "add", - "path": "/mounts/-", - "value": { - "destination": "/run/host/rootfs", - "type": "bind", - "source": "/", - "options": ["rbind"] - } - } - ] -} diff --git a/misc/lib/linglong/container/config.d/25-host-statics.json b/misc/lib/linglong/container/config.d/25-host-statics.json deleted file mode 100644 index ae305297b..000000000 --- a/misc/lib/linglong/container/config.d/25-host-statics.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "ociVersion": "1.0.1", - "patch": [ - { - "op": "add", - "path": "/mounts/-", - "value": { - "destination": "/usr/share/fonts", - "type": "bind", - "source": "/usr/share/fonts", - "options": ["rbind", "ro"] - } - }, - { - "op": "add", - "path": "/mounts/-", - "value": { - "destination": "/usr/share/icons", - "type": "bind", - "source": "/usr/share/icons", - "options": ["rbind", "ro"] - } - }, - { - "op": "add", - "path": "/mounts/-", - "value": { - "destination": "/etc/ssl/certs", - "type": "bind", - "source": "/etc/ssl/certs", - "options": ["rbind", "ro"] - } - }, - { - "op": "add", - "path": "/mounts/-", - "value": { - "destination": "/etc/machine-id", - "type": "bind", - "source": "/etc/machine-id", - "options": ["rbind", "ro"] - } - }, - { - "op": "add", - "path": "/mounts/-", - "value": { - "destination": "/usr/share/themes", - "type": "bind", - "source": "/usr/share/themes", - "options": ["rbind", "ro"] - } - } - ] -} diff --git a/misc/lib/linglong/container/config.d/30-user-home b/misc/lib/linglong/container/config.d/30-user-home deleted file mode 100644 index 3e575a283..000000000 --- a/misc/lib/linglong/container/config.d/30-user-home +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash - -# SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. -# -# SPDX-License-Identifier: LGPL-3.0-or-later - -echo "This is a placeholder file for using builtin oci configuration generator. -If you want to customize the behavior of current generator, -you could replace this file with a same name executable file." 1>&2 - -exit 255 diff --git a/misc/lib/linglong/container/config.d/40-host-ipc b/misc/lib/linglong/container/config.d/40-host-ipc deleted file mode 100644 index 3e575a283..000000000 --- a/misc/lib/linglong/container/config.d/40-host-ipc +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash - -# SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. -# -# SPDX-License-Identifier: LGPL-3.0-or-later - -echo "This is a placeholder file for using builtin oci configuration generator. -If you want to customize the behavior of current generator, -you could replace this file with a same name executable file." 1>&2 - -exit 255 diff --git a/misc/lib/linglong/container/config.d/90-legacy b/misc/lib/linglong/container/config.d/90-legacy deleted file mode 100644 index 3e575a283..000000000 --- a/misc/lib/linglong/container/config.d/90-legacy +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash - -# SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. -# -# SPDX-License-Identifier: LGPL-3.0-or-later - -echo "This is a placeholder file for using builtin oci configuration generator. -If you want to customize the behavior of current generator, -you could replace this file with a same name executable file." 1>&2 - -exit 255 diff --git a/misc/lib/linglong/container/config.json b/misc/lib/linglong/container/config.json deleted file mode 100644 index 7e9c0a9bf..000000000 --- a/misc/lib/linglong/container/config.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "ociVersion": "1.0.1", - "hostname": "linglong", - "annotations": { - "org.deepin.linglong.appID": "" - }, - "root": { - "path": "" - }, - "linux": { - "namespaces": [ - { - "type": "pid" - }, - { - "type": "mount" - }, - { - "type": "uts" - }, - { - "type": "user" - } - ] - }, - "mounts": [], - "process": { - "env": [], - "cwd": "/", - "args": ["bash"] - } -}