答案内容由AI生成,仅供参考:
如何实现表单形式请求体的 Redfish POST 接口
为了支持通过表单上传固件文件和升级参数的 Redfish 接口,需在 /redfish/v1/UpdateService/update-multipart 路径下实现一个处理 multipart/form-data 类型请求的 POST 接口。以下基于 openUBMC 架构和 Redfish 标准的实现步骤。
接口背景
Redfish 是一种标准化的 RESTful API 协议,用于管理服务器硬件(如 BMC)。在固件升级场景中,MultipartHttpPushUri 属性指向支持多部分(multipart)HTTP 文件上传的端点。该接口需支持:
- 接收
.hpm等格式的二进制升级包 - 接收 JSON 格式的升级配置参数
- 返回异步任务(Task)的位置信息以便轮询进度
实现目标
实现以下功能的 Redfish POST 接口:
POST /redfish/v1/UpdateService/update-multipart
Content-Type: multipart/form-data
包含两个关键表单项:
UpdateFile:上传的固件二进制文件UpdateParameters:描述升级目标与策略的 JSON 配置
成功响应为 202 Accepted,并返回异步任务链接。
实现步骤
步骤 1:配置 Multipart 接口路径
在 Redfish 资源模型中注册路径:
{
"UpdateService": {
"@odata.id": "/redfish/v1/UpdateService",
"MultipartHttpPushUri": "/redfish/v1/UpdateService/update-multipart"
}
}
该属性需在系统启动时由 UpdateService 模块暴露。
步骤 2:定义接口映射配置(Mapping Config)
根据 openUBMC 的 接口映射机制,将 /redfish/v1/UpdateService/update-multipart 映射到资源协作接口。配置文件位于:
rackmount/interface_config/redfish/mapping_config/update_service.json
添加如下映射配置:
{
"Resources": [
{
"Uri": "/redfish/v1/UpdateService/update-multipart",
"Interfaces": [
{
"Type": "POST",
"ReqBody": {
"ContentType": "multipart/form-data"
},
"ProcessingFlow": [
{
"Service": "bmc.kepler.firmware_mgmt",
"Interface": "bmc.kepler.firmware_mgmt.UpdateHandler",
"Method": "HandleMultipartUpdate",
"Params": [
{"Key": "UpdateFile", "Source": "FormData/UpdateFile"},
{"Key": "UpdateParameters", "Source": "FormData/UpdateParameters"}
]
}
],
"RspHeader": {
"Location": "${TaskLocation}"
},
"RspBody": {},
"Statements": [
{
"SetHttpStatus": 202
}
]
}
]
}
]
}
支持
multipart/form-data解析,并提取UpdateFile和UpdateParameters字段。
步骤 3:编写后端处理逻辑
在 D-Bus 服务 bmc.kepler.firmware_mgmt 中添加 HandleMultipartUpdate 方法以处理上传:
def HandleMultipartUpdate(self, update_file_data, update_parameters_json):
# 解析 UpdateParameters JSON
params = json.loads(update_parameters_json)
targets = params.get("Targets", [])
oem_config = params.get("Oem", {})
# 保存上传文件到临时路径
file_path = "/tmp/bmc_update.hpm"
with open(file_path, "wb") as f:
f.write(update_file_data)
# 创建升级任务
task_id = self.create_update_task(file_path, targets, oem_config)
# 返回任务 URI
return f"/redfish/v1/TaskService/TaskMonitors/{task_id}"
此方法应触发异步任务,并返回唯一任务 ID。
步骤 4:集成 TaskService 任务管理
上传成功后,启动一个异步任务监控升级流程。任务信息注册在:
/redfish/v1/TaskService/TaskMonitors/{TaskID}
使用 openUBMC 的通用 Task Service 框架(参考 task_mgmt.lua)管理任务状态,确保支持以下状态:
RunningCompletedException
示例响应头:
HTTP/1.1 202 Accepted
Location: /redfish/v1/TaskService/TaskMonitors/1361570031
客户端通过 GET 查询此地址获取进度。
步骤 5:客户端使用方法(curl 示例)
curl -X POST \
-H "Expect:" \
-H "Content-Type: multipart/form-data" \
-u root:root \
-F 'UpdateFile=@bmc_update.hpm;type=application/octet-stream' \
-F 'UpdateParameters={
"Targets": ["/redfish/v1/UpdateService/FirmwareInventory/Microcode"],
"Oem": {
"XXXX": {
"IsSeamless": true,
"KeepConfig": true
}
}
};type=application/json' \
https://<BMC_IP>/redfish/v1/UpdateService/update-multipart \
-k -i
![]()
-H "Expect:"可防止某些服务器过早断开连接。
步骤 6:状态监控(轮询 Task)
收到 Location 后轮询任务状态:
curl -u root:root https://<BMC_IP>/redfish/v1/TaskService/TaskMonitors/1361570031 -k
返回示例:
{
"Id": "1361570031",
"Name": "Firmware Update Task",
"TaskState": "Running",
"PercentComplete": 75
}
当 TaskState 为 Completed 时,表示升级成功。
技术依赖项
| 组件 | 作用 |
|---|---|
bmc.kepler.firmware_mgmt |
处理固件上传与升级逻辑 |
UpdateService |
提供 Redfish 接口 /UpdateService 支持 |
Task Service Tasks (/redfish/v1/TaskService/Tasks/) |
管理异步任务生命周期 |
interface_config/redfish/mapping_config/ |
定义接口映射规则 |
openUBMC Update Sh |
实际执行 hpm 包解析与刷写脚本 |
期望结果
成功实现后,系统支持:
- 使用
multipart/form-data上传升级包和配置 - 自动创建异步任务
- 通过标准 Redfish Task 接口查询进度
- 支持静默升级、配置保留 (
KeepConfig)、无缝切换 (IsSeamless) 等高级特性 - 兼容上游管理系统调用
参考资料
- 《接口映射配置》
- openUBMC 项目仓库:https://gitcode.com/openUBMC
- Redfish Specification DSP0266(UpdateService)
- 文档 ID #1: “升级你的BMC”
- 文档 ID #8: “rackmount” 接口映射机制说明
以上方案完全符合 openUBMC 架构与 Redfish 标准,可稳定实现带参数的多部分固件上传功能。
相关链接: