Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions apps/ll-cli/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,44 @@ void addInspectCommand(CLI::App &commandParser,
->check(validatorString);
}

// Function to add the extension subcommand
void addExtensionCommand(CLI::App &commandParser,
ExtensionOptions &extensionOptions,
const std::string &group)
{
auto *cliExtension =
commandParser.add_subcommand("extension", _("Manage extension overrides"))
->group(group)
->usage(_("Usage: ll-cli extension SUBCOMMAND [OPTIONS]"));

cliExtension->require_subcommand(1);

auto *cliImportCdi =
cliExtension
->add_subcommand("import-cdi", _("Import CDI rules into extension overrides"))
->usage(_("Usage: ll-cli extension import-cdi [OPTIONS]"));
cliImportCdi
->add_option("--name",
extensionOptions.name,
_("Specify extension name prefix to update"))
->type_name("NAME")
->check(validatorString);
cliImportCdi
->add_option("--config",
extensionOptions.configPath,
_("Specify config path (default: ~/.config/linglong/config.json)"))
->type_name("FILE");
cliImportCdi
->add_option("--cdi",
extensionOptions.cdiPath,
_("Specify CDI JSON path (default: nvidia-ctk cdi generate --format json)"))
->type_name("FILE");
cliImportCdi
->add_flag("--apply-when-installed",
extensionOptions.applyWhenInstalled,
_("Apply overrides even when extension is installed"));
}

} // namespace

using namespace linglong::utils::global;
Expand Down Expand Up @@ -690,12 +728,14 @@ You can report bugs to the linyaps team under this project: https://github.com/O
ContentOptions contentOptions{};
RepoOptions repoOptions{};
InspectOptions inspectOptions{};
ExtensionOptions extensionOptions{};

// groups for subcommands
auto *CliBuildInGroup = _("Managing installed applications and runtimes");
auto *CliAppManagingGroup = _("Managing running applications");
auto *CliSearchGroup = _("Finding applications and runtimes");
auto *CliRepoGroup = _("Managing remote repositories");
auto *CliExtensionGroup = _("Managing extensions");

// add all subcommands using the new functions
addRunCommand(commandParser, runOptions, CliAppManagingGroup);
Expand All @@ -712,6 +752,7 @@ You can report bugs to the linyaps team under this project: https://github.com/O
addContentCommand(commandParser, contentOptions, CliBuildInGroup);
addPruneCommand(commandParser, CliAppManagingGroup);
addInspectCommand(commandParser, inspectOptions, CliHiddenGroup);
addExtensionCommand(commandParser, extensionOptions, CliExtensionGroup);

auto res = transformOldExec(argc, argv);
CLI11_PARSE(commandParser, std::move(res));
Expand Down Expand Up @@ -920,6 +961,8 @@ You can report bugs to the linyaps team under this project: https://github.com/O
result = cli->inspect(*ret, inspectOptions);
} else if (name == "repo") {
result = cli->repo(*ret, repoOptions);
} else if (name == "extension") {
result = cli->extension(*ret, extensionOptions);
} else {
// if subcommand name is not found, print help
std::cout << commandParser.help("", CLI::AppFormatMode::All);
Expand Down
2 changes: 1 addition & 1 deletion docs/pages/en/guide/reference/driver.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@ The base that applications depend on already includes the appropriate version of

Drivers not included in the base that require additional installation:

- NVIDIA proprietary drivers: Install via `sudo ll-cli install org.deepin.driver.display.nvidia.570-124-04`. The `570-124-04` is the driver version number, which must match the driver version installed on the host system. Check the host driver version through the `/sys/module/nvidia/version` file.
- NVIDIA proprietary drivers: Install via `sudo ll-cli install org.deepin.driver.display.nvidia.570-124-04`. The `570-124-04` is the driver version number, which must match the driver version installed on the host system. Check the host driver version through the `/sys/module/nvidia/version` file. If the extension is not installed, linyaps will attempt to link NVIDIA driver files from the host at runtime.
- Glenfly graphics drivers: Install via `sudo ll-cli install com.glenfly.driver.display.arise`.
- Intel video codec drivers (VAAPI): Install via `sudo ll-cli install org.deepin.driver.media.intel`, which includes support for both new and legacy Intel graphics cards.
2 changes: 1 addition & 1 deletion docs/pages/guide/reference/driver.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@

不在 base 中携带的,需要额外安装的驱动:

- 英伟达闭源驱动,通过 `sudo ll-cli install org.deepin.driver.display.nvidia.570-124-04` 安装。其中 `570-124-04` 是驱动版本号,需要与宿主机安装的驱动版本匹配,通过宿主机 `/sys/module/nvidia/version` 文件查看宿主机驱动的版本。
- 英伟达闭源驱动,推荐通过 `sudo ll-cli install org.deepin.driver.display.nvidia.570-124-04` 安装。其中 `570-124-04` 是驱动版本号,需要与宿主机安装的驱动版本匹配,通过宿主机 `/sys/module/nvidia/version` 文件查看宿主机驱动的版本。未安装扩展时,linyaps 会在运行时尝试从宿主机自动链接 NVIDIA 驱动文件
- 格兰菲显卡驱动,通过 `sudo ll-cli install com.glenfly.driver.display.arise` 安装。
- 英特尔视频编解码驱动(VAAPI),通过 `sudo ll-cli install org.deepin.driver.media.intel` 安装,包含了新/旧 Intel 显卡的支持。
5 changes: 5 additions & 0 deletions libs/linglong/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,16 @@ pfl_add_library(
src/linglong/cli/dbus_notifier.h
src/linglong/cli/dummy_notifier.cpp
src/linglong/cli/dummy_notifier.h
src/linglong/cli/extension_override.cpp
src/linglong/cli/extension_override.h
src/linglong/cli/interactive_notifier.h
src/linglong/cli/json_printer.cpp
src/linglong/cli/json_printer.h
src/linglong/cli/printer.h
src/linglong/cli/terminal_notifier.cpp
src/linglong/cli/terminal_notifier.h
src/linglong/extension/cdi.cpp
src/linglong/extension/cdi.h
src/linglong/extension/extension.cpp
src/linglong/extension/extension.h
src/linglong/package/architecture.cpp
Expand Down Expand Up @@ -94,6 +98,7 @@ pfl_add_library(
src/linglong/runtime/container_builder.h
src/linglong/runtime/container.cpp
src/linglong/runtime/container.h
src/linglong/runtime/host_nvidia_fallback.cpp
src/linglong/runtime/run_context.cpp
src/linglong/runtime/run_context.h
src/linglong/runtime/security_context.cpp
Expand Down
99 changes: 98 additions & 1 deletion libs/linglong/src/linglong/cli/cli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,13 @@
#include "linglong/api/types/v1/PackageManager1SearchResult.hpp"
#include "linglong/api/types/v1/PackageManager1UninstallParameters.hpp"
#include "linglong/api/types/v1/RepositoryCacheLayersItem.hpp"
#include "linglong/api/types/v1/State.hpp"

Check warning on line 25 in libs/linglong/src/linglong/cli/cli.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: "linglong/api/types/v1/State.hpp" not found.
#include "linglong/api/types/v1/UpgradeListResult.hpp"

Check warning on line 26 in libs/linglong/src/linglong/cli/cli.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: "linglong/api/types/v1/UpgradeListResult.hpp" not found.
#include "linglong/cli/printer.h"

Check warning on line 27 in libs/linglong/src/linglong/cli/cli.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: "linglong/cli/printer.h" not found.
#include "linglong/cli/extension_override.h"

Check warning on line 28 in libs/linglong/src/linglong/cli/cli.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: "linglong/cli/extension_override.h" not found.
#include "linglong/common/dir.h"

Check warning on line 29 in libs/linglong/src/linglong/cli/cli.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: "linglong/common/dir.h" not found.
#include "linglong/common/strings.h"

Check warning on line 30 in libs/linglong/src/linglong/cli/cli.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: "linglong/common/strings.h" not found.
#include "linglong/oci-cfg-generators/container_cfg_builder.h"

Check warning on line 31 in libs/linglong/src/linglong/cli/cli.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: "linglong/oci-cfg-generators/container_cfg_builder.h" not found.
#include "linglong/package/layer_file.h"
#include "linglong/package/reference.h"
#include "linglong/repo/config.h"
Expand Down Expand Up @@ -55,10 +56,12 @@
#include <algorithm>
#include <cassert>
#include <charconv>
#include <cstdint>

Check warning on line 59 in libs/linglong/src/linglong/cli/cli.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <cstdint> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <cstdlib>

Check warning on line 60 in libs/linglong/src/linglong/cli/cli.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <cstdlib> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <filesystem>

Check warning on line 61 in libs/linglong/src/linglong/cli/cli.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <filesystem> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <fstream>
#include <iostream>
#include <map>
#include <optional>
#include <system_error>
#include <thread>
Expand All @@ -67,6 +70,7 @@

#include <fcntl.h>
#include <sys/mman.h>
#include <sys/resource.h>
#include <unistd.h>

using namespace linglong::utils::error;
Expand Down Expand Up @@ -519,10 +523,21 @@
linglong::runtime::ResolveOptions opts;
opts.baseRef = options.base;
opts.runtimeRef = options.runtime;
// 处理多个扩展
if (!options.extensions.empty()) {
opts.extensionRefs = options.extensions;
}
auto configPath = extension_override::getUserConfigPath();
if (configPath) {
auto overrides = extension_override::loadOverrides(*configPath);
if (overrides) {
if (!overrides->empty()) {
runContext.setExtensionOverrides(std::move(*overrides));
}
} else {
qWarning() << "failed to load extension overrides:"
<< overrides.error().message().c_str();
}
}

// 调整日志输出,打印扩展列表(用逗号拼接)
std::string extStr =
Expand Down Expand Up @@ -2137,6 +2152,22 @@
{
LINGLONG_TRACE("generate ld cache");

{
struct rlimit limit {};
if (::getrlimit(RLIMIT_NOFILE, &limit) == 0) {
rlim_t target = limit.rlim_max;
if (target == RLIM_INFINITY) {
target = 65535;
}
if (limit.rlim_cur < target) {
struct rlimit newLimit { target, limit.rlim_max };
if (::setrlimit(RLIMIT_NOFILE, &newLimit) != 0) {
qWarning() << "failed to raise RLIMIT_NOFILE:" << ::strerror(errno);
}
}
}
}

auto appLayerItem = runContext.getCachedAppItem();
if (!appLayerItem) {
return LINGLONG_ERR(appLayerItem);
Expand Down Expand Up @@ -2211,6 +2242,28 @@
process.args =
std::vector<std::string>{ "/sbin/ldconfig", "-X", "-C", "/run/linglong/cache/ld.so.cache" };

{
// Ensure ldconfig inside the container has a sufficiently large FD limit.
// Raising RLIMIT_NOFILE only on the host process may not reliably propagate
// into the OCI process, depending on the runtime's defaults.
rlim_t target = 65535;
struct rlimit limit {};
if (::getrlimit(RLIMIT_NOFILE, &limit) == 0) {
if (limit.rlim_max != RLIM_INFINITY) {
target = limit.rlim_max;
}
}
if (target == RLIM_INFINITY) {
target = 65535;
}
int64_t nofile = static_cast<int64_t>(target);
process.rlimits = std::vector<ocppi::runtime::config::types::Rlimit>{
ocppi::runtime::config::types::Rlimit{ .hard = nofile,
.soft = nofile,
.type = "RLIMIT_NOFILE" },
};
}

ocppi::runtime::RunOption opt{};
auto result = (*container)->run(process, opt);
if (!result) {
Expand Down Expand Up @@ -2327,6 +2380,21 @@
return 0;
}

int Cli::extension(CLI::App *app, const ExtensionOptions &options)
{
LINGLONG_TRACE("command extension");

auto argsParseFunc = [&app](const std::string &name) -> bool {
return app->get_subcommand(name)->parsed();
};

if (argsParseFunc("import-cdi")) {
return importCdi(options);
}

return 0;
}

int Cli::getLayerDir(const InspectOptions &options)
{
LINGLONG_TRACE("Get Layer dir");
Expand Down Expand Up @@ -2388,6 +2456,35 @@
return 0;
}

int Cli::importCdi(const ExtensionOptions &options)
{
LINGLONG_TRACE("import CDI config");

std::filesystem::path configPath;
if (options.configPath) {
configPath = *options.configPath;
} else {
auto userConfigPath = extension_override::getUserConfigPath();
if (!userConfigPath) {
this->printer.printErr(LINGLONG_ERRV("failed to resolve user config path"));
return -1;
}
configPath = *userConfigPath;
}

auto res = extension_override::importCdiOverrides(configPath,
options.cdiPath,
options.name,
!options.applyWhenInstalled);
if (!res) {
this->printer.printErr(res.error());
return -1;
}

this->printer.printMessage("CDI config imported into " + configPath.string());
return 0;
}

utils::error::Result<void> Cli::initInteraction()
{
LINGLONG_TRACE("initInteraction");
Expand Down
10 changes: 10 additions & 0 deletions libs/linglong/src/linglong/cli/cli.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,14 @@ struct InspectOptions
std::string dirType{ "layer" };
};

struct ExtensionOptions
{
std::optional<std::string> configPath;
std::optional<std::string> cdiPath;
std::string name{ "org.deepin.driver.display.nvidia" };
bool applyWhenInstalled{ false };
};

enum class TaskType : int {
None,
Install,
Expand Down Expand Up @@ -186,6 +194,7 @@ class Cli : public QObject
int content(const ContentOptions &options);
int prune();
int inspect(CLI::App *subcommand, const InspectOptions &options);
int extension(CLI::App *subcommand, const ExtensionOptions &options);

void cancelCurrentTask();

Expand Down Expand Up @@ -225,6 +234,7 @@ class Cli : public QObject
std::vector<std::string> getRunningAppContainers(const std::string &appid);
int getLayerDir(const InspectOptions &options);
int getBundleDir(const InspectOptions &options);
int importCdi(const ExtensionOptions &options);
utils::error::Result<void> initInteraction();
void detectDrivers();

Expand Down
Loading
Loading