openbmc web/redfish到底层设计(持续更新...)
1.说明
本节是厘清openbmc的界面层web或者redfish到底层数据获取与展示。
不可或缺的是先阅读官方关于redfish的设计文档:
- 1.https://github.com/openbmc/docs/blob/master/designs/redfish-authorization.md
 - 2.https://github.com/openbmc/docs/blob/master/designs/redfish-postcodes.md
 - 3.https://github.com/openbmc/docs/blob/master/development/web-ui.md
 
需要注意的是,官方的文档一定要细读与分析背后的设计。
2.代码简单流程分析
2.1 大致总体流程
代码包包含web和redfish,均在bmcweb中,可以使用如下命令抽取代码:
# devtool modify bmcweb
 
调用关系如下:
(bmcweb/src/webserver_main.cpp)
int main(int /*argc*/, char** /*argv*/) noexcept(false)
---> run()  (bmcweb/src/webserver_run.cpp)---> server.add_interface("/xyz/openbmc_project/bmcweb","xyz.openbmc_project.bmcweb");---> if constexpr (BMCWEB_REDFISH)---> redfish::RedfishService redfish(app);---> redfish::EventServiceManager::getInstance(&*io);---> crow::login_routes::requestRoutes(app);---> app.run();---> systemBus->request_name("xyz.openbmc_project.bmcweb");---> io->run();
 
redfish()定义在文件bmcweb/redfish-core/src/redfish.cpp中,关系如下:
RedfishService::RedfishService(App& app)
---> requestRoutesMetadata(app);
---> requestRoutesOdata(app);
---> requestAccountServiceRoutes(app);
---> requestRoutesRoles(app);
---> ...
---> requestRoutesManager(app);
---> ...
---> requestRoutesSystemsLogServicesPostCode(app);
---> ...
---> requestRoutesRedfish(app);
 
因此,如果需要添加自己的redfish功能,可以在这里添加顶层函数功能。
拿一个函数调用:requestRoutesManager(app)举例:
(bmcweb/redfish-core/lib/managers.hpp)
inline void requestRoutesManager(App& app)
---> BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/")...
 
调用返回数据。
2.2 web与redfish结合
 
openbmc的web与redfish怎么结合去服务用户呢?
web理解就是前端展现给用户的网页,redfish其实是与web进行沟通,所以openbmc设计理念是redfish(bmcweb)作为后台与web(web-vue)作为前端搭配起来使用的。
顺便提一下,openbmc是使用nghttp2作为web server的。
举一个简单例子,在前端js中获取数据:
async getChassisCollection() {
--->  ...
---> .get('/redfish/v1/Chassis')
 
2.3 针对官方文档,简单分析一个例子
这一部分针对官方文档的内容,看一下例子。
官方文档如下:
- https://github.com/openbmc/docs/blob/master/designs/redfish-postcodes.md
 
该文档说的bios postcode的事情,可以找到代码位置:
bmcweb/redfish-core/lib/systems_logservices_postcodes.hpp
bmcweb/redfish-core/src/redfish.cpp
 
在文件bmcweb/redfish-core/src/redfish.cpp中调用函数requestRoutesSystemsLogServicesPostCode(),在文件bmcweb/redfish-core/lib/systems_logservices_postcodes.hpp中定义了函数:requestRoutesSystemsLogServicesPostCode():
inline void requestRoutesSystemsLogServicesPostCode(App& app)
---> BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/PostCodes/")...
---> BMCWEB_ROUTE(app,"/redfish/v1/Systems/<str>/LogServices/PostCodes/Actions/LogService.ClearLog/")
---> BMCWEB_ROUTE(app,"/redfish/v1/Systems/<str>/LogServices/PostCodes/Entries/")
---> BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/PostCodes/Entries/<str>/")
---> BMCWEB_ROUTE(app,"/redfish/v1/Systems/<str>/LogServices/PostCodes/Entries/<str>/attachment/")
 
比较关心的是对于设置操作如何处理。可以看到,调用的是函数handleSystemsLogServicesPostCodesPost():
inline void handleSystemsLogServicesPostCodesPost()
---> crow::connections::systemBus->async_method_call(..,"xyz.openbmc_project.State.Boot.PostCode0",
"/xyz/openbmc_project/State/Boot/PostCode0",
"xyz.openbmc_project.Collection.DeleteAll", 
"DeleteAll");
 
因此,采取的就是一种函数调用的办法去处理的。
2.4 web获取后台数据的例子
 
这一节借一个web例子,可以看到web和后台是怎么交互的。
例如,在web下可以看到如下内容:

 因此,明显看到后台以(redfish)json数据呈现给web,web解析即可。
