*openUBMC bingo支持模型归档功能 - 详细设计说明书*

<table>
    <tr>
        <td>所属SIG组:</td>
        <td>CICD</td>
    </tr>
    <tr>
        <td>落入版本:</td>
        <td>26.03</td>
    </tr>
    <tr>
        <td>设计人员:</td>
        <td>李睿宸</td>
    </tr>
    <tr>
        <td>日期:</td>
        <td>2026.1.15</td>
    </tr>
</table>

**Copyright © 2025 openUBMC Community**

您对&quot;本文档&quot;的复制，使用，修改及分发受木兰宽松许可证, 第2版协议(以下简称&quot;MulanPSL2&quot;)的约束。
为了方便用户理解，您可以通过访问<https://license.coscl.org.cn/MulanPSL2>了解MulanPSL2的概要 (但不是替代)。
MulanPSL2的完整协议内容您可以访问如下网址获取：<https://license.coscl.org.cn/MulanPSL2>。

**改版记录**

<table>
    <tr>
        <th>日期</th>
        <th>修订版本</th>
        <th>修订描述</th>
        <th>作者</th>
        <th>审核</th>
    </tr>
    <tr>
        <td>2025/01/15</td>
        <td>0.0.1</td>
        <td>初始版本</td>
        <td>李睿宸</td>
        <td></td>
    </tr>
</table>

**List of abbreviations**  **缩略语清单** ：

<table>
    <tr>
        <th>Abbreviations 缩略语</th>
        <th>Full spelling 英文全名</th>
        <th>Chinese explanation 中文解释</th>
    </tr>
    <tr>
        <td>Conan</td>
        <td>Conan Package Manager</td>
        <td>C/C++依赖管理和包分发工具</td>
    </tr>
    <tr>
        <td>BMC</td>
        <td>Baseboard Management Controller</td>
        <td>基板管理控制器</td>
    </tr>
    <tr>
        <td>RootFS</td>
        <td>Root File System</td>
        <td>根文件系统</td>
    </tr>
</table>

[TOC]

# 1.功能分析

## 1.1 功能背景
<!-- 描述该需求的来源或背景，比如：支撑XXX功能、XXX优化等；以及该需求对用户（含组件）带来什么具体价值，如果没有该需求，对用户（含组件）带来什么损失； -->

### 需求来源

在openUBMC项目构建过程中，MDS和MDB模型定义文件分散在各个组件中，缺乏统一的归档和分发机制。这导致：

1. **版本追溯困难**：MDS/MDB文件随组件发布，无法明确追踪整个固件模型的版本演进
2. **复用成本高**：其他项目或工具需要完整的MDS/MDB时，需完整编译整个BMC固件
3. **审计成本高**：无法快速比对不同版本间的元数据差异

### 用户价值

通过将MDS/MDB归档为Conan制品，为openUBMC社区带来以下价值：

1. **独立版本管理**：MDS/MDB可匹配固件版本作为独立制品进行发布和追溯
2. **便捷分发**：用户可通过`conan download`命令快速获取特定板型的元数据
3. **工具链支持**：IDE、调试工具可直接依赖metadata制品提供智能提示
4. **CI/CD集成**：自动化测试和持续集成流程可显式声明元数据版本依赖

### 损失描述

若无此功能，将导致：

- 模型数据变更无法独立审计，需追溯整个固件各组件的版本
- 第三方工具（如CI门禁，BMC Studio）获取元数据需完整构建固件
- 跨版本元数据对比困难

## 1.2 功能描述
<!-- 描述该需求交付的整体功能，主要实现XXX功能，解决XXX问题，明确方案如何实现 -->

### 整体功能

openUBMC-metadata制品功能实现将BMC固件构建过程中收集的MDS/MDB文件打包为Conan制品，提供版本化、可分发的模型归档方案。

### 解决问题
 修改名称？
1. **模型数据归档**：在`work.work.build.conan`之后自动收集MDS/MDB文件
2. **版本标识**：通过metadata.yml记录板型名称、版本号、构建类型等信息
3. **可选上传**：支持本地创建或上传至远程Conan仓库

### 实现方式

- 通过新增`bmcgo.tasks.task_package_metadata.TaskClass`任务类实现
- 任务在`work.task_build_conan`完成后执行
- 动态生成conanfile.py和metadata.yml
- 调用`conan create`命令完成制品创建

## 1.3 功能场景
<!-- 描述该需求的业务使用场景，内容包括：
1) 场景出发条件及对象：什么角色/工具/接口等在什么具体情况下使用该特性，使用对象技能如何？
2) 使用时间及频度
3) 描述该特性主要有哪些场景、子场景及关键任务操作 -->

### 业务场景

| 场景编号 | 场景名称 | 描述 | 使用对象 |
| -------- | -------- | ---- | -------- |
| SC-01 | 固件构建归档 | 构建完成后自动打包元数据 | 构建系统 |
| SC-02 | 元数据版本发布 | 将特定版本元数据发布到Conan仓库 | CMO |
| SC-03 | 工具链依赖获取 | 开发工具获取模型数据用于配置校验 | 开发者 |

### 使用对象

| 对象 | 技能要求 | 使用频度 |
| ---- | -------- | -------- |
| 构建工具 | 熟悉Python、Conan基础 | 每次构建 |
| 版本管理员 | 了解Conan仓库操作 | 版本发布时 |
| 开发者 | 基础命令行操作与工具使用 | 开发调试时 |
| CI/CD系统 | 了解shell编程，流水线维护 | 持续集成 |

### 使用时间

- **构建时自动执行**：作为构建流程的一环，无需手动触发
- **按需发布**：通过配置`upload_to_remote`控制是否上传远程仓库
- **按需获取**：下游工具通过`conan search`查找，通过`conan install`获取

## 1.4 功能列表
<!-- 描述该需求交付的功能列表，内容包括：列出功能详细描述，标题、描述。 -->
| 功能编号 | 功能标题 | 功能描述 |
| ------- | ------- | -------- |
| F-01 | MDS/MDB文件收集 | 从`output/mdb/`目录自动收集已归档的MDS和MDB文件 |
| F-02 | metadata.yml生成 | 根据manifest.yml生成制品清单文件，记录版本、板型等信息 |
| F-03 | conanfile.py动态生成 | 动态生成适配的配方文件 |
| F-04 | Conan制品创建 | 执行`conan create`命令创建本地制品 |
| F-05 | 远程仓库上传（可选）| 支持将制品上传至配置的Conan远程仓库 |
| F-06 | 构建流程集成 | 集成到personal.yml和publish.yml构建目标中 |

# 2.功能设计

## 2.1 总体方案分析
<!-- 描述该方案的总体设计（注：相关输出方案可同步刷新到各组件仓） -->

### 2.1.1 方案详细设计

#### 2.1.1.1 方案概述
<!-- 描述该方案的整体实现，内容包括：涉及的关键点，实现策略等 -->

**整体实现**

本方案通过在构建流程末尾插入新的打包任务，将已收集的MDS/MDB文件打包为Conan制品。核心实现分为五个阶段：

1. **文件收集阶段**：从`self.config.mdb_output`（即`output/mdb/`）复制已整理的MDS/MDB文件到临时目录
2. **元数据生成阶段**：生成`metadata.yml`清单文件，记录板型名称、版本、构建类型等关键信息
3. **配方生成阶段**：动态生成`conanfile.py`, 适配不同的单板
4. **制品创建阶段**：调用`conan create`命令创建本地制品
5. **可选发布阶段**：根据配置决定是否上传至远程仓库

**关键点**

| 关键点 | 描述 | 技术实现 |
| ------ | ---- | -------- |
| 版本号获取 | 从manifest.yml的`base/version`字段读取 | `self.get_manufacture_config("base/version")` |
| 包名生成 | 格式为`{board_name}-{supporte_code}/{zip_code}`，Conan v2强制小写 | `package_name.lower()` |
| 文件权限 | 确保跨平台可读权限 | `chmod 644` (S_IRUSR\|S_IRGRP\|S_IROTH) |
| 临时目录清理 | 打包完成后自动清理临时文件 | `shutil.rmtree` in finally block |
| 错误处理 | MDS/MDB不存在时跳过而非失败 | `_check_mds_mdb_exists()`前置检查 |

**实现策略**

1. **任务驱动**：继承`bmcgo.tasks.task.Task`基类，实现标准任务接口
2. **依赖声明**：通过`wait`字段声明依赖`work.task_build_rootfs_img`
3. **配置驱动**：通过`work_config`支持`upload_to_remote`配置项
4. **仅支持conanv2**：通过`misc.conan_v2()`判断，对于V1场景跳过打包

#### 2.1.1.2 开发视图
<!-- 开发视图面向系统开发及软件管理，描述系统代码结构，构建结构的视图，主要解决系统技术实现和开发的问题，它依托逻辑视图，描述代码、构建结构 -->

**代码结构**

```text
bmcgo/tasks/
├── task.py                          # Task基类，定义run()/install()接口
└── task_package_metadata.py          # MDS/MDB打包任务实现（新增）

bmcgo/target/
├── personal.yml                     # 个人构建目标，集成新任务
└── publish.yml                      # 发布构建目标，集成新任务

bmcgo/utils/
├── config.py                        # Config类，定义mdb_output路径
└── misc.py                          # 工具函数，包含conan_v2()判断

bmcgo/tasks/conan/template/
└── conanfile.py.mako                 # Conanfile模板，mako格式（新增）
```

**类关系图**

```text
┌─────────────────────────────────────────────────────────────┐
│                    bmcgo.tasks.task.Task                     │
│  + run(): abstract                                          │
│  + install(): abstract                                      │
│  + get_manufacture_config(key): str                         │
└─────────────────────────────────────────────────────────────┘
                              ▲
                              │
┌─────────────────────────────────────────────────────────────┐
│          bmcgo.tasks.task_package_metadata.TaskClass         │
│  + enabled: bool                                            │
│  + upload_to_remote: bool                                   │
│  + package_dir: str                                         │
│  - run(): void                                              │
│  - _check_mds_mdb_exists(): bool                            │
│  - _prepare_package_dir(): str                              │
│  - _collect_and_prepare_files(): void                       │
│  - _generate_metadata(): void                               │
│  - _generate_conanfile(): void                              │
│  - _create_conan_package(): void                            │
└─────────────────────────────────────────────────────────────┘
```

**构建产物目录结构**

```text
output/
└── mdb/                          # MDS/MDB收集目录

临时打包目录结构（运行时）:
mds_mdb_package_{board_name}_*/
├── mdb/                          # 复制自output/mdb/
├── metadata.yml                  # 生成的元数据清单
└── conanfile.py                  # 动态生成的配方文件
```

#### 2.1.1.3 运行视图
<!-- 运行视图面向系统运行，描述系统启动过程、运行期交互的视图，主要解决系统运行期交互，描述各可执行交付件在运行期的交互关系 -->

**构建流程时序**

```text
┌─────────────┐     ┌──────────────┐     ┌──────────────────┐
│  bmcgo CLI  │────▶│ work.prepare │────▶│ work.build.conan │
│   (frame)   │     │    _env      │     │  (收集MDS/MDB到   │
└─────────────┘     └──────────────┘     │   output/mdb/)    │
                          └──────────────┴────────┬─────────┘
                                                 │
                    ┌────────────────────────────┴─────────────────────┐
                    │                                                   │
                    ▼                                                   ▼
            ┌──────────────┐                                   ┌──────────────┐
            │ work.build_  │                                   │  work.task_  │
            │   wbd_up     │                                   │  package_    │
            └──────┬───────┘                                   │  mds_mdb     │
                   │                                           └──────┬───────┘
                   ▼                                                  │
            ┌──────────────┐                                          │
            │ work.task_   │                                          │
            │ build_rootfs │                                          │
            │    _img      │                                          │
            └──────────────┘                                          │
                   │                                                  │
                   └──────────────────────────────────────────────────┘
                                                                   │
                                                                   ▼
                                                           ┌──────────────────┐
                                                           │ work.create_     │
                                                           │ interface_config │
                                                           └──────────────────┘

┌─────────────────────────────────────────────────────────────────┐
│         work.task_package_metadata (新增任务)                     │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │ 1. _check_mds_mdb_exists() - 检查目录是否存在          │   │
│  └─────────────────────────────────────────────────────────┘   │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │ 2. _prepare_package_dir() - 创建临时目录                │   │
│  └─────────────────────────────────────────────────────────┘   │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │ 3. _collect_and_prepare_files() - 复制MDS/MDB文件       │   │
│  │    _generate_metadata() - 生成metadata.yml              │   │
│  └─────────────────────────────────────────────────────────┘   │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │ 4. _generate_conanfile() - 动态生成conanfile.py         │   │
│  └─────────────────────────────────────────────────────────┘   │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │ 5. _create_conan_package() - 执行conan create           │   │
│  │    (可选) conan upload --recurse                        │   │
│  └─────────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────────┘
```

### 2.1.2 内部依赖分析
<!-- 是否涉及与其他组件接口依赖，如果涉及需要确认当前是否已完成，是否匹配当前需求开发诉求 -->

| 依赖项 | 依赖组件 | 依赖内容 | 完成状态 |
| ------ | -------- | -------- | -------- |
| MDS/MDB文件收集 | task_build_conan.CopyComponent._copy_files() | 从package_folder收集MDS/MDB到output/mdb/ | 已完成 |
| 配置读取 | bmcgo.utils.config.Config | 版本号、板型名称、构建类型等 | 已完成 |
| 任务框架 | bmcgo.tasks.task.Task | 任务基类和日志接口 | 已完成 |
| Conan版本检测 | bmcgo.misc.conan_v2() | 判断当前Conan版本 | 已完成 |

### 2.1.3 外部依赖分析
<!-- 是否涉及与平台SDK的依赖关系 -->

| 外部依赖 | 类型 | 版本要求 | 用途 |
| -------- | ---- | -------- | ---- |
| Conan | 外部工具 | v2.x | 包管理和制品创建 |
| Python | 运行环境 | >= 3.6 | 脚本执行 |
| PyYAML | Python库 | >= 5.1 | metadata.yml生成 |

### 2.1.4 北向接口分析
<!-- 需要分析当前功能是否有以下接口影响，如果有影响，则需要具体的补充影响点。其中注意点如下：
（1）如果有新增IPMI接口，请排查代码中IPMI命令注册的过滤字段，是否完全和IPMI命令的定义一致？
（2）新增一个接口时，需要咨询SIG组是否还有其他的接口受影响 -->

本功能为构建流程内部功能，不对外暴露北向接口。

### 2.1.5 兼容性分析
<!-- 当前的功能对现有在网的功能是否有影响，具体的影响点进行分析之后输出影响分析表格 -->

**Conan版本兼容性**

| Conan版本 | 包名要求 | 命令格式 | 状态 |
| --------- | -------- | -------- | ---- |
| Conan v1.x | 大小写敏感 | `conan create . name/version@user/channel` | 支持 |
| Conan v2.x | 必须小写 | `conan create .` | 支持 |

**影响分析**

- 只支持conanv2
- 默认仅本地创建，不影响现有发布流程

### 2.1.6 定制化接口分析
<!-- 如果支持定制化设置，则需要给出定制化时的默认值（空定制化项条件下的设置值），如果涉及到定制化接口变更或新增，注意定制化接口文档需配套修改。注意定制化默认值变更对白牌包的影响 -->

本功能不支持定制化配置，所有行为由work_config控制：

| 配置项 | 类型 | 默认值 | 说明 |
| ------ | ---- | ------ | ---- |
| upload_to_remote | bool | false | 是否上传到远程仓库 |

### 2.1.7 导入导出分析
<!-- 如果支持导入导出的配置，则需要分析导入导出的schema。 -->
不涉及配置导入导出。

### 2.1.8 传感器分析
<!-- 如果需要新增传感器，则需要提前登记和评审新增的传感器要素。新增传感器评审需要上SIG-Interface进行评审 -->
不涉及传感器新增。

### 2.1.9 精准告警事件分析
<!-- 如果需要新增事件，则需要提前登记和评审新增的时间要素 -->
不涉及事件新增。

### 2.1.10 系统锁定分析
<!-- 对外的接口或者命令是否支持系统锁定 -->
不涉及系统锁定。

### 2.1.11 用例场景分析
<!-- 以表格的形式输出该需求涉及的用例场景 -->

| 用例编号 | 用例名称 | 前置条件 | 操作步骤 | 预期结果 |
| -------- | -------- | -------- | -------- | -------- |
| UC-01 | 正常打包流程 | MDS/MDB文件已收集 | 1. 执行构建 2. 自动触发打包任务 | 成功创建Conan制品 |
| UC-02 | MDS/MDB不存在 | output/mdb/为空 | 1. 执行构建 | 跳过打包，输出警告日志 |
| UC-03 | Conan v2环境 | Conan v2已安装 | 1. 执行打包任务 | 生成v2兼容的conanfile.py，包名小写 |

## 2.2 非功能质量属性设计

### 2.2.1 扩展性分析
<!-- 考虑后续新增类似功能可以很好地扩展 -->

1. **新增元数据类型**：metadata.yml结构支持扩展
2. **多仓库支持**：通过`config.remote`配置支持上传到不同仓库
3. **包命名规则**：`{board_name}-{supporte_code}/{zip_code}`格式可扩展支持其他编码的模型

### 2.2.2 重用性分析
<!-- 是否为通用处理方式、接口，如果是得考虑重用性 -->
不涉及

### 2.2.3 可测试性分析
<!-- 此需求如何验证，是否可直接验证，or通过XXX功能覆盖验证，or需要单独怎加测试接口验证 -->

1. **单元测试**：各私有方法可独立测试
不涉及

2. **集成测试**：
不涉及

### 2.2.4 资料分析
<!-- 是否涉及资料修改 -->

| 资料类型 | 是否涉及 | 说明 |
| -------- | -------- | ---- |
| 用户手册 | 否 | 用户不直接可见，通过工具承载 |
| 开发指南 | 否 | 内部实现，无需用户文档 |
| API文档 | 否 | 无对外API |

### 2.2.5 资源使用分析
<!-- 新增线程、内存分配、模型属性名长度是否合理，CPU占用率是否会激增，Flash中新增文件是否合理（频繁读写Flash会大幅缩短emmc寿命）；是否涉及消息队列，如果涉及请检查是否存在某些场景下消息队列会满导致消息丢失，例如大量消息发送到队列且处理消息需要耗费较长时间的场景。 -->

不涉及

### 2.2.6 可靠性分析

不涉及

### 2.2.7 安全性分析

不涉及

# 3.功能实现
<!-- 通过表格、流程图、简明文字描述提供，力求容易看懂、容易实现，详细描述细节。 -->
## 3.1 MDS/MDB元数据归档功能实现

### 3.1.1 功能实现设计

**配置文件修改**

在`bmcgo/target/personal.yml`和`bmcgo/target/publish.yml`中添加任务配置：

```yaml
- name: work.task_package_metadata
  klass: bmcgo.tasks.task_package_metadata
  wait:
    - work.task_build_rootfs_img
  work_config:
    upload_to_remote: false  # 默认不上传，需显式配置
```

**制品结构**

```text
{board_name}-{supporte_code}/{zip_code}/
├── mdb/                          # MDS/MDB文件根目录
├── metadata.yml                  # 元数据清单文件（记录版本、机型等信息）
└── conanfile.py                  # Conan配方文件（由mako模板动态生成）
```

**模板实现**

本功能使用mako模板引擎动态生成conanfile.py，支持Conan v2：

| 文件路径 | 说明 |
|---------|------|
| `bmcgo/tasks/template/conanfile.py.mako` | 统一模板，包名称的差异 |
| `bmcgo/tasks/task_package_metadata.py` | 使用`TemplateLookup`加载模板并渲染 |

**metadata.yml结构**

```yaml
metadata:
  board_name: demo-board          # 板型名称
  version: "1.0.0"                # 版本号（来自manifest.yml）
  build_type: release             # 构建类型
  stage: dev                      # 发布阶段
```

### 3.1.2 功能详细设计

见第 2 节 功能设计

### 3.1.3 开发者测试
<!--
增加模块接口：以活动图/流程图等形式明确模块内处理流程，针对模块处理流程中的分支进行覆盖
修改模块接口处理流程：覆盖修改影响流程分支
-->

#### 3.1.3.1 单元测试
<!-- UT，主要是功能单元测试，测试对象是功能单元接口。UT测试设计要从黑盒（功能）角度设计，从输入(I)、处理（B）、预期输出（O）的角度进行用例分析设计，测试覆盖率仅作为反馈，用于分析哪些功能场景没有覆盖到，从而指导测试设计优化并补充测试用例 -->

不涉及

#### 3.1.3.2 集成测试
<!-- IT，主要是组件/模块内的集成测试，测试对象是模块/组件接口。IT测试设计将模块/组件当作黑盒测试，IT测试用例中禁止对组件/模块内部代码打桩，如果确实有少量场景难以构造，可以考虑在测试框架中统一打桩并提供接口供测试用例调用构造场景。
说明：API测试属于IT，其测试对象是微服务接口。
PCST，是指PC上的服务集成测试，测试对象是功能需求。PCST测试设计，要覆盖正常功能、异常功能和交叉功能，采用灰盒 -->

不涉及
