[ Technical exchange] 玲珑杀手Go - layer子命令:高效构建玲珑应用,大幅降低磁盘压力
Tofloor
poster avatar
System233
deepin
2025-03-11 22:19
Author

玲珑杀手Go - layer子命令:玲珑应用构建革命中的最后一块拼图

前言

在玲珑杀手Go最近更新的v1.4.x版本中,引入了全新的layer子命令,该命令独立于ll-builder之外实现了对玲珑layer文件的构建、打包、挂载/卸载和解析功能,无需生成~/.cache/linglong-builder构建缓存浪费存储空间,也不会产生大量无用的文件复制,大幅增强了玲珑应用的构建体验。

项目主页: https://github.com/System233/ll-killer-go.git

引言

在玲珑应用的打包过程中,传统的 ll-builder 工具因其重复性数据存储、低效的磁盘操作以及对构建环境的不够灵活支持,存在严重弊端。

相较之下,ll-killer 中的 layer 子命令工具以更高效、更轻量、灵活性更强的方式实现了构建与打包流程,尤其在 layer 文件管理上展现出明显优势。

本文将详细介绍 ll-builder 的不足,并着重阐述 ll-killer layer 子命令的核心优势、下载安装步骤以及常用子命令的实际使用案例。

相关内容:关于使用ll-kiler进行应用打包的详细信息,请查看上一篇文章:

玲珑杀手Go:全新玲珑应用本地构建系统,附Ubuntu源GIMP迁移示例-论坛-深度科技

目录


一、ll-builder 的缺点和弊端

ll-builder 在设计上存在严重缺陷,主要包括:

1. 存储浪费严重

每个使用 ll-builder 构建的应用都会在 ~/.cache/linglong-builderlinglong/output 下产生两份副本。即使是玲珑在后续更新中优化了重复的 develop 模块文件,最终仍会有两份重复的 binary 副本。早期玲珑甚至可能产生多达四份副本,虽然玲珑引入的 ostree 仓库可以对部分重复文件做硬链接处理,但依然难以避免同时在~/.cache/linglong-builderlinglong/output 下存在两份重复文件。

玲珑builder的文件存储结构

~/.cache/linglong-builder
├── layers
│   ├── {base}
│   └── {app}       # binary+delelop模块 linglong/output的副本
├── merged
│   └── {app+base}  # 通过ostree硬链接叠加实现的副本
├── repo            # ostree仓库
└── states.json

.                   # 玲珑工程目录
├── linglong
│   ├── entry.sh
│   └── output
│       ├── _build
│       ├── binary  # binary模块 _build的副本
│       └── delelop # delelop模块 _build的副本
├── linglong.yaml

2. 磁盘损耗大

在构建过程中,玲珑工程内的 build构建脚本 会将应用文件写入 $PREFIX,之后 ll-builder 会将其复制到 linglong/output/binarydevelop,再复制到 ~/.cache/linglong-builder。打包过程中,由于 mkfs.erofs 不能很好的支持预留文件头空间,还需再复制一遍临时文件以添加文件头,整个流程至少涉及 5 次文件复制,导致读写放大严重,增加了磁盘负担。

数据复制过程:

  1. build构建脚本->$PREFIX(linglong/output/_build)
  2. linglong/output/{binary,develop}
  3. ~/.cache/linglong-builder/{repo,binary,develop}
  4. tmp.erofs
  5. app.layer
  • 在旧版玲珑(约<=1.6.3)中,步骤2和3的读写量继续翻倍。

3. 默认执行 strip

默认启用 strip-symbols 对二进制文件进行符号剔除,这一行为可能对应用产生不可预知的影响,破坏用户对文件的预期。

4. 多任务并行构建问题

由于 ~/.cache/linglong-builder 中引入了 ostree,仅允许单个任务写入;此外,在新版本(v1.7.x)中,多任务构建可能导致自动重命名缓存目录,进而造成缓存损坏,ll-builder无法自行从错误中恢复。

只要同时跑两个ll-builder就有几率导致cache被重命名而重新构建cache。

5. 构建内容频繁清空

每次构建均会清空之前的构建内容,使得在同一构建环境中进行多次调整输出变得困难,同时伴随大量文件复制操作,让构建过程中本就不堪重负的磁盘雪上加霜。

6. 工具扩展性差

ll-builder 只支持内置的工具链,无法动态安装新工具,需要特制的 runtime,而且baseruntime相关的文档说明不足,导致构建难度大。

7. 构建环境与运行时环境不一致

构建时强制引入开发依赖,且开发依赖会在运行时消失,导致在构建环境中不能可靠地进行依赖检查,在构建环境中测试正常的应用可能在构建后无法运行。

8. 不可配置的压缩算法

玲珑在1.7.7版本中给layer引入了高版本erofs才支持的zstd压缩算法,旧版玲珑无法安装,也无法检测是什么问题并告知用户解决方案,且用户无法手动配置压缩算法,这彻底破坏了layer文件的兼容性。

二、ll-killer 构建环境及其优势

针对 ll-builder 的种种弊端,ll-killer 提出了全新的构建与打包解决方案,其核心思路在于将构建环境与运行时环境完全一致,并消除不必要的文件复制与缓存浪费。主要特点包括:

1. 构建环境一致性

  • 在项目的 linglong/filesystem 内维护应用文件,ll-builder 仅作为 base 下载器。
  • 使用 ll-killer build 命令可反复进入构建环境,且退出后不会重置构建内容。
  • 构建环境仅使用 base 中的 binary 模块,完全避免了开发依赖问题,保证了构建与运行时环境一致性。

2. 打包过程更高效

  • ll-killer layer build 命令打包时仅需 2~3 次文件复制:首先运行工程内的buildScript脚本将应用文件复制到 $PREFIX,再利用 mkfs.erofs 命令创建 layer 文件并写入文件头。
  • 通过 mmap+memmove 技术,尽管受 mkfs.erofs 部分 bug 影响,仍然显著提升了在文件头部插入操作的性能。
  • 注:目前第3次复制为mkfs.erofs的bug所致,理想情况下为2次。

复制路径:

  1. build构建脚本->$PREFIX(linglong/output/build)
  2. app.layer
  3. app.layer (插入layer文件头)

3. 磁盘空间与缓存管理优化

  • 打包过程中只会生成一份文件副本,杜绝了 ~./cache/linglong-builder 下大量难以清理的缓存数据。
  • 支持多任务构建,无 ostree 参与,避免了多个项目间的缓存冲突。

4. 速度与灵活性提升

  • 相比 ll-builderll-killer 构建速度更快。
  • 可在宿主机上构建与打包,允许使用宿主机上的工具,提升了整体构建效率与灵活性。
  • 可以自由配置layer文件的各种参数,包括压缩算法。
  • 支持指定根文件系统,可以在任何根文件系统或base中构建。

5. 可靠性加强

  • 没有自定义复制行为,不会出现ll-builder的复制错误 (#1039)
  • 不会擅自修改构建结果中的二进制文件内容(no-strip)

三、ll-killer layer 子命令使用案例

ll-killer 提供了多个子命令来管理 layer 文件,下面分别介绍常用命令及其使用场景。

命令概览

$ ll-killer layer --help
独立于玲珑的layer管理器,提供强大的layer文件处理支持,需要安装erofs-utils。

Usage:
  ll-killer layer [command]

Available Commands:
  pack        将文件夹打包为layer。
  build       无需ll-builder, 直接将当前项目构建为layer。
  mount       挂载layer文件。
  umount      卸载layer挂载点。
  dump        输出layer信息。

Flags:
  -h, --help   help for layer

Use "ll-killer layer [command] --help" for more information about a command.
  • 每一个子命令都有详尽的帮助文档,推荐查看。

1. 获取与配置最新 ll-killer

在使用ll-killer工具之前,需要在主机上获取此工具,如果你已经安装最新版本的ll-killer (版本>=1.4.0) 则可以跳过本步骤。

  1. 安装必要依赖
    确保系统中安装了以下依赖:

    # 用于依赖检查和搜索功能
    sudo apt install apt-file
    
  2. 下载最新版本的 ll-killer
    当前最新版本为 v1.4.5,下载命令如下:

    wget https://github.com/System233/ll-killer-go/releases/latest/download/ll-killer-amd64 -O ll-killer
    chmod +x ll-killer
    
    # 镜像地址,如果上面的链接下载不动,可以尝试将链接替换为这个镜像地址。
    # https://ll-killer.win/releases/latest/download/ll-killer-amd64
    

    以上脚本下载的是 amd64架构,ll-killer-go还支持 arm64loong64架构,可以修改链接中的 amd64至其他版本,或进入项目Releases页手动下载。

    03-23日更新 镜像地址:为了解决国内用户的下载问题,维护了一个镜像地址,大家可以将上面命令中的GitHub链接替换为此地址进行下载

    https://ll-killer.win/releases/latest/download/ll-killer-amd64
    同时可以在此地址查看项目的release页,获取更新说明以及每个文件的哈希值等信息:
    https://ll-killer.win/releases

    其他下载方式
    如果上面的链接下不动,可以网上搜索github release 下载加速,然后把链接粘进去加速下载,再把文件放入相应位置。

    ⚠警告:从第三方地址加速下载时,注意文件的安全性。Releases页面提供了各个文件的sha1校验码,在文件下载完成后务必使用 sha1sum校验文件的完整性。

    
    
  3. 全局安装(可选)
    为了方便全局使用,可以将 ll-killer 安装到 ~/.local/bin

    mkdir -p ~/.local/bin
    mv ll-killer ~/.local/bin
    ll-killer -v
    

    如果提示找不到命令或 ~/.local/bin 未添加至 PATH,请执行:

    echo 'export PATH=$HOME/.local/bin:$PATH' >>~/.bashrc
    source ~/.bashrc
    
  • 后续章节假设ll-killer已全局安装,且ll-killer版本>=1.4.x

2. 高效构建玲珑项目并生成layer

  • 功能说明
    ll-killer layer build子命令在宿主机上启动一个模拟ll-builder的构建环境,直接在宿主机上将当前项目构建为 layer,避免不必要的ostree提交和磁盘复制。

    • 本命令用于取代ll-killer项目中的 ll-builder build+ll-builder export --layer命令组合。
    • 如果项目不基于ll-killer,但构建脚本不使用任何base特定功能,也可以使用本命令加速打包。
    • 如果你希望在构建脚本中使用宿主机中的工具,可以使用本命令进行构建。
    • 🚀 你可以在命令参数中指定根文件系统,如指定使用玲珑的base所在的路径作为rootfs,如不指定则使用宿主机的根目录。

    此构建模式提供以下内容,以模拟ll-builder环境:

    环境变量

    LINGLONG_APPID="{APPID}"
    PREFIX="/opt/apps/{APPID}/files"
    TRIPLET="x86_64-linux-gnu|aarch64-linux-gnu|loongarch64-linux-gnu|..." 
    KILLER_PACKER=1 ## killer构建环境标识
    

    目录

    • /project: 项目目录
    • /run/host/rootfs: 与宿主机相同
    • /: 与指定的rootfs相同。

    后处理

    • 为快捷方式和服务单元添加ll-cli run前缀
    • KILLER_PACKER 标识当前处于killer环境,killer环境下setup.sh会自动跳过符号链接修复,
      可以在启动前设置KILLER_PACKER=0禁用该行为。
  • 示例

3. 打包文件夹为 layer

  • 功能说明
    将具有 layer 结构的文件夹(参考 linglong/output/binary 目录)打包为 layer。该命令利用 mkfs.erofs 直接对目录进行打包,省去了传统 ll-builder 中将文件提交到 ostree 的步骤,减少了不必要的文件复制和缓存生成,保护磁盘寿命。

    • 上一节中的 ll-killer layer build 子命令会自动调用本功能,本功能也可以单独使用。
  • 示例

4. 挂载和卸载 layer

  • 挂载 layer
    使用该命令可以将 layer 文件挂载到指定目录,方便查看和调试。

    ll-killer layer mount  <挂载目标目录> -- [erofsfuse 选项]
    

    示例

    $ ll-killer layer mount curl_8.11.1.0_x86_64_binary.layer curl
    erofsfuse 1.8.2
     erofs: curl_8.11.1.0_x86_64_binary.layer mounted on curl with offset 868
    
    $ ls curl -l
    总计 20
    -rw-r--r-- 1 system system 291  3月11日 17:36 curl.install
    drwxr-xr-x 3 system system  44  3月11日 17:36 entries
    drwxr-xr-x 4 system system 236  3月11日 17:36 files
    -rwxr-xr-x 1 system system 801  3月11日 17:36 info.json
    -rwxr-xr-x 1 system system 763  3月11日 17:36 linglong.yaml
    
  • 卸载 layer
    当不再需要访问挂载内容时,可使用以下命令卸载:

    ll-killer layer umount <挂载目录> -- [fusermount 选项]
    

    示例

    $ ll-killer layer umount curl
    $ ls curl -l
    总计 0
    

5. 输出 layer 信息

  • 功能说明
    该命令用于输出 layer 文件的详细信息,帮助用户诊断和验证 layer 内容。

  • 使用方法

    ll-killer layer dump  -- [dump.erofs 选项]
    

    常用参数:

    • -x:显示文件头信息;
    • -l:显示 Layer 信息;
    • -e:显示 Erofs 信息;
    • -a:显示全部信息(默认启用)。

    示例:

    $ ll-killer layer dump curl_8.11.1.0_x86_64_binary.layer 
      Layer文件头:
      文件名: curl_8.11.1.0_x86_64_binary.layer
      文件大小: 25444 字节
      魔数: <<
    

四、总结

ll-killer 通过重构构建环境,打破 ll-builder 在文件复制、缓存管理、多任务构建及环境一致性方面的局限,实现了更高效、节省资源的构建与打包流程。

无论是打包layer的高效处理,还是直接在宿主机构建的便捷操作,都使得 ll-killer 成为当前构建领域的强有力工具。用户可以通过简单的下载安装步骤迅速上手,并利用丰富的子命令灵活应对各种场景,从而大大提高开发与发布效率。

对玲珑ll-builder的建议

ll-killer已经通过实践中证明在构建阶段引入ostree是100%的负优化,强烈建议删除构建的阶段的~/.cache/linglong-builder,仅保留baseruntime下载功能,进一步降低对磁盘的压力和损耗。

Reply Favorite View the author
All Replies
2 / 2
To page
MeGusta
deepin
2025-03-24 20:22
#21

deepin25更新到当前的linglong1.7.10版本,ll-killer就无法正常运行了,报错如下:

ll-killer-output-20250324.zip

我运行的脚本:

build-qgis-stable-with-inkscape-saga-20250322.zip

Reply View the author
System233
deepin
2025-03-29 02:38
#22
MeGusta

deepin25更新到当前的linglong1.7.10版本,ll-killer就无法正常运行了,报错如下:

ll-killer-output-20250324.zip

我运行的脚本:

build-qgis-stable-with-inkscape-saga-20250322.zip

抱歉现在才看到反馈,之前看到玲珑某个版本改了/tmp目录,会对依赖ll-builder的ll-killer build模式产生影响,因为ll-killer依赖/tmp文件系统与ll-builder容器内的ll-killer传输文件,来实现环境的重入。
由于/tmp文件系统的变化,可能不好修复,不过已经有替代方法,就是弃用ll-builder,使用killer完全接管构建环境。

以下是对你的构建流程有用的更新:

  • 1.4.17 实现了完全无需ll-builder情况下的构建支持,基于layer的自定义base功能,可以使用原生ostree管理玲珑的base,使用make中的ENABLE_OSTREE参数启用。
  • v1.4.11 开始,支持应用的自动化测试,运行make test以使用。
  • v1.4.27 开始,make自动删除不属于当前应用的快捷方式,不用再自己手动删除了,【默认启用】,使用make ENABLE_RM_DESKTOP=1启用。
  • v1.4.34 开始,支持无需ll-cli的自动化测试,从构建到测试可以完全不需要安装玲珑,使用make ENABLE_TEST_NOCLI=1选项启用。
  • v1.5.0 开始,优化了ptarce环境的性能,【默认启用】,使用make ENABLE_PTRACE=1启用。

由于需要代替ll-builder管理ostree,于是做了这个功能在makefile里,建议使用make管理项目。
你的构建脚本可以简化为:

# 提前准备sources.list,apt.conf.d/limit.conf等

# 初始化项目文件
ll-killer init

# 可选:创建build.sh并赋予可执行权限,在make执行apt安装步骤【之前】自动调用

# 可选:创建post-build.sh并赋予可执行权限,在make执行apt安装步骤【之后】自动调用
# 如执行“添加程序入口版本号”,“去除QGIS的jpg文件关联”等步骤,注意这个脚本是在容器中运行的,$BUILD_DIR/diff/usr/之类的文件已经叠加到容器根目录。
# 可以运行`make build`进入当前配置(config.mk)下的构建环境,在环境中测试相关的命令,测试完可以在外面$BUILD_DIR/diff/中查看效果。

# 可选:创建deps.list文件,写入依赖包名,空格隔开或一行一个,在apt安装步骤过程中一起安装。
# 如 python3-pip python3-geopandas python3-shapely inkscape fcitx5-frontend-qt5 fcitx-frontend-qt5 saga mdbtools fonts-open-sans


# 自动创建yaml并构建项目,最后输出layer文件
# ENABLE_OSTREE:启用ostree,移除ll-builder依赖。
# ENABLE_TEST_NOCLI:启用ll-cli.sh,使用killer模拟的玲珑环境进行自动化测试,移除ll-cli依赖。
make PKG=qgis ENABLE_OSTREE=1

# 执行自动化测试
make test

关于make的其他更多选项可以运行make help,如需修改参数可以make config 参数=值,或直接编辑config.mk。

关于更新killer时的github网络问题可以用这个地址解决: https://ll-killer.win/releases/latest/download/ll-killer-amd64

Reply View the author
锵锵枪ᯤ
deepin
2025-04-10 18:33
#23
System233

保留沙发
o( ̄︶ ̄)o

大佬

23 25都提示

remount:/proc: operation not permitted

这个咋解决呢

make

[更新APT缓存]
ll-killer apt -- apt update -y 2>&1 | tee apt-update.log~
remount:/proc: operation not permitted
make: *** [Makefile:157:apt-update.log] 错误 1
root@lq-pc:/home/lq2009/ryll/vdi#
root@lq-pc:/home/lq2009/ryll/vdi#

Reply View the author
System233
deepin
2025-04-16 11:05
#24
锵锵枪ᯤ

大佬

23 25都提示

remount:/proc: operation not permitted

这个咋解决呢

make

[更新APT缓存]
ll-killer apt -- apt update -y 2>&1 | tee apt-update.log~
remount:/proc: operation not permitted
make: *** [Makefile:157:apt-update.log] 错误 1
root@lq-pc:/home/lq2009/ryll/vdi#
root@lq-pc:/home/lq2009/ryll/vdi#

看这个提示和克亮的有点不太一样,可以先尝试下关闭磐石,看看是否有效。
由于我这暂时无法复现,还需要更多环境测试。

remount proc的功能主要用于解决玲珑本身没有进程管理的问题,某些应用拉起个后台就退出了,然后容器也跟着退出,导致无法使用。
这个功能本应该在玲珑容器上实现,或者需要ll-box让出PID 1的位置。

Reply View the author
2 / 2
To page