定制化redfish的post的空响应体

问题描述

现在需要实现一个无参POST接口/redfish/v1/Managers/1/LogServices/Actions/Oem/openUBMC/CollectNPULog,当前执行成功的返回体:

要求定制响应内容,当执行成功时返回空内容,错误时返回错误信息。

按照 Redfish定制指南(开发中) | 文档中心 | openUBMC 的指导我完成了以下脚本:

local cjson = require ‘cjson’

local http = require ‘http’

local function rsp_postprocess(code, body, header, manufacture)

local rsp_body

local rsp_header = header \~= nil and header or {}

if code >= http.HTTP_OK and code < http.HTTP_SPECIAL_RESPONSE then

    rsp_body = {}

    rsp_header\['Content-Length'\] = 0

else

    if body \~= nil and body \~= '' then

        rsp_body = cjson.json_object_ordered_decode(body)

    else

        rsp_body = cjson.json_object_new_object()

    end

end



rsp_header\['Content-Type'\] = 'application/json'

return cjson.json_object_ordered_encode(rsp_body), rsp_header

end

return {

...

\['rsp_postprocess'\] = rsp_postprocess

}

请问这个脚本我怎么配置或调用?怎么跟/redfish/v1/Managers/1/LogServices/Actions/Oem/openUBMC/CollectNPULog关联起来?

环境信息

基于openubmc 2512_lts

~ ~ $ ipmcget -d version
------------------- openUBMC INFO -------------------
IPMC CPU: Hi1711
IPMI Version: 2.0
Active openUBMC Version: 1.17.10
Active openUBMC Build: 01
Active openUBMC Built: 14:33:07 Mar 27 2026
Backup openUBMC Version: 1.17.10
Available openUBMC Version: 1.00.16
Available openUBMC Build: 01
Active Uboot Version: 21.3.10.1 (09:53:00 Dec 30 2025)
Backup Uboot Version: 21.3.10.1 (09:53:00 Dec 30 2025)
Active Secure Bootloader Version: 21.3.10.1 (09:51:37 Dec 30 2025)
Backup Secure Bootloader Version: 21.3.10.1 (09:51:37 Dec 30 2025)
Active Secure Firmware Version: 21.3.10.1 (09:51:38 Dec 30 2025)
Backup Secure Firmware Version: 21.3.10.1 (09:51:38 Dec 30 2025)
Active BMCSDK Version: 5.12.00.01
----------------- Product INFO -----------------
Product ID: 0x0000
Product Name: Atlas 800I A3
Product Unique ID: 0x000000010302BF02
Active BIOS Version: (U75)21.23
Backup BIOS Version: 21.23

重现步骤

见问题描述

期望结果

成功执行定制化脚本

实际结果

不知道怎么配置或调用定制化脚本

尝试过的解决方案

无。

分析结论

无。

答案内容由AI生成,仅供参考:

:white_check_mark: 总结

要使您的定制化脚本生效,必须完成以下三步:

  1. 创建映射 JSON 文件,绑定 URI 和 Plugin 函数;
  2. 编写 Lua Plugin 脚本,包含业务逻辑和 rsp_postprocess 后处理函数;
  3. 将配置纳入构建系统,确保部署后能被 Redfish 框架加载。

:white_check_mark: 推荐方式:将所有自定义接口统一放在 managers/, systems/ 等子目录下管理,便于维护。

点击此处查看详细分析解答

如何配置并调用 Redfish 接口的定制化脚本以实现空响应体

根据您提供的需求和环境信息,您希望为一个自定义 Redfish POST 接口 /redfish/v1/Managers/1/LogServices/Actions/Oem/openUBMC/CollectNPULog 实现:执行成功时返回空响应体(Empty Body),失败时返回标准错误信息

这属于 openUBMC 中的 Redfish 接口定制化范畴。以下是详细的配置和调用方法,基于 openUBMC 2512_lts 版本。


:wrench: 一、需求分析

需求项 当前行为 期望行为
成功响应 返回带有 "Base.1.0.Success" 的 error 结构(虽然 Success,但语义不一致) 返回 空响应体,HTTP 状态码为 200 OK
失败响应 返回错误信息 保持原样,返回标准 Redfish 错误结构
HTTP Header Content-Type 正确,但 Content-Length 未显式控制 成功时 Content-Length: 0

您的 Lua 脚本逻辑是正确的,但需要正确注册到 Redfish 映射配置中才能生效。


:file_folder: 二、相关文件结构与位置

在 openUBMC 架构中,接口的响应处理通过 接口映射配置 + Lua Plugin / Script 实现:

interface_config/
└── redfish/
    └── mapping_config/
        ├── config.json                          # 主配置,定义模块加载
        ├── managers/
        │   └── logservices_actions_oem_collectnpulog.json   # 自定义接口映射文件
        └── plugins/
            └── collectnpulog_postprocessor.lua  # 您的脚本存放位置

:white_check_mark: 三、实现步骤

第一步:创建定制接口的映射文件

文件路径示例:

interface_config/redfish/mapping_config/managers/logservices_actions_oem_collectnpulog.json

{
  "Uri": "/redfish/v1/Managers/1/LogServices/Actions/Oem/openUBMC/CollectNPULog",
  "Plugin": {
    "Name": "CollectNPULogPlugin",
    "Formula": "collectnpulog_plugin:handle_collectnpulog_post"
  },
  "Type": "Post",
  "ResourceExist": true,
  "ReqBody": {
    "Schema": "ActionSchema"
  },
  "RspBody": {
    "Formula": "rsp_postprocess"
  },
  "ProcessingFlow": [
    {
      "Plugin": {
        "Name": "PostProcessHook",
        "Formula": "collectnpulog_plugin:rsp_postprocess"
      }
    }
  ]
}

:warning: 注意:该 URI 必须与您实际注册的 Redfish 路径一致。


第二步:编写 Lua Plugin 脚本

文件路径示例:

interface_config/redfish/plugins/collectnpulog_postprocessor.lua

local cjson = require 'cjson'
local http = require 'http'

-- 主处理函数
local function handle_collectnpulog_post(req_body)
    -- 模拟业务逻辑,例如触发 NPU 日志收集
    local success, err_msg = pcall(function()
        -- TODO: 调用底层命令或服务收集 NPU Log
        -- 如:os.execute("collect_npu_logs.sh")
    end)

    if success then
        return { code = http.HTTP_OK }
    else
        return {
            code = http.HTTP_INTERNAL_SERVER_ERROR,
            body = {
                error = {
                    code = "Base.1.0.GeneralError",
                    message = "Failed to collect NPU log.",
                    ["@Message.ExtendedInfo"] = {
                        {
                            ["@odata.type"] = "#Message.v1_0_0.Message",
                            MessageId = "Base.1.4.InternalError",
                            Severity = "Warning",
                            Resolution = "Retry or contact technical support."
                        }
                    }
                }
            }
        }
    end
end

-- 响应后处理函数(定制响应体和头)
local function rsp_postprocess(code, body, header, manufacture)
    local rsp_body
    local rsp_header = header or {}

    if code >= http.HTTP_OK and code < http.HTTP_SPECIAL_RESPONSE then
        -- 成功情况:返回空响应体
        rsp_body = nil
        rsp_header["Content-Length"] = "0"
    else
        -- 失败情况:解码原有 body 或构造默认 error
        if body and body ~= "" then
            rsp_body = cjson.decode(body)
        else
            rsp_body = {
                error = {
                    code = "Base.1.0.GeneralError",
                    message = "An unknown error occurred."
                }
            }
        end
        rsp_header["Content-Type"] = "application/json"
    end

    return rsp_body and cjson.encode(rsp_body) or "", rsp_header
end

return {
    handle_collectnpulog_post = handle_collectnpulog_post,
    rsp_postprocess = rsp_postprocess
}

第三步:确保主配置加载自定义模块

修改 interface_config/redfish/mapping_config/config.json

添加插件路径:

{
  "JsonPath": "mapping_config",
  "SchemaPath": "schema",
  "PluginPath": "plugins",
  "ScriptPath": "scripts",
  "Modules": [
    "managers/logservices_actions_oem_collectnpulog.json"
  ]
}

第四步:构建并部署配置文件

  1. 将上述文件加入您的构建系统(如 manifest 编译流程)。
  2. 确保最终生成的镜像包含更新后的 mapping_config 目录。
  3. 刷写固件或更新文件系统后重启 BMC。

第五步:使用 Postman 测试接口

请求方式:

POST /redfish/v1/Managers/1/LogServices/Actions/Oem/openUBMC/CollectNPULog
Host: <BMC_IP>
Authorization: Basic xxx
Content-Type: application/json

请求体(可选):

{}

成功响应(期望):

HTTP/1.1 200 OK
Content-Length: 0
Date: Mon, 06 Jan 2025 10:00:00 GMT

:white_check_mark: 无响应体内容。

失败响应示例:

{
  "error": {
    "code": "Base.1.0.GeneralError",
    "message": "Failed to collect NPU log.",
    "@Message.ExtendedInfo": [
      {
        "@odata.type": "#Message.v1_0_0.Message",
        "MessageId": "Base.1.4.InternalError",
        "Severity": "Warning",
        "Resolution": "Retry or contact technical support."
      }
    ]
  }
}

:pushpin: 四、关键知识点说明

概念 说明
Mapping Config Redfish 接口的核心定义文件,决定 URI、方法、参数、响应处理流程
Plugin vs Script Plugin 是可复用的函数模块;Script 是一次性逻辑(不推荐用于此场景)
ProcessingFlow 接口执行流程控制,可用于插入前置/后置处理逻辑
RspPostProcess 特殊 hook 函数,用于定制最终返回内容和 Header
http.HTTP_OK 通常为 200,定义在 http 模块中

:police_car_light: 常见问题排查

问题 可能原因 解决方案
接口 404 Not Found 映射文件未加载或路径错误 检查 config.jsonModules 列表
返回仍是 error 结构 rsp_postprocess 未注册进 ProcessingFlow 或未返回 nil 确保流程中调用了 postprocess 函数
Content-Length 不为 0 未显式设置 rsp_header["Content-Length"] = "0" 显式设置 Header
脚本语法错误 Lua 语法问题或 require 失败 检查日志 /var/log/redfish.log 或使用 luac 预编译验证

:white_check_mark: 总结

要使您的定制化脚本生效,必须完成以下三步:

  1. 创建映射 JSON 文件,绑定 URI 和 Plugin 函数;
  2. 编写 Lua Plugin 脚本,包含业务逻辑和 rsp_postprocess 后处理函数;
  3. 将配置纳入构建系统,确保部署后能被 Redfish 框架加载。

:white_check_mark: 推荐方式:将所有自定义接口统一放在 managers/, systems/ 等子目录下管理,便于维护。


:link: 参考文档

如果您使用的是定制仓,建议将以上修改放入 custom_request_response.lua 或独立 plugin 文件中,并通过 Formula 引用。

如有需要,可进一步提供 bmcgomanifest.yml 构建配置以协助集成。

                "RspBody": {
                    "@odata.type": "${Statements/GetDataType()}",
                    "MessageId": "${Statements/GetMessageId()}",
                    ....
                 }

GetMessageId 用Script,直接return lua_nil

@AweiHe 帮忙检查一下下面的写法有没有问题,不起作用:

{

        "Uri": "/redfish/v1/Managers/:managerid/LogServices/Actions/Oem/{{OemIdentifier}}/CollectAllLog",

        "Interfaces": \[

            {

                "Type": "POST",

                "LockdownAllow": true,

                "ResourceExist": {

                    "${Statements/IsValidManagersId()}": true

                },

                "ReqBody": {

                    "Type": "object",

                    "Required": true,

                    "Properties": {}

                },

                "RspBody": {

                    "MessageId": "${Statements/GetMessageId()}"

                },

                "Statements": {

                    "IsValidManagersId": {

                        "Steps": \[

                            {

                                "Type": "Plugin",

                                "Formula": "utils.is_valid_managers_id(Uri.managerid)"

                            }

                        \]

                    },

                    "CollectAllLog": {

                        "Steps": \[

                            {

                                "Type": "Script",

                                "Formula": "if orchestrator.logservices.collect_all_log() then return lua_nil else return lua_nil end"

                            }

                        \]

                    },

                     "GetMessageId": {

                        "Steps": \[

                            {

                                "Type": "Script",

                                "Formula": "return lua_nil"

                            }

                        \]

                    }

                }

            }

        \]

    }

@AweiHe

AI答复里面的RspBody能直接用Formula调脚本里面的函数rsp_postprocess?

“ProcessingFlow”: [
{
“Plugin”: {
“Name”: “PostProcessHook”,
“Formula”: “collectnpulog_plugin:rsp_postprocess”
}
}
]

可以有这种写法吗?

AI该部分回答是错误的,正确用法参考文档 接口映射配置 | 文档中心 | openUBMC

要求定制响应内容,当执行成功时返回空内容。怎么才叫做空?

@AweiHe ,要求返回的是这种空内容:

@AweiHe

根据Redfish定制指南(开发中) | 文档中心 | openUBMC写的CTCC/src/plugins/redfish/custom_request_response.lua影响到了所有的redfish请求的返回体,我只需要定制特定的几个URL的请求的返回体,不是所有的。