openubmc-bingo 0.5.240__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of openubmc-bingo might be problematic. Click here for more details.

Files changed (242) hide show
  1. bmcgo/__init__.py +12 -0
  2. bmcgo/bmcgo.py +22 -0
  3. bmcgo/bmcgo_config.py +176 -0
  4. bmcgo/cli/__init__.py +10 -0
  5. bmcgo/cli/cli.py +584 -0
  6. bmcgo/codegen/__init__.py +14 -0
  7. bmcgo/codegen/c/__init__.py +9 -0
  8. bmcgo/codegen/c/annotation.py +52 -0
  9. bmcgo/codegen/c/argument.py +42 -0
  10. bmcgo/codegen/c/codegen.py +153 -0
  11. bmcgo/codegen/c/comment.py +22 -0
  12. bmcgo/codegen/c/ctype_defination.py +353 -0
  13. bmcgo/codegen/c/helper.py +87 -0
  14. bmcgo/codegen/c/interface.py +63 -0
  15. bmcgo/codegen/c/method.py +82 -0
  16. bmcgo/codegen/c/property.py +180 -0
  17. bmcgo/codegen/c/renderer.py +21 -0
  18. bmcgo/codegen/c/signal.py +64 -0
  19. bmcgo/codegen/c/template/client.c.mako +145 -0
  20. bmcgo/codegen/c/template/client.h.mako +36 -0
  21. bmcgo/codegen/c/template/interface.c.mako +0 -0
  22. bmcgo/codegen/c/template/interface.introspect.xml.mako +99 -0
  23. bmcgo/codegen/c/template/micro_component.c.mako +32 -0
  24. bmcgo/codegen/c/template/public.c.mako +228 -0
  25. bmcgo/codegen/c/template/public.h.mako +128 -0
  26. bmcgo/codegen/c/template/server.c.mako +104 -0
  27. bmcgo/codegen/c/template/server.h.mako +36 -0
  28. bmcgo/codegen/lua/.lua-format +7 -0
  29. bmcgo/codegen/lua/Makefile +101 -0
  30. bmcgo/codegen/lua/__init__.py +9 -0
  31. bmcgo/codegen/lua/codegen.py +171 -0
  32. bmcgo/codegen/lua/proto/Makefile +87 -0
  33. bmcgo/codegen/lua/proto/ipmi_types.proto +17 -0
  34. bmcgo/codegen/lua/proto/types.proto +52 -0
  35. bmcgo/codegen/lua/script/check_intfs.py +161 -0
  36. bmcgo/codegen/lua/script/dto/__init__.py +11 -0
  37. bmcgo/codegen/lua/script/dto/exception.py +53 -0
  38. bmcgo/codegen/lua/script/dto/kepler_abstract.py +47 -0
  39. bmcgo/codegen/lua/script/dto/options.py +33 -0
  40. bmcgo/codegen/lua/script/dto/print_simple.py +19 -0
  41. bmcgo/codegen/lua/script/dto/redfish_api.py +241 -0
  42. bmcgo/codegen/lua/script/dto/url_route.py +195 -0
  43. bmcgo/codegen/lua/script/gen_db_json.py +444 -0
  44. bmcgo/codegen/lua/script/gen_depends.py +89 -0
  45. bmcgo/codegen/lua/script/gen_entry.py +263 -0
  46. bmcgo/codegen/lua/script/gen_feature_json.py +156 -0
  47. bmcgo/codegen/lua/script/gen_historical_local_db_json.py +88 -0
  48. bmcgo/codegen/lua/script/gen_intf_json.py +261 -0
  49. bmcgo/codegen/lua/script/gen_intf_rpc_json.py +575 -0
  50. bmcgo/codegen/lua/script/gen_ipmi_json.py +485 -0
  51. bmcgo/codegen/lua/script/gen_mdb_json.py +117 -0
  52. bmcgo/codegen/lua/script/gen_rpc_msg_json.py +487 -0
  53. bmcgo/codegen/lua/script/gen_schema.py +302 -0
  54. bmcgo/codegen/lua/script/ipmi_types_pb2.py +135 -0
  55. bmcgo/codegen/lua/script/loader/__init__.py +11 -0
  56. bmcgo/codegen/lua/script/loader/file_utils.py +33 -0
  57. bmcgo/codegen/lua/script/loader/kepler_abstract_collect.py +79 -0
  58. bmcgo/codegen/lua/script/loader/kepler_abstract_loader.py +47 -0
  59. bmcgo/codegen/lua/script/loader/redfish_loader.py +127 -0
  60. bmcgo/codegen/lua/script/lua_format.py +62 -0
  61. bmcgo/codegen/lua/script/mds_util.py +385 -0
  62. bmcgo/codegen/lua/script/merge_model.py +330 -0
  63. bmcgo/codegen/lua/script/merge_proto_algo.py +85 -0
  64. bmcgo/codegen/lua/script/proto_loader.py +47 -0
  65. bmcgo/codegen/lua/script/proto_plugin.py +140 -0
  66. bmcgo/codegen/lua/script/redfish_source_tree.py +118 -0
  67. bmcgo/codegen/lua/script/render_utils/__init__.py +38 -0
  68. bmcgo/codegen/lua/script/render_utils/base.py +25 -0
  69. bmcgo/codegen/lua/script/render_utils/client_lua.py +98 -0
  70. bmcgo/codegen/lua/script/render_utils/controller_lua.py +71 -0
  71. bmcgo/codegen/lua/script/render_utils/db_lua.py +224 -0
  72. bmcgo/codegen/lua/script/render_utils/error_lua.py +185 -0
  73. bmcgo/codegen/lua/script/render_utils/factory.py +52 -0
  74. bmcgo/codegen/lua/script/render_utils/ipmi_lua.py +159 -0
  75. bmcgo/codegen/lua/script/render_utils/ipmi_message_lua.py +24 -0
  76. bmcgo/codegen/lua/script/render_utils/mdb_lua.py +177 -0
  77. bmcgo/codegen/lua/script/render_utils/mdb_register.py +215 -0
  78. bmcgo/codegen/lua/script/render_utils/message_lua.py +26 -0
  79. bmcgo/codegen/lua/script/render_utils/messages_lua.py +156 -0
  80. bmcgo/codegen/lua/script/render_utils/model_lua.py +485 -0
  81. bmcgo/codegen/lua/script/render_utils/old_model_lua.py +429 -0
  82. bmcgo/codegen/lua/script/render_utils/plugin_lua.py +38 -0
  83. bmcgo/codegen/lua/script/render_utils/redfish_proto.py +86 -0
  84. bmcgo/codegen/lua/script/render_utils/request_lua.py +76 -0
  85. bmcgo/codegen/lua/script/render_utils/service_lua.py +130 -0
  86. bmcgo/codegen/lua/script/render_utils/utils_message_lua.py +125 -0
  87. bmcgo/codegen/lua/script/render_utils/validate_lua.py +221 -0
  88. bmcgo/codegen/lua/script/sep_ipmi_message_cmds.py +217 -0
  89. bmcgo/codegen/lua/script/template.py +166 -0
  90. bmcgo/codegen/lua/script/types_pb2.py +516 -0
  91. bmcgo/codegen/lua/script/utils.py +663 -0
  92. bmcgo/codegen/lua/script/validate.py +80 -0
  93. bmcgo/codegen/lua/script/yaml_to_json.py +73 -0
  94. bmcgo/codegen/lua/templates/Makefile +114 -0
  95. bmcgo/codegen/lua/templates/apps/Makefile +261 -0
  96. bmcgo/codegen/lua/templates/apps/Makefile.mdb.mk +64 -0
  97. bmcgo/codegen/lua/templates/apps/app.lua.mako +19 -0
  98. bmcgo/codegen/lua/templates/apps/class.lua.mako +35 -0
  99. bmcgo/codegen/lua/templates/apps/client.lua.mako +429 -0
  100. bmcgo/codegen/lua/templates/apps/controller.lua.mako +276 -0
  101. bmcgo/codegen/lua/templates/apps/datas.lua.mako +8 -0
  102. bmcgo/codegen/lua/templates/apps/db.lua.mako +89 -0
  103. bmcgo/codegen/lua/templates/apps/entry.lua.mako +128 -0
  104. bmcgo/codegen/lua/templates/apps/feature.lua.mako +37 -0
  105. bmcgo/codegen/lua/templates/apps/generate_route.mako +25 -0
  106. bmcgo/codegen/lua/templates/apps/impl_feature.lua.mako +72 -0
  107. bmcgo/codegen/lua/templates/apps/ipmi.lua.mako +97 -0
  108. bmcgo/codegen/lua/templates/apps/ipmi_cmd.lua.mako +18 -0
  109. bmcgo/codegen/lua/templates/apps/ipmi_message.lua.mako +36 -0
  110. bmcgo/codegen/lua/templates/apps/local_db.lua.mako +263 -0
  111. bmcgo/codegen/lua/templates/apps/main.lua.mako +25 -0
  112. bmcgo/codegen/lua/templates/apps/mc.lua.mako +77 -0
  113. bmcgo/codegen/lua/templates/apps/mdb.lua.mako +45 -0
  114. bmcgo/codegen/lua/templates/apps/mdb_interface.lua.mako +73 -0
  115. bmcgo/codegen/lua/templates/apps/message.lua.mako +38 -0
  116. bmcgo/codegen/lua/templates/apps/model.lua.mako +239 -0
  117. bmcgo/codegen/lua/templates/apps/orm_classes.lua.mako +16 -0
  118. bmcgo/codegen/lua/templates/apps/plugin.lua.mako +8 -0
  119. bmcgo/codegen/lua/templates/apps/redfish.proto.mako +47 -0
  120. bmcgo/codegen/lua/templates/apps/service.lua.mako +440 -0
  121. bmcgo/codegen/lua/templates/apps/signal_listen.lua.mako +19 -0
  122. bmcgo/codegen/lua/templates/apps/utils/default_intf.lua.mako +41 -0
  123. bmcgo/codegen/lua/templates/apps/utils/enum.mako +10 -0
  124. bmcgo/codegen/lua/templates/apps/utils/imports.mako +13 -0
  125. bmcgo/codegen/lua/templates/apps/utils/mdb_intf.lua.mako +25 -0
  126. bmcgo/codegen/lua/templates/apps/utils/mdb_obj.lua.mako +23 -0
  127. bmcgo/codegen/lua/templates/apps/utils/message.mako +160 -0
  128. bmcgo/codegen/lua/templates/apps/utils/request.lua.mako +59 -0
  129. bmcgo/codegen/lua/templates/apps/utils/validate.mako +83 -0
  130. bmcgo/codegen/lua/templates/errors.lua.mako +36 -0
  131. bmcgo/codegen/lua/templates/messages.lua.mako +32 -0
  132. bmcgo/codegen/lua/templates/new_app/.clang-format.mako +170 -0
  133. bmcgo/codegen/lua/templates/new_app/.gitignore.mako +26 -0
  134. bmcgo/codegen/lua/templates/new_app/CHANGELOG.md.mako +0 -0
  135. bmcgo/codegen/lua/templates/new_app/CMakeLists.txt.mako +29 -0
  136. bmcgo/codegen/lua/templates/new_app/Makefile.mako +25 -0
  137. bmcgo/codegen/lua/templates/new_app/README.md.mako +0 -0
  138. bmcgo/codegen/lua/templates/new_app/conanfile.py.mako +7 -0
  139. bmcgo/codegen/lua/templates/new_app/config.cfg.mako +6 -0
  140. bmcgo/codegen/lua/templates/new_app/mds/model.json.mako +3 -0
  141. bmcgo/codegen/lua/templates/new_app/mds/service.json.mako +21 -0
  142. bmcgo/codegen/lua/templates/new_app/permissions.ini.mako +16 -0
  143. bmcgo/codegen/lua/templates/new_app/src/lualib/${project_name}_app.lua.mako +16 -0
  144. bmcgo/codegen/lua/templates/new_app/src/service/main.lua.mako +25 -0
  145. bmcgo/codegen/lua/templates/new_app/test/integration/test_${project_name}.conf.mako +9 -0
  146. bmcgo/codegen/lua/templates/new_app/test/integration/test_${project_name}.lua.mako +47 -0
  147. bmcgo/codegen/lua/templates/new_app/test/unit/test.lua.mako +23 -0
  148. bmcgo/codegen/lua/templates/new_app/user_conf/rootfs/etc/systemd/system/${project_name}.service.mako +18 -0
  149. bmcgo/codegen/lua/templates/new_app/user_conf/rootfs/etc/systemd/system/multi-user.target.wants/${project_name}.service.link +1 -0
  150. bmcgo/component/__init__.py +10 -0
  151. bmcgo/component/analysis/analysis.py +183 -0
  152. bmcgo/component/analysis/build_deps.py +165 -0
  153. bmcgo/component/analysis/data_deps.py +333 -0
  154. bmcgo/component/analysis/dep-rules.json +912 -0
  155. bmcgo/component/analysis/dep_node.py +110 -0
  156. bmcgo/component/analysis/intf_deps.py +163 -0
  157. bmcgo/component/analysis/intf_validation.py +254 -0
  158. bmcgo/component/analysis/rule.py +211 -0
  159. bmcgo/component/analysis/smc_dfx_whitelist.json +11 -0
  160. bmcgo/component/analysis/sr_validation.py +391 -0
  161. bmcgo/component/build.py +222 -0
  162. bmcgo/component/component_dt_version_parse.py +348 -0
  163. bmcgo/component/component_helper.py +114 -0
  164. bmcgo/component/coverage/__init__.py +11 -0
  165. bmcgo/component/coverage/c_incremental_cov_report.template +53 -0
  166. bmcgo/component/coverage/incremental_cov.py +464 -0
  167. bmcgo/component/deploy.py +110 -0
  168. bmcgo/component/gen.py +169 -0
  169. bmcgo/component/package_info.py +236 -0
  170. bmcgo/component/template/conanbase.py.mako +278 -0
  171. bmcgo/component/template/conanfile.deploy.py.mako +40 -0
  172. bmcgo/component/test.py +947 -0
  173. bmcgo/errors.py +119 -0
  174. bmcgo/frame.py +217 -0
  175. bmcgo/functional/__init__.py +10 -0
  176. bmcgo/functional/analysis.py +96 -0
  177. bmcgo/functional/bmc_studio_action.py +98 -0
  178. bmcgo/functional/check.py +185 -0
  179. bmcgo/functional/conan_index_build.py +251 -0
  180. bmcgo/functional/config.py +332 -0
  181. bmcgo/functional/csr_build.py +724 -0
  182. bmcgo/functional/deploy.py +263 -0
  183. bmcgo/functional/diff.py +235 -0
  184. bmcgo/functional/fetch.py +235 -0
  185. bmcgo/functional/full_component.py +391 -0
  186. bmcgo/functional/maintain.py +381 -0
  187. bmcgo/functional/new.py +166 -0
  188. bmcgo/functional/schema_valid.py +111 -0
  189. bmcgo/functional/simple_sign.py +104 -0
  190. bmcgo/functional/upgrade.py +78 -0
  191. bmcgo/ipmigen/__init__.py +13 -0
  192. bmcgo/ipmigen/ctype_defination.py +82 -0
  193. bmcgo/ipmigen/ipmigen.py +309 -0
  194. bmcgo/ipmigen/template/cmd.c.mako +366 -0
  195. bmcgo/ipmigen/template/ipmi.c.mako +25 -0
  196. bmcgo/ipmigen/template/ipmi.h.mako +51 -0
  197. bmcgo/logger.py +176 -0
  198. bmcgo/misc.py +117 -0
  199. bmcgo/target/app.yml +17 -0
  200. bmcgo/target/install_sdk.yml +15 -0
  201. bmcgo/target/personal.yml +53 -0
  202. bmcgo/target/publish.yml +45 -0
  203. bmcgo/tasks/__init__.py +11 -0
  204. bmcgo/tasks/download_buildtools_hm.py +124 -0
  205. bmcgo/tasks/misc.py +15 -0
  206. bmcgo/tasks/task.py +354 -0
  207. bmcgo/tasks/task_build_conan.py +714 -0
  208. bmcgo/tasks/task_build_rootfs_img.py +595 -0
  209. bmcgo/tasks/task_buildgppbin.py +88 -0
  210. bmcgo/tasks/task_buildhpm_ext4.py +82 -0
  211. bmcgo/tasks/task_create_interface_config.py +122 -0
  212. bmcgo/tasks/task_download_buildtools.py +99 -0
  213. bmcgo/tasks/task_download_dependency.py +72 -0
  214. bmcgo/tasks/task_hpm_envir_prepare.py +112 -0
  215. bmcgo/tasks/task_packet_to_supporte.py +87 -0
  216. bmcgo/tasks/task_prepare.py +105 -0
  217. bmcgo/tasks/task_sign_and_pack_hpm.py +42 -0
  218. bmcgo/utils/__init__.py +10 -0
  219. bmcgo/utils/buffer.py +128 -0
  220. bmcgo/utils/combine_json_schemas.py +170 -0
  221. bmcgo/utils/component_post.py +54 -0
  222. bmcgo/utils/component_version_check.py +86 -0
  223. bmcgo/utils/config.py +1067 -0
  224. bmcgo/utils/fetch_component_code.py +232 -0
  225. bmcgo/utils/install_manager.py +61 -0
  226. bmcgo/utils/installations/__init__.py +10 -0
  227. bmcgo/utils/installations/base_installer.py +70 -0
  228. bmcgo/utils/installations/install_consts.py +30 -0
  229. bmcgo/utils/installations/install_plans/bingo.yml +11 -0
  230. bmcgo/utils/installations/install_workflow.py +50 -0
  231. bmcgo/utils/installations/installers/apt_installer.py +177 -0
  232. bmcgo/utils/installations/installers/pip_installer.py +46 -0
  233. bmcgo/utils/installations/version_util.py +100 -0
  234. bmcgo/utils/mapping_config_patch.py +443 -0
  235. bmcgo/utils/perf_analysis.py +114 -0
  236. bmcgo/utils/tools.py +704 -0
  237. bmcgo/worker.py +417 -0
  238. openubmc_bingo-0.5.240.dist-info/METADATA +30 -0
  239. openubmc_bingo-0.5.240.dist-info/RECORD +242 -0
  240. openubmc_bingo-0.5.240.dist-info/WHEEL +5 -0
  241. openubmc_bingo-0.5.240.dist-info/entry_points.txt +2 -0
  242. openubmc_bingo-0.5.240.dist-info/top_level.txt +1 -0
bmcgo/worker.py ADDED
@@ -0,0 +1,417 @@
1
+ #! /usr/bin/env python3
2
+ # -*- coding: UTF-8 -*-
3
+ # Copyright (c) 2024 Huawei Technologies Co., Ltd.
4
+ # openUBMC is licensed under Mulan PSL v2.
5
+ # You can use this software according to the terms and conditions of the Mulan PSL v2.
6
+ # You may obtain a copy of Mulan PSL v2 at:
7
+ # http://license.coscl.org.cn/MulanPSL2
8
+ # THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
9
+ # EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
10
+ # MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
11
+ # See the Mulan PSL v2 for more details.
12
+ '''
13
+ 功 能:任务调度框架
14
+ 修改记录:2025-5-20 创建
15
+ '''
16
+ import json
17
+ import importlib
18
+ import os
19
+ import time
20
+ import threading
21
+ from socket import socket, AF_INET, SOCK_STREAM, SOL_SOCKET, SO_REUSEADDR
22
+ from multiprocessing import Process, Queue
23
+
24
+ import yaml
25
+
26
+ from bmcgo import errors
27
+ from bmcgo.utils.perf_analysis import PerfAnalysis
28
+ from bmcgo.utils.tools import Tools
29
+
30
+ # 注意端口号需要与V3的配置不同
31
+ WORK_SERVER_PORT = 62345
32
+ # 任务失败状态
33
+ TASK_STATUS_FAILED = "Failed"
34
+ # 用于通知主程序 server已经启动
35
+ q = Queue(1)
36
+ tool = Tools(__name__)
37
+ log = tool.log
38
+
39
+
40
+ class WsServerCommException(errors.BmcGoException):
41
+ """
42
+ 与状态服务通信失败
43
+ """
44
+
45
+ def __init__(self, *arg, **kwarg):
46
+ super(WsServerCommException, self).__init__(*arg, **kwarg)
47
+
48
+
49
+ class WorkStatusServer(Process):
50
+ """
51
+ 全局任务状态管理器
52
+ """
53
+ def __init__(self):
54
+ super().__init__()
55
+ self.task_status_dict = {}
56
+ self.start_time = time.time()
57
+ self.fd = socket(AF_INET, SOCK_STREAM)
58
+ self.fd.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
59
+ address = ("", WORK_SERVER_PORT)
60
+ try:
61
+ self.fd.bind(address)
62
+ self.fd.listen(10)
63
+ # 向主进程发送准备好的消息
64
+ q.put(1)
65
+ except Exception as e:
66
+ log.error(f"任务状态错误: {e}")
67
+ raise Exception(f"请手动运行此命令(sudo fuser -k {WORK_SERVER_PORT}/tcp), 若命令不存在执行apt install psmisc安装") from e
68
+ self.has_work_failed = False
69
+
70
+ def run(self):
71
+ while True:
72
+ self._accept()
73
+
74
+ def _accept(self):
75
+ cur_time = time.time()
76
+ if int(cur_time - self.start_time) / 60 > 60:
77
+ self.start_time = time.time()
78
+ log.warning(f"任务状态字典为: {self.task_status_dict}")
79
+ log.warning("构建时长已超 60 分钟")
80
+
81
+ cli_fd, _ = self.fd.accept()
82
+ recv = cli_fd.recv(1024)
83
+ recv_json = recv.decode()
84
+ msg = json.loads(recv_json)
85
+ act = msg["action"]
86
+ resp = ""
87
+ wn = msg["work_name"]
88
+ if act == "set_if_not_exist":
89
+ st = msg["work_status"]
90
+ resp = "False"
91
+ status = self.task_status_dict.get(wn)
92
+ if status is None:
93
+ self.task_status_dict[wn] = st
94
+ resp = "True"
95
+ elif act == "set":
96
+ st = msg["work_status"]
97
+ self.task_status_dict[wn] = st
98
+ if st == TASK_STATUS_FAILED:
99
+ self.has_work_failed = True
100
+ resp = "True"
101
+ elif act == "get":
102
+ if self.has_work_failed:
103
+ resp = TASK_STATUS_FAILED
104
+ else:
105
+ st = self.task_status_dict.get(wn)
106
+ resp = "None" if st is None else st
107
+
108
+ cli_fd.send(resp.encode())
109
+ cli_fd.close()
110
+
111
+
112
+ class WorkStatusClient():
113
+ """
114
+ 全局任务状态管理器
115
+ """
116
+ def __init__(self):
117
+ super().__init__()
118
+ self.task_status_dict = {}
119
+
120
+ @staticmethod
121
+ def __comm(msg, ignore_error):
122
+ fd = socket(AF_INET, SOCK_STREAM)
123
+ fd.settimeout(2)
124
+ while True:
125
+ try:
126
+ fd.connect(("", WORK_SERVER_PORT))
127
+ fd.send(msg.encode())
128
+ msg = fd.recv(1024)
129
+ fd.close()
130
+ return msg.decode()
131
+ except Exception as e:
132
+ if ignore_error:
133
+ log.info(str(e))
134
+ return None
135
+ else:
136
+ raise WsServerCommException("与任务状态服务器通信失败") from e
137
+
138
+ # 获取任务状态
139
+ def get(self, target_name, work_name, ignore_error=False):
140
+ return self.__comm("{\"action\":\"get\", \"work_name\":\"%s/%s\"}" % (target_name, work_name), ignore_error)
141
+
142
+ # 任务不存在时创建任务状态,否则返回False
143
+ def set_if_not_exist(self, target_name, work_name, status, ignore_error=False):
144
+ return self.__comm("{\"action\":\"set_if_not_exist\", \"work_name\":\"%s/%s\", \"work_status\":\"%s\"}" %
145
+ (target_name, work_name, status), ignore_error)
146
+
147
+ # 设置任务状态
148
+ def set(self, target_name, work_name, status, ignore_error=False):
149
+ self.__comm("{\"action\":\"set\", \"work_name\":\"%s/%s\", \"work_status\":\"%s\"}" %
150
+ (target_name, work_name, status), ignore_error)
151
+
152
+
153
+ ws_client = WorkStatusClient()
154
+
155
+
156
+ def wait_finish(target_name, wait_list, prev_work_name):
157
+ if not wait_list:
158
+ return True
159
+ start_time = time.time()
160
+ cnt = 0
161
+ while True:
162
+ finish = True
163
+ time.sleep(0.1)
164
+ for work_name in wait_list:
165
+ cur_time = time.time()
166
+ status = ws_client.get(target_name, work_name, ignore_error=True)
167
+ if status is None:
168
+ log.debug(f"任务{target_name}/{prev_work_name}执行失败,原因是未能获取到任务{target_name}/{work_name}的状态")
169
+ ws_client.set(target_name, prev_work_name, TASK_STATUS_FAILED, ignore_error=True)
170
+ return False
171
+ if status == "Done":
172
+ continue
173
+ if status == TASK_STATUS_FAILED:
174
+ log.debug(f"任务{target_name}/{prev_work_name}执行失败,原因其等待的任务{target_name}/{work_name}失败")
175
+ ws_client.set(target_name, prev_work_name, TASK_STATUS_FAILED, ignore_error=True)
176
+ return False
177
+ finish = False
178
+ # 每等待60s打印一次日志
179
+ if int(cur_time - start_time) >= 60:
180
+ start_time = time.time()
181
+ cnt += 60
182
+ log.info("目标 {} 正在等待任务: {}, 当前已等待 {} 秒".format(target_name, work_name, cnt))
183
+ break
184
+ if finish:
185
+ return True
186
+
187
+
188
+ class WorkerScheduler(Process):
189
+ '''
190
+ '''
191
+ def __init__(self, target_name, work, perf: PerfAnalysis, config, args):
192
+ super().__init__()
193
+ self.work = work
194
+ self.target_name = target_name
195
+ self.work_name = self.work["name"]
196
+ self.klass = self.work.get("klass", "")
197
+ self.perf = perf
198
+ self.config = config
199
+ self.args = args
200
+
201
+ def load_class(self):
202
+ if self.klass == "":
203
+ return None
204
+ # bmcgo的任务类名固定为TaskClass
205
+ if self.klass.startswith("bmcgo"):
206
+ work_path = self.klass
207
+ class_name = "TaskClass"
208
+ else:
209
+ split = self.klass.split(".", -1)
210
+ work_path = ".".join(split[:-1])
211
+ class_name = split[-1]
212
+ log.debug("工作路径: {}, 类名: {}".format(work_path, class_name))
213
+ try:
214
+ work_py_file = importlib.import_module(work_path)
215
+ return getattr(work_py_file, class_name)
216
+ except ModuleNotFoundError as e:
217
+ ignore = self.work.get("ignore_not_exist", False)
218
+ if ignore:
219
+ log.warning(f"{self.klass} 已配置 ignore_not_exist 且为真, 跳过执行")
220
+ return None
221
+ else:
222
+ raise e
223
+
224
+ def run(self):
225
+ ret = -1
226
+ try:
227
+ ret = self._run(self.config, self.args)
228
+ if ret != 0:
229
+ ws_client.set(self.target_name, self.work_name, TASK_STATUS_FAILED, ignore_error=True)
230
+ except WsServerCommException as exc:
231
+ msg = str(exc)
232
+ log.debug(msg)
233
+ ret = -1
234
+ except Exception as exc:
235
+ if os.environ.get("LOG"):
236
+ import traceback
237
+ log.info(traceback.format_exc())
238
+ msg = str(exc)
239
+ log.error(msg)
240
+ ws_client.set(self.target_name, self.work_name, TASK_STATUS_FAILED, ignore_error=True)
241
+ ret = -1
242
+ if ret != 0:
243
+ log.debug(f"任务名: {self.work_name}, 类名: {self.klass} 退出状态错误")
244
+ return ret
245
+
246
+ def _run(self, config, args):
247
+ '''
248
+ 功能描述:执行work
249
+ '''
250
+ work_name = self.work_name
251
+ log.debug(f"任务名: {self.work_name}, 类: {self.klass}) 已就绪")
252
+ ret = wait_finish(self.target_name, self.work.get("wait"), work_name)
253
+ if not ret:
254
+ log.debug(f"等待任务 {self.work_name} 类 {self.klass} 发生错误")
255
+ return -1
256
+ target_config = self.work.get("target_config")
257
+ config.deal_conf(target_config)
258
+ # bmcgo的任务类名固定为TaskClass
259
+ work_class = self.load_class()
260
+ # 如果未指定类时,不需要执行
261
+ if work_class is not None:
262
+ work_x = work_class(config, work_name)
263
+ # work配置项和target配置项
264
+ work_config = self.work.get("work_config")
265
+ work_x.deal_conf(work_config)
266
+ ret = ws_client.set_if_not_exist(self.target_name, work_name, "Running")
267
+ self.perf.add_data(work_name, "running")
268
+ if not args.debug_frame and ret:
269
+ # 创建进程并且等待完成或超时
270
+ ret = work_x.run()
271
+ if ret is not None and ret != 0:
272
+ return -1
273
+ elif not args.debug_frame and not ret:
274
+ # 不需要创建进程,等待任务执行完成即可
275
+ wait_list = []
276
+ wait_list.append(work_name)
277
+ ret = wait_finish(self.target_name, wait_list, work_name)
278
+ if not ret:
279
+ log.debug(f"等待任务 {self.work_name} 类 {self.klass} 发生错误")
280
+ return -1
281
+
282
+ log.debug(f"任务 {work_name} 开始安装步骤")
283
+ if not args.debug_frame:
284
+ ret = work_x.install()
285
+ if ret is not None and ret != 0:
286
+ return -1
287
+ self.perf.add_data(work_name, "finish")
288
+
289
+ # 创建子任务
290
+ ret = exec_works(self.target_name, self.work.get("subworks"), work_name, self.perf, self.config, self.args)
291
+ if not ret:
292
+ ws_client.set(self.target_name, self.work_name, TASK_STATUS_FAILED, ignore_error=True)
293
+ log.error(f"运行子任务 {self.work_name} 类 {self.klass}失败")
294
+ return -1
295
+ # 创建include_target子任务
296
+ target_include = self.work.get("target_include")
297
+ if target_include:
298
+ ret = create_target_scheduler(work_name, target_include, self.perf, self.config, self.args)
299
+ if not ret:
300
+ ws_client.set(self.target_name, self.work_name, TASK_STATUS_FAILED, ignore_error=True)
301
+ log.error(f"创建计划表 {target_include} 失败")
302
+ return -1
303
+ log.success(f"任务 {work_name} 完成")
304
+ ws_client.set(self.target_name, self.work_name, "Done")
305
+ return 0
306
+
307
+
308
+ class Worker():
309
+ """
310
+ 任务执行器
311
+ """
312
+ work_name = ""
313
+ target_name = ""
314
+
315
+ def __init__(self, config, args):
316
+ self.config = config
317
+ self.args = args
318
+
319
+ def exec_work(self, target_name, work, perf: PerfAnalysis):
320
+ try:
321
+ return self._exec_work(target_name, work, perf)
322
+ except Exception as exc:
323
+ msg = str(exc)
324
+ log.debug(msg)
325
+ return -1
326
+
327
+ def run(self, target_name, work, perf: PerfAnalysis):
328
+ self.work_name = work["name"]
329
+ self.target_name = target_name
330
+ t = threading.Thread(target=self.exec_work, args=(target_name, work, perf))
331
+ t.start()
332
+
333
+ def _exec_work(self, target_name, work, perf: PerfAnalysis):
334
+ ws = WorkerScheduler(target_name, work, perf, self.config, self.args)
335
+ ws.start()
336
+ try_cnt = 0
337
+ while ws.is_alive():
338
+ try_cnt += 1
339
+ time.sleep(0.1)
340
+
341
+ # 每个任务的超时时间为70分钟(42000次循环),如果超时则失败
342
+ if try_cnt > 42000:
343
+ log.error(f"任务{self.target_name}/{self.work_name}执行超时(>70min),强制退出")
344
+ ws.kill()
345
+ return -1
346
+ if ws.exitcode is not None and ws.exitcode == 0:
347
+ return 0
348
+ return -1
349
+
350
+
351
+ def exec_works(target_name, work_list, prev_work_name, perf: PerfAnalysis, config, args):
352
+ if not work_list:
353
+ return True
354
+ # 创建任务并等待完成
355
+ wait_list = []
356
+ for work in work_list:
357
+ worker = Worker(config, args)
358
+ worker.run(target_name, work, perf)
359
+ wait_list.append(work["name"])
360
+ return wait_finish(target_name, wait_list, prev_work_name)
361
+
362
+
363
+ def read_config(file_path: str, conan_args):
364
+ '''
365
+ 功能描述:读取json内容
366
+ '''
367
+ if not os.path.exists(file_path):
368
+ raise errors.NotFoundException(f"{file_path} 路径不存在")
369
+
370
+ # conan专用处理
371
+ with open(file_path, "r") as fp:
372
+ data = fp.read()
373
+ if conan_args:
374
+ if conan_args.upload_package:
375
+ data = data.replace('${upload}', "true")
376
+ else:
377
+ data = data.replace('${upload}', "false")
378
+ data = data.replace('${conan_package}', conan_args.conan_package)
379
+ return yaml.safe_load(data)
380
+
381
+
382
+ def create_target_scheduler(target_alias, target_name, perf: PerfAnalysis, config, args, conan_args, target):
383
+ log.info(f"创建新目标 {target_name} 构建计划表")
384
+ if args.debug_task is None:
385
+ if os.path.isfile(target):
386
+ target_file = target
387
+ else:
388
+ raise Exception(f"构建目标文件 [target_]{target_name}.yml 不存在")
389
+ # 创建配置
390
+
391
+ work_list = read_config(target_file, conan_args)
392
+ else:
393
+ work_list = [
394
+ {
395
+ "name": "test_task",
396
+ "klass": args.debug_task
397
+ }
398
+ ]
399
+ if isinstance(work_list, dict):
400
+ target_cfg = work_list.get("target_config", {})
401
+ config.deal_conf(target_cfg)
402
+ environments = work_list.get("environment", {})
403
+ for key, value in environments.items():
404
+ log.success(f"配置环境变量 {key}: {value}")
405
+ os.environ[key] = value
406
+ # 打印配置
407
+ config.print_config()
408
+ # 打印任务清单
409
+ log.debug(f"任务列表:{work_list}")
410
+ # 创建任务调度器
411
+ if isinstance(work_list, dict):
412
+ subworks = work_list.get("subworks")
413
+ if not subworks or not isinstance(subworks, list):
414
+ raise errors.BmcGoException(f"target文件{target_file}缺少subworks配置")
415
+ return exec_works(target_alias, subworks, "TOP", perf, config, args)
416
+ else:
417
+ return exec_works(target_alias, work_list, "TOP", perf, config, args)
@@ -0,0 +1,30 @@
1
+ Metadata-Version: 2.1
2
+ Name: openubmc-bingo
3
+ Version: 0.5.240
4
+ Summary: Tools provided by openubmc
5
+ Home-page: https://openubmc.cn
6
+ Classifier: Programming Language :: Python :: 3
7
+ Classifier: License :: OSI Approved :: Mulan Permissive Software License v2 (MulanPSL-2.0)
8
+ Classifier: Operating System :: OS Independent
9
+ Description-Content-Type: text/markdown
10
+ Requires-Dist: conan <=1.62.0
11
+ Requires-Dist: cryptography <=42.0.7
12
+ Requires-Dist: dbus-python
13
+ Requires-Dist: ecdsa
14
+ Requires-Dist: gitpython
15
+ Requires-Dist: inflection
16
+ Requires-Dist: jsonref
17
+ Requires-Dist: jsonschema
18
+ Requires-Dist: launchpadlib
19
+ Requires-Dist: mako
20
+ Requires-Dist: meson
21
+ Requires-Dist: protobuf ==3.19.1
22
+ Requires-Dist: psutil
23
+ Requires-Dist: pyecharts
24
+ Requires-Dist: pyinstaller
25
+ Requires-Dist: pyopenssl <=24.1.0,>=23.2.0
26
+ Requires-Dist: pysftp
27
+ Requires-Dist: pyyaml-include
28
+ Requires-Dist: typeguard ==2.13.3
29
+
30
+ build and code generate tools