容器
在应用程序管理器上下文中,一个容器描述了一个可执行程序的执行环境:在多进程模式下可以是应用程序的二进制文件或其运行时二进制文件。容器不必像 Docker 容器那样复杂,可以简单到像 Unix 进程。
预定义容器
使用 bubblewrap 工具在内核命名空间中启动一个进程。 | |
启动一个新的 Unix 进程来执行所需的二进制文件。 |
配置
容器配置有三个部分
加载容器插件
为了在应用程序管理器中使用现有的容器插件进行配置,您需要将其完整路径添加到应用程序管理器配置文件中要加载的插件列表中
plugins: container: [ "/full/path/to/softwarecontainers.so", "/another/plugin.so" ]
安装到 Qt 插件目录中的 appman_container
文件夹中的插件将自动拾取,但您仍然需要通过在主 containers
:配置字段中为容器的 ID 创建条目来启用容器使用。
containers: bubblewrap: ...
容器选择配置
当您从应用程序管理器启动应用程序时,有多种方式可以控制使用哪种容器集成
- 如果配置文件不包含
containers/selection
键,容器集成 ID 默认为process
。 - 如果存在
containers/selection
键,则将其内容解析为包含多个映射的列表,每个映射只映射一个。虽然这个单个映射有些笨拙,但它是必要的,以保留映射的顺序。每个键被解释为与应用程序 ID 匹配的标准 Unix 通配符表达式。第一个匹配项将停止算法,并使用该映射的值作为容器集成 ID。如果没有找到匹配项,则生成的容器集成 ID 为空字符串。containers: selection: - com.pelagicore.*: "process" - com.navigation: "special-container" - '*': "softwarecontainers" # a single asterisk needs to be quoted
- 之后,如果系统 UI 将 ApplicationManager::containerSelectionFunction 属性设置为有效的 JavaScript 函数,则将调用此函数,第一个参数设置为应用程序的 ID,第二个参数设置为步骤 1 和 2 的结果所示的容器集成 ID。
ApplicationManager.containerSelectionFunction = function(appId, containerId) { var app = ApplicationManager.application(appId) if (app.capabilities.indexOf("non-secure") != -1) return "process" else return containerId }
通过容器插件扩展
通过插件可以添加自定义容器解决方案。这些插件不需要作为应用管理器的一部分构建,但它们需要针对私有Qt模块构建以获取接口定义。
软件容器插件示例可以用作蓝图,要么创建一个具有自定义特定生产版本的软件容器插件,要么集成另一容器解决方案。
以下简要介绍构建您自己插件所需的步骤。首先,您需要配置您的构建系统。
以下是如何使用CMake进行这一操作的示例片段。
... find_package(Qt6 COMPONENTS AppManPluginInterfacesPrivate) qt_add_plugin(mycontainer-plugin) target_link_libraries(mycontainer-plugin PUBLIC Qt::AppManPluginInterfacesPrivate) ...
以下是如何使用qmake进行这一操作的示例。
... TEMPLATE = lib CONFIG += plugin TARGET = mycontainer-plugin QT += appman_plugininterfaces-private ...
然后,您只需要实现两个类,它们分别从ContainerInterface和ContainerManagerInterface派生而来。
#include <QtAppManPluginInterfaces/containerinterface.h> class SoftwareContainer : public ContainerInterface { // ... }; class SoftwareContainerManager : public QObject, public ContainerManagerInterface { Q_OBJECT Q_PLUGIN_METADATA(IID AM_ContainerManagerInterface_iid) Q_INTERFACES(ContainerManagerInterface) // .... };
请注意,您的容器插件必须支持一些基本要求,以便在多进程模式下支持UI客户端。
- 插件必须能够将Unix本地套接字转发到容器中。这对于Wayland套接字以及私有点对点D-Bus连接都是必需的。如果插件无法将这些套接字映射到容器内的正确位置,那么插件将需要修改相应位置的环境变量,然后再将它们传递到容器中。下表列出了相关环境变量。
- 为了支持硬件OpenGL加速,容器需要访问必要的设备。对于遵循Linux标准的GPU(如Intel),请确保容器内可访问
/dev/dri/*
。 - 您必须在插件中实现PID映射;除非您的容器解决方案与其余系统共享PID命名空间。如果您想利用应用管理器的安全功能,这是必要的。通过ContainerInterface::processId(),应用管理器将查询通过Wayland或D-Bus Unix本地套接字进入应用管理器的每个连接的应用程序的PID。应用管理器通过所有运行中的应用程序的PID核对这些PID。不匹配PID的连接将不被接受。然而,您可以通过
--no-security
命令行选项禁用此行为。
应用管理器使用以下环境变量将各种设置传递给应用程序。自定义容器插件必须转发这些变量或相应地进行调整。
名称 | 描述 |
---|---|
WAYLAND_DISPLAY | Wayland服务器套接字路径。如果您的容器使用自己的文件系统命名空间,请确保相应地转发此套接字。 |
QT_QPA_PLATFORM | 始终设置为wayland 。 |
QT_IM_MODULE | 未设置,且由应用管理器显式未设置。确保保持未设置,以便使用自动的Wayland输入法实现。 |
QT_SCALE_FACTOR | 为空(未设置),防止wayland客户端相对于合成器缩放。否则,在4K桌面上缩放运行应用管理器会导致应用管理器内应用程序双重缩放。 |
QT_WAYLAND_SHELL_INTEGRATION | 设置为xdg-shell 。这是首选的wayland shell集成方式。 |
DBUS_SESSION_BUS_ADDRESS | 标准D-Bus会话总线。 |
AM_CONFIG | amConfig映射的YAML,UTF-8编码字符串版本。 |
AM_NO_DLT_LOGGING | 如果设置为1 ,告诉应用不要使用DLT进行日志记录。 |
© 2024 Qt公司有限公司。本文档中包含的文档贡献的版权属于其各自的所有者。本提供在此的文档是根据自由软件基金会发布的GNU自由文档许可协议第1.3版许可的。GNU自由文档许可协议第1.3版。Qt及其相关徽标是Qt公司在芬兰和/或其他全球国家的商标。所有其他商标均为其各自所有者的财产。