克亮
4 hours ago Moderator
不说内容如何,光看流程图,就很上档次
Reply Like 0 View the author
不说内容如何,光看流程图,就很上档次
AI写的东西AI看,有同样需求的朋友,直接把本文丢给AI(下面的txt),应该大概就能复现了。不过deepin社区页面没有一键复制markdown的功能,AI不友好型社区。
玲珑容器调用宿主机shell的方法.txt
我好像有这么一个需求,我的QGIS的deb版有个方便的功能,就是在程序内的文件浏览器中调用终端,然后利用终端来执行一些地理处理命令,但是玲珑版和flatpak版都无法实现这个功能。琢磨一下你的大作,看能不能解决。
Popular Events
More
玲珑容器内调用宿主机 Shell:基于 D-Bus 的透明代理方案
目前玲珑容器内是没有调用宿主机 Shell 的官方方法的,但是开发基于tauri的玲珑商店社区版2.0的时候,由于tauri2.0对glibc要求比较高,所以没办法在一些比较老的Linux发行版上运行,于是打算使用玲珑包解决glibc问题,但是又遇到了没办法调用宿主机的
ll-cli的问题,所以研究出来了本方案。因为tauri仍然有一些webview兼容性问题,甚至不同发行版里面的样式都有细微的差别或者是bug,所以换flutter方案了,于是就有了玲珑商店社区版3.0(bug即将改完的阶段),虽然tauri的商店2.0被放弃了,但是这个方案还是有一些意义的,在官方发布官方方法之前。
但是根据目前玲珑的机制,可以自己实现这个功能——而且不需要修改 linyaps 源码,玲珑安装包直接安装好就可以调用。
原理大致是:在容器外启动一个服务(Server),监听容器内(Client)的请求,代理容器在宿主机执行命令,然后把命令的输出返回给容器内的程序。这样容器内就能达到执行 Shell 的目的。
这个事情最关键的问题就是如何把 Server 启动起来——解决了这个问题,其他的问题就迎刃而解了。
众所周知,玲珑的 home 目录容器内外是相通的。既然 home 是通的,那就可以写入用户 systemd 和 D-Bus 配置,然后利用 D-Bus 唤醒机制 唤醒玲珑容器自带的 systemd 服务。
下面以玲珑商店社区版2.0介绍这个 Server 和 Client 的实现。
声明:下面是AI写的,不过所有的内容都由本人审计过。
C/S 架构设计
整个方案采用 C/S 架构,容器内的程序作为 Client,通过 D-Bus 向容器外的 Server 发起命令执行请求。
源码:https://github.com/guanzi008/org.linglong-store.LinyapsManager
整体架构
激活流程
Server 不需要常驻后台。核心机制是 systemd + D-Bus 联动激活:
流式传输协议
D-Bus 方法调用是同步的,长时间运行的命令会阻塞连接。所以采用 operationID + 信号 的异步模式:
Client 身份识别
Client 采用一个二进制、多个符号链接的方案:
用户完全感知不到中间层——输入的是
ll-cli install foo,退出的也是ll-cli的退出码,体验是透明的。如何部署:把 Server 启动起来
这是整个方案最关键的一步。核心思路:利用玲珑容器的 home 目录共享特性,在容器内写入宿主机可识别的 systemd 和 D-Bus 配置。
原理
玲珑容器的 home 目录与宿主机 home 是同一个目录。因此容器内可以写入以下文件到
~/.config下:~/.config/systemd/user/*.service~/.config/dbus-1/services/*.servicesystemd 服务配置为
Type=dbus,当第一次 D-Bus 调用到达时,systemd 自动启动 Server 进程,Server 注册服务名后 systemd 标记服务就绪。后续调用直接复用已有的 Server。部署流程
安全机制:命令白名单
并非任意命令都能被代理执行。Server 内置了一套可插拔的规则系统,每个命令一个规则文件,通过
init()函数自动注册:特别值得注意的是
pkexec规则——它实现了递归验证:当用户调用pkexec ll-cli install foo时,pkexec 规则提取嵌套的ll-cli命令,委托给 ll-cli 规则做二次验证。pkexec rm -rf /被直接拒绝,而pkexec ll-cli install foo则可以通过。快速搭建:构建一个能调用宿主机 Shell 的玲珑包
以 linglong-store-linyaps-build 为例,这个包需要用到
ll-cli命令。第一步:创建玲珑包目录
第二步:编写 linglong.yaml
以
linglong-store-linyaps-build的实际配置为例:关键点:
sources中的name字段是下载后的文件名,build阶段的install命令决定了安装到容器内的最终名字ll-cli,就在build阶段把linyapsctl安装为ll-clill-cli和pkexec)第三步:编写入口脚本
resources/usr/bin/setup-linyaps-dbus.sh负责两件事:部署 Server、启动应用。第四步:构建
第五步:安装运行
添加新命令支持:编写 Rules
LinyapsManager 使用可插拔的规则系统——每个命令一个规则文件,通过
init()自动注册。要添加新命令,需要:org.linglong-store.LinyapsManager项目internal/cmdwhitelist/rules/下新建规则文件Rule 接口
示例 1:最简单的规则 —— killall
文件:
internal/cmdwhitelist/rules/killall.go示例 2:复杂规则 —— ll-cli(子命令白名单 + 全局标志)
文件:
internal/cmdwhitelist/rules/llcli.go示例 3:递归验证 —— pkexec
文件:
internal/cmdwhitelist/rules/pkexec.go添加自定义命令的完整流程
编写规则的要点清单
Name()"ll-cli")Program()NeedsEnv()trueValidate()-u,--user,-9等危险参数init()中调用cmdwhitelist.Register()make编译完整数据流
总结
整个方案不需要修改 linyaps 源码,安装包装好后就能用。核心要点就三个:
AI写代码现在是真的快,有明确业务逻辑的情况下,几天就能搞出来完整功能的雏形。
向本方案提出人致谢:@罐子