From 623ace0bb095919261a1c5466fe8c506ea1b65f7 Mon Sep 17 00:00:00 2001 From: mahaoliang Date: Thu, 28 Aug 2025 18:30:55 +0800 Subject: [PATCH] docs(README): update core concepts and add SDF generation workflow - Update core concepts section to explain Slice Definition File (SDF) in detail - Add new section on automated SDF generation using the `gen` command - Include workflow diagrams for SDF generation in both Chinese and English --- README.en.md | 64 ++++++++++++++++--- README.md | 59 +++++++++++++++-- docs/pictures/sdf-generation-workflow-cn.png | Bin 0 -> 27538 bytes docs/pictures/sdf-generation-workflow-en.png | Bin 0 -> 29020 bytes 4 files changed, 110 insertions(+), 13 deletions(-) create mode 100644 docs/pictures/sdf-generation-workflow-cn.png create mode 100644 docs/pictures/sdf-generation-workflow-en.png diff --git a/README.en.md b/README.en.md index 6449f4e..31501c7 100644 --- a/README.en.md +++ b/README.en.md @@ -53,14 +53,15 @@ The `bin/splitter-docker.sh` script will automatically pull and use the official SPLITTER_VERSION=1.0.3 ./bin/splitter-docker.sh cut -r 24.03-LTS -a x86_64 -o ./output python3_standard ``` -## Usage Instructions +## Core Concepts -### slice releases +The core of the splitter tool is the Slice Definition File (SDF). This section aims to help you understand SDFs and how they are generated. -The generation of openEuler slices depends on the package splitting rules defined in the **Slice Definition File (SDF)**. SDFs are released separately based on the openEuler version to which the slice belongs. All SDFs exist as yaml files in [slice-releases](https://gitee.com/openeuler/slice-releases). The [slice-releases](https://gitee.com/openeuler/slice-releases) repository uses branch names to represent different openEuler versions. +### Slice Definition File (SDF) -Taking the SDF for python3.11 (named `python3.11.yaml`) as an example: +The generation of openEuler slices depends on the package splitting rules defined in the **Slice Definition File (SDF)**. An SDF file, in YAML format, precisely defines how an RPM package is to be broken down into multiple functionally independent and combinable "Slices". +Taking the SDF for python3.11 (named `python3.11.yaml`) as an example: ```yaml package: python3 @@ -121,10 +122,56 @@ slices: common: /usr/share/licenses/python3/LICENSE: ``` - In the SDF above, i.e., the `python3.yaml` file, `slices` indicates that the `python3` package is split into four slices: `python3_core`, `python3_standard`, `python3_utils`, and `python3_copyright`, along with the file contents these slices contain (for details, please see [slice-releases](https://gitee.com/openeuler/slice-releases)). -### Generating slices with splitter +### Current State of SDFs + +Currently, all official SDF files are **manually written** by community experts and are released separately according to their respective openEuler versions. All SDFs exist as YAML files in the [slice-releases](https://gitee.com/openeuler/slice-releases) repository, which uses branch names to represent different openEuler versions. + +As the openEuler ecosystem continues to grow, the number of packages and versions increases, making the manual creation and maintenance of SDFs a growing bottleneck. + +### Automated SDF Generation + +To address the inefficiency of manually writing SDFs, splitter introduces the `gen` command. This command's automated pipeline aims to simulate the analysis process of experts to generate a high-quality SDF draft for any given RPM package. + +![sdf-generation-workflow](./docs/pictures/sdf-generation-workflow-en.png) + +Its automated workflow is divided into the following stages: + +1. **Download**: Fetches the target RPM package. +2. **Extract**: Extracts all files from the package into a temporary directory. +3. **File Classification**: Categorizes each file into its corresponding Slice. +4. **Dependency Analysis**: Identifies the dependencies between various Slices. +5. **Write**: Writes the analysis results into a formatted SDF YAML file. + +The most critical steps in this pipeline are "File Classification" and "Dependency Analysis". + +#### File Classification + +The goal of this step is to accurately determine which Slice each file in the RPM package belongs to. + +* **Classification by Convention**: Based on the practices observed in a large number of manually created SDFs, a rule-based engine was established using file paths (e.g., files starting with `/etc/` are assigned to the `_config` slice, those starting with `/usr/bin/` or `/usr/sbin/` to the `_bins` slice, etc.). +* **Validation by Type**: To avoid misclassifying non-binary files like scripts, the classifier uses the `file` command for validation. Only files confirmed to be in **ELF** format as executables or shared libraries are assigned to the `_bins` and `_libs` slices, respectively. + +#### Slice Dependency Analysis + +The goal of this step is to automatically trace the dependency chain of binary files to determine the dependencies between Slices. + +This process uses a three-step "**Parse -> Locate -> Trace**" strategy: + +1. **Parse Needs**: Using `readelf -d`, it statically analyzes each ELF file to safely extract the list of shared libraries it **NEEDS** at runtime (e.g., `libc.so.6`). +2. **Locate Library Path**: Leveraging the system's cache maintained by `ldconfig -p`, it quickly maps a library name to its absolute path on the filesystem. +3. **Trace Ownership**: With the library's path, it uses the `rpm -qf ` command to trace back and identify the source RPM package that owns the file (e.g., `glibc`). + +**The final dependency chain is formed as follows:** + +`brotli_libs` -> needs `libc.so.6` -> located at `/usr/lib64/libc.so.6` -> traced to `glibc` package -> **therefore depends on `glibc_libs`**. + +## Usage Instructions + +`splitter` provides two core commands: `cut` for splitting packages based on SDFs, and `gen` for automatically generating SDF files. This section explains how to use these commands. + +### Generating Slices (`cut` command) splitter uses the `cut` command line to split packages and generate the required slices (you can set the `SPLITTER_SLICE_REPO` environment variable to a custom slice-releases source). Using a locally installed splitter: @@ -136,13 +183,14 @@ splitter cut -r 24.03-LTS -a x86_64 -o /path/to/output python3_standard python3_ Or, using the official container image to run: ```bash # Example -./bin/splitter-docker.sh cut -r 24.03-LTS -a x86_64 -o /path/to/output python3_standard python3_utils``` +./bin/splitter-docker.sh cut -r 24.03-LTS -a x86_64 -o /path/to/output python3_standard python3_utils +``` In the command above, `-r/--release` specifies the openEuler version to which the required slices belong, `-a/--arch` specifies the OS architecture, `-o/--output` specifies the output path for the generated slices, and `python3_standard python3_utils` are the slices specified by the user to be generated. All the finally generated slices are packaged and saved in the `/path/to/output` directory. -### Automatically generate SDF files +### Automatically Generating SDFs (`gen` command) splitter has added a `gen` command, which can automatically generate an initial SDF file based on the contents of an RPM package, making it convenient for developers to quickly create and maintain SDFs. diff --git a/README.md b/README.md index 0215ef8..6c6246f 100644 --- a/README.md +++ b/README.md @@ -54,11 +54,13 @@ splitter 提供了官方应用容器镜像,你可以通过 [bin/splitter-docke SPLITTER_VERSION=1.0.3 ./bin/splitter-docker.sh cut -r 24.03-LTS -a x86_64 -o ./output python3_standard ``` -## 使用说明 +## 核心概念 + +splitter 工具的核心在于 Slice Definition File (SDF),本章节旨在帮助你理解 SDF 及其生成方式。 -### slice releases +### Slice Definition File (SDF) -openEuler的slice生成依赖于**Slice Definition File(SDF)**定义的软件包切分规则,SDF按照以slice所属的openEuler版本为依据分别发布,所有SDFs以yaml文件存在于[slice-releases](https://gitee.com/openeuler/slice-releases)。[slice-releases](https://gitee.com/openeuler/slice-releases)仓库使用分支名来表示不同的openEuler版本。 +openEuler 的 slice 生成依赖于 **Slice Definition File(SDF)** 定义的软件包切分规则。SDF 文件以 YAML 格式定义了一个RPM包如何被精确地拆解成多个功能独立的、可按需组合的 “Slice”。 以python3.11的SDF(命名为:python3.11.yaml)为例: @@ -125,7 +127,54 @@ slices: ``` 上述SDF,即python3.yaml文件中,`slices`指示python3的软件包被切分为:`python3_core`、`python3_standard`、`python3_utils`和`python3_copyright`四个slices,以及这些slice所包含的文件内容(详细信息请查看[slice-releases](https://gitee.com/openeuler/slice-releases))。 -### splitter生成slice +### SDF 的现状 + +目前,所有官方的SDF文件都由社区专家**手工编写**,并按照以slice所属的openEuler版本为依据分别发布,所有SDFs以yaml文件存在于[slice-releases](https://gitee.com/openeuler/slice-releases)。[slice-releases](https://gitee.com/openeuler/slice-releases)仓库使用分支名来表示不同的openEuler版本。 + +随着openEuler生态的不断发展,软件包数量和版本持续增多,手工编写和维护SDF逐渐成为一个效率瓶颈。 + +### SDF 的自动化生成 + +为了解决手工编写SDF的效率问题,splitter引入了gen命令。该命令的自动化流水线,旨在模拟专家的分析过程,为任意RPM包生成一个高质量的SDF草稿。 + +![sdf-generation-workflow](./docs/pictures/sdf-generation-workflow-cn.png) + +其自动化流程分为以下几个阶段: + +1. **下载**: 获取目标RPM包。 +2. **解压**: 将包内所有文件提取至临时目录。 +3. **文件分类**: 将每个文件归类到对应的Slice中。 +4. **依赖分析**: 找出各个Slice之间的依赖关系。 +5. **写入**: 将分析结果写入格式化的SDF YAML文件。 + +其中,最核心的步骤是“文件分类”和“依赖分析”。 + +#### 文件分类 + +此步骤的目标是精确判断每个文件应归属哪个Slice。 + +* **基于约定分类**: 依据大量手工SDF的实践,建立了一套基于文件路径的规则引擎(如以`/etc/`开头的文件归入`_config` slice,以`/usr/bin/`或`/usr/sbin/`开头的文件归入`_bins` slice等)。 +* **基于类型校验**: 为避免将脚本等非二进制文件错误归类,分类器会调用 `file` 命令进行校验。只有确认为 **ELF** 格式的可执行文件或共享库,才会被分别归入 `_bins` 和 `_libs` slice。 + +#### Slice 依赖分析 + +此步骤的目标是自动追溯二进制文件的依赖链,以确定Slice间的依赖关系。 + +该过程采用“**解析 -> 定位 -> 溯源**”的三步策略: + +1. **解析需求**: 使用 `readelf -d` 静态分析每个ELF文件,安全地提取其运行时**需要 (NEEDED)** 的共享库列表(如 `libc.so.6`)。 +2. **定位库路径**: 借助 `ldconfig -p` 的系统缓存,将库名快速映射到其在文件系统上的绝对路径。 +3. **追溯归属**: 通过 `rpm -qf <路径>` 命令,根据库文件的路径反查出它所属的源RPM包(如 `glibc`)。 + +**最终形成的依赖链如下:** + +`brotli_libs` -> 需要 `libc.so.6` -> 定位到 `/usr/lib64/libc.so.6` -> 溯源到 `glibc` 包 -> **因此依赖 `glibc_libs`**。 + +## 使用说明 + +`splitter` 提供了两个核心命令:`cut` 用于根据SDF切分软件包,`gen` 用于自动生成SDF文件。本章节介绍这两个命令的具体使用方法。 + +### 生成 Slices (`cut` 命令) splitter使用cut命令行对软件包切分生成所需的slices(可设置SPLITTER_SLICE_REPO环境变量到自定义slice-releases源) 使用本地安装的splitter: @@ -144,7 +193,7 @@ splitter cut -r 24.03-LTS -a x86_64 -o /path/to/output python3_standard python3_ 最终生成的所有slices打包保存在`/path/to/output`目录中。 -### 自动生成SDF文件 +### 自动生成 SDF (gen 命令) splitter 新增了 `gen` 命令,可以根据RPM包的内容自动生成初始的SDF文件,方便开发者快速创建和维护SDF。 diff --git a/docs/pictures/sdf-generation-workflow-cn.png b/docs/pictures/sdf-generation-workflow-cn.png new file mode 100644 index 0000000000000000000000000000000000000000..4269e084300de92f2dc189f41439d31c224c3c4b GIT binary patch literal 27538 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 literal 0 HcmV?d00001 diff --git a/docs/pictures/sdf-generation-workflow-en.png b/docs/pictures/sdf-generation-workflow-en.png new file mode 100644 index 0000000000000000000000000000000000000000..af35ec79216991f8fcca68f7ea54144fd1569b5c GIT binary patch literal 29020 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 GdG|l^JzsVJ literal 0 HcmV?d00001 -- Gitee