本文内容转自社区用户 System233 的项目 linglong-killer-self-service ,原文链接>>>

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

前言

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

引言

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

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

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

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

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

目录

一、ll-builder 的缺点和弊端
1.存储浪费严重
2.磁盘损耗大
3.默认执行 strip
4.多任务并行构建问题
5.构建内容频繁清空
6.工具扩展性差
7.构建环境与运行时环境不一致
8.不可配置的压缩算法
二、ll-killer 构建环境及其优势
1.构建环境一致性
2.打包过程高效
3.磁盘空间与缓存管理优化
4.速度与灵活性提升
5.可靠性加强
三、ll-killer layer 子命令使用案例
1.获取ll-killer
2.打包文件夹为 layer
3.高效构建玲珑项目并生成layer
4.挂载和卸载 layer
5.输出 layer 信息
四、总结


一、ll-builder 的缺点和弊端

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

1. 存储浪费严重

每个使用 ll-builder 构建的应用都会在 ~/.cache/linglong-builder 和 linglong/output 下产生两份副本。即使经过优化消除重复的 develop 文件,但最终仍会有两份重复的 binary 副本。早期甚至可能产生多达四份副本,虽然 ostree 仓库可以对部分重复文件做硬链接处理,但依然难以避免在 linglong/output 下存在两份独立文件。
重复文件存储:

~/.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. 磁盘损耗大

在构建过程中,玲珑工程内的 buildScript 写入 $PREFIX 后,ll-builder 会复制到 linglong/output/binary 和 develop,再复制到 ~/.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无法自行从错误中恢复。

5. 构建内容频繁清空

每次构建均会清空之前的构建内容,使得在同一构建环境中进行多次调整输出变得困难,同时伴随大量文件复制操作。

6. 工具扩展性差

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

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

构建时强制引入开发依赖,致使构建环境与最终运行时环境出现偏差,导致在构建环境中测试正常的应用导出后反而无法运行。

8. 不可配置的压缩算法

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

二、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文件的各种参数,包括压缩算法。

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 带来的优势,请按照以下步骤进行下载安装和配置:

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

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

    wget https://github.com/System233/ll-killer-go/releases/latest/download/ll-killer-amd64 -O ll-killer
    chmod +x ll-killer
    

    以上脚本下载的是 amd64架构,ll-killer-go还支持 arm64和 loong64架构,可以修改链接中的 amd64至其他版本,或进入项目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已全局安装。

2. 打包文件夹为 layer

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

  • 示例

    $ tree -L 1 linglong/output/binary
    linglong/output/binary
    ├── curl.install
    ├── entries
    ├── files
    ├── info.json
    └── linglong.yaml
    
    $ ll-killer layer pack linglong/output/binary
    mkfs.erofs 1.8.2
    Build completed.
    ------
    Filesystem UUID: 2e8c228f-d0d3-4eb4-9bfa-db276c6d9f09
    Filesystem total blocks: 10 (of 4096-byte blocks)
    Filesystem total inodes: 30
    Filesystem total metadata blocks: 4
    Filesystem total deduplicated bytes (of source files): 0
    文件已输出至: curl_8.11.1.0_x86_64_binary.layer
    

3. 高效构建玲珑项目并生成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禁用该行为。
  • 示例

    $ ll-killer layer build
    [准备构建环境]
    Layer元数据:
        名称: curl
        ID: curl
        版本: 8.11.1.0
        模块: binary
        类型: app
        基础: main:org.deepin.base/23.1.0/x86_64
        渠道: main
        命令行: [/opt/apps/curl/files/entrypoint.sh]
        元数据版本: 1.0
        描述: command line tool for transferring data with URL syntax
    curl is a command line tool for transferring data with URL syntax, supporting
    DICT, FILE, FTP, FTPS, GOPHER, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3,
    POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, TELNET and TFTP.
    
    curl supports SSL certificates, HTTP POST, HTTP PUT, FTP uploading, HTTP form
    based upload, proxies, cookies, user+password authentication (Basic, Digest,
    NTLM, Negotiate, kerberos...), file transfer resume, proxy tunneling and a
    busload of other useful tricks.
        架构: x86_64
    [运行构建脚本]
    'test-rel' -> 'test'
    'test-abs' -> '/opt/apps/curl/files/test'
    'file-abs' -> '/opt/apps/curl/files/file'
    'file-rel' -> 'file'
    'noext-abs' -> '/notexist'
    'noext-rel' -> 'notexist'
    'bin-abs' -> '/bin'
    'bin-rel' -> 'bin'
    '/project/applications' -> '/opt/apps/curl/files/share/applications'
    '/project/applications/gimp.desktop' -> '/opt/apps/curl/files/share/applications/gimp.desktop'
    '/project/applications/zutty.desktop' -> '/opt/apps/curl/files/share/applications/zutty.desktop'
    '/project/applications/zutty2.desktop' -> '/opt/apps/curl/files/share/applications/zutty2.desktop'
    '/project/applications/zutty3.desktop' -> '/opt/apps/curl/files/share/applications/zutty3.desktop'
    '/project/applications/zutty4.desktop' -> '/opt/apps/curl/files/share/applications/zutty4.desktop'
    [文件后处理]
    *处理快捷方式和右键菜单
    /opt/apps/curl/files/share/applications/gimp.desktop
    /opt/apps/curl/files/share/applications/zutty.desktop
    /opt/apps/curl/files/share/applications/zutty3.desktop
    /opt/apps/curl/files/share/applications/zutty4.desktop
    /opt/apps/curl/files/share/applications/zutty2.desktop
    [打包输出]
    mkfs.erofs 1.8.2
    Build completed.
    ------
    Filesystem UUID: 7009cb7f-896e-4916-9782-4f17dbfc35a0
    Filesystem total blocks: 6 (of 4096-byte blocks)
    Filesystem total inodes: 25
    Filesystem total metadata blocks: 3
    Filesystem total deduplicated bytes (of source files): 0
    文件已输出至: curl_8.11.1.0_x86_64_binary.layer
    

4. 挂载和卸载 layer

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

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

    示例

    $ ll-killer layer mount curl_8.11.1.0_x86_64_binary.layer curl
    erofsfuse 1.8.2
    <W> 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 <layer文件> -- [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 字节
      魔数: <<< deepin linglong layer archive >>>
      元数据大小: 824 字节
      数据偏移量: 868
      Layer元数据版本:
          版本: 1
      Layer元数据:
          名称: curl
          ID: curl
          版本: 8.11.1.0
          模块: binary
          类型: app
          基础: main:org.deepin.base/23.1.0/x86_64
          渠道: main
          命令行: [/opt/apps/curl/files/entrypoint.sh]
          元数据版本: 1.0
          描述: command line tool for transferring data with URL syntax
      curl is a command line tool for transferring data with URL syntax, supporting
      DICT, FILE, FTP, FTPS, GOPHER, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3,
      POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, TELNET and TFTP.
    
      curl supports SSL certificates, HTTP POST, HTTP PUT, FTP uploading, HTTP form
      based upload, proxies, cookies, user+password authentication (Basic, Digest,
      NTLM, Negotiate, kerberos...), file transfer resume, proxy tunneling and a
      busload of other useful tricks.
          大小: 32063 字节
          架构: x86_64
      Erofs信息:
      Filesystem magic number:                      0xE0F5E1E2
      Filesystem blocksize:                         4096
      Filesystem blocks:                            6
      Filesystem inode metadata start block:        0
      Filesystem shared xattr metadata start block: 0
      Filesystem root nid:                          36
      Filesystem lz4_max_distance:                  65535
      Filesystem sb_size:                           128
      Filesystem inode count:                       25
      Filesystem created:                           Tue Mar 11 17:36:11 2025
      Filesystem features:                          sb_csum mtime 0padding 
      Filesystem UUID:                              cb6e643e-a762-4310-8d50-61d271f1a51d
    

四、总结

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

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

对玲珑ll-builder的建议

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


评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注