自动生成lua代码说明
更新时间:2025/10/15
在Gitcode上查看源码

自动生成Lua代码说明

1. 自动生成文件目录结构

目录文件名依据的文件说明
gen/classmodel.luamodel.json以及mdb_interface接口定义文件包含每个类的属性(包括资源树属性和私有属性)校验信息,以及服务端资源树方法注册函数
gen/class/types类名.luamodel.json每个类一个文件,完成私有属性的校验和默认值配置,会被model.lua引用
gen/class/typestypes.luatypes.json包含枚举、结构体、字典等自定义类型的定义
gen/App名client.luaservice.json以及mdb_interface接口定义文件根据required部分定义的接口依赖生成,客户端资源树接口方法调用、对象获取和信号订阅等函数
gen/App名datas.luadatas.yaml远程持久化内存数据库/本地持久化数据库初始化加载的默认数据
gen/App名db.luamodel.json远程持久化内存数据库表格创建和数据库操作函数
gen/App名local_db.luamodel.json本地持久化数据库表格创建和数据库操作函数(model.json中配置了"tableLocation": "Local"的表)
gen/App名orm_classes.luamodel.json为配置了远程持久化的每个类初始化ORM对象
gen/App名service.luamodel.json、service.json以及mdb_interface接口定义文件服务入口,包含App初始化和服务端资源树方法注册、对象创建等
gen/App名/ipmiipmi.luaipmi.jsonIPMI命令定义,是IPMI模块的入口
gen/App名/ipmiipmi_message.luaipmi.jsonIPMI命令请求和响应汇总,会被ipmi.lua引用
gen/App名/ipmi/cmds命令名.luaipmi.json每个IPMI命令一个文件,包含请求和响应参数定义和校验,会被ipmi_message.lua引用
gen/App名/json_types接口末段.luamodel.json、service.json以及mdb_interface接口定义文件每个接口一个文件,包含资源树接口注册属性定义方法参数校验

2. mdb_interface依赖配置

自动生成代码会使用service.json中dependencies配置的mdb_interface版本进行代码生成。如果build和test部分都配置了mdb_interface依赖,则优先选用build部分的配置。

本地开发调试时,修改mdb_interface后,可以在mdb_interface目录执行bingo build,然后将构建生成的包配置到组件的service.json中,再到组件目录下执行bingo gen生成代码。

3. 代码生成策略配置

代码生成策略需要在组件MDS/service.json文件中的codegen_policy中指定,具体配置方式参考《代码生成策略版本特性说明》文档。

4. 校验说明

4.1 model.json中配置的资源树属性、方法、信号没有在mdb_interface对应接口下定义

例如,Temperature类在interfaces下配置了TemperatureType属性,但是对应的接口bmc.kepler.Systems.HistoryTemperature在mdb_interface中没有定义该属性。

修复建议: 在mdb_interface对应的接口定义下补充定义。

4.2 mdb_interface中接口属性options配置错误

属性options可选字段为emitsChangedSignal、explicit、deprecated、volatile。其中emitsChangedSignal取值必须是字符串类型,其他取值必须是布尔类型。

修复建议: 在mdb_interface对应的属性定义下纠正配置。

4.3 model.json中配置了持久化的类没有配置表名

配置了持久化指的是类配置了tableType或者至少一个属性的usage里配置了持久化类型,并且类型取值在允许范围内。目前支持的持久化类型有PoweroffPer、ResetPer、TemporaryPer、PoweroffPerRetain、ResetPerRetain、TemporaryPerRetain、PermanentPer,其中PermanentPer只支持远程持久化。

表名可以通过tableName字段配置。

修复建议: 如果需要持久化,在model.json对应的类补充表名配置;如果不需要持久化,则去掉持久化类型配置。

4.4 model.json中配置了远程持久化的类没有配置主键

配置了远程持久化指的是配置了持久化并且没有配置tableLocation: "Local"。配置主键指的是至少一个属性配置了primaryKey: true。

修复建议: 如果需要远程持久化,在model.json对应的类选择属性配置为主键;如果不需要持久化,则去掉表名和持久化类型配置。

4.5 service.json中配置的接口和路径在mdb_interface中没有匹配的定义

自动生成代码会根据组件service.json中required部分配置的path,去掉动态参数后按/分段与json/path/mdb/拼接得到mdb_interface下的目录路径,在该目录下寻找与service.json配置的接口和路径匹配的定义(路径匹配忽略动态参数的不同写法)。

例如,service.json配置了路径/bmc/kepler/Systems/Bios和接口bmc.kepler.Systems.Bios时,则在mdb_interface/json/path/mdb/bmc/kepler/Systems/Bios目录下必须存在path与/bmc/kepler/Systems/Bios匹配并且interfaces至少一个元素与bmc.kepler.Systems.Bios一致。

修复建议: 纠正service.json的接口和路径,与mdb_interface中定义的一致。

5. 注意事项

5.1 如果组件配置的不同资源树接口末段重复,生成代码时相关的命名会进行扩展,手写代码需要适配修改

不同资源树接口末段重复时,所有使用接口末段命名的文件和代码都会防冲突重命名。

例如,gen/App名/json_types目录下生成的文件是以接口末段命名的,如果原先配有接口bmc.kepler.Aa.Bb,生成Bb.lua,新增接口bmc.kepler.Cc.Bb之后,会新生成CcBb.lua,并且原先的Bb.lua也会重命名为AaBb.lua,文件内所有命名用到Bb的地方也会修改为AaBb包括client.lua中命名用Bb拼接的函数,都会修改为用AaBb拼接,所以手写代码中所有调用这些函数的地方都需要适配修改

5.2 model.json配置的类名、资源树路径和接口需要与mdb_interface中定义的一致

  • model.json类配置中定义了path时,其取值去掉动态参数后,必须在mdb_interface/json/path/mdb中目录层级匹配的子目录下有对应的路径定义文件 例如,path定义为/bmc/kepler/Systems/${SystemId}/Boards/CpuBoard/${Id},去掉动态参数后为/bmc/kepler/Systems/Boards/CpuBoard,所以mdb_interface中对应的路径定义文件必须在mdb_interface/json/path/mdb/bmc/kepler/Systems/Boards/CpuBoard目录下

  • mdb_interface路径定义文件的名称必须与model.json里配置了该path的类名一致 例如,model.json配置类名为CpuBoardpath,则对应的路径定义文件必须命名为CpuBoardpath.json

  • model.json在interfaces中配置的接口名称,必须在mdb_interface/json/intf/mdb中存在目录层级匹配的接口定义文件 例如,model.json配置了接口bmc.kepler.Systems.Board,则mdb_interface中对应的接口定义文件路径必须是mdb_interface/json/intf/mdb/bmc/kepler/Systems/Board.json

6. 自动生成代码调试

调试方法:本地bingo仓修改代码并重新安装本地bingo

git clone远程bingo仓后,可以在本地bingo代码仓修改代码,再在本地bingo代码仓中执行sh install_local.sh命令重新安装本地bingo工具,然后再到组件目录生成代码进行验证。

7. 常见问题

7.1 Bingo gen没有报错但是生成的文件变成空的

通常是因为Lua格式化失败,生成的文件Lua语法错误。原因包括MDS或MDB中定义了非法的属性名(Lua变量名不能以数字开头)等。

可以修改自动生成代码逻辑,注释掉bingo仓template.py文件中的格式化逻辑,然后重新执行bingo gen并检查生成文件的语法错误:

7.2 接口权限错误地配置在methods下,自动生成报"方法 privilege 在mdb_interface中没有定义"

问题是因为MDS/model.json类配置的methods中配置了mdb_interface对应接口下没有定义的方法,纠正错误配置即可。

7.3 mdb_interface文件找不到

报错信息:FileNotFoundError: [Errno 2] No such file or directory: '../temp/opt/bmc/apps/mdb_interface/..'

问题是因为MDS/model.json类配置的path字段配置了mdb_interface中没有定义的路径,需要在mdb_interface补充定义。

注意: 如果查看了mdb_interface里是有定义的,请参考常见问题7.6。

7.4 报错mds_class["interfaces"][intf_name]出现keyError: 'bmc.kepler.xxx'

问题是因为mdb_interface中路径文件定义的interfaces中某个接口在MDS/model.json中没有定义,需要在MDS/model.json补充定义。

例如,/bmc/kepler/Managers/:Id/LogServices/:LogType这个路径在mdb_interface中定义的interfaces包含接口bmc.kepler.Managers.LogService,那么MDS/model.json中对应的类LogService的interface部分也必须配置bmc.kepler.Managers.LogService这个接口。

7.5 组件仓库MDS什么都没有改,为什么生成的代码变了,或者生成的时候报错配置错误

问题是因为变更或报错的资源树配置不在组件仓库,而在mdb_interface仓库。

自动生成代码是根据组件仓库MDS配置,加上MDS里资源树接口/路径在mdb_interface仓库的配置,两者结合生成的。mdb_interface仓库修改了也会影响代码生成。需要排查对应的属性、方法等在mdb_interface的配置。

7.6 查看了mdb_interface是没问题的,为什么生成代码还是变了/报错

问题是因为查看的mdb_interface版本跟自动生成使用的版本不一致。从bingo gen的输出可以看出使用的mdb_interface版本。

7.7 自动生成时mdb_interface没有拉最新版本

问题主要有以下两个原因:

  1. 由于conan的机制,生成代码时如果本地conan缓存中的mdb_interface满足service.json配置的版本范围,会优先使用本地缓存,而不会拉取最新的mdb_interface版本。如果需要使用最新版本,可以使用官方命令conan remove "*" -c手动删除本地缓存。

  2. 可以执行conan remote list查看是否有配置openubmc_dev,没有的话需要配置如下:

bash
conan config init
conan remote add openubmc_dev "https://conan.openubmc.cn/conan_1/" false -f
conan user <openUBMC社区用户> -p <openUBMC社区用户密> -r openubmc_dev

说明: openUBMC社区用户指的是 https://openubmc.cn/ 里的账号。

7.8 查看了mdb_interface中是有定义的,但是service.lua没有生成资源树对象和接口的代码

组件在model.json中字段配置错误会导致对象和接口无法识别。

对象路径是path,接口是interfaces

7.9 报错/bin/sh: line 0: cd: too many arguments,直接退出

问题是因为本地组件仓库路径包含空格,导致执行cd命令报错。

自动生成代码调用的入口是组件目录下的Makefile,可以在Makefile文件中给TPL_DIR变量加引号解决此问题。

7.10 报错 model.json中类XXX接口XXX的字段XXX超出取值范围

接口下面只能配置properties、signals、methods、privilege这些字段。资源树接口下面挂的属性要放在properties下面。

7.11 报错 protoc: No such file or directory

问题原因是缺少protobuf工具,可以执行命令安装:

bash
apt update
apt install libprotobuf-dev protobuf-compiler

7.12 报错 get_ref_type ... KeyError: '$ref'

原因是baseType配置了复杂类型(Array、Struct、Dictionary、Enum),但是没有引用复杂类型的定义。正确配置参考如下例子:

7.13 报错 属性 XXX 没有基类定义或找不到引用

原因是MDS或者mdb_interface中的属性定义没有配置baseType,需要补充baseType字段。

7.14 报错 ALLOW_BASIC_TYPES[prop_data["baseType"]] ... KeyError: XXX

原因是MDS或者mdb_interface中属性配置的baseType不是允许的类型。

baseType配置的值必须在这个范围内:"U8", "U8[]", "U16", "U16[]", "U32", "U32[]", "U64", "U64[]", "S8", "S16", "S16[]", "S32", "S32[]", "S64", "S64[]", "Double", "Double[]", "String", "String[]", "Boolean", "Boolean[]", "Array", "Struct", "Enum", "Dictionary"

7.15 yaml_include中报错TypeError: 'type' object is not subscriptable

原因是Python版本与pyyaml-include包版本不匹配,以Python 3.8为例,执行以下命令安装与Python版本匹配的pyyaml-include包:

bash
pip install pyyaml-include==1.4.1

7.16 为什么自动生成的db.lua和orm_classes.lua中的某个类被删除了

问题是因为这个类在model.json中只配置了tableName,没有配置tableType。

旧版本的自动生成代码(codegenPolicy版本 < 14),只配置了tableName,没有配置tableType,并且不是本地持久化的表,默认使用内存数据库。

新版本(codegenPolicy版本 >= 14)需要在model.json中明确声明tableType: Memory

7.17 报错CalledProcessError: Command 'LUA_FORMAT...', Exec format error: '/usr/bin/lua-format'

问题是因为开发者环境没有安装lua-format工具,需要执行manifest仓库的init.py脚本初始化开发者环境。

如果执行之后仍没有/usr/bin/lua-format文件,建议联系软件工程组构建同事定位问题。

如果执行之后仍有报错,可删除lua-format工具(rm /usr/bin/lua-format),重新在manifest仓库执行init.py脚本初始化。

7.18 merge_model.py报错intf_json[intf_name]出现keyError: 'bmc.kepler.xxx'

问题是因为mdb_interface对应的接口定义文件中,没有定义报错的接口名。

通常是因为开发人员的配置错误基础问题:接口定义文件格式错误,或者接口名拼写错误。

原理: 自动生成代码时,根据model.json中定义接口在mdb_interface的json/intf中找到对应的文件路径,再从文件中读取接口定义,如果文件中没有这个接口的定义就会报此错误。