Compare commits

...

62 Commits

Author SHA1 Message Date
guanzi008 336f39a95c
Merge bf24e8397e into dd641d0b94 2025-11-20 16:16:53 +08:00
EIC dd641d0b94 Update runtime documentation for version 25.2.1
build / ubuntu_24.04 (push) Has been cancelled Details
build / ubuntu_22.04 (push) Has been cancelled Details
coverage / codecov (push) Has been cancelled Details
更新 文档25.2.1 的运行时版本
2025-11-20 10:51:56 +08:00
transifex-integration[bot] 49236a8ce7 i18n: Translate policy.ts in sq
100% translated source file: 'policy.ts'
on 'sq'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] a228cf235d i18n: Translate policy.ts in bn
100% translated source file: 'policy.ts'
on 'bn'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] ba3673d8ad i18n: Translate policy.ts in hr
100% translated source file: 'policy.ts'
on 'hr'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] cd9e32e4d0 i18n: Translate policy.ts in de
100% translated source file: 'policy.ts'
on 'de'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] 38b4083a1b i18n: Translate policy.ts in ru
100% translated source file: 'policy.ts'
on 'ru'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] caab7a9ef2 i18n: Translate policy.ts in lo
100% translated source file: 'policy.ts'
on 'lo'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] d8af48d17b i18n: Translate policy.ts in vi
100% translated source file: 'policy.ts'
on 'vi'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] fea198a0d1 i18n: Translate policy.ts in el
100% translated source file: 'policy.ts'
on 'el'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] 9170842ab1 i18n: Translate policy.ts in mn
100% translated source file: 'policy.ts'
on 'mn'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] b97deb5e77 i18n: Translate policy.ts in bo
100% translated source file: 'policy.ts'
on 'bo'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] 2540402b4f i18n: Translate policy.ts in si
100% translated source file: 'policy.ts'
on 'si'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] 4993a8d407 i18n: Translate policy.ts in fr
100% translated source file: 'policy.ts'
on 'fr'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] 13177e9643 i18n: Translate policy.ts in ro
100% translated source file: 'policy.ts'
on 'ro'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] c79a4ec2ea i18n: Translate policy.ts in fa
100% translated source file: 'policy.ts'
on 'fa'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] 52348f941c i18n: Translate policy.ts in it
100% translated source file: 'policy.ts'
on 'it'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] 59d7355522 i18n: Translate policy.ts in ne
100% translated source file: 'policy.ts'
on 'ne'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] 17561cf2cd i18n: Translate policy.ts in az
100% translated source file: 'policy.ts'
on 'az'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] a6fc017b2b i18n: Translate policy.ts in id
100% translated source file: 'policy.ts'
on 'id'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] 693703ce09 i18n: Translate policy.ts in hu
100% translated source file: 'policy.ts'
on 'hu'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] 6b2d1188a8 i18n: Translate policy.ts in ko
100% translated source file: 'policy.ts'
on 'ko'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] 7510db3c60 i18n: Translate policy.ts in uk
100% translated source file: 'policy.ts'
on 'uk'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] 38a2e34684 i18n: Translate policy.ts in pt_BR
100% translated source file: 'policy.ts'
on 'pt_BR'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] dc63dea68b i18n: Translate policy.ts in da
100% translated source file: 'policy.ts'
on 'da'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] c795ef1d01 i18n: Translate policy.ts in cs
100% translated source file: 'policy.ts'
on 'cs'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] 053944192c i18n: Translate policy.ts in sw
100% translated source file: 'policy.ts'
on 'sw'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] 969e08087c i18n: Translate policy.ts in zh_TW
100% translated source file: 'policy.ts'
on 'zh_TW'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] af88083001 i18n: Translate policy.ts in gl_ES
100% translated source file: 'policy.ts'
on 'gl_ES'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] e5387b28a1 i18n: Translate policy.ts in kab
100% translated source file: 'policy.ts'
on 'kab'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] 2d13ca7a87 i18n: Translate policy.ts in ms
100% translated source file: 'policy.ts'
on 'ms'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] 8897dc4eb8 i18n: Translate policy.ts in sl
100% translated source file: 'policy.ts'
on 'sl'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] 778baaf7db i18n: Translate policy.ts in ja
100% translated source file: 'policy.ts'
on 'ja'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] 0ff728f693 i18n: Translate policy.ts in sr
100% translated source file: 'policy.ts'
on 'sr'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] 9bb80f2de2 i18n: Translate policy.ts in zh_CN
100% translated source file: 'policy.ts'
on 'zh_CN'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] 98d8f009a1 i18n: Translate policy.ts in tr
100% translated source file: 'policy.ts'
on 'tr'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] 8cabbc7dd8 i18n: Translate policy.ts in pt
100% translated source file: 'policy.ts'
on 'pt'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] 75ce1cf839 i18n: Translate policy.ts in en_GB
100% translated source file: 'policy.ts'
on 'en_GB'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] d9e5dc391a i18n: Translate policy.ts in ug
100% translated source file: 'policy.ts'
on 'ug'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] c460d8f920 i18n: Translate policy.ts in lt
100% translated source file: 'policy.ts'
on 'lt'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] e92dc86c42 i18n: Translate policy.ts in pl
100% translated source file: 'policy.ts'
on 'pl'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] 887e145965 i18n: Translate policy.ts in hi_IN
100% translated source file: 'policy.ts'
on 'hi_IN'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] 87dd23a9d0 i18n: Translate policy.ts in sk
100% translated source file: 'policy.ts'
on 'sk'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] 14af4861a4 i18n: Translate policy.ts in zh_HK
100% translated source file: 'policy.ts'
on 'zh_HK'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] d0b739d529 i18n: Translate policy.ts in sv
100% translated source file: 'policy.ts'
on 'sv'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] ce9dafcde2 i18n: Translate policy.ts in pa
100% translated source file: 'policy.ts'
on 'pa'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] 4d630bd341 i18n: Translate policy.ts in nl
100% translated source file: 'policy.ts'
on 'nl'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] df6e0f0ef2 i18n: Translate policy.ts in ca
100% translated source file: 'policy.ts'
on 'ca'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] d9db7435ca i18n: Translate policy.ts in fi
100% translated source file: 'policy.ts'
on 'fi'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] d25b28d638 i18n: Translate policy.ts in lv
100% translated source file: 'policy.ts'
on 'lv'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] d4cdc41f4a i18n: Translate policy.ts in eo
100% translated source file: 'policy.ts'
on 'eo'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] a5024fb127 i18n: Translate policy.ts in es
100% translated source file: 'policy.ts'
on 'es'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] be45ffccd8 i18n: Translate policy.ts in ar
100% translated source file: 'policy.ts'
on 'ar'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] f751db6c10 i18n: Translate policy.ts in en_AU
100% translated source file: 'policy.ts'
on 'en_AU'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] 336f69a0cd i18n: Translate policy.ts in ast
100% translated source file: 'policy.ts'
on 'ast'.
2025-11-20 10:49:40 +08:00
transifex-integration[bot] e40b7dc5de i18n: Translate policy.ts in bg
100% translated source file: 'policy.ts'
on 'bg'.
2025-11-20 10:49:40 +08:00
Wang Zichong 164eb83420 i18n: remove de_DE and de_CH translation resources
Log:
2025-11-20 09:44:15 +08:00
Wang Zichong 36ade87414 i18n: add policy file for translation
build / ubuntu_24.04 (push) Waiting to run Details
build / ubuntu_22.04 (push) Waiting to run Details
coverage / codecov (push) Waiting to run Details
Merging translation can be done using deepin-policy-ts-convert utility.

Log:
2025-11-19 16:06:40 +08:00
guanzi008 bf24e8397e feat: Implement loading of extensions from config files....
调整了一下
2025-10-30 17:35:35 +08:00
guanzi008 ef0a7539ca feat: Implement loading of extensions from config files....
添加了严格沙箱模式
2025-10-21 20:06:24 +08:00
guanzi008 c40805bf34 feat: Implement loading of extensions from config files.... 2025-10-21 18:16:17 +08:00
guanzi008 3213d097af feat: Implement loading of extensions from config files 2025-10-21 08:43:47 +08:00
79 changed files with 3077 additions and 2049 deletions

View File

@ -7,5 +7,10 @@ filters:
file_format: PO
source_language: en_US
translation_files_expression: po/<lang>.po
- filter_type: file
source_file: misc/share/polkit-1/translations/policy.ts
file_format: QT
source_language: en_US
translation_files_expression: misc/share/polkit-1/translations/policy_<lang>.ts
settings:
pr_branch_name: transifex_update_<br_unique_id>

View File

@ -172,7 +172,7 @@ SPDX-FileCopyrightText = "2018 Xiphos Development Team"
SPDX-License-Identifier = "GPL-2.0-or-later"
[[annotations]]
path = ["po/**.po", "po/**.pot", "po/POTFILES.in", "po/LINGUAS"]
path = ["po/**.po", "po/**.pot", "po/POTFILES.in", "po/LINGUAS", "misc/share/polkit-1/translations/*.ts"]
precedence = "aggregate"
SPDX-FileCopyrightText = "UnionTech Software Technology Co., Ltd."
SPDX-License-Identifier = "LGPL-3.0-only"

View File

@ -105,6 +105,118 @@
}
}
},
"LlCliFilesystemEntry": {
"title": "LlCliFilesystemEntry",
"description": "filesystem entry used by ll-cli configuration",
"type": "object",
"required": [
"host",
"target"
],
"properties": {
"host": {
"type": "string",
"description": "source path on host"
},
"target": {
"type": "string",
"description": "mount target path inside container"
},
"mode": {
"type": "string",
"description": "mount mode, either ro or rw"
},
"persist": {
"type": "boolean",
"description": "whether this mount should persist in sandbox storage"
}
}
},
"LlCliCommandConfig": {
"title": "LlCliCommandConfig",
"description": "per-command overrides for ll-cli configuration",
"type": "object",
"properties": {
"env": {
"type": "object",
"description": "environment variables applied to command",
"additionalProperties": {
"type": "string"
}
},
"filesystem": {
"type": "array",
"description": "filesystem entries applied to command",
"items": {
"$ref": "#/$defs/LlCliFilesystemEntry"
}
},
"args_prefix": {
"type": "array",
"description": "arguments prepended before command",
"items": {
"type": "string"
}
},
"args_suffix": {
"type": "array",
"description": "arguments appended after command",
"items": {
"type": "string"
}
},
"entrypoint": {
"type": "string",
"description": "override entrypoint for command"
},
"cwd": {
"type": "string",
"description": "working directory for command"
}
}
},
"LlCliConfig": {
"title": "LlCliConfig",
"description": "default ll-cli configuration provided by package",
"type": "object",
"properties": {
"filesystem_allow_only": {
"type": "array",
"description": "explicit mount allowlist; when present only these mounts are permitted",
"items": {
"$ref": "#/$defs/LlCliFilesystemEntry"
}
},
"filesystem": {
"type": "array",
"description": "additional filesystem mounts appended to defaults",
"items": {
"$ref": "#/$defs/LlCliFilesystemEntry"
}
},
"env": {
"type": "object",
"description": "default environment variables",
"additionalProperties": {
"type": "string"
}
},
"commands": {
"type": "object",
"description": "command specific overrides",
"additionalProperties": {
"$ref": "#/$defs/LlCliCommandConfig"
}
},
"extensions": {
"type": "array",
"description": "default extensions applied when launching app",
"items": {
"type": "string"
}
}
}
},
"ContainerProcessStateInfo": {
"description": "information about process which in container that start by ll-cli, all content\nwill write to /run/linglong/UID/PID\n",
"type": "object",
@ -379,6 +491,10 @@
"permissions": {
"$ref": "#/$defs/ApplicationConfigurationPermissions"
},
"cli_config": {
"$ref": "#/$defs/LlCliConfig",
"description": "default ll-cli configuration delivered with package"
},
"runtime": {
"type": "string",
"description": "used runtime of package"
@ -773,6 +889,10 @@
"$ref": "#/$defs/ExtensionDefine"
}
},
"cli_config": {
"$ref": "#/$defs/LlCliConfig",
"description": "default ll-cli configuration provided by package"
},
"ext_impl": {
"$ref": "#/$defs/ExtensionImpl"
}
@ -1418,6 +1538,15 @@
"ApplicationConfigurationPermissions": {
"$ref": "#/$defs/ApplicationConfigurationPermissions"
},
"LlCliFilesystemEntry": {
"$ref": "#/$defs/LlCliFilesystemEntry"
},
"LlCliCommandConfig": {
"$ref": "#/$defs/LlCliCommandConfig"
},
"LlCliConfig": {
"$ref": "#/$defs/LlCliConfig"
},
"ContainerProcessStateInfo": {
"$ref": "#/$defs/ContainerProcessStateInfo"
},

View File

@ -95,6 +95,87 @@ $defs:
destination:
type: string
description: mount source file to the another position of container
LlCliFilesystemEntry:
title: LlCliFilesystemEntry
description: filesystem entry used by ll-cli configuration
type: object
required:
- host
- target
properties:
host:
type: string
description: source path on host
target:
type: string
description: mount target path inside container
mode:
type: string
description: mount mode, either ro or rw
persist:
type: boolean
description: whether this mount should persist in sandbox storage
LlCliCommandConfig:
title: LlCliCommandConfig
description: per-command overrides for ll-cli configuration
type: object
properties:
env:
type: object
description: environment variables applied to command
additionalProperties:
type: string
filesystem:
type: array
description: filesystem entries applied to command
items:
$ref: '#/$defs/LlCliFilesystemEntry'
args_prefix:
type: array
description: arguments prepended before command
items:
type: string
args_suffix:
type: array
description: arguments appended after command
items:
type: string
entrypoint:
type: string
description: override entrypoint for command
cwd:
type: string
description: working directory for command
LlCliConfig:
title: LlCliConfig
description: default ll-cli configuration provided by package
type: object
properties:
filesystem_allow_only:
type: array
description: explicit mount allowlist; when present only these mounts are permitted
items:
$ref: '#/$defs/LlCliFilesystemEntry'
filesystem:
type: array
description: additional filesystem mounts appended to defaults
items:
$ref: '#/$defs/LlCliFilesystemEntry'
env:
type: object
description: default environment variables
additionalProperties:
type: string
commands:
type: object
description: command specific overrides
additionalProperties:
$ref: '#/$defs/LlCliCommandConfig'
extensions:
type: array
description: default extensions applied when launching app
items:
type: string
ContainerProcessStateInfo:
description: |
information about process which in container that start by ll-cli, all content
@ -312,6 +393,9 @@ $defs:
type: string
permissions:
$ref: '#/$defs/ApplicationConfigurationPermissions'
cli_config:
$ref: '#/$defs/LlCliConfig'
description: default ll-cli configuration delivered with package
runtime:
type: string
description: used runtime of package
@ -604,6 +688,9 @@ $defs:
description: description of extension
items:
$ref: '#/$defs/ExtensionDefine'
cli_config:
$ref: '#/$defs/LlCliConfig'
description: default ll-cli configuration provided by package
ext_impl:
$ref: '#/$defs/ExtensionImpl'
PackageInfo:

View File

@ -5,6 +5,8 @@
*/
#include "configure.h"
#include "linglong/api/dbus/v1/dbus_peer.h"
#include "linglong/api/types/v1/Generators.hpp"
#include "linglong/api/types/v1/PackageInfoV2.hpp"
#include "linglong/cli/cli.h"
#include "linglong/cli/cli_printer.h"
#include "linglong/cli/dbus_notifier.h"
@ -33,10 +35,20 @@
#include <memory>
#include <thread>
#include <cstdio>
#include <string>
#include <fcntl.h>
#include <unistd.h>
#include <wordexp.h>
#include <nlohmann/json.hpp>
#include <filesystem>
#include <fstream>
#include <optional>
#include <sstream>
#include <tuple>
#include <unordered_set>
using namespace linglong::utils::error;
using namespace linglong::package;
using namespace linglong::cli;
@ -631,22 +643,887 @@ linglong::utils::error::Result<linglong::repo::OSTreeRepo *> initOSTreeRepo()
return repo;
}
// ===== begin: ll-cli config helpers =====
using json = nlohmann::json;
static std::string configUsageLines()
{
return std::string{
_(" ll-cli config set-extensions [--global | <appid> | --base <baseid>] ext1,ext2\n"
" ll-cli config add-extensions [--global | <appid> | --base <baseid>] ext1,ext2\n"
" ll-cli config set-env [--global | <appid> | --base <baseid>] KEY=VAL [KEY=VAL ...]\n"
" ll-cli config unset-env [--global | <appid> | --base <baseid>] KEY [KEY ...]\n"
" ll-cli config add-fs [--global | <appid> | --base <baseid>] --host PATH --target PATH [--mode "
"ro|rw] [--persist]\n"
" ll-cli config rm-fs [--global | <appid> | --base <baseid>] (--target PATH | --index N)\n"
" ll-cli config add-fs-allow [--global | <appid> | --base <baseid>] --host PATH --target PATH [--mode "
"ro|rw] [--persist]\n"
" ll-cli config rm-fs-allow [--global | <appid> | --base <baseid>] (--target PATH | --index N)\n"
" ll-cli config clear-fs-allow [--global | <appid> | --base <baseid>]\n"
" ll-cli config set-command [--global | <appid> | --base <baseid>] <cmd> [--entrypoint P] [--cwd D] "
"[--args-prefix \"...\"] [--args-suffix \"...\"] [KEY=VAL ...]\n"
" ll-cli config unset-command [--global | <appid> | --base <baseid>] <cmd>\n") };
}
static std::string configShortHelp()
{
return std::string{ _("Configuration commands:\n"
" config Manage ll-cli configuration (see `ll-cli config --help`)\n") };
}
static std::string configFooterMessage()
{
return std::string{ _("If you found any problems during use,\n"
"You can report bugs to the linyaps team under this project: "
"https://github.com/OpenAtom-Linyaps/linyaps/issues") };
}
static void printConfigUsage(FILE *stream = stderr)
{
auto usageLines = configUsageLines();
std::fprintf(stream, "%s\n%s", _("Usage:"), usageLines.c_str());
}
enum class Scope { Global, App, Base };
static std::filesystem::path getBaseConfigDir()
{
const char *xdg = ::getenv("XDG_CONFIG_HOME");
if (xdg && xdg[0]) {
return std::filesystem::path(xdg) / "linglong";
}
const char *home = ::getenv("HOME");
if (home && home[0]) {
return std::filesystem::path(home) / ".config" / "linglong";
}
return {};
}
static std::filesystem::path getSystemConfigDir()
{
return std::filesystem::path(LINGLONG_DATA_DIR) / "config";
}
static std::filesystem::path buildConfigPath(const std::filesystem::path &base,
Scope scope,
const std::string &appId,
const std::string &baseId)
{
if (base.empty()) {
return {};
}
switch (scope) {
case Scope::Global:
return base / "config.json";
case Scope::App:
return base / "apps" / appId / "config.json";
case Scope::Base:
return base / "base" / baseId / "config.json";
}
return {};
}
static std::filesystem::path getConfigPath(Scope scope,
const std::string &appId,
const std::string &baseId)
{
return buildConfigPath(getBaseConfigDir(), scope, appId, baseId);
}
static std::vector<std::filesystem::path> getConfigSearchPaths(Scope scope,
const std::string &appId,
const std::string &baseId)
{
std::vector<std::filesystem::path> paths;
std::unordered_set<std::string> seen;
auto addPath = [&](const std::filesystem::path &candidate) {
if (candidate.empty()) {
return;
}
auto normalized = candidate.lexically_normal();
auto key = normalized.string();
if (!key.empty() && seen.insert(key).second) {
paths.emplace_back(std::move(normalized));
}
};
addPath(buildConfigPath(getBaseConfigDir(), scope, appId, baseId));
addPath(buildConfigPath(getSystemConfigDir(), scope, appId, baseId));
return paths;
}
static bool ensureParentDir(const std::filesystem::path &p)
{
std::error_code ec;
auto parent = p.parent_path();
if (parent.empty()) {
return true;
}
return std::filesystem::create_directories(parent, ec) || std::filesystem::exists(parent);
}
static std::optional<json> readJsonIfExists(const std::filesystem::path &p, bool *existed = nullptr)
{
try {
std::error_code ec;
if (!std::filesystem::exists(p, ec)) {
if (existed) {
*existed = false;
}
return json::object();
}
std::ifstream in(p);
if (!in.is_open()) {
return std::nullopt;
}
if (existed) {
*existed = true;
}
json j;
in >> j;
return j.is_null() ? json::object() : j;
} catch (...) {
return std::nullopt;
}
}
static bool writeJsonAtomic(const std::filesystem::path &p, const json &j)
{
try {
if (!ensureParentDir(p)) {
return false;
}
auto tmp = p;
tmp += ".tmp";
{
std::ofstream out(tmp);
if (!out.is_open()) {
return false;
}
out << j.dump(2) << "\n";
}
std::error_code ec;
std::filesystem::rename(tmp, p, ec);
if (ec) {
std::filesystem::remove(p, ec);
std::filesystem::rename(tmp, p, ec);
}
return !ec;
} catch (...) {
return false;
}
}
static std::vector<std::string> splitCsv(const std::string &s)
{
std::vector<std::string> out;
std::stringstream ss(s);
std::string tok;
while (std::getline(ss, tok, ',')) {
if (!tok.empty()) {
out.push_back(tok);
}
}
return out;
}
static std::string trim(const std::string &s)
{
const char *ws = " \t\r\n";
size_t b = s.find_first_not_of(ws);
if (b == std::string::npos) {
return "";
}
size_t e = s.find_last_not_of(ws);
return s.substr(b, e - b + 1);
}
static void jsonSetExtensions(json &root, const std::vector<std::string> &exts, bool overwrite)
{
auto &arr = root["extensions"];
if (!arr.is_array() || overwrite) {
arr = json::array();
}
std::unordered_set<std::string> exist;
if (arr.is_array()) {
for (auto &e : arr) {
if (e.is_string()) {
exist.insert(e.get<std::string>());
}
}
}
for (auto &s : exts) {
if (!s.empty() && !exist.count(s)) {
arr.push_back(s);
exist.insert(s);
}
}
}
static void jsonSetEnv(json &root, const std::vector<std::string> &kvs)
{
auto &obj = root["env"];
if (!obj.is_object()) {
obj = json::object();
}
for (auto &kv : kvs) {
auto pos = kv.find('=');
if (pos == std::string::npos) {
continue;
}
auto k = trim(kv.substr(0, pos));
auto v = kv.substr(pos + 1);
if (k.empty()) {
continue;
}
obj[k] = v;
}
}
static void jsonUnsetEnv(json &root, const std::vector<std::string> &keys)
{
if (!root.contains("env") || !root["env"].is_object()) {
return;
}
for (auto &k : keys) {
root["env"].erase(k);
}
}
struct FsArg {
std::string host, target, mode;
bool persist = false;
};
static void jsonAddFsTo(json &root, const FsArg &fs, const char *field)
{
auto &arr = root[field];
if (!arr.is_array()) {
arr = json::array();
}
for (auto &e : arr) {
if (!e.is_object()) {
continue;
}
if (e.value("host", "") == fs.host && e.value("target", "") == fs.target) {
return;
}
}
json o = json::object();
o["host"] = fs.host;
o["target"] = fs.target;
o["mode"] = (fs.mode == "rw" ? "rw" : "ro");
if (fs.persist) {
o["persist"] = true;
}
arr.push_back(std::move(o));
}
static void jsonAddFs(json &root, const FsArg &fs)
{
jsonAddFsTo(root, fs, "filesystem");
}
static void jsonAddFsAllow(json &root, const FsArg &fs)
{
jsonAddFsTo(root, fs, "filesystem_allow_only");
}
static bool jsonRmFsByTargetFrom(json &root, const std::string &target, const char *field)
{
if (!root.contains(field) || !root[field].is_array()) {
return false;
}
auto &arr = root[field];
auto old = arr.size();
arr.erase(std::remove_if(arr.begin(), arr.end(), [&](const json &e) {
return e.is_object() && e.value("target", "") == target;
}),
arr.end());
return arr.size() != old;
}
static bool jsonRmFsByTarget(json &root, const std::string &target)
{
return jsonRmFsByTargetFrom(root, target, "filesystem");
}
static bool jsonRmFsAllowByTarget(json &root, const std::string &target)
{
return jsonRmFsByTargetFrom(root, target, "filesystem_allow_only");
}
static bool jsonRmFsByIndexFrom(json &root, size_t idx, const char *field)
{
if (!root.contains(field) || !root[field].is_array()) {
return false;
}
auto &arr = root[field];
if (idx >= arr.size()) {
return false;
}
arr.erase(arr.begin() + idx);
return true;
}
static bool jsonRmFsByIndex(json &root, size_t idx)
{
return jsonRmFsByIndexFrom(root, idx, "filesystem");
}
static bool jsonRmFsAllowByIndex(json &root, size_t idx)
{
return jsonRmFsByIndexFrom(root, idx, "filesystem_allow_only");
}
static void jsonClearFsAllow(json &root)
{
root["filesystem_allow_only"] = json::array();
}
struct CmdSetArg {
std::string cmd;
std::optional<std::string> entrypoint;
std::optional<std::string> cwd;
std::vector<std::string> argsPrefix;
std::vector<std::string> argsSuffix;
std::vector<std::string> envKVs;
};
static void jsonSetCommand(json &root, const CmdSetArg &a)
{
if (a.cmd.empty()) {
return;
}
auto &cmds = root["commands"];
if (!cmds.is_object()) {
cmds = json::object();
}
auto &node = cmds[a.cmd];
if (!node.is_object()) {
node = json::object();
}
if (a.entrypoint) {
node["entrypoint"] = *a.entrypoint;
}
if (a.cwd) {
node["cwd"] = *a.cwd;
}
if (!a.argsPrefix.empty()) {
auto &arr = node["args_prefix"];
arr = json::array();
for (auto &s : a.argsPrefix) {
arr.push_back(s);
}
}
if (!a.argsSuffix.empty()) {
auto &arr = node["args_suffix"];
arr = json::array();
for (auto &s : a.argsSuffix) {
arr.push_back(s);
}
}
if (!a.envKVs.empty()) {
auto &env = node["env"];
if (!env.is_object()) {
env = json::object();
}
for (auto &kv : a.envKVs) {
auto pos = kv.find('=');
if (pos == std::string::npos) {
continue;
}
auto k = trim(kv.substr(0, pos));
auto v = kv.substr(pos + 1);
if (!k.empty()) {
env[k] = v;
}
}
}
}
static void jsonUnsetCommand(json &root, const std::string &cmd)
{
if (!root.contains("commands") || !root["commands"].is_object()) {
return;
}
root["commands"].erase(cmd);
}
// ===== end: ll-cli config helpers =====
class ConfigAwareFormatter : public CLI::Formatter {
public:
ConfigAwareFormatter(std::string shortSection, std::string fullSection, std::string footerMessage)
: shortSection_(std::move(shortSection))
, fullSection_(std::move(fullSection))
, footerMessage_(std::move(footerMessage))
{}
std::string make_help(const CLI::App *app, std::string name, CLI::AppFormatMode mode) const override
{
std::string result = Formatter::make_help(app, std::move(name), mode);
const std::string &section = (mode == CLI::AppFormatMode::All) ? fullSection_ : shortSection_;
if (!section.empty()) {
if (!result.empty() && result.back() != '\n') {
result.push_back('\n');
}
result += section;
if (!section.empty() && result.back() != '\n') {
result.push_back('\n');
}
}
if (!footerMessage_.empty()) {
if (!result.empty() && result.back() != '\n') {
result.push_back('\n');
}
result += footerMessage_;
if (result.back() != '\n') {
result.push_back('\n');
}
}
return result;
}
private:
std::string shortSection_;
std::string fullSection_;
std::string footerMessage_;
};
int runCliApplication(int argc, char **mainArgv)
{
// ===== begin: "ll-cli config ..." dispatcher =====
{
if (argc >= 2 && std::string(mainArgv[1]) == "config") {
if (argc < 3) {
printConfigUsage();
return 1;
}
std::string sub = mainArgv[2];
auto parseScope = [&](int start) -> std::tuple<Scope, std::string, std::string, int> {
if (start >= argc) {
return { Scope::Global, "", "", start };
}
std::string t = mainArgv[start];
if (t == "--global") {
return { Scope::Global, "", "", start + 1 };
}
if (t == "--base") {
if (start + 1 >= argc) {
fprintf(stderr, "--base requires <baseid>\n");
return { Scope::Global, "", "", argc };
}
return { Scope::Base, "", mainArgv[start + 1], start + 2 };
}
return { Scope::App, t, "", start + 1 };
};
auto loadCliConfigFromPackage = [&](Scope scope,
const std::string &appId,
const std::string &baseId)
-> std::optional<json> {
if (scope == Scope::Global) {
return std::nullopt;
}
auto repoResult = initOSTreeRepo();
if (!repoResult) {
qWarning() << "load cli config from package failed:" << repoResult.error();
return std::nullopt;
}
auto *repoPtr = *repoResult;
auto list = repoPtr->listLocal();
if (!list) {
qWarning() << "list local packages failed:" << list.error();
return std::nullopt;
}
const auto matcher = [&](const linglong::api::types::v1::PackageInfoV2 &info) -> bool {
if (scope == Scope::App) {
return info.id == appId && info.kind == "app";
}
if (scope == Scope::Base) {
return info.id == baseId && info.kind == "base";
}
return false;
};
auto it = std::find_if(list->begin(), list->end(), matcher);
if (it == list->end() || !it->cliConfig) {
return std::nullopt;
}
json packaged = *(it->cliConfig);
return packaged;
};
auto openConfig = [&](Scope scope,
const std::string &appId,
const std::string &baseId) -> std::optional<json> {
auto userPath = getConfigPath(scope, appId, baseId);
if (userPath.empty()) {
fprintf(stderr, "invalid config path\n");
return std::nullopt;
}
bool userExists = false;
auto userJson = readJsonIfExists(userPath, &userExists);
if (!userJson) {
fprintf(stderr, "failed to read %s\n", userPath.string().c_str());
return std::nullopt;
}
if (!userExists) {
auto searchPaths = getConfigSearchPaths(scope, appId, baseId);
for (size_t idx = 1; idx < searchPaths.size(); ++idx) {
bool existed = false;
auto fallback = readJsonIfExists(searchPaths[idx], &existed);
if (!fallback || !existed) {
continue;
}
return fallback;
}
if (auto packaged = loadCliConfigFromPackage(scope, appId, baseId)) {
return packaged;
}
}
return userJson;
};
auto saveConfig = [&](Scope scope,
const std::string &appId,
const std::string &baseId,
const json &j) -> bool {
auto path = getConfigPath(scope, appId, baseId);
if (path.empty()) {
return false;
}
if (!writeJsonAtomic(path, j)) {
fprintf(stderr, "failed to write %s\n", path.string().c_str());
return false;
}
printf("Written %s\n", path.string().c_str());
return true;
};
if (sub == "set-extensions" || sub == "add-extensions") {
auto [scope, appId, baseId, i] = parseScope(3);
if (i >= argc) {
printConfigUsage();
return 1;
}
std::vector<std::string> exts = splitCsv(mainArgv[i]);
auto j = openConfig(scope, appId, baseId);
if (!j) {
return 1;
}
jsonSetExtensions(*j, exts, sub == "set-extensions");
if (!saveConfig(scope, appId, baseId, *j)) {
return 1;
}
return 0;
}
if (sub == "set-env") {
auto [scope, appId, baseId, i] = parseScope(3);
if (i >= argc) {
printConfigUsage();
return 1;
}
std::vector<std::string> kvs;
for (; i < argc; ++i) {
kvs.push_back(mainArgv[i]);
}
auto j = openConfig(scope, appId, baseId);
if (!j) {
return 1;
}
jsonSetEnv(*j, kvs);
if (!saveConfig(scope, appId, baseId, *j)) {
return 1;
}
return 0;
}
if (sub == "unset-env") {
auto [scope, appId, baseId, i] = parseScope(3);
if (i >= argc) {
printConfigUsage();
return 1;
}
std::vector<std::string> keys;
for (; i < argc; ++i) {
keys.push_back(mainArgv[i]);
}
auto j = openConfig(scope, appId, baseId);
if (!j) {
return 1;
}
jsonUnsetEnv(*j, keys);
if (!saveConfig(scope, appId, baseId, *j)) {
return 1;
}
return 0;
}
if (sub == "add-fs") {
auto [scope, appId, baseId, i] = parseScope(3);
FsArg fs;
fs.mode = "ro";
fs.persist = false;
for (; i < argc; ++i) {
std::string a = mainArgv[i];
if (a == "--persist") {
fs.persist = true;
} else if (a == "--host" && i + 1 < argc) {
fs.host = mainArgv[++i];
} else if (a == "--target" && i + 1 < argc) {
fs.target = mainArgv[++i];
} else if (a == "--mode" && i + 1 < argc) {
fs.mode = mainArgv[++i];
} else {
fprintf(stderr, "unknown arg: %s\n", a.c_str());
return 1;
}
}
if (fs.host.empty() || fs.target.empty()) {
printConfigUsage();
return 1;
}
auto j = openConfig(scope, appId, baseId);
if (!j) {
return 1;
}
jsonAddFs(*j, fs);
if (!saveConfig(scope, appId, baseId, *j)) {
return 1;
}
return 0;
}
if (sub == "add-fs-allow") {
auto [scope, appId, baseId, i] = parseScope(3);
FsArg fs;
fs.mode = "ro";
fs.persist = false;
for (; i < argc; ++i) {
std::string a = mainArgv[i];
if (a == "--persist") {
fs.persist = true;
} else if (a == "--host" && i + 1 < argc) {
fs.host = mainArgv[++i];
} else if (a == "--target" && i + 1 < argc) {
fs.target = mainArgv[++i];
} else if (a == "--mode" && i + 1 < argc) {
fs.mode = mainArgv[++i];
} else {
fprintf(stderr, "unknown arg: %s\n", a.c_str());
return 1;
}
}
if (fs.host.empty() || fs.target.empty()) {
printConfigUsage();
return 1;
}
auto j = openConfig(scope, appId, baseId);
if (!j) {
return 1;
}
jsonAddFsAllow(*j, fs);
if (!saveConfig(scope, appId, baseId, *j)) {
return 1;
}
return 0;
}
if (sub == "rm-fs") {
auto [scope, appId, baseId, i] = parseScope(3);
std::optional<std::string> target;
std::optional<size_t> index;
for (; i < argc; ++i) {
std::string a = mainArgv[i];
if (a == "--target" && i + 1 < argc) {
target = mainArgv[++i];
} else if (a == "--index" && i + 1 < argc) {
index = static_cast<size_t>(std::stoul(mainArgv[++i]));
} else {
fprintf(stderr, "unknown arg: %s\n", a.c_str());
return 1;
}
}
if (!target && !index) {
printConfigUsage();
return 1;
}
auto j = openConfig(scope, appId, baseId);
if (!j) {
return 1;
}
bool ok = false;
if (target) {
ok = jsonRmFsByTarget(*j, *target);
}
if (!ok && index) {
ok = jsonRmFsByIndex(*j, *index);
}
if (!ok) {
fprintf(stderr, "no filesystem entry removed\n");
return 1;
}
if (!saveConfig(scope, appId, baseId, *j)) {
return 1;
}
return 0;
}
if (sub == "rm-fs-allow") {
auto [scope, appId, baseId, i] = parseScope(3);
std::optional<std::string> target;
std::optional<size_t> index;
for (; i < argc; ++i) {
std::string a = mainArgv[i];
if (a == "--target" && i + 1 < argc) {
target = mainArgv[++i];
} else if (a == "--index" && i + 1 < argc) {
index = static_cast<size_t>(std::stoul(mainArgv[++i]));
} else {
fprintf(stderr, "unknown arg: %s\n", a.c_str());
return 1;
}
}
if (!target && !index) {
printConfigUsage();
return 1;
}
auto j = openConfig(scope, appId, baseId);
if (!j) {
return 1;
}
bool ok = false;
if (target) {
ok = jsonRmFsAllowByTarget(*j, *target);
}
if (!ok && index) {
ok = jsonRmFsAllowByIndex(*j, *index);
}
if (!ok) {
fprintf(stderr, "no filesystem_allow entry removed\n");
return 1;
}
if (!saveConfig(scope, appId, baseId, *j)) {
return 1;
}
return 0;
}
if (sub == "clear-fs-allow") {
auto [scope, appId, baseId, i] = parseScope(3);
auto j = openConfig(scope, appId, baseId);
if (!j) {
return 1;
}
jsonClearFsAllow(*j);
if (!saveConfig(scope, appId, baseId, *j)) {
return 1;
}
return 0;
}
if (sub == "set-command") {
auto [scope, appId, baseId, i] = parseScope(3);
if (i >= argc) {
printConfigUsage();
return 1;
}
CmdSetArg a;
a.cmd = mainArgv[i++];
for (; i < argc; ++i) {
std::string t = mainArgv[i];
if (t == "--entrypoint" && i + 1 < argc) {
a.entrypoint = mainArgv[++i];
} else if (t == "--cwd" && i + 1 < argc) {
a.cwd = mainArgv[++i];
} else if (t == "--args-prefix" && i + 1 < argc) {
std::stringstream ss(mainArgv[++i]);
std::string tok;
while (ss >> tok) {
a.argsPrefix.push_back(tok);
}
} else if (t == "--args-suffix" && i + 1 < argc) {
std::stringstream ss(mainArgv[++i]);
std::string tok;
while (ss >> tok) {
a.argsSuffix.push_back(tok);
}
} else if (t.find('=') != std::string::npos) {
a.envKVs.push_back(t);
} else {
fprintf(stderr, "unknown arg: %s\n", t.c_str());
return 1;
}
}
auto j = openConfig(scope, appId, baseId);
if (!j) {
return 1;
}
jsonSetCommand(*j, a);
if (!saveConfig(scope, appId, baseId, *j)) {
return 1;
}
return 0;
}
if (sub == "unset-command") {
auto [scope, appId, baseId, i] = parseScope(3);
if (i >= argc) {
printConfigUsage();
return 1;
}
std::string cmd = mainArgv[i];
auto j = openConfig(scope, appId, baseId);
if (!j) {
return 1;
}
jsonUnsetCommand(*j, cmd);
if (!saveConfig(scope, appId, baseId, *j)) {
return 1;
}
return 0;
}
printConfigUsage();
return 1;
}
}
// ===== end: "ll-cli config ..." dispatcher =====
CLI::App commandParser{ _(
"linyaps CLI\n"
"A CLI program to run application and manage application and runtime\n") };
auto shortConfigHelp = configShortHelp();
auto fullConfigHelp = shortConfigHelp + configUsageLines();
commandParser.formatter(std::make_shared<ConfigAwareFormatter>(shortConfigHelp,
fullConfigHelp,
configFooterMessage()));
commandParser.option_defaults()->group(_("Options"));
if (auto formatter = commandParser.get_formatter()) {
formatter->label("OPTIONS", _("OPTIONS"));
formatter->label("SUBCOMMAND", _("SUBCOMMAND"));
formatter->label("SUBCOMMANDS", _("SUBCOMMANDS"));
formatter->label("POSITIONALS", _("POSITIONALS"));
formatter->label("Usage", _("Usage"));
formatter->label("REQUIRED", _("REQUIRED"));
}
auto argv = commandParser.ensure_utf8(mainArgv);
if (argc == 1) {
std::cout << commandParser.help() << std::endl;
return 0;
}
commandParser.get_help_ptr()->description(_("Print this help message and exit"));
commandParser.set_help_all_flag("--help-all", _("Expand all help"));
if (auto *helpOption = commandParser.get_help_ptr()) {
helpOption->description(_("Print this help message and exit"));
helpOption->group(_("Options"));
}
if (auto *helpAllOption = commandParser.set_help_all_flag("--help-all", _("Expand all help"))) {
helpAllOption->group(_("Options"));
}
commandParser.usage(_("Usage: ll-cli [OPTIONS] [SUBCOMMAND]"));
commandParser.footer(_(R"(If you found any problems during use,
You can report bugs to the linyaps team under this project: https://github.com/OpenAtom-Linyaps/linyaps/issues)"));
commandParser.footer("");
// group empty will hide command
constexpr auto CliHiddenGroup = "";

File diff suppressed because one or more lines are too long

View File

@ -18,6 +18,7 @@
#include "linglong/api/types/v1/helper.hpp"
#include "linglong/api/types/v1/BuilderProjectBuildEXT.hpp"
#include "linglong/api/types/v1/LlCLIConfig.hpp"
#include "linglong/api/types/v1/BuilderProjectModules.hpp"
#include "linglong/api/types/v1/BuilderProjectPackage.hpp"
#include "linglong/api/types/v1/ApplicationConfigurationPermissions.hpp"
@ -50,6 +51,10 @@ std::string build;
*/
std::optional<BuilderProjectBuildEXT> buildext;
/**
* default ll-cli configuration delivered with package
*/
std::optional<LlCLIConfig> cliConfig;
/**
* command of builder project
*/
std::optional<std::vector<std::string>> command;

View File

@ -67,6 +67,9 @@
#include "linglong/api/types/v1/BuilderProjectSource.hpp"
#include "linglong/api/types/v1/BuilderProjectPackage.hpp"
#include "linglong/api/types/v1/BuilderProjectModules.hpp"
#include "linglong/api/types/v1/LlCLIConfig.hpp"
#include "linglong/api/types/v1/LlCLICommandConfig.hpp"
#include "linglong/api/types/v1/LlCLIFilesystemEntry.hpp"
#include "linglong/api/types/v1/BuilderProjectBuildEXT.hpp"
#include "linglong/api/types/v1/Apt.hpp"
#include "linglong/api/types/v1/BuilderConfig.hpp"
@ -108,6 +111,15 @@ void to_json(json & j, const Apt & x);
void from_json(const json & j, BuilderProjectBuildEXT & x);
void to_json(json & j, const BuilderProjectBuildEXT & x);
void from_json(const json & j, LlCLIFilesystemEntry & x);
void to_json(json & j, const LlCLIFilesystemEntry & x);
void from_json(const json & j, LlCLICommandConfig & x);
void to_json(json & j, const LlCLICommandConfig & x);
void from_json(const json & j, LlCLIConfig & x);
void to_json(json & j, const LlCLIConfig & x);
void from_json(const json & j, BuilderProjectModules & x);
void to_json(json & j, const BuilderProjectModules & x);
@ -383,6 +395,83 @@ j["apt"] = x.apt;
}
}
inline void from_json(const json & j, LlCLIFilesystemEntry& x) {
x.host = j.at("host").get<std::string>();
x.mode = get_stack_optional<std::string>(j, "mode");
x.persist = get_stack_optional<bool>(j, "persist");
x.target = j.at("target").get<std::string>();
}
inline void to_json(json & j, const LlCLIFilesystemEntry & x) {
j = json::object();
j["host"] = x.host;
if (x.mode) {
j["mode"] = x.mode;
}
if (x.persist) {
j["persist"] = x.persist;
}
j["target"] = x.target;
}
inline void from_json(const json & j, LlCLICommandConfig& x) {
x.argsPrefix = get_stack_optional<std::vector<std::string>>(j, "args_prefix");
x.argsSuffix = get_stack_optional<std::vector<std::string>>(j, "args_suffix");
x.cwd = get_stack_optional<std::string>(j, "cwd");
x.entrypoint = get_stack_optional<std::string>(j, "entrypoint");
x.env = get_stack_optional<std::map<std::string, std::string>>(j, "env");
x.filesystem = get_stack_optional<std::vector<LlCLIFilesystemEntry>>(j, "filesystem");
}
inline void to_json(json & j, const LlCLICommandConfig & x) {
j = json::object();
if (x.argsPrefix) {
j["args_prefix"] = x.argsPrefix;
}
if (x.argsSuffix) {
j["args_suffix"] = x.argsSuffix;
}
if (x.cwd) {
j["cwd"] = x.cwd;
}
if (x.entrypoint) {
j["entrypoint"] = x.entrypoint;
}
if (x.env) {
j["env"] = x.env;
}
if (x.filesystem) {
j["filesystem"] = x.filesystem;
}
}
inline void from_json(const json & j, LlCLIConfig& x) {
x.commands = get_stack_optional<std::map<std::string, LlCLICommandConfig>>(j, "commands");
x.env = get_stack_optional<std::map<std::string, std::string>>(j, "env");
x.extensions = get_stack_optional<std::vector<std::string>>(j, "extensions");
x.filesystem = get_stack_optional<std::vector<LlCLIFilesystemEntry>>(j, "filesystem");
x.filesystemAllowOnly = get_stack_optional<std::vector<LlCLIFilesystemEntry>>(j, "filesystem_allow_only");
}
inline void to_json(json & j, const LlCLIConfig & x) {
j = json::object();
if (x.commands) {
j["commands"] = x.commands;
}
if (x.env) {
j["env"] = x.env;
}
if (x.extensions) {
j["extensions"] = x.extensions;
}
if (x.filesystem) {
j["filesystem"] = x.filesystem;
}
if (x.filesystemAllowOnly) {
j["filesystem_allow_only"] = x.filesystemAllowOnly;
}
}
inline void from_json(const json & j, BuilderProjectModules& x) {
x.files = j.at("files").get<std::vector<std::string>>();
x.name = j.at("name").get<std::string>();
@ -468,6 +557,7 @@ inline void from_json(const json & j, BuilderProject& x) {
x.base = j.at("base").get<std::string>();
x.build = j.at("build").get<std::string>();
x.buildext = get_stack_optional<BuilderProjectBuildEXT>(j, "buildext");
x.cliConfig = get_stack_optional<LlCLIConfig>(j, "cli_config");
x.command = get_stack_optional<std::vector<std::string>>(j, "command");
x.exclude = get_stack_optional<std::vector<std::string>>(j, "exclude");
x.include = get_stack_optional<std::vector<std::string>>(j, "include");
@ -487,6 +577,9 @@ j["build"] = x.build;
if (x.buildext) {
j["buildext"] = x.buildext;
}
if (x.cliConfig) {
j["cli_config"] = x.cliConfig;
}
if (x.command) {
j["command"] = x.command;
}
@ -746,6 +839,7 @@ inline void from_json(const json & j, PackageInfoDisplay& x) {
x.arch = j.at("arch").get<std::vector<std::string>>();
x.base = j.at("base").get<std::string>();
x.channel = j.at("channel").get<std::string>();
x.cliConfig = get_stack_optional<LlCLIConfig>(j, "cli_config");
x.command = get_stack_optional<std::vector<std::string>>(j, "command");
x.compatibleVersion = get_stack_optional<std::string>(j, "compatible_version");
x.description = get_stack_optional<std::string>(j, "description");
@ -769,6 +863,9 @@ j = json::object();
j["arch"] = x.arch;
j["base"] = x.base;
j["channel"] = x.channel;
if (x.cliConfig) {
j["cli_config"] = x.cliConfig;
}
if (x.command) {
j["command"] = x.command;
}
@ -809,6 +906,7 @@ inline void from_json(const json & j, PackageInfoV2& x) {
x.arch = j.at("arch").get<std::vector<std::string>>();
x.base = j.at("base").get<std::string>();
x.channel = j.at("channel").get<std::string>();
x.cliConfig = get_stack_optional<LlCLIConfig>(j, "cli_config");
x.command = get_stack_optional<std::vector<std::string>>(j, "command");
x.compatibleVersion = get_stack_optional<std::string>(j, "compatible_version");
x.description = get_stack_optional<std::string>(j, "description");
@ -831,6 +929,9 @@ j = json::object();
j["arch"] = x.arch;
j["base"] = x.base;
j["channel"] = x.channel;
if (x.cliConfig) {
j["cli_config"] = x.cliConfig;
}
if (x.command) {
j["command"] = x.command;
}
@ -1248,6 +1349,9 @@ x.interactionMessageType = get_stack_optional<InteractionMessageType>(j, "Intera
x.interactionReply = get_stack_optional<InteractionReply>(j, "InteractionReply");
x.interactionRequest = get_stack_optional<InteractionRequest>(j, "InteractionRequest");
x.layerInfo = get_stack_optional<LayerInfo>(j, "LayerInfo");
x.llCLICommandConfig = get_stack_optional<LlCLICommandConfig>(j, "LlCliCommandConfig");
x.llCLIConfig = get_stack_optional<LlCLIConfig>(j, "LlCliConfig");
x.llCLIFilesystemEntry = get_stack_optional<LlCLIFilesystemEntry>(j, "LlCliFilesystemEntry");
x.ociConfigurationPatch = get_stack_optional<OciConfigurationPatch>(j, "OCIConfigurationPatch");
x.packageInfo = get_stack_optional<PackageInfo>(j, "PackageInfo");
x.packageInfoDisplay = get_stack_optional<PackageInfoDisplay>(j, "PackageInfoDisplay");
@ -1336,6 +1440,15 @@ j["InteractionRequest"] = x.interactionRequest;
if (x.layerInfo) {
j["LayerInfo"] = x.layerInfo;
}
if (x.llCLICommandConfig) {
j["LlCliCommandConfig"] = x.llCLICommandConfig;
}
if (x.llCLIConfig) {
j["LlCliConfig"] = x.llCLIConfig;
}
if (x.llCLIFilesystemEntry) {
j["LlCliFilesystemEntry"] = x.llCLIFilesystemEntry;
}
if (x.ociConfigurationPatch) {
j["OCIConfigurationPatch"] = x.ociConfigurationPatch;
}
@ -1435,7 +1548,7 @@ case InteractionMessageType::Install: j = "Install"; break;
case InteractionMessageType::Uninstall: j = "Uninstall"; break;
case InteractionMessageType::Unknown: j = "Unknown"; break;
case InteractionMessageType::Upgrade: j = "Upgrade"; break;
default: throw std::runtime_error("Unexpected value in enumeration \"[object Object]\": " + std::to_string(static_cast<int>(x)));
default: throw std::runtime_error("Unexpected value in enumeration \"InteractionMessageType\": " + std::to_string(static_cast<int>(x)));
}
}
@ -1461,7 +1574,7 @@ case State::Processing: j = "Processing"; break;
case State::Queued: j = "Queued"; break;
case State::Succeed: j = "Succeed"; break;
case State::Unknown: j = "Unknown"; break;
default: throw std::runtime_error("Unexpected value in enumeration \"[object Object]\": " + std::to_string(static_cast<int>(x)));
default: throw std::runtime_error("Unexpected value in enumeration \"State\": " + std::to_string(static_cast<int>(x)));
}
}
@ -1489,7 +1602,7 @@ case SubState::PostAction: j = "PostAction"; break;
case SubState::PreAction: j = "PreAction"; break;
case SubState::Uninstall: j = "Uninstall"; break;
case SubState::Unknown: j = "Unknown"; break;
default: throw std::runtime_error("Unexpected value in enumeration \"[object Object]\": " + std::to_string(static_cast<int>(x)));
default: throw std::runtime_error("Unexpected value in enumeration \"SubState\": " + std::to_string(static_cast<int>(x)));
}
}
@ -1501,7 +1614,7 @@ else { throw std::runtime_error("Input JSON does not conform to schema!"); }
inline void to_json(json & j, const Version & x) {
switch (x) {
case Version::The1: j = "1"; break;
default: throw std::runtime_error("Unexpected value in enumeration \"[object Object]\": " + std::to_string(static_cast<int>(x)));
default: throw std::runtime_error("Unexpected value in enumeration \"Version\": " + std::to_string(static_cast<int>(x)));
}
}
}

View File

@ -35,6 +35,9 @@
#include "linglong/api/types/v1/InteractionReply.hpp"
#include "linglong/api/types/v1/InteractionRequest.hpp"
#include "linglong/api/types/v1/LayerInfo.hpp"
#include "linglong/api/types/v1/LlCLICommandConfig.hpp"
#include "linglong/api/types/v1/LlCLIConfig.hpp"
#include "linglong/api/types/v1/LlCLIFilesystemEntry.hpp"
#include "linglong/api/types/v1/OciConfigurationPatch.hpp"
#include "linglong/api/types/v1/PackageInfo.hpp"
#include "linglong/api/types/v1/PackageInfoDisplay.hpp"
@ -106,6 +109,9 @@ std::optional<InteractionMessageType> interactionMessageType;
std::optional<InteractionReply> interactionReply;
std::optional<InteractionRequest> interactionRequest;
std::optional<LayerInfo> layerInfo;
std::optional<LlCLICommandConfig> llCLICommandConfig;
std::optional<LlCLIConfig> llCLIConfig;
std::optional<LlCLIFilesystemEntry> llCLIFilesystemEntry;
std::optional<OciConfigurationPatch> ociConfigurationPatch;
std::optional<PackageInfo> packageInfo;
std::optional<PackageInfoDisplay> packageInfoDisplay;

View File

@ -0,0 +1,66 @@
// 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
//
// LlCLICommandConfig.hpp data = nlohmann::json::parse(jsonString);
#pragma once
#include <optional>
#include <nlohmann/json.hpp>
#include "linglong/api/types/v1/helper.hpp"
#include "linglong/api/types/v1/LlCLIFilesystemEntry.hpp"
namespace linglong {
namespace api {
namespace types {
namespace v1 {
/**
* per-command overrides for ll-cli configuration
*/
using nlohmann::json;
/**
* per-command overrides for ll-cli configuration
*/
struct LlCLICommandConfig {
/**
* arguments prepended before command
*/
std::optional<std::vector<std::string>> argsPrefix;
/**
* arguments appended after command
*/
std::optional<std::vector<std::string>> argsSuffix;
/**
* working directory for command
*/
std::optional<std::string> cwd;
/**
* override entrypoint for command
*/
std::optional<std::string> entrypoint;
/**
* environment variables applied to command
*/
std::optional<std::map<std::string, std::string>> env;
/**
* filesystem entries applied to command
*/
std::optional<std::vector<LlCLIFilesystemEntry>> filesystem;
};
}
}
}
}
// clang-format on

View File

@ -0,0 +1,67 @@
// 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
//
// LlCLIConfig.hpp data = nlohmann::json::parse(jsonString);
#pragma once
#include <optional>
#include <nlohmann/json.hpp>
#include "linglong/api/types/v1/helper.hpp"
#include "linglong/api/types/v1/LlCLICommandConfig.hpp"
#include "linglong/api/types/v1/LlCLIFilesystemEntry.hpp"
namespace linglong {
namespace api {
namespace types {
namespace v1 {
/**
* default ll-cli configuration delivered with package
*
* default ll-cli configuration provided by package
*/
using nlohmann::json;
/**
* default ll-cli configuration delivered with package
*
* default ll-cli configuration provided by package
*/
struct LlCLIConfig {
/**
* command specific overrides
*/
std::optional<std::map<std::string, LlCLICommandConfig>> commands;
/**
* default environment variables
*/
std::optional<std::map<std::string, std::string>> env;
/**
* default extensions applied when launching app
*/
std::optional<std::vector<std::string>> extensions;
/**
* additional filesystem mounts appended to defaults
*/
std::optional<std::vector<LlCLIFilesystemEntry>> filesystem;
/**
* explicit mount allowlist; when present only these mounts are permitted
*/
std::optional<std::vector<LlCLIFilesystemEntry>> filesystemAllowOnly;
};
}
}
}
}
// clang-format on

View File

@ -0,0 +1,56 @@
// 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
//
// LlCLIFilesystemEntry.hpp data = nlohmann::json::parse(jsonString);
#pragma once
#include <optional>
#include <nlohmann/json.hpp>
#include "linglong/api/types/v1/helper.hpp"
namespace linglong {
namespace api {
namespace types {
namespace v1 {
/**
* filesystem entry used by ll-cli configuration
*/
using nlohmann::json;
/**
* filesystem entry used by ll-cli configuration
*/
struct LlCLIFilesystemEntry {
/**
* source path on host
*/
std::string host;
/**
* mount mode, either ro or rw
*/
std::optional<std::string> mode;
/**
* whether this mount should persist in sandbox storage
*/
std::optional<bool> persist;
/**
* mount target path inside container
*/
std::string target;
};
}
}
}
}
// clang-format on

View File

@ -17,6 +17,7 @@
#include <nlohmann/json.hpp>
#include "linglong/api/types/v1/helper.hpp"
#include "linglong/api/types/v1/LlCLIConfig.hpp"
#include "linglong/api/types/v1/ExtensionImpl.hpp"
#include "linglong/api/types/v1/ExtensionDefine.hpp"
#include "linglong/api/types/v1/ApplicationConfigurationPermissions.hpp"
@ -52,6 +53,10 @@ std::string base;
*/
std::string channel;
/**
* default ll-cli configuration provided by package
*/
std::optional<LlCLIConfig> cliConfig;
/**
* command of package info
*/
std::optional<std::vector<std::string>> command;

View File

@ -17,6 +17,7 @@
#include <nlohmann/json.hpp>
#include "linglong/api/types/v1/helper.hpp"
#include "linglong/api/types/v1/LlCLIConfig.hpp"
#include "linglong/api/types/v1/ExtensionImpl.hpp"
#include "linglong/api/types/v1/ExtensionDefine.hpp"
#include "linglong/api/types/v1/ApplicationConfigurationPermissions.hpp"
@ -52,6 +53,10 @@ std::string base;
*/
std::string channel;
/**
* default ll-cli configuration provided by package
*/
std::optional<LlCLIConfig> cliConfig;
/**
* command of package info
*/
std::optional<std::vector<std::string>> command;

View File

@ -1164,7 +1164,9 @@ utils::error::Result<void> Builder::commitToLocalRepo() noexcept
auto info = api::types::v1::PackageInfoV2{
.arch = { projectRef->arch.toStdString() },
.base = project.base,
.channel = projectRef->channel,
.cliConfig = project.cliConfig,
.command = project.command,
.description = project.package.description,
.id = project.package.id,
@ -1176,7 +1178,6 @@ utils::error::Result<void> Builder::commitToLocalRepo() noexcept
.version = project.package.version,
};
info.base = project.base;
if (project.runtime) {
info.runtime = project.runtime;
}

View File

@ -664,6 +664,9 @@ int Cli::run(const RunOptions &options)
runContext.enableSecurityContext(runtime::getDefaultSecurityContexts());
const auto &fsPolicy = runContext.filesystemPolicy();
const bool restrictFilesystem = fsPolicy.allowListConfigured;
linglong::generator::ContainerCfgBuilder cfgBuilder;
cfgBuilder.setAppId(curAppRef->id)
.setAnnotation(generator::ANNOTATION::LAST_PID, std::to_string(pid))
@ -673,15 +676,28 @@ int Cli::run(const RunOptions &options)
.bindDevNode()
.bindCgroup()
.bindXDGRuntime()
.bindUserGroup()
.bindRemovableStorageMounts()
.bindHostRoot()
.bindHostStatics()
.bindHome(homeEnv)
.enablePrivateDir()
.mapPrivate(std::string{ homeEnv } + "/.ssh", true)
.mapPrivate(std::string{ homeEnv } + "/.gnupg", true)
.bindIPC()
.bindUserGroup();
if (!restrictFilesystem) {
cfgBuilder.bindRemovableStorageMounts()
.bindHostRoot()
.bindHostStatics();
}
cfgBuilder.bindHome(homeEnv).enablePrivateDir();
if (restrictFilesystem) {
cfgBuilder.disableHostHomeBind();
}
if (restrictFilesystem) {
cfgBuilder.mapPrivate(std::string{ homeEnv }, true);
} else {
cfgBuilder.mapPrivate(std::string{ homeEnv } + "/.ssh", true)
.mapPrivate(std::string{ homeEnv } + "/.gnupg", true);
}
cfgBuilder.bindIPC()
.forwardDefaultEnv()
.enableSelfAdjustingMount();

View File

@ -3,6 +3,9 @@
*/
#include "run_context.h"
#include "configure.h"
#include "linglong/api/types/v1/Generators.hpp"
#include "linglong/common/display.h"
#include "linglong/extension/extension.h"
@ -11,8 +14,359 @@
#include <utility>
#include <algorithm>
#include <filesystem>
#include <fstream>
#include <iterator>
#include <map>
#include <nlohmann/json.hpp>
#include <optional>
#include <sstream>
#include <unordered_set>
#include <vector>
namespace linglong::runtime {
static std::vector<std::filesystem::path> configBasesUserFirst()
{
namespace fs = std::filesystem;
std::vector<fs::path> bases;
std::unordered_set<std::string> seen;
auto addBase = [&](const fs::path &candidate) {
if (candidate.empty()) {
return;
}
auto normalized = candidate.lexically_normal();
auto key = normalized.string();
if (key.empty()) {
return;
}
if (seen.insert(key).second) {
bases.emplace_back(std::move(normalized));
}
};
if (const char *xdgConfigHome = ::getenv("XDG_CONFIG_HOME");
xdgConfigHome && xdgConfigHome[0] != '\0') {
addBase(fs::path(xdgConfigHome) / "linglong");
} else if (const char *homeEnv = ::getenv("HOME"); homeEnv && homeEnv[0] != '\0') {
addBase(fs::path(homeEnv) / ".config" / "linglong");
}
addBase(fs::path(LINGLONG_DATA_DIR) / "config");
return bases;
}
static std::vector<std::filesystem::path> configBasesFallbackFirst()
{
auto bases = configBasesUserFirst();
if (bases.size() <= 1) {
return bases;
}
std::rotate(bases.begin(), std::prev(bases.end()), bases.end());
return bases;
}
static std::vector<std::string> loadExtensionsFromConfig(const std::string &appId)
{
namespace fs = std::filesystem;
std::vector<std::string> result;
// 2. 定义解析函数:从指定 JSON 文件提取 "extensions" 数组,并加入 result
auto parseExtensions = [&](const fs::path &p) {
try {
if (!fs::exists(p)) return;
std::ifstream in(p);
if (!in.is_open()) return;
nlohmann::json j;
in >> j;
if (!j.contains("extensions") || !j.at("extensions").is_array()) return;
for (const auto &elem : j.at("extensions")) {
if (elem.is_string()) {
std::string ext = elem.get<std::string>();
if (std::find(result.begin(), result.end(), ext) == result.end()) {
result.emplace_back(std::move(ext));
}
}
}
} catch (...) {
// 文件不存在或解析失败时忽略
}
};
for (const auto &base : configBasesUserFirst()) {
parseExtensions(base / "config.json");
if (!appId.empty()) {
parseExtensions(base / "apps" / appId / "config.json");
}
}
return result;
}
static std::vector<std::string> loadExtensionsFromBase(const std::string &baseId)
{
namespace fs = std::filesystem;
std::vector<std::string> result;
if (baseId.empty()) {
return result;
}
for (const auto &root : configBasesUserFirst()) {
fs::path cfgPath = root / "base" / baseId / "config.json";
try {
if (!fs::exists(cfgPath)) {
continue;
}
std::ifstream in(cfgPath);
if (!in.is_open()) {
continue;
}
nlohmann::json j;
in >> j;
if (!j.contains("extensions") || !j.at("extensions").is_array()) {
continue;
}
for (const auto &elem : j.at("extensions")) {
if (elem.is_string()) {
std::string ext = elem.get<std::string>();
if (std::find(result.begin(), result.end(), ext) == result.end()) {
result.emplace_back(std::move(ext));
}
}
}
} catch (...) {
// ignore parse errors
}
}
return result;
}
// ===== begin: config helpers for env/mount/commands (Global->Base->App merge) =====
using json = nlohmann::json;
static json loadMergedJsonWithBase(const std::string &appId, const std::string &baseId)
{
namespace fs = std::filesystem;
json merged = json::object();
auto readIfExists = [](const fs::path &p) -> std::optional<json> {
try {
if (!fs::exists(p)) {
return std::nullopt;
}
std::ifstream in(p);
if (!in.is_open()) {
return std::nullopt;
}
json j;
in >> j;
return j;
} catch (...) {
return std::nullopt;
}
};
for (const auto &root : configBasesFallbackFirst()) {
if (auto g = readIfExists(root / "config.json")) {
merged.merge_patch(*g);
}
if (!baseId.empty()) {
if (auto b = readIfExists(root / "base" / baseId / "config.json")) {
merged.merge_patch(*b);
}
}
if (!appId.empty()) {
if (auto a = readIfExists(root / "apps" / appId / "config.json")) {
merged.merge_patch(*a);
}
}
}
return merged;
}
static std::string expandUserHome(const std::string &path)
{
if (path == "~" || path.rfind("~/", 0) == 0) {
const char *home = ::getenv("HOME");
if (home && home[0]) {
return path == "~" ? std::string(home) : (std::string(home) + path.substr(1));
}
}
return path;
}
static void collectEnvFromJson(const json &j, std::vector<std::string> &out)
{
if (!j.contains("env") || !j.at("env").is_object()) {
return;
}
for (auto it = j.at("env").begin(); it != j.at("env").end(); ++it) {
const std::string key = it.key();
std::string val = it.value().is_string() ? it.value().get<std::string>() : std::string();
if (val.find('$') != std::string::npos) {
qWarning() << "ignore env with variable expansion:" << QString::fromStdString(key);
continue;
}
if (!key.empty() && key.back() == '+') {
out.emplace_back(key.substr(0, key.size() - 1) + "+=" + val);
} else {
out.emplace_back(key + "=" + val);
}
}
}
static std::vector<ocppi::runtime::config::types::Mount>
parseFilesystemMounts(const std::string &appId, const json &arr)
{
using Mount = ocppi::runtime::config::types::Mount;
std::vector<Mount> mounts;
if (!arr.is_array()) {
return mounts;
}
for (const auto &e : arr) {
if (!e.is_object()) {
continue;
}
std::string host = e.value("host", "");
std::string target = e.value("target", "");
std::string mode = e.value("mode", "ro");
bool persist = e.value("persist", false);
if (host.empty() || target.empty()) {
continue;
}
if (host.find('$') != std::string::npos || target.find('$') != std::string::npos) {
qWarning() << "ignore mount with variable expansion:" << QString::fromStdString(host)
<< "->" << QString::fromStdString(target);
continue;
}
host = expandUserHome(host);
if (persist) {
const char *home = ::getenv("HOME");
if (home && home[0] && !appId.empty()) {
std::filesystem::path p(home);
p /= ".var/app";
p /= appId;
p /= std::filesystem::path(host).filename();
host = p.string();
}
std::error_code ec;
std::filesystem::path hostPath(host);
if (!std::filesystem::exists(hostPath, ec)) {
ec.clear();
if (!std::filesystem::create_directories(hostPath, ec) && ec) {
ec.clear();
auto parent = hostPath.parent_path();
if (!parent.empty()) {
std::filesystem::create_directories(parent, ec);
}
}
}
if (ec || !std::filesystem::exists(hostPath, ec)) {
qWarning() << "failed to prepare persist directory for"
<< QString::fromStdString(host) << ":" << ec.message().c_str();
continue;
}
}
Mount m;
m.type = "bind";
m.source = host;
m.destination = target;
m.options = { { (mode == "rw" ? "rw" : "ro"), "rbind" } };
mounts.emplace_back(std::move(m));
}
return mounts;
}
static void collectMountsFromJson(const std::string &appId,
const json &j,
std::vector<ocppi::runtime::config::types::Mount> &out)
{
if (!j.contains("filesystem") || !j.at("filesystem").is_array()) {
return;
}
auto mounts = parseFilesystemMounts(appId, j.at("filesystem"));
std::move(mounts.begin(), mounts.end(), std::back_inserter(out));
}
struct CommandSettings {
std::vector<std::string> envKVs;
std::vector<ocppi::runtime::config::types::Mount> mounts;
std::vector<std::string> argsPrefix;
std::vector<std::string> argsSuffix;
std::optional<std::string> entrypoint;
std::optional<std::string> cwd;
};
static const json *pickCommandNode(const json &merged, const std::string &execName)
{
if (!merged.contains("commands") || !merged.at("commands").is_object()) {
return nullptr;
}
const auto &cmds = merged.at("commands");
if (auto it = cmds.find(execName); it != cmds.end() && it->is_object()) {
return &(*it);
}
if (auto it = cmds.find("*"); it != cmds.end() && it->is_object()) {
return &(*it);
}
return nullptr;
}
static void loadStrVec(const json &node, const char *key, std::vector<std::string> &out)
{
if (!node.contains(key) || !node.at(key).is_array()) {
return;
}
for (const auto &v : node.at(key)) {
if (v.is_string()) {
out.emplace_back(v.get<std::string>());
}
}
}
static CommandSettings parseCommandSettings(const std::string &appId, const json &node)
{
CommandSettings cs;
if (node.contains("env") && node.at("env").is_object()) {
for (auto it = node.at("env").begin(); it != node.at("env").end(); ++it) {
const std::string key = it.key();
std::string val = it.value().is_string() ? it.value().get<std::string>() : std::string();
if (val.find('$') != std::string::npos) {
qWarning() << "ignore env with variable expansion in command settings:"
<< QString::fromStdString(key);
continue;
}
if (!key.empty() && key.back() == '+') {
cs.envKVs.emplace_back(key.substr(0, key.size() - 1) + "+=" + val);
} else {
cs.envKVs.emplace_back(key + "=" + val);
}
}
}
if (node.contains("filesystem") && node.at("filesystem").is_array()) {
collectMountsFromJson(appId, node, cs.mounts);
}
loadStrVec(node, "args_prefix", cs.argsPrefix);
loadStrVec(node, "args_suffix", cs.argsSuffix);
if (node.contains("entrypoint") && node.at("entrypoint").is_string()) {
cs.entrypoint = node.at("entrypoint").get<std::string>();
}
if (node.contains("cwd") && node.at("cwd").is_string()) {
cs.cwd = node.at("cwd").get<std::string>();
}
return cs;
}
// ===== end: config helpers =====
RuntimeLayer::RuntimeLayer(package::Reference ref, RunContext &context)
: reference(std::move(ref))
, runContext(context)
@ -82,6 +436,8 @@ utils::error::Result<void> RunContext::resolve(const linglong::package::Referenc
{
LINGLONG_TRACE("resolve RunContext from runnable " + runnable.toString());
filesystemPolicyCache.reset();
containerID = runtime::genContainerID(runnable);
auto item = repo.getLayerItem(runnable);
@ -155,8 +511,50 @@ utils::error::Result<void> RunContext::resolve(const linglong::package::Referenc
}
// 手动解析多个扩展
// 先从命令行选项或配置文件获取扩展列表
// 先从命令行选项或应用/全局配置获取扩展列表
std::vector<std::string> extRefs;
if (options.extensionRefs && !options.extensionRefs->empty()) {
auto manualExtensionDef = makeManualExtensionDefine(*options.extensionRefs);
extRefs = *options.extensionRefs;
} else {
extRefs = loadExtensionsFromConfig(runnable.id);
}
if (extRefs.empty() && info.cliConfig && info.cliConfig->extensions) {
extRefs = *info.cliConfig->extensions;
}
// 如果未获取到扩展列表,则尝试根据 base 层加载
if (extRefs.empty()) {
// 获取 baseId
std::string baseId;
// 1. 优先使用 ResolveOptions::baseRef如果提供
if (options.baseRef && !options.baseRef->empty()) {
// 假设存在 FuzzyReference::parse可解析出 id 部分
auto baseRef = linglong::package::FuzzyReference::parse(*options.baseRef);
if (baseRef) {
baseId = baseRef->id;
}
}
// 2. 否则从当前运行包信息中获取
if (baseId.empty()) {
auto item = repo.getLayerItem(runnable);
if (item && !item->info.base.empty()) {
baseId = item->info.base;
}
}
// 3. 若 baseId 非空,则读取 base 配置
if (!baseId.empty()) {
extRefs = loadExtensionsFromBase(baseId);
}
}
// 若 extRefs 非空,继续使用原有的手动解析逻辑
if (!extRefs.empty()) {
auto manualExtensionDef = makeManualExtensionDefine(extRefs);
if (!manualExtensionDef) {
return LINGLONG_ERR(manualExtensionDef);
}
@ -177,6 +575,8 @@ utils::error::Result<void> RunContext::resolve(const api::types::v1::BuilderProj
{
LINGLONG_TRACE("resolve RunContext from builder project " + target.package.id);
filesystemPolicyCache.reset();
auto targetRef = package::Reference::fromBuilderProject(target);
if (!targetRef) {
return LINGLONG_ERR(targetRef);
@ -572,10 +972,176 @@ RunContext::fillContextCfg(linglong::generator::ContainerCfgBuilder &builder)
return res;
}
// === begin: merge Global->Base->App config ===
std::string currentAppId;
if (appLayer) currentAppId = appLayer->getReference().id;
else if (!targetId.empty()) currentAppId = targetId;
std::string currentBaseId;
if (baseLayer) currentBaseId = baseLayer->getReference().id;
json mergedCfg = json::object();
auto mergeCliConfig = [&](RuntimeLayer *layer) {
if (layer == nullptr) {
return;
}
auto item = layer->getCachedItem();
if (!item) {
return;
}
if (item->info.cliConfig) {
json cfg = *(item->info.cliConfig);
if (mergedCfg.empty()) {
mergedCfg = std::move(cfg);
} else {
mergedCfg.merge_patch(cfg);
}
}
};
mergeCliConfig(baseLayer ? &*baseLayer : nullptr);
mergeCliConfig(appLayer ? &*appLayer : nullptr);
auto configFromDirs = loadMergedJsonWithBase(currentAppId, currentBaseId);
if (mergedCfg.empty()) {
mergedCfg = configFromDirs;
} else {
mergedCfg.merge_patch(configFromDirs);
}
std::optional<std::string> mergedPath;
// 1) common env
{
std::vector<std::string> envKVs;
collectEnvFromJson(mergedCfg, envKVs);
if (!envKVs.empty()) {
std::map<std::string, std::string> genEnv;
std::string basePath;
if (auto sysPath = ::getenv("PATH")) {
basePath = sysPath;
}
auto extPathIt = environment.find("PATH");
for (const auto &kv : envKVs) {
auto pos = kv.find("+=");
if (pos != std::string::npos) {
auto key = kv.substr(0, pos);
auto add = kv.substr(pos + 2);
if (key == "PATH") {
if (genEnv.count("PATH")) {
genEnv["PATH"] += ":" + add;
} else if (extPathIt != environment.end()) {
genEnv["PATH"] =
extPathIt->second.empty() ? add : extPathIt->second + ":" + add;
} else if (!basePath.empty()) {
genEnv["PATH"] = basePath + ":" + add;
} else {
genEnv["PATH"] = add;
}
} else {
qWarning() << "ignore '+=' env for key:" << QString::fromStdString(key);
}
continue;
}
auto eq = kv.find('=');
if (eq == std::string::npos) {
continue;
}
genEnv[kv.substr(0, eq)] = kv.substr(eq + 1);
}
if (!genEnv.empty()) {
if (auto it = genEnv.find("PATH"); it != genEnv.end()) {
mergedPath = it->second;
}
builder.appendEnv(genEnv);
}
}
}
// 2) common filesystem
{
const auto &fsPolicy = filesystemPolicy();
if (fsPolicy.allowListConfigured) {
if (!fsPolicy.allowList.empty()) {
auto allowList = fsPolicy.allowList;
builder.addExtraMounts(std::move(allowList));
}
} else if (!fsPolicy.extra.empty()) {
auto extraMounts = fsPolicy.extra;
builder.addExtraMounts(std::move(extraMounts));
}
}
// === end: merge Global->Base->App config ===
if (!environment.empty()) {
if (auto it = environment.find("PATH"); it != environment.end()) {
mergedPath = it->second;
}
builder.appendEnv(environment);
}
// === begin: command-level settings (highest priority) ===
{
std::string execName = currentAppId;
if (!execName.empty()) {
if (const json *node = pickCommandNode(mergedCfg, execName)) {
CommandSettings cs = parseCommandSettings(currentAppId, *node);
if (!cs.envKVs.empty()) {
std::map<std::string, std::string> cmdEnv;
std::string basePath;
if (auto sysPath = ::getenv("PATH")) {
basePath = sysPath;
}
auto extPathIt = environment.find("PATH");
for (const auto &kv : cs.envKVs) {
auto posp = kv.find("+=");
if (posp != std::string::npos) {
auto key = kv.substr(0, posp);
auto add = kv.substr(posp + 2);
if (key == "PATH") {
if (cmdEnv.count("PATH")) {
cmdEnv["PATH"] += ":" + add;
} else if (mergedPath) {
cmdEnv["PATH"] =
mergedPath->empty() ? add : *mergedPath + ":" + add;
} else if (extPathIt != environment.end()) {
cmdEnv["PATH"] =
extPathIt->second.empty()
? add
: extPathIt->second + ":" + add;
} else if (!basePath.empty()) {
cmdEnv["PATH"] = basePath + ":" + add;
} else {
cmdEnv["PATH"] = add;
}
} else {
qWarning() << "ignore '+=' env for key in command settings:"
<< QString::fromStdString(key);
}
continue;
}
auto eq = kv.find('=');
if (eq == std::string::npos) {
continue;
}
cmdEnv[kv.substr(0, eq)] = kv.substr(eq + 1);
}
if (!cmdEnv.empty()) {
if (auto it = cmdEnv.find("PATH"); it != cmdEnv.end()) {
mergedPath = it->second;
}
builder.appendEnv(cmdEnv);
}
}
if (!cs.mounts.empty()) builder.addExtraMounts(cs.mounts);
// TODO: when builder exposes API for entrypoint/cwd/args, apply here as well.
}
}
}
// === end: command-level settings ===
detectDisplaySystem(builder);
for (auto ctx = securityContexts.begin(); ctx != securityContexts.end(); ++ctx) {
@ -726,6 +1292,45 @@ utils::error::Result<std::filesystem::path> RunContext::getBaseLayerPath() const
return std::filesystem::path{ layerDir->absolutePath().toStdString() };
}
std::string RunContext::currentAppId() const
{
if (appLayer) {
return appLayer->getReference().id;
}
return targetId;
}
const RunContext::FilesystemPolicy &RunContext::filesystemPolicy() const
{
if (!filesystemPolicyCache) {
FilesystemPolicy policy;
auto appId = currentAppId();
std::string baseId;
if (baseLayer) {
baseId = baseLayer->getReference().id;
}
auto mergedCfg = loadMergedJsonWithBase(appId, baseId);
if (auto it = mergedCfg.find("filesystem_allow_only"); it != mergedCfg.end()) {
policy.allowListConfigured = true;
if (it->is_array()) {
policy.allowList = parseFilesystemMounts(appId, *it);
}
}
if (!policy.allowListConfigured) {
if (auto it = mergedCfg.find("filesystem"); it != mergedCfg.end()) {
policy.extra = parseFilesystemMounts(appId, *it);
}
}
filesystemPolicyCache = std::move(policy);
}
return *filesystemPolicyCache;
}
utils::error::Result<std::filesystem::path> RunContext::getRuntimeLayerPath() const
{
LINGLONG_TRACE("get runtime layer path");

View File

@ -16,6 +16,9 @@
#include <filesystem>
#include <list>
#include <optional>
#include <string>
#include <vector>
namespace linglong::runtime {
@ -65,6 +68,13 @@ struct ResolveOptions
class RunContext
{
public:
struct FilesystemPolicy
{
bool allowListConfigured{ false };
std::vector<ocppi::runtime::config::types::Mount> allowList;
std::vector<ocppi::runtime::config::types::Mount> extra;
};
RunContext(repo::OSTreeRepo &r)
: repo(r)
{
@ -83,6 +93,9 @@ public:
repo::OSTreeRepo &getRepo() const { return repo; }
std::string currentAppId() const;
const FilesystemPolicy &filesystemPolicy() const;
const std::string &getContainerId() const { return containerID; }
const std::optional<RuntimeLayer> &getBaseLayer() const { return baseLayer; }
@ -128,6 +141,7 @@ private:
std::string containerID;
std::filesystem::path bundle;
std::map<std::string, std::string> environment;
mutable std::optional<FilesystemPolicy> filesystemPolicyCache;
};
} // namespace linglong::runtime

View File

@ -769,11 +769,12 @@ bool ContainerCfgBuilder::buildMountHome() noexcept
.type = "tmpfs" });
auto containerHome = homePath->string();
homeMount->emplace_back(Mount{ .destination = containerHome,
.options = string_list{ "rbind" },
.source = *homePath,
.type = "bind" });
if (!skipHostHome) {
homeMount->emplace_back(Mount{ .destination = containerHome,
.options = string_list{ "rbind" },
.source = *homePath,
.type = "bind" });
}
environment["HOME"] = containerHome;
auto mountDir = [this](const std::filesystem::path &hostDir, const std::string &containerDir) {
@ -803,7 +804,7 @@ bool ContainerCfgBuilder::buildMountHome() noexcept
value ? std::filesystem::path{ value } : *homePath / ".local" / "share";
std::string containerDataHome = containerHome + "/.local/share";
if (XDG_DATA_HOME != containerDataHome) {
if (!mountDir(XDG_DATA_HOME, containerDataHome)) {
if (!skipHostHome && !mountDir(XDG_DATA_HOME, containerDataHome)) {
error_.reason = XDG_DATA_HOME.string() + " can't be mount";
error_.code = BUILD_MOUNT_HOME_ERROR;
return false;
@ -834,7 +835,7 @@ bool ContainerCfgBuilder::buildMountHome() noexcept
}
std::string containerConfigHome = containerHome + "/.config";
if (XDGConfigHome != containerConfigHome) {
if (!mountDir(XDGConfigHome, containerConfigHome)) {
if (!skipHostHome && !mountDir(XDGConfigHome, containerConfigHome)) {
error_.reason = XDGConfigHome.string() + " can't be mount";
error_.code = BUILD_MOUNT_HOME_ERROR;
return false;
@ -852,7 +853,7 @@ bool ContainerCfgBuilder::buildMountHome() noexcept
}
std::string containerCacheHome = containerHome + "/.cache";
if (XDGCacheHome != containerCacheHome) {
if (!mountDir(XDGCacheHome, containerCacheHome)) {
if (!skipHostHome && !mountDir(XDGCacheHome, containerCacheHome)) {
error_.reason = XDGCacheHome.string() + " can't be mount";
error_.code = BUILD_MOUNT_HOME_ERROR;
return false;
@ -869,7 +870,7 @@ bool ContainerCfgBuilder::buildMountHome() noexcept
}
std::string containerStateHome = containerHome + "/.local/state";
if (XDG_STATE_HOME != containerStateHome) {
if (!mountDir(XDG_STATE_HOME, containerStateHome)) {
if (!skipHostHome && !mountDir(XDG_STATE_HOME, containerStateHome)) {
error_.reason = XDG_STATE_HOME.string() + " can't be mount";
error_.code = BUILD_MOUNT_HOME_ERROR;
return false;
@ -881,10 +882,12 @@ bool ContainerCfgBuilder::buildMountHome() noexcept
auto hostSystemdUserDir = XDG_CONFIG_HOME / "systemd" / "user";
if ((XDG_CONFIG_HOME != containerConfigHome)
&& std::filesystem::exists(hostSystemdUserDir, ec)) {
homeMount->emplace_back(Mount{ .destination = containerConfigHome + "/systemd/user",
if (!skipHostHome) {
homeMount->emplace_back(Mount{ .destination = containerConfigHome + "/systemd/user",
.options = string_list{ "rbind" },
.source = hostSystemdUserDir,
.type = "bind" });
}
}
// FIXME: Many applications get configurations from dconf, so we expose dconf to all
@ -893,15 +896,18 @@ bool ContainerCfgBuilder::buildMountHome() noexcept
auto hostUserDconfPath = XDG_CONFIG_HOME / "dconf";
if ((XDG_CONFIG_HOME != containerConfigHome)
&& std::filesystem::exists(hostUserDconfPath, ec)) {
homeMount->emplace_back(Mount{ .destination = containerConfigHome + "/dconf",
if (!skipHostHome) {
homeMount->emplace_back(Mount{ .destination = containerConfigHome + "/dconf",
.options = string_list{ "rbind" },
.source = hostUserDconfPath,
.type = "bind" });
}
}
// for dde application theme
auto hostDDEApiPath = XDG_CACHE_HOME / "deepin" / "dde-api";
if ((XDG_CACHE_HOME != containerCacheHome) && std::filesystem::exists(hostDDEApiPath, ec)) {
if (!skipHostHome && (XDG_CACHE_HOME != containerCacheHome)
&& std::filesystem::exists(hostDDEApiPath, ec)) {
homeMount->emplace_back(Mount{ .destination = containerCacheHome + "/deepin/dde-api",
.options = string_list{ "rbind" },
.source = hostDDEApiPath,
@ -910,7 +916,8 @@ bool ContainerCfgBuilder::buildMountHome() noexcept
// for xdg-user-dirs
auto XDGUserDirs = XDG_CONFIG_HOME / "user-dirs.dirs";
if ((XDG_CONFIG_HOME != containerConfigHome) && std::filesystem::exists(XDGUserDirs, ec)) {
if (!skipHostHome && (XDG_CONFIG_HOME != containerConfigHome)
&& std::filesystem::exists(XDGUserDirs, ec)) {
homeMount->push_back(Mount{ .destination = containerConfigHome + "/user-dirs.dirs",
.options = string_list{ "rbind" },
.source = XDGUserDirs,
@ -918,7 +925,8 @@ bool ContainerCfgBuilder::buildMountHome() noexcept
}
auto XDGUserLocale = XDG_CONFIG_HOME / "user-dirs.locale";
if ((XDG_CONFIG_HOME != containerConfigHome) && std::filesystem::exists(XDGUserLocale, ec)) {
if (!skipHostHome && (XDG_CONFIG_HOME != containerConfigHome)
&& std::filesystem::exists(XDGUserLocale, ec)) {
homeMount->push_back(Mount{ .destination = containerConfigHome + "/user-dirs.locale",
.options = string_list{ "rbind" },
.source = XDGUserLocale,

View File

@ -143,6 +143,11 @@ public:
ContainerCfgBuilder &bindHostRoot() noexcept;
ContainerCfgBuilder &bindHostStatics() noexcept;
ContainerCfgBuilder &bindHome(std::filesystem::path hostHome) noexcept;
ContainerCfgBuilder &disableHostHomeBind() noexcept
{
skipHostHome = true;
return *this;
}
ContainerCfgBuilder &bindXOrgSocket(const std::filesystem::path &socket) noexcept;
ContainerCfgBuilder &bindXAuthFile(const std::filesystem::path &authFile) noexcept;
@ -304,6 +309,7 @@ private:
// home dir
std::optional<std::filesystem::path> homePath;
std::optional<std::vector<ocppi::runtime::config::types::Mount>> homeMount;
bool skipHostHome{ false };
// private dir
std::filesystem::path privatePath;

View File

@ -1,133 +1,128 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE policyconfig PUBLIC "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
"http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
<!-- this file only used to skip DBus security check, it will be removed later -->
<policyconfig>
<vendor />
<vendor_url />
<icon_name>stock_person</icon_name>
<action id="org.deepin.linglong.PackageManager1.checkAuthentication">
<description>Check Authentication</description>
<message>Authentication is required to perform this action</message>
<defaults>
<allow_any>auth_admin</allow_any>
<allow_inactive>auth_admin</allow_inactive>
<allow_active>auth_admin_keep</allow_active>
</defaults>
<annotate key="org.freedesktop.policykit.exec.path">@CMAKE_INSTALL_FULL_BINDIR@/@LINGLONG_CLI_BIN@</annotate>
<description xml:lang="ar">التحقق من المصادقة</description>
<message xml:lang="ar">المصادقة مطلوبة لتنفيذ هذا الإجراء</message>
<description xml:lang="ast">Comprobar l'autenticación</description>
<message xml:lang="ast">Ríquese l'autenticación pa realizar esta aición</message>
<description xml:lang="az">Doğrulamaya nəzarət et</description>
<message xml:lang="az">Bu əməliyyatı yerinə yetirmək üçün doğrulama tələບ olunur</message>
<description xml:lang="bg">Проверете удостоверяването</description>
<message xml:lang="bg">Удостоверяването е задължително за извършване на това действие</message>
<description xml:lang="bn">প্রমাণীকরণ পরীক্ষা করুন</description>
<message xml:lang="bn">এই কাজটি সম্পন্ন করার জন্য প্রমাণীকরণের প্রয়োজন</message>
<description xml:lang="bo">ར་ສྤྲོད་བསྐྱར་ཞິບབྱེད་པ།</description>
<message xml:lang="bo">ལས་ཀ་འདི་སྒྲུབ་པར་ར་སྤྲོད་བྱེད་དགོས།</message>
<description xml:lang="ca">Comprova l'autenticació</description>
<message xml:lang="ca">Cal autenticació per a dur a terme aquesta acció.</message>
<description xml:lang="cs">Ověřit autentizaci</description>
<message xml:lang="cs">Provedení této akce vyžaduje autentizaci</message>
<description xml:lang="da">Kontroller godkendelse</description>
<message xml:lang="da">Der kræves godkendelse for at udføre denne handling</message>
<description xml:lang="de">Authentifizierung prüfen</description>
<message xml:lang="de">Zur Durchführung dieser Aktion ist eine Authentifizierung erforderlich</message>
<description xml:lang="de_DE">Authentifizierung prüfen</description>
<message xml:lang="de_DE">Für diese Aktion ist eine Authentifizierung erforderlich</message>
<description xml:lang="el">Έλεγχος ταυτότητας</description>
<message xml:lang="el">Απαιτείται πιστοποίηση για την εκτέλεση αυτής της ενέργειας</message>
<description xml:lang="en_AU">Check Authentication</description>
<message xml:lang="en_AU">Authentication is required to perform this action</message>
<description xml:lang="en_GB">Check Authentication</description>
<message xml:lang="en_GB">Authentication is required to perform this action</message>
<description xml:lang="en_US">Check Authentication</description>
<message xml:lang="en_US">Authentication is required to perform this action</message>
<description xml:lang="eo">Kontroli Aŭtentigon</description>
<message xml:lang="eo">Aŭtentigo bezonatas por plenumi ĉi tiun agon</message>
<description xml:lang="es">Comprobar autenticación</description>
<message xml:lang="es">Se requiere autenticación para realizar esta acción</message>
<description xml:lang="es_419">Comprobar autenticación</description>
<message xml:lang="es_419">Se requiere autenticación para realizar esta acción</message>
<description xml:lang="fa">بررسی احراز هویت</description>
<message xml:lang="fa">احراز هویت برای انجام این عمل لازم است</message>
<description xml:lang="fi">Tarkista todennus</description>
<message xml:lang="fi">Tämän toiminnon suorittaminen edellyttää todennusta</message>
<description xml:lang="fr">Vérifier l'authentification</description>
<message xml:lang="fr">L'authentification est requise pour effectuer cette action</message>
<description xml:lang="gl_ES">Comprobar autenticación</description>
<message xml:lang="gl_ES">Requírese autenticación para realizar esta acción</message>
<description xml:lang="hi_IN">प्रमाणीकरण की जाँच करें</description>
<message xml:lang="hi_IN">यह कार्य करने हेतु प्रमाणीकरण आवश्यक है</message>
<description xml:lang="hr">Provjera ovjere</description>
<message xml:lang="hr">Potrebna je ovjera za obavljanje ove radnje</message>
<description xml:lang="hu">Hitelesítés ellenőrzése</description>
<message xml:lang="hu">A művelet végrehajtásához hitelesítés szükséges</message>
<description xml:lang="id">Periksa Otentikasi</description>
<message xml:lang="id">Otentikasi diperlukan untuk melakukan tindakan ini</message>
<description xml:lang="it">Verifica Autenticazione</description>
<message xml:lang="it">Autenticazione richiesta per eseguire questa operazione</message>
<description xml:lang="ja">認証を確認</description>
<message xml:lang="ja">この操作を実行するには認証が必要です</message>
<description xml:lang="kab">Sesteb n usemdu</description>
<message xml:lang="kab">Yetwasra usesteb akken ad tbeddeleḍ tazzla-a.</message>
<description xml:lang="ko">인증 확인</description>
<message xml:lang="ko">이 작업을 수행하려면 인증이 필요합니다</message>
<description xml:lang="lo">ກວດສອບການຢັ້ງຢືນຕົວຕົນ</description>
<message xml:lang="lo">ຕ້ອງມີການຢັ້ງຢືນຕົວຕົນເພື່ອປະຕິບັດການດຳເນີນການນີ້</message>
<description xml:lang="lt">Patikrinti tapatybės nustatymą</description>
<message xml:lang="lt">Norint atlikti šį veiksmą, reikalingas tapatybės nustatymas</message>
<description xml:lang="lv">Pārbaudīt autentifikāciju</description>
<message xml:lang="lv">Lai veiktu šo darbību, nepieciešama autentifikācija</message>
<description xml:lang="mn">Баталгаажуулалт шалгах</description>
<message xml:lang="mn">Энэ үйлдлийг хийхэд баталгаажуулалт шаардлагатай</message>
<description xml:lang="ms">Semak Pengesahihan</description>
<message xml:lang="ms">Pengesahihan diperlukan untuk melakukan tindakan ini</message>
<description xml:lang="ne">प्रमाणीकरण जाँच गर्नुहोस्</description>
<message xml:lang="ne">यो कार्य गर्न प्रमाणीकरण आवश्यक छ</message>
<description xml:lang="nl">Authenticatie controleren</description>
<message xml:lang="nl">Authenticatie vereist om deze actie uit te voeren</message>
<description xml:lang="pa">ਪ੍ਰਮਾਣਕਤਾ ਦੀ ਜਾਂਚ ਕਰੋ</description>
<message xml:lang="pa">ਇਹ ਕਾਰਵਾਈ ਕਰਨ ਲਈ ਪ੍ਰਮਾਣਕਤਾ ਦੀ ਲੋੜ ਹੈ</message>
<description xml:lang="pl">Sprawdź uwierzytelnienie</description>
<message xml:lang="pl">Wymagane jest uwierzytelnienie, aby wykonać tę czynność</message>
<description xml:lang="pt">Verificar autenticação</description>
<message xml:lang="pt">É necessária a autenticação para efetuar esta ação</message>
<description xml:lang="pt_BR">Verificar autenticação</description>
<message xml:lang="pt_BR">A autenticação é necessária para realizar esta ação</message>
<description xml:lang="ro">Verificare autentificare</description>
<message xml:lang="ro">Autentificarea este necesară pentru a efectua această acțiune</message>
<description xml:lang="ru">Проверить аутентификацию</description>
<message xml:lang="ru">Для выполнения этого действия требуется аутентификация</message>
<description xml:lang="si">සත්‍යාපනය පරීක්ෂා කරන්න</description>
<message xml:lang="si">මෙම ක්‍රියාව සිදු කිරීමට සත්‍යාපනය අවශ්‍ය වේ</message>
<description xml:lang="sk">Skontrolovať overenie totožnosti</description>
<message xml:lang="sk">Na vykonanie tejto akcie sa vyžaduje overenie totožnosti</message>
<description xml:lang="sl">Preverite avtentikacijo</description>
<message xml:lang="sl">Za izvedbo tega dejanja je potrebna avtentikacija</message>
<description xml:lang="sq">Kontrollo Mirëfilltësimin</description>
<message xml:lang="sq">Për të kryer këtë veprim, lypset mirëfilltësim</message>
<description xml:lang="sr">Провери идентификацију</description>
<message xml:lang="sr">Идентификација је неопходна за извршење ове радње</message>
<description xml:lang="sv">Kontrollera autentisering</description>
<message xml:lang="sv">Autentisering krävs för att utföra denna åtgärd</message>
<description xml:lang="sw">Angalia Uthibitishaji</description>
<message xml:lang="sw">Uthibitishaji unahitajika kutekeleza kitendo hiki</message>
<description xml:lang="tr">Kimlik Doğrulamayı Kontrol Et</description>
<message xml:lang="tr">Bu eylemi gerçekleştirmek için kimlik doğrulaması gereklidir</message>
<description xml:lang="ug">سالاھىيەتنى دەلىللەش</description>
<message xml:lang="ug">بۇ ھەرىكەتنى ئىجرا قىلىش ئۈچۈن سالاھىيەتنى دەلىللەش كېرەك</message>
<description xml:lang="uk">Перевірити розпізнавання</description>
<message xml:lang="uk">Для виконання цієї дії потрібно пройти розпізнавання</message>
<description xml:lang="vi">Kiểm tra Xác thực</description>
<message xml:lang="vi">Cần xác thực để thực hiện hành động này</message>
<description xml:lang="zh_CN">检查认证</description>
<message xml:lang="zh_CN">当前操作需要密码认证</message>
<description xml:lang="zh_TW">檢查驗證</description>
<message xml:lang="zh_TW">執行此操作需要驗證</message>
<description xml:lang="zh_HK">檢查認證</description>
<message xml:lang="zh_HK">執行此操作需要認證</message>
</action>
<vendor />
<vendor_url />
<icon_name>stock_person</icon_name>
<action id="org.deepin.linglong.PackageManager1.checkAuthentication">
<description>Check Authentication</description>
<message>Authentication is required to perform this action</message>
<defaults>
<allow_any>auth_admin</allow_any>
<allow_inactive>auth_admin</allow_inactive>
<allow_active>auth_admin_keep</allow_active>
</defaults>
<annotate key="org.freedesktop.policykit.exec.path">@CMAKE_INSTALL_FULL_BINDIR@/@LINGLONG_CLI_BIN@</annotate>
<description xml:lang="ar">التحقق من المصادقة</description>
<message xml:lang="ar">المصادقة مطلوبة لتنفيذ هذا الإجراء</message>
<description xml:lang="ast">Comprobar l'autenticación</description>
<message xml:lang="ast">Ríquese l'autenticación pa realizar esta aición</message>
<description xml:lang="az">Doğrulamaya nəzarət et</description>
<message xml:lang="az">Bu əməliyyatı yerinə yetirmək üçün doğrulama tələບ olunur</message>
<description xml:lang="bg">Проверете удостоверяването</description>
<message xml:lang="bg">Удостоверяването е задължително за извършване на това действие</message>
<description xml:lang="bn">প্রমাণীকরণ পরীক্ষা করুন</description>
<message xml:lang="bn">এই কাজটি সম্পন্ন করার জন্য প্রমাণীকরণের প্রয়োজন</message>
<description xml:lang="bo">ར་ສྤྲོད་བསྐྱར་ཞິບབྱེད་པ།</description>
<message xml:lang="bo">ལས་ཀ་འདི་སྒྲུབ་པར་ར་སྤྲོད་བྱེད་དགོས།</message>
<description xml:lang="ca">Comprova l'autenticació</description>
<message xml:lang="ca">Cal autenticació per a dur a terme aquesta acció.</message>
<description xml:lang="cs">Ověřit autentizaci</description>
<message xml:lang="cs">Provedení této akce vyžaduje autentizaci</message>
<description xml:lang="da">Kontroller godkendelse</description>
<message xml:lang="da">Der kræves godkendelse for at udføre denne handling</message>
<description xml:lang="de">Authentifizierung prüfen</description>
<message xml:lang="de">Zur Durchführung dieser Aktion ist eine Authentifizierung erforderlich</message>
<description xml:lang="el">Έλεγχος ταυτότητας</description>
<message xml:lang="el">Απαιτείται πιστοποίηση για την εκτέλεση αυτής της ενέργειας</message>
<description xml:lang="en_AU">Check Authentication</description>
<message xml:lang="en_AU">Authentication is required to perform this action</message>
<description xml:lang="en_GB">Check Authentication</description>
<message xml:lang="en_GB">Authentication is required to perform this action</message>
<description xml:lang="en_US">Check Authentication</description>
<message xml:lang="en_US">Authentication is required to perform this action</message>
<description xml:lang="eo">Kontroli Aŭtentigon</description>
<message xml:lang="eo">Aŭtentigo bezonatas por plenumi ĉi tiun agon</message>
<description xml:lang="es">Comprobar autenticación</description>
<message xml:lang="es">Se requiere autenticación para realizar esta acción</message>
<description xml:lang="fa">بررسی احراز هویت</description>
<message xml:lang="fa">احراز هویت برای انجام این عمل لازم است</message>
<description xml:lang="fi">Tarkista todennus</description>
<message xml:lang="fi">Tämän toiminnon suorittaminen edellyttää todennusta</message>
<description xml:lang="fr">Vérifier l'authentification</description>
<message xml:lang="fr">L'authentification est requise pour effectuer cette action</message>
<description xml:lang="gl_ES">Comprobar autenticación</description>
<message xml:lang="gl_ES">Requírese autenticación para realizar esta acción</message>
<description xml:lang="hi_IN">प्रमाणीकरण की जाँच करें</description>
<message xml:lang="hi_IN">यह कार्य करने हेतु प्रमाणीकरण आवश्यक है</message>
<description xml:lang="hr">Provjera ovjere</description>
<message xml:lang="hr">Potrebna je ovjera za obavljanje ove radnje</message>
<description xml:lang="hu">Hitelesítés ellenőrzése</description>
<message xml:lang="hu">A művelet végrehajtásához hitelesítés szükséges</message>
<description xml:lang="id">Periksa Otentikasi</description>
<message xml:lang="id">Otentikasi diperlukan untuk melakukan tindakan ini</message>
<description xml:lang="it">Verifica Autenticazione</description>
<message xml:lang="it">Autenticazione richiesta per eseguire questa operazione</message>
<description xml:lang="ja">認証を確認</description>
<message xml:lang="ja">この操作を実行するには認証が必要です</message>
<description xml:lang="kab">Sesteb n usemdu</description>
<message xml:lang="kab">Yetwasra usesteb akken ad tbeddeleḍ tazzla-a.</message>
<description xml:lang="ko">인증 확인</description>
<message xml:lang="ko">이 작업을 수행하려면 인증이 필요합니다</message>
<description xml:lang="lo">ກວດສອບການກວດສອບຄວາມຖືກຕ້ອງ</description>
<message xml:lang="lo">ຕ້ອງການການພິສູດຢືນຢັນຕົວຕົນເພື່ອປະຕິບັດການກະທຳນີ້</message>
<description xml:lang="lt">Patikrinti tapatybės nustatymą</description>
<message xml:lang="lt">Norint atlikti šį veiksmą, reikalingas tapatybės nustatymas</message>
<description xml:lang="lv">Pārbaudīt autentifikāciju</description>
<message xml:lang="lv">Lai veiktu šo darbību, nepieciešama autentifikācija</message>
<description xml:lang="mn">Баталгаажуулалт шалгах</description>
<message xml:lang="mn">Энэ үйлдлийг хийхэд баталгаажуулалт шаардлагатай</message>
<description xml:lang="ms">Semak Pengesahihan</description>
<message xml:lang="ms">Pengesahihan diperlukan untuk melakukan tindakan ini</message>
<description xml:lang="ne">प्रमाणीकरण जाँच गर्नुहोस्</description>
<message xml:lang="ne">यो कार्य गर्न प्रमाणीकरण आवश्यक छ</message>
<description xml:lang="nl">Authenticatie controleren</description>
<message xml:lang="nl">Authenticatie vereist om deze actie uit te voeren</message>
<description xml:lang="pa">ਪ੍ਰਮਾਣਕਤਾ ਦੀ ਜਾਂਚ ਕਰੋ</description>
<message xml:lang="pa">ਇਹ ਕਾਰਵਾਈ ਕਰਨ ਲਈ ਪ੍ਰਮਾਣਕਤਾ ਦੀ ਲੋੜ ਹੈ</message>
<description xml:lang="pl">Sprawdź uwierzytelnienie</description>
<message xml:lang="pl">Wymagane jest uwierzytelnienie, aby wykonać tę czynność</message>
<description xml:lang="pt">Verificar autenticação</description>
<message xml:lang="pt">É necessária a autenticação para efetuar esta ação</message>
<description xml:lang="pt_BR">Verificar autenticação</description>
<message xml:lang="pt_BR">A autenticação é necessária para realizar esta ação</message>
<description xml:lang="ro">Verificare autentificare</description>
<message xml:lang="ro">Autentificarea este necesară pentru a efectua această acțiune</message>
<description xml:lang="ru">Проверить аутентификацию</description>
<message xml:lang="ru">Для выполнения этого действия требуется аутентификация</message>
<description xml:lang="si">සත්‍යාපනය පරීක්ෂා කරන්න</description>
<message xml:lang="si">මෙම ක්‍රියාව සිදු කිරීමට සත්‍යාපනය අවශ්‍ය වේ</message>
<description xml:lang="sk">Skontrolovať overenie totožnosti</description>
<message xml:lang="sk">Na vykonanie tejto akcie sa vyžaduje overenie totožnosti</message>
<description xml:lang="sl">Preverite avtentikacijo</description>
<message xml:lang="sl">Za izvedbo tega dejanja je potrebna avtentikacija</message>
<description xml:lang="sq">Kontrollo Mirëfilltësimin</description>
<message xml:lang="sq">Për të kryer këtë veprim, lypset mirëfilltësim</message>
<description xml:lang="sr">Провери идентификацију</description>
<message xml:lang="sr">Идентификација је неопходна за извршење ове радње</message>
<description xml:lang="sv">Kontrollera autentisering</description>
<message xml:lang="sv">Autentisering krävs för att utföra denna åtgärd</message>
<description xml:lang="sw">Angalia Uthibitishaji</description>
<message xml:lang="sw">Uthibitishaji unahitajika kutekeleza kitendo hiki</message>
<description xml:lang="tr">Kimlik Doğrulamayı Kontrol Et</description>
<message xml:lang="tr">Bu eylemi gerçekleştirmek için kimlik doğrulaması gereklidir</message>
<description xml:lang="ug">سالاھىيەتنى دەلىللەش</description>
<message xml:lang="ug">بۇ ھەرىكەتنى ئىجرا قىلىش ئۈچۈن سالاھىيەتنى دەلىللەش كېرەك</message>
<description xml:lang="uk">Перевірити розпізнавання</description>
<message xml:lang="uk">Для виконання цієї дії потрібно пройти розпізнавання</message>
<description xml:lang="vi">Kiểm tra Xác thực</description>
<message xml:lang="vi">Cần xác thực để thực hiện hành động này</message>
<description xml:lang="zh_CN">检查认证</description>
<message xml:lang="zh_CN">当前操作需要密码认证</message>
<description xml:lang="zh_HK">檢查認證</description>
<message xml:lang="zh_HK">執行此操作需要認證</message>
<description xml:lang="zh_TW">檢查驗證</description>
<message xml:lang="zh_TW">執行此操作需要驗證</message>
</action>
</policyconfig>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE TS>
<TS version="2.1">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0" />
<source>Authentication is required to perform this action</source>
<translation type="unfinished" />
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0" />
<source>Check Authentication</source>
<translation type="unfinished" />
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="ar">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation>المصادقة مطلوبة لتنفيذ هذا الإجراء</translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation>التحقق من المصادقة</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="ast">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation>Ríquese l&apos;autenticación pa realizar esta aición</translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation>Comprobar l&apos;autenticación</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="az">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation>Bu əməliyyatı yerinə yetirmək üçün doğrulama tələບ olunur</translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation>Doğrulamaya nəzarət et</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="bg">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation>Удостоверяването е задължително за извършване на това действие</translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation>Проверете удостоверяването</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="bn">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation> ি </translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation> </translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="bo">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation></translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation></translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="ca">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation>Cal autenticació per a dur a terme aquesta acció.</translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation>Comprova l&apos;autenticació</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="cs">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation>Provedení této akce vyžaduje autentizaci</translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation>Ověřit autentizaci</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="da">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation>Der kræves godkendelse for at udføre denne handling</translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation>Kontroller godkendelse</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="de">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation>Zur Durchführung dieser Aktion ist eine Authentifizierung erforderlich</translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation>Authentifizierung prüfen</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="el">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation>Απαιτείται πιστοποίηση για την εκτέλεση αυτής της ενέργειας</translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation>Έλεγχος ταυτότητας</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="en_AU">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation>Authentication is required to perform this action</translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation>Check Authentication</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="en_GB">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation>Authentication is required to perform this action</translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation>Check Authentication</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="en_US">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0" />
<source>Authentication is required to perform this action</source>
<translation>Authentication is required to perform this action</translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0" />
<source>Check Authentication</source>
<translation>Check Authentication</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="eo">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation>Aŭtentigo bezonatas por plenumi ĉi tiun agon</translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation>Kontroli Aŭtentigon</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="es">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation>Se requiere autenticación para realizar esta acción</translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation>Comprobar autenticación</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="fa">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation>احراز هویت برای انجام این عمل لازم است</translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation>بررسی احراز هویت</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="fi">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation>Tämän toiminnon suorittaminen edellyttää todennusta</translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation>Tarkista todennus</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="fr">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation>L&apos;authentification est requise pour effectuer cette action</translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation>Vérifier l&apos;authentification</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="gl_ES">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation>Requírese autenticación para realizar esta acción</translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation>Comprobar autenticación</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="hi_IN">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation> </translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation> </translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="hr">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation>Potrebna je ovjera za obavljanje ove radnje</translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation>Provjera ovjere</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="hu">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation>A művelet végrehajtásához hitelesítés szükséges</translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation>Hitelesítés ellenőrzése</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="id">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation>Otentikasi diperlukan untuk melakukan tindakan ini</translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation>Periksa Otentikasi</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="it">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation>Autenticazione richiesta per eseguire questa operazione</translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation>Verifica Autenticazione</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="ja">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation></translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation></translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="kab">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation>Yetwasra usesteb akken ad tbeddeleḍ tazzla-a.</translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation>Sesteb n usemdu</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="ko">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation> </translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation> </translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="lo">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation></translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation></translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="lt">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation>Norint atlikti šį veiksmą, reikalingas tapatybės nustatymas</translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation>Patikrinti tapatybės nustatymą</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="lv">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation>Lai veiktu šo darbību, nepieciešama autentifikācija</translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation>Pārbaudīt autentifikāciju</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="mn">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation>Энэ үйлдлийг хийхэд баталгаажуулалт шаардлагатай</translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation>Баталгаажуулалт шалгах</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="ms">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation>Pengesahihan diperlukan untuk melakukan tindakan ini</translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation>Semak Pengesahihan</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="ne">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation> </translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation> </translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="nl">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation>Authenticatie vereist om deze actie uit te voeren</translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation>Authenticatie controleren</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="pa">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation> </translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation> </translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="pl">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation>Wymagane jest uwierzytelnienie, aby wykonać czynność</translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation>Sprawdź uwierzytelnienie</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="pt">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation>É necessária a autenticação para efetuar esta ação</translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation>Verificar autenticação</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="pt_BR">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation>A autenticação é necessária para realizar esta ação</translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation>Verificar autenticação</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="ro">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation>Autentificarea este necesară pentru a efectua această acțiune</translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation>Verificare autentificare</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="ru">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation>Для выполнения этого действия требуется аутентификация</translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation>Проверить аутентификацию</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="si">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation> </translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation> </translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="sk">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation>Na vykonanie tejto akcie sa vyžaduje overenie totožnosti</translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation>Skontrolovať overenie totožnosti</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="sl">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation>Za izvedbo tega dejanja je potrebna avtentikacija</translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation>Preverite avtentikacijo</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="sq">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation>Për kryer këtë veprim, lypset mirëfilltësim</translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation>Kontrollo Mirëfilltësimin</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="sr">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation>Идентификација је неопходна за извршење ове радње</translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation>Провери идентификацију</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="sv">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation>Autentisering krävs för att utföra denna åtgärd</translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation>Kontrollera autentisering</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="sw">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation>Uthibitishaji unahitajika kutekeleza kitendo hiki</translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation>Angalia Uthibitishaji</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="tr">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation>Bu eylemi gerçekleştirmek için kimlik doğrulaması gereklidir</translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation>Kimlik Doğrulamayı Kontrol Et</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="ug">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation>بۇ ھەرىكەتنى ئىجرا قىلىش ئۈچۈن سالاھىيەتنى دەلىللەش كېرەك</translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation>سالاھىيەتنى دەلىللەش</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="uk">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation>Для виконання цієї дії потрібно пройти розпізнавання</translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation>Перевірити розпізнавання</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="vi">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation>Cần xác thực đ thực hiện hành đng này</translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation>Kiểm tra Xác thực</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="zh_CN">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation></translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation></translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="zh_HK">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation></translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation></translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="zh_TW">
<context>
<name>policy</name>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!message" line="0"/>
<source>Authentication is required to perform this action</source>
<translation></translation>
</message>
<message>
<location filename="org.deepin.linglong.PackageManager1.checkAuthentication!description" line="0"/>
<source>Check Authentication</source>
<translation></translation>
</message>
</context>
</TS>

View File

@ -1,941 +0,0 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-09-10 17:13+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: ../libs/linglong/src/linglong/cli/cli.cpp:74
msgid "Permission denied, please check whether you are running as root."
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli.cpp:526
msgid "To install the module, one must first install the app."
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli.cpp:529
msgid "Module is already installed."
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli.cpp:532
#: ../libs/linglong/src/linglong/cli/cli.cpp:1259
msgid "Install failed"
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli.cpp:535
msgid "The module could not be found remotely."
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli.cpp:538
#: ../libs/linglong/src/linglong/cli/cli.cpp:1731
msgid "Uninstall failed"
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli.cpp:541
msgid "Upgrade failed"
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli.cpp:544
#: ../libs/linglong/src/linglong/cli/cli.cpp:1712
msgid "Application is not installed."
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli.cpp:547
msgid "Latest version is already installed."
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli.cpp:1233
#: ../libs/linglong/src/linglong/cli/cli.cpp:1527
msgid ""
"Network connection failed. Please:\n"
"1. Check your internet connection\n"
"2. Verify network proxy settings if used"
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli.cpp:1239
msgid ""
"Application already installed, If you want to replace it, try using 'll-cli "
"install %1 --force'"
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli.cpp:1245
msgid "Application %1 is not found in remote repo."
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli.cpp:1249
msgid "Cannot specify a version when installing a module."
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli.cpp:1253
msgid ""
"The latest version has been installed. If you want to replace it, try using "
"'ll-cli install %1/version --force'"
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli.cpp:1716
msgid ""
"Multiple versions of the package are installed. Please specify a single "
"version to uninstall:\n"
"%1"
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli.cpp:1722
msgid ""
"The application is currently running and cannot be uninstalled. Please turn "
"off the application and try again."
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli.cpp:1727
msgid "Base or runtime cannot be uninstalled, please use 'll-cli prune'."
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli.cpp:2735
msgid ""
"The cache generation failed, please uninstall and reinstall the application."
msgstr ""
#: ../apps/ll-cli/src/main.cpp:146 ../apps/ll-cli/src/main.cpp:563
#: ../apps/ll-builder/src/main.cpp:95
msgid "Input parameter is empty, please input valid parameter instead"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:157
msgid "Run an application"
msgstr ""
#. add sub command run options
#: ../apps/ll-cli/src/main.cpp:160
msgid "Specify the application ID"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:163
msgid ""
"Usage: ll-cli run [OPTIONS] APP [COMMAND...]\n"
"\n"
"Example:\n"
"# run application by appid\n"
"ll-cli run org.deepin.demo\n"
"# execute commands in the container rather than running the application\n"
"ll-cli run org.deepin.demo bash\n"
"ll-cli run org.deepin.demo -- bash\n"
"ll-cli run org.deepin.demo -- bash -x /path/to/bash/script"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:175
msgid "Pass file to applications running in a sandbox"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:179
msgid "Pass url to applications running in a sandbox"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:182
msgid "Set environment variables for the application"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:188
msgid "Input parameter is invalid, please input valid parameter instead"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:194
msgid "Specify the base used by the application to run"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:200
msgid "Specify the runtime used by the application to run"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:203 ../apps/ll-cli/src/main.cpp:234
msgid "Run commands in a running sandbox"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:209
msgid "List running applications"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:212
msgid "Usage: ll-cli ps [OPTIONS]"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:221
msgid "Enter the namespace where the application is running"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:227
msgid "Specify the application running instance(you can get it by ps command)"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:231
msgid "Specify working directory"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:240
msgid "Stop running applications"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:243
msgid "Usage: ll-cli kill [OPTIONS] APP"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:247
msgid "Specify the signal to send to the application"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:249
msgid "Specify the running application"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:260
msgid "Installing an application or runtime"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:263
msgid ""
"Usage: ll-cli install [OPTIONS] APP\n"
"\n"
"Example:\n"
"# install application by appid\n"
"ll-cli install org.deepin.demo\n"
"# install application by linyaps layer\n"
"ll-cli install demo_0.0.0.1_x86_64_binary.layer\n"
"# install application by linyaps uab\n"
"ll-cli install demo_x86_64_0.0.0.1_main.uab\n"
"# install specified module of the appid\n"
"ll-cli install org.deepin.demo --module=binary\n"
"# install specified version of the appid\n"
"ll-cli install org.deepin.demo/0.0.0.1\n"
"# install application by detailed reference\n"
"ll-cli install stable:org.deepin.demo/0.0.0.1/x86_64\n"
" "
msgstr ""
#: ../apps/ll-cli/src/main.cpp:282
msgid "Specify the application ID, and it can also be a .uab or .layer file"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:285
msgid "Install a specify module"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:288
msgid "Install from a specific repo"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:291
msgid "Force install the application"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:294
msgid "Automatically answer yes to all questions"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:303
msgid "Uninstall the application or runtimes"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:306
msgid "Usage: ll-cli uninstall [OPTIONS] APP"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:307
msgid "Specify the applications ID"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:310
msgid "Uninstall a specify module"
msgstr ""
#. below options are used for compatibility with old ll-cli
#: ../apps/ll-cli/src/main.cpp:315
msgid "Remove all unused modules"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:319
msgid "Uninstall all modules"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:329
msgid "Upgrade the application or runtimes"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:332
msgid "Usage: ll-cli upgrade [OPTIONS] [APP]"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:336
msgid ""
"Specify the application ID. If it not be specified, all applications will be "
"upgraded"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:348
msgid ""
"Search the applications/runtimes containing the specified text from the "
"remote repository"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:352
msgid ""
"Usage: ll-cli search [OPTIONS] KEYWORDS\n"
"\n"
"Example:\n"
"# find remotely application(s), base(s) or runtime(s) by keywords\n"
"ll-cli search org.deepin.demo\n"
"# find all of app of remote\n"
"ll-cli search .\n"
"# find all of base(s) of remote\n"
"ll-cli search . --type=base\n"
"# find all of runtime(s) of remote\n"
"ll-cli search . --type=runtime"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:363
msgid "Specify the Keywords"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:370 ../apps/ll-cli/src/main.cpp:409
msgid ""
"Filter result with specify type. One of \"runtime\", \"base\", \"app\" or "
"\"all\""
msgstr ""
#: ../apps/ll-cli/src/main.cpp:374
msgid "Specify the repo"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:379
msgid "Include develop application in result"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:382
msgid "Show all versions of an application(s), base(s) or runtime(s)"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:390
msgid "List installed application(s), base(s) or runtime(s)"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:393
msgid ""
"Usage: ll-cli list [OPTIONS]\n"
"\n"
"Example:\n"
"# show installed application(s), base(s) or runtime(s)\n"
"ll-cli list\n"
"# show installed base(s)\n"
"ll-cli list --type=base\n"
"# show installed runtime(s)\n"
"ll-cli list --type=runtime\n"
"# show the latest version list of the currently installed application(s)\n"
"ll-cli list --upgradable\n"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:415
msgid ""
"Show the list of latest version of the currently installed application(s), "
"base(s) or runtime(s)"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:425
msgid "Display or modify information of the repository currently using"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:427
msgid "Usage: ll-cli repo SUBCOMMAND [OPTIONS]"
msgstr ""
#. add repo sub command add
#: ../apps/ll-cli/src/main.cpp:431 ../apps/ll-builder/src/main.cpp:953
msgid "Add a new repository"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:432
msgid "Usage: ll-cli repo add [OPTIONS] NAME URL"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:433 ../apps/ll-cli/src/main.cpp:445
#: ../apps/ll-builder/src/main.cpp:955
msgid "Specify the repo name"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:436 ../apps/ll-cli/src/main.cpp:448
#: ../apps/ll-cli/src/main.cpp:466 ../apps/ll-builder/src/main.cpp:958
#: ../apps/ll-builder/src/main.cpp:981
msgid "Url of the repository"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:439 ../apps/ll-cli/src/main.cpp:455
#: ../apps/ll-cli/src/main.cpp:463 ../apps/ll-cli/src/main.cpp:474
#: ../apps/ll-cli/src/main.cpp:486 ../apps/ll-cli/src/main.cpp:496
#: ../apps/ll-cli/src/main.cpp:503 ../apps/ll-builder/src/main.cpp:962
#: ../apps/ll-builder/src/main.cpp:970 ../apps/ll-builder/src/main.cpp:978
#: ../apps/ll-builder/src/main.cpp:990 ../apps/ll-builder/src/main.cpp:999
#: ../apps/ll-builder/src/main.cpp:1008
msgid "Alias of the repo name"
msgstr ""
#. add repo sub command modify
#: ../apps/ll-cli/src/main.cpp:444
msgid "Modify repository URL"
msgstr ""
#. add repo sub command remove
#: ../apps/ll-cli/src/main.cpp:453 ../apps/ll-builder/src/main.cpp:967
msgid "Remove a repository"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:454
msgid "Usage: ll-cli repo remove [OPTIONS] NAME"
msgstr ""
#. add repo sub command update
#. TODO: add --repo and --url options
#. add repo sub command update
#: ../apps/ll-cli/src/main.cpp:461 ../apps/ll-builder/src/main.cpp:975
msgid "Update the repository URL"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:462
msgid "Usage: ll-cli repo update [OPTIONS] NAME URL"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:472 ../apps/ll-builder/src/main.cpp:987
msgid "Set a default repository name"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:473
msgid "Usage: ll-cli repo set-default [OPTIONS] NAME"
msgstr ""
#. add repo sub command show
#: ../apps/ll-cli/src/main.cpp:479 ../apps/ll-builder/src/main.cpp:1013
msgid "Show repository information"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:480
msgid "Usage: ll-cli repo show [OPTIONS]"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:484
msgid "Set the priority of the repo"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:485
msgid "Usage: ll-cli repo set-priority ALIAS PRIORITY"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:489
msgid "Priority of the repo"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:494 ../apps/ll-builder/src/main.cpp:996
msgid "Enable mirror for the repo"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:495
msgid "Usage: ll-cli repo enable-mirror [OPTIONS] ALIAS"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:501 ../apps/ll-builder/src/main.cpp:1005
msgid "Disable mirror for the repo"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:502
msgid "Usage: ll-cli repo disable-mirror [OPTIONS] ALIAS"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:513
msgid "Display information about installed apps or runtimes"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:516
msgid "Usage: ll-cli info [OPTIONS] APP"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:520
msgid "Specify the application ID, and it can also be a .layer file"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:532
msgid "Display the exported files of installed application"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:535
msgid "Usage: ll-cli content [OPTIONS] APP"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:536
msgid "Specify the installed application ID"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:544
msgid "Remove the unused base or runtime"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:546
msgid "Usage: ll-cli prune [OPTIONS]"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:556
msgid "Display the information of installed application"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:558
msgid "Usage: ll-cli inspect [OPTIONS]"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:560
msgid "Specify the process id"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:569
msgid "Invalid process id"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:572
msgid "Invalid pid format"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:587
msgid "Specify the installed app(base or runtime)"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:590
msgid "Specify a module"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:630
msgid ""
"linyaps CLI\n"
"A CLI program to run application and manage application and runtime\n"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:638 ../apps/ll-builder/src/main.cpp:753
msgid "Print this help message and exit"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:639 ../apps/ll-builder/src/main.cpp:754
msgid "Expand all help"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:640
msgid "Usage: ll-cli [OPTIONS] [SUBCOMMAND]"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:641
msgid ""
"If you found any problems during use,\n"
"You can report bugs to the linyaps team under this project: https://github."
"com/OpenAtom-Linyaps/linyaps/issues"
msgstr ""
#. version flag
#: ../apps/ll-cli/src/main.cpp:648 ../apps/ll-builder/src/main.cpp:778
msgid "Show version"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:653
msgid ""
"Use peer to peer DBus, this is used only in case that DBus daemon is not "
"available"
msgstr ""
#. json flag
#: ../apps/ll-cli/src/main.cpp:658
msgid "Use json format to output result"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:665
msgid "Show debug info (verbose logs)"
msgstr ""
#. groups for subcommands
#: ../apps/ll-cli/src/main.cpp:683
msgid "Managing installed applications and runtimes"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:684
msgid "Managing running applications"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:685
msgid "Finding applications and runtimes"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:686
msgid "Managing remote repositories"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:713
msgid "linyaps CLI version "
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:71
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:134
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:329
msgid "ID"
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:72
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:135
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:253
msgid "Name"
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:73
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:136
msgid "Version"
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:74
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:137
msgid "Channel"
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:75
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:138
msgid "Module"
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:76
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:140
msgid "Description"
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:107
msgid "No packages found in the remote repo."
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:139
msgid "Repo"
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:174
msgid "No containers are running."
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:178
msgid "App"
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:179
msgid "ContainerID"
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:180
msgid "Pid"
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:254
msgid "Url"
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:255
msgid "Alias"
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:256
msgid "Priority"
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:317
msgid "No apps available for update."
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:330
msgid "Installed"
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:331
msgid "New"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:751
msgid ""
"linyaps builder CLI \n"
"A CLI program to build linyaps application\n"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:756
msgid "Usage: ll-builder [OPTIONS] [SUBCOMMAND]"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:758
msgid ""
"If you found any problems during use\n"
"You can report bugs to the linyaps team under this project: https://github."
"com/OpenAtom-Linyaps/linyaps/issues"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:782
msgid "Create linyaps build template project"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:783
msgid "Usage: ll-builder create [OPTIONS] NAME"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:784
msgid "Project name"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:792
msgid "Build a linyaps project"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:793
msgid "Usage: ll-builder build [OPTIONS] [COMMAND...]"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:794 ../apps/ll-builder/src/main.cpp:835
#: ../apps/ll-builder/src/main.cpp:862 ../apps/ll-builder/src/main.cpp:908
msgid "File path of the linglong.yaml"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:800
msgid "Enter the container to execute command instead of building applications"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:803
msgid ""
"Only use local files. This implies --skip-fetch-source and --skip-pull-"
"depend will be set"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:808
msgid "Build full develop packages, runtime requires"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:812
msgid "Skip fetch sources"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:815
msgid "Skip pull dependency"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:818
msgid "Skip run container"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:821
msgid "Skip commit build output"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:824
msgid "Skip output check"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:827
msgid "Skip strip debug symbols"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:830
msgid "Build in an isolated network environment"
msgstr ""
#. add builder run
#: ../apps/ll-builder/src/main.cpp:833
msgid "Run built linyaps app"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:834
msgid "Usage: ll-builder run [OPTIONS] [COMMAND...]"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:841
msgid "Run specified module. eg: --modules binary,develop"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:847
msgid "Enter the container to execute command instead of running application"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:850
msgid "Run in debug mode (enable develop module)"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:852
msgid "List built linyaps app"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:853
msgid "Usage: ll-builder list [OPTIONS]"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:854
msgid "Remove built linyaps app"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:855
msgid "Usage: ll-builder remove [OPTIONS] [APP...]"
msgstr ""
#. build export
#: ../apps/ll-builder/src/main.cpp:859
msgid "Export to linyaps layer or uab"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:860
msgid "Usage: ll-builder export [OPTIONS]"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:872
msgid "Uab icon (optional)"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:877
msgid "Export to linyaps layer file (deprecated)"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:880
msgid "Use custom loader"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:887
msgid "Don't export the develop module"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:889
msgid "Output file"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:893
msgid "Reference of the package"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:898
msgid "Modules to export"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:906
msgid "Push linyaps app to remote repo"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:907
msgid "Usage: ll-builder push [OPTIONS]"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:911
msgid "Remote repo url"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:914
msgid "Remote repo name"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:917
msgid "Push single module"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:921
msgid "Import linyaps layer to build repo"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:922
msgid "Usage: ll-builder import [OPTIONS] LAYER"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:923 ../apps/ll-builder/src/main.cpp:940
msgid "Layer file path"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:930
msgid "Import linyaps layer dir to build repo"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:932
msgid "Usage: ll-builder import-dir PATH"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:933
msgid "Layer dir path"
msgstr ""
#. add build extract
#: ../apps/ll-builder/src/main.cpp:938
msgid "Extract linyaps layer to dir"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:939
msgid "Usage: ll-builder extract [OPTIONS] LAYER DIR"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:943
msgid "Destination directory"
msgstr ""
#. add build repo
#: ../apps/ll-builder/src/main.cpp:948
msgid "Display and manage repositories"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:949
msgid "Usage: ll-builder repo [OPTIONS] SUBCOMMAND"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:954
msgid "Usage: ll-builder repo add [OPTIONS] NAME URL"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:968
msgid "Usage: ll-builder repo remove [OPTIONS] NAME"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:976
msgid "Usage: ll-builder repo update [OPTIONS] NAME URL"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:988
msgid "Usage: ll-builder repo set-default [OPTIONS] NAME"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:997
msgid "Usage: ll-builder repo enable-mirror [OPTIONS] ALIAS"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:1006
msgid "Usage: ll-builder repo disable-mirror [OPTIONS] ALIAS"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:1014
msgid "Usage: ll-builder repo show [OPTIONS]"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:1019
msgid "linyaps build tool version "
msgstr ""
#: ../apps/ll-dialog/src/permissionDialog.cpp:34
msgid "Whether to allow %1 to access %2?"
msgstr ""
#. button
#: ../apps/ll-dialog/src/permissionDialog.cpp:43
msgid "Allow"
msgstr ""
#: ../apps/ll-dialog/src/permissionDialog.cpp:48
#, c-format
msgid "Deny (%1s)"
msgstr ""
#: ../apps/ll-dialog/src/cache_dialog.cpp:53
msgid "Linglong Package Manager"
msgstr ""
#: ../apps/ll-dialog/src/cache_dialog.cpp:54
msgid "is starting"
msgstr ""

View File

@ -1,941 +0,0 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-09-10 17:13+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: ../libs/linglong/src/linglong/cli/cli.cpp:74
msgid "Permission denied, please check whether you are running as root."
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli.cpp:526
msgid "To install the module, one must first install the app."
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli.cpp:529
msgid "Module is already installed."
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli.cpp:532
#: ../libs/linglong/src/linglong/cli/cli.cpp:1259
msgid "Install failed"
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli.cpp:535
msgid "The module could not be found remotely."
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli.cpp:538
#: ../libs/linglong/src/linglong/cli/cli.cpp:1731
msgid "Uninstall failed"
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli.cpp:541
msgid "Upgrade failed"
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli.cpp:544
#: ../libs/linglong/src/linglong/cli/cli.cpp:1712
msgid "Application is not installed."
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli.cpp:547
msgid "Latest version is already installed."
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli.cpp:1233
#: ../libs/linglong/src/linglong/cli/cli.cpp:1527
msgid ""
"Network connection failed. Please:\n"
"1. Check your internet connection\n"
"2. Verify network proxy settings if used"
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli.cpp:1239
msgid ""
"Application already installed, If you want to replace it, try using 'll-cli "
"install %1 --force'"
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli.cpp:1245
msgid "Application %1 is not found in remote repo."
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli.cpp:1249
msgid "Cannot specify a version when installing a module."
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli.cpp:1253
msgid ""
"The latest version has been installed. If you want to replace it, try using "
"'ll-cli install %1/version --force'"
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli.cpp:1716
msgid ""
"Multiple versions of the package are installed. Please specify a single "
"version to uninstall:\n"
"%1"
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli.cpp:1722
msgid ""
"The application is currently running and cannot be uninstalled. Please turn "
"off the application and try again."
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli.cpp:1727
msgid "Base or runtime cannot be uninstalled, please use 'll-cli prune'."
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli.cpp:2735
msgid ""
"The cache generation failed, please uninstall and reinstall the application."
msgstr ""
#: ../apps/ll-cli/src/main.cpp:146 ../apps/ll-cli/src/main.cpp:563
#: ../apps/ll-builder/src/main.cpp:95
msgid "Input parameter is empty, please input valid parameter instead"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:157
msgid "Run an application"
msgstr ""
#. add sub command run options
#: ../apps/ll-cli/src/main.cpp:160
msgid "Specify the application ID"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:163
msgid ""
"Usage: ll-cli run [OPTIONS] APP [COMMAND...]\n"
"\n"
"Example:\n"
"# run application by appid\n"
"ll-cli run org.deepin.demo\n"
"# execute commands in the container rather than running the application\n"
"ll-cli run org.deepin.demo bash\n"
"ll-cli run org.deepin.demo -- bash\n"
"ll-cli run org.deepin.demo -- bash -x /path/to/bash/script"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:175
msgid "Pass file to applications running in a sandbox"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:179
msgid "Pass url to applications running in a sandbox"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:182
msgid "Set environment variables for the application"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:188
msgid "Input parameter is invalid, please input valid parameter instead"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:194
msgid "Specify the base used by the application to run"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:200
msgid "Specify the runtime used by the application to run"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:203 ../apps/ll-cli/src/main.cpp:234
msgid "Run commands in a running sandbox"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:209
msgid "List running applications"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:212
msgid "Usage: ll-cli ps [OPTIONS]"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:221
msgid "Enter the namespace where the application is running"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:227
msgid "Specify the application running instance(you can get it by ps command)"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:231
msgid "Specify working directory"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:240
msgid "Stop running applications"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:243
msgid "Usage: ll-cli kill [OPTIONS] APP"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:247
msgid "Specify the signal to send to the application"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:249
msgid "Specify the running application"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:260
msgid "Installing an application or runtime"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:263
msgid ""
"Usage: ll-cli install [OPTIONS] APP\n"
"\n"
"Example:\n"
"# install application by appid\n"
"ll-cli install org.deepin.demo\n"
"# install application by linyaps layer\n"
"ll-cli install demo_0.0.0.1_x86_64_binary.layer\n"
"# install application by linyaps uab\n"
"ll-cli install demo_x86_64_0.0.0.1_main.uab\n"
"# install specified module of the appid\n"
"ll-cli install org.deepin.demo --module=binary\n"
"# install specified version of the appid\n"
"ll-cli install org.deepin.demo/0.0.0.1\n"
"# install application by detailed reference\n"
"ll-cli install stable:org.deepin.demo/0.0.0.1/x86_64\n"
" "
msgstr ""
#: ../apps/ll-cli/src/main.cpp:282
msgid "Specify the application ID, and it can also be a .uab or .layer file"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:285
msgid "Install a specify module"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:288
msgid "Install from a specific repo"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:291
msgid "Force install the application"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:294
msgid "Automatically answer yes to all questions"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:303
msgid "Uninstall the application or runtimes"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:306
msgid "Usage: ll-cli uninstall [OPTIONS] APP"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:307
msgid "Specify the applications ID"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:310
msgid "Uninstall a specify module"
msgstr ""
#. below options are used for compatibility with old ll-cli
#: ../apps/ll-cli/src/main.cpp:315
msgid "Remove all unused modules"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:319
msgid "Uninstall all modules"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:329
msgid "Upgrade the application or runtimes"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:332
msgid "Usage: ll-cli upgrade [OPTIONS] [APP]"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:336
msgid ""
"Specify the application ID. If it not be specified, all applications will be "
"upgraded"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:348
msgid ""
"Search the applications/runtimes containing the specified text from the "
"remote repository"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:352
msgid ""
"Usage: ll-cli search [OPTIONS] KEYWORDS\n"
"\n"
"Example:\n"
"# find remotely application(s), base(s) or runtime(s) by keywords\n"
"ll-cli search org.deepin.demo\n"
"# find all of app of remote\n"
"ll-cli search .\n"
"# find all of base(s) of remote\n"
"ll-cli search . --type=base\n"
"# find all of runtime(s) of remote\n"
"ll-cli search . --type=runtime"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:363
msgid "Specify the Keywords"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:370 ../apps/ll-cli/src/main.cpp:409
msgid ""
"Filter result with specify type. One of \"runtime\", \"base\", \"app\" or "
"\"all\""
msgstr ""
#: ../apps/ll-cli/src/main.cpp:374
msgid "Specify the repo"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:379
msgid "Include develop application in result"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:382
msgid "Show all versions of an application(s), base(s) or runtime(s)"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:390
msgid "List installed application(s), base(s) or runtime(s)"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:393
msgid ""
"Usage: ll-cli list [OPTIONS]\n"
"\n"
"Example:\n"
"# show installed application(s), base(s) or runtime(s)\n"
"ll-cli list\n"
"# show installed base(s)\n"
"ll-cli list --type=base\n"
"# show installed runtime(s)\n"
"ll-cli list --type=runtime\n"
"# show the latest version list of the currently installed application(s)\n"
"ll-cli list --upgradable\n"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:415
msgid ""
"Show the list of latest version of the currently installed application(s), "
"base(s) or runtime(s)"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:425
msgid "Display or modify information of the repository currently using"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:427
msgid "Usage: ll-cli repo SUBCOMMAND [OPTIONS]"
msgstr ""
#. add repo sub command add
#: ../apps/ll-cli/src/main.cpp:431 ../apps/ll-builder/src/main.cpp:953
msgid "Add a new repository"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:432
msgid "Usage: ll-cli repo add [OPTIONS] NAME URL"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:433 ../apps/ll-cli/src/main.cpp:445
#: ../apps/ll-builder/src/main.cpp:955
msgid "Specify the repo name"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:436 ../apps/ll-cli/src/main.cpp:448
#: ../apps/ll-cli/src/main.cpp:466 ../apps/ll-builder/src/main.cpp:958
#: ../apps/ll-builder/src/main.cpp:981
msgid "Url of the repository"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:439 ../apps/ll-cli/src/main.cpp:455
#: ../apps/ll-cli/src/main.cpp:463 ../apps/ll-cli/src/main.cpp:474
#: ../apps/ll-cli/src/main.cpp:486 ../apps/ll-cli/src/main.cpp:496
#: ../apps/ll-cli/src/main.cpp:503 ../apps/ll-builder/src/main.cpp:962
#: ../apps/ll-builder/src/main.cpp:970 ../apps/ll-builder/src/main.cpp:978
#: ../apps/ll-builder/src/main.cpp:990 ../apps/ll-builder/src/main.cpp:999
#: ../apps/ll-builder/src/main.cpp:1008
msgid "Alias of the repo name"
msgstr ""
#. add repo sub command modify
#: ../apps/ll-cli/src/main.cpp:444
msgid "Modify repository URL"
msgstr ""
#. add repo sub command remove
#: ../apps/ll-cli/src/main.cpp:453 ../apps/ll-builder/src/main.cpp:967
msgid "Remove a repository"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:454
msgid "Usage: ll-cli repo remove [OPTIONS] NAME"
msgstr ""
#. add repo sub command update
#. TODO: add --repo and --url options
#. add repo sub command update
#: ../apps/ll-cli/src/main.cpp:461 ../apps/ll-builder/src/main.cpp:975
msgid "Update the repository URL"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:462
msgid "Usage: ll-cli repo update [OPTIONS] NAME URL"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:472 ../apps/ll-builder/src/main.cpp:987
msgid "Set a default repository name"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:473
msgid "Usage: ll-cli repo set-default [OPTIONS] NAME"
msgstr ""
#. add repo sub command show
#: ../apps/ll-cli/src/main.cpp:479 ../apps/ll-builder/src/main.cpp:1013
msgid "Show repository information"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:480
msgid "Usage: ll-cli repo show [OPTIONS]"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:484
msgid "Set the priority of the repo"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:485
msgid "Usage: ll-cli repo set-priority ALIAS PRIORITY"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:489
msgid "Priority of the repo"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:494 ../apps/ll-builder/src/main.cpp:996
msgid "Enable mirror for the repo"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:495
msgid "Usage: ll-cli repo enable-mirror [OPTIONS] ALIAS"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:501 ../apps/ll-builder/src/main.cpp:1005
msgid "Disable mirror for the repo"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:502
msgid "Usage: ll-cli repo disable-mirror [OPTIONS] ALIAS"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:513
msgid "Display information about installed apps or runtimes"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:516
msgid "Usage: ll-cli info [OPTIONS] APP"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:520
msgid "Specify the application ID, and it can also be a .layer file"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:532
msgid "Display the exported files of installed application"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:535
msgid "Usage: ll-cli content [OPTIONS] APP"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:536
msgid "Specify the installed application ID"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:544
msgid "Remove the unused base or runtime"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:546
msgid "Usage: ll-cli prune [OPTIONS]"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:556
msgid "Display the information of installed application"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:558
msgid "Usage: ll-cli inspect [OPTIONS]"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:560
msgid "Specify the process id"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:569
msgid "Invalid process id"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:572
msgid "Invalid pid format"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:587
msgid "Specify the installed app(base or runtime)"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:590
msgid "Specify a module"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:630
msgid ""
"linyaps CLI\n"
"A CLI program to run application and manage application and runtime\n"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:638 ../apps/ll-builder/src/main.cpp:753
msgid "Print this help message and exit"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:639 ../apps/ll-builder/src/main.cpp:754
msgid "Expand all help"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:640
msgid "Usage: ll-cli [OPTIONS] [SUBCOMMAND]"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:641
msgid ""
"If you found any problems during use,\n"
"You can report bugs to the linyaps team under this project: https://github."
"com/OpenAtom-Linyaps/linyaps/issues"
msgstr ""
#. version flag
#: ../apps/ll-cli/src/main.cpp:648 ../apps/ll-builder/src/main.cpp:778
msgid "Show version"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:653
msgid ""
"Use peer to peer DBus, this is used only in case that DBus daemon is not "
"available"
msgstr ""
#. json flag
#: ../apps/ll-cli/src/main.cpp:658
msgid "Use json format to output result"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:665
msgid "Show debug info (verbose logs)"
msgstr ""
#. groups for subcommands
#: ../apps/ll-cli/src/main.cpp:683
msgid "Managing installed applications and runtimes"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:684
msgid "Managing running applications"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:685
msgid "Finding applications and runtimes"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:686
msgid "Managing remote repositories"
msgstr ""
#: ../apps/ll-cli/src/main.cpp:713
msgid "linyaps CLI version "
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:71
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:134
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:329
msgid "ID"
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:72
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:135
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:253
msgid "Name"
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:73
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:136
msgid "Version"
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:74
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:137
msgid "Channel"
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:75
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:138
msgid "Module"
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:76
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:140
msgid "Description"
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:107
msgid "No packages found in the remote repo."
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:139
msgid "Repo"
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:174
msgid "No containers are running."
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:178
msgid "App"
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:179
msgid "ContainerID"
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:180
msgid "Pid"
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:254
msgid "Url"
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:255
msgid "Alias"
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:256
msgid "Priority"
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:317
msgid "No apps available for update."
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:330
msgid "Installed"
msgstr ""
#: ../libs/linglong/src/linglong/cli/cli_printer.cpp:331
msgid "New"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:751
msgid ""
"linyaps builder CLI \n"
"A CLI program to build linyaps application\n"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:756
msgid "Usage: ll-builder [OPTIONS] [SUBCOMMAND]"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:758
msgid ""
"If you found any problems during use\n"
"You can report bugs to the linyaps team under this project: https://github."
"com/OpenAtom-Linyaps/linyaps/issues"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:782
msgid "Create linyaps build template project"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:783
msgid "Usage: ll-builder create [OPTIONS] NAME"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:784
msgid "Project name"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:792
msgid "Build a linyaps project"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:793
msgid "Usage: ll-builder build [OPTIONS] [COMMAND...]"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:794 ../apps/ll-builder/src/main.cpp:835
#: ../apps/ll-builder/src/main.cpp:862 ../apps/ll-builder/src/main.cpp:908
msgid "File path of the linglong.yaml"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:800
msgid "Enter the container to execute command instead of building applications"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:803
msgid ""
"Only use local files. This implies --skip-fetch-source and --skip-pull-"
"depend will be set"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:808
msgid "Build full develop packages, runtime requires"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:812
msgid "Skip fetch sources"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:815
msgid "Skip pull dependency"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:818
msgid "Skip run container"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:821
msgid "Skip commit build output"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:824
msgid "Skip output check"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:827
msgid "Skip strip debug symbols"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:830
msgid "Build in an isolated network environment"
msgstr ""
#. add builder run
#: ../apps/ll-builder/src/main.cpp:833
msgid "Run built linyaps app"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:834
msgid "Usage: ll-builder run [OPTIONS] [COMMAND...]"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:841
msgid "Run specified module. eg: --modules binary,develop"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:847
msgid "Enter the container to execute command instead of running application"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:850
msgid "Run in debug mode (enable develop module)"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:852
msgid "List built linyaps app"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:853
msgid "Usage: ll-builder list [OPTIONS]"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:854
msgid "Remove built linyaps app"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:855
msgid "Usage: ll-builder remove [OPTIONS] [APP...]"
msgstr ""
#. build export
#: ../apps/ll-builder/src/main.cpp:859
msgid "Export to linyaps layer or uab"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:860
msgid "Usage: ll-builder export [OPTIONS]"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:872
msgid "Uab icon (optional)"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:877
msgid "Export to linyaps layer file (deprecated)"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:880
msgid "Use custom loader"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:887
msgid "Don't export the develop module"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:889
msgid "Output file"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:893
msgid "Reference of the package"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:898
msgid "Modules to export"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:906
msgid "Push linyaps app to remote repo"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:907
msgid "Usage: ll-builder push [OPTIONS]"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:911
msgid "Remote repo url"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:914
msgid "Remote repo name"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:917
msgid "Push single module"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:921
msgid "Import linyaps layer to build repo"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:922
msgid "Usage: ll-builder import [OPTIONS] LAYER"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:923 ../apps/ll-builder/src/main.cpp:940
msgid "Layer file path"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:930
msgid "Import linyaps layer dir to build repo"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:932
msgid "Usage: ll-builder import-dir PATH"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:933
msgid "Layer dir path"
msgstr ""
#. add build extract
#: ../apps/ll-builder/src/main.cpp:938
msgid "Extract linyaps layer to dir"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:939
msgid "Usage: ll-builder extract [OPTIONS] LAYER DIR"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:943
msgid "Destination directory"
msgstr ""
#. add build repo
#: ../apps/ll-builder/src/main.cpp:948
msgid "Display and manage repositories"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:949
msgid "Usage: ll-builder repo [OPTIONS] SUBCOMMAND"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:954
msgid "Usage: ll-builder repo add [OPTIONS] NAME URL"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:968
msgid "Usage: ll-builder repo remove [OPTIONS] NAME"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:976
msgid "Usage: ll-builder repo update [OPTIONS] NAME URL"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:988
msgid "Usage: ll-builder repo set-default [OPTIONS] NAME"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:997
msgid "Usage: ll-builder repo enable-mirror [OPTIONS] ALIAS"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:1006
msgid "Usage: ll-builder repo disable-mirror [OPTIONS] ALIAS"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:1014
msgid "Usage: ll-builder repo show [OPTIONS]"
msgstr ""
#: ../apps/ll-builder/src/main.cpp:1019
msgid "linyaps build tool version "
msgstr ""
#: ../apps/ll-dialog/src/permissionDialog.cpp:34
msgid "Whether to allow %1 to access %2?"
msgstr ""
#. button
#: ../apps/ll-dialog/src/permissionDialog.cpp:43
msgid "Allow"
msgstr ""
#: ../apps/ll-dialog/src/permissionDialog.cpp:48
#, c-format
msgid "Deny (%1s)"
msgstr ""
#: ../apps/ll-dialog/src/cache_dialog.cpp:53
msgid "Linglong Package Manager"
msgstr ""
#: ../apps/ll-dialog/src/cache_dialog.cpp:54
msgid "is starting"
msgstr ""