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.
- bmcgo/__init__.py +12 -0
- bmcgo/bmcgo.py +22 -0
- bmcgo/bmcgo_config.py +176 -0
- bmcgo/cli/__init__.py +10 -0
- bmcgo/cli/cli.py +584 -0
- bmcgo/codegen/__init__.py +14 -0
- bmcgo/codegen/c/__init__.py +9 -0
- bmcgo/codegen/c/annotation.py +52 -0
- bmcgo/codegen/c/argument.py +42 -0
- bmcgo/codegen/c/codegen.py +153 -0
- bmcgo/codegen/c/comment.py +22 -0
- bmcgo/codegen/c/ctype_defination.py +353 -0
- bmcgo/codegen/c/helper.py +87 -0
- bmcgo/codegen/c/interface.py +63 -0
- bmcgo/codegen/c/method.py +82 -0
- bmcgo/codegen/c/property.py +180 -0
- bmcgo/codegen/c/renderer.py +21 -0
- bmcgo/codegen/c/signal.py +64 -0
- bmcgo/codegen/c/template/client.c.mako +145 -0
- bmcgo/codegen/c/template/client.h.mako +36 -0
- bmcgo/codegen/c/template/interface.c.mako +0 -0
- bmcgo/codegen/c/template/interface.introspect.xml.mako +99 -0
- bmcgo/codegen/c/template/micro_component.c.mako +32 -0
- bmcgo/codegen/c/template/public.c.mako +228 -0
- bmcgo/codegen/c/template/public.h.mako +128 -0
- bmcgo/codegen/c/template/server.c.mako +104 -0
- bmcgo/codegen/c/template/server.h.mako +36 -0
- bmcgo/codegen/lua/.lua-format +7 -0
- bmcgo/codegen/lua/Makefile +101 -0
- bmcgo/codegen/lua/__init__.py +9 -0
- bmcgo/codegen/lua/codegen.py +171 -0
- bmcgo/codegen/lua/proto/Makefile +87 -0
- bmcgo/codegen/lua/proto/ipmi_types.proto +17 -0
- bmcgo/codegen/lua/proto/types.proto +52 -0
- bmcgo/codegen/lua/script/check_intfs.py +161 -0
- bmcgo/codegen/lua/script/dto/__init__.py +11 -0
- bmcgo/codegen/lua/script/dto/exception.py +53 -0
- bmcgo/codegen/lua/script/dto/kepler_abstract.py +47 -0
- bmcgo/codegen/lua/script/dto/options.py +33 -0
- bmcgo/codegen/lua/script/dto/print_simple.py +19 -0
- bmcgo/codegen/lua/script/dto/redfish_api.py +241 -0
- bmcgo/codegen/lua/script/dto/url_route.py +195 -0
- bmcgo/codegen/lua/script/gen_db_json.py +444 -0
- bmcgo/codegen/lua/script/gen_depends.py +89 -0
- bmcgo/codegen/lua/script/gen_entry.py +263 -0
- bmcgo/codegen/lua/script/gen_feature_json.py +156 -0
- bmcgo/codegen/lua/script/gen_historical_local_db_json.py +88 -0
- bmcgo/codegen/lua/script/gen_intf_json.py +261 -0
- bmcgo/codegen/lua/script/gen_intf_rpc_json.py +575 -0
- bmcgo/codegen/lua/script/gen_ipmi_json.py +485 -0
- bmcgo/codegen/lua/script/gen_mdb_json.py +117 -0
- bmcgo/codegen/lua/script/gen_rpc_msg_json.py +487 -0
- bmcgo/codegen/lua/script/gen_schema.py +302 -0
- bmcgo/codegen/lua/script/ipmi_types_pb2.py +135 -0
- bmcgo/codegen/lua/script/loader/__init__.py +11 -0
- bmcgo/codegen/lua/script/loader/file_utils.py +33 -0
- bmcgo/codegen/lua/script/loader/kepler_abstract_collect.py +79 -0
- bmcgo/codegen/lua/script/loader/kepler_abstract_loader.py +47 -0
- bmcgo/codegen/lua/script/loader/redfish_loader.py +127 -0
- bmcgo/codegen/lua/script/lua_format.py +62 -0
- bmcgo/codegen/lua/script/mds_util.py +385 -0
- bmcgo/codegen/lua/script/merge_model.py +330 -0
- bmcgo/codegen/lua/script/merge_proto_algo.py +85 -0
- bmcgo/codegen/lua/script/proto_loader.py +47 -0
- bmcgo/codegen/lua/script/proto_plugin.py +140 -0
- bmcgo/codegen/lua/script/redfish_source_tree.py +118 -0
- bmcgo/codegen/lua/script/render_utils/__init__.py +38 -0
- bmcgo/codegen/lua/script/render_utils/base.py +25 -0
- bmcgo/codegen/lua/script/render_utils/client_lua.py +98 -0
- bmcgo/codegen/lua/script/render_utils/controller_lua.py +71 -0
- bmcgo/codegen/lua/script/render_utils/db_lua.py +224 -0
- bmcgo/codegen/lua/script/render_utils/error_lua.py +185 -0
- bmcgo/codegen/lua/script/render_utils/factory.py +52 -0
- bmcgo/codegen/lua/script/render_utils/ipmi_lua.py +159 -0
- bmcgo/codegen/lua/script/render_utils/ipmi_message_lua.py +24 -0
- bmcgo/codegen/lua/script/render_utils/mdb_lua.py +177 -0
- bmcgo/codegen/lua/script/render_utils/mdb_register.py +215 -0
- bmcgo/codegen/lua/script/render_utils/message_lua.py +26 -0
- bmcgo/codegen/lua/script/render_utils/messages_lua.py +156 -0
- bmcgo/codegen/lua/script/render_utils/model_lua.py +485 -0
- bmcgo/codegen/lua/script/render_utils/old_model_lua.py +429 -0
- bmcgo/codegen/lua/script/render_utils/plugin_lua.py +38 -0
- bmcgo/codegen/lua/script/render_utils/redfish_proto.py +86 -0
- bmcgo/codegen/lua/script/render_utils/request_lua.py +76 -0
- bmcgo/codegen/lua/script/render_utils/service_lua.py +130 -0
- bmcgo/codegen/lua/script/render_utils/utils_message_lua.py +125 -0
- bmcgo/codegen/lua/script/render_utils/validate_lua.py +221 -0
- bmcgo/codegen/lua/script/sep_ipmi_message_cmds.py +217 -0
- bmcgo/codegen/lua/script/template.py +166 -0
- bmcgo/codegen/lua/script/types_pb2.py +516 -0
- bmcgo/codegen/lua/script/utils.py +663 -0
- bmcgo/codegen/lua/script/validate.py +80 -0
- bmcgo/codegen/lua/script/yaml_to_json.py +73 -0
- bmcgo/codegen/lua/templates/Makefile +114 -0
- bmcgo/codegen/lua/templates/apps/Makefile +261 -0
- bmcgo/codegen/lua/templates/apps/Makefile.mdb.mk +64 -0
- bmcgo/codegen/lua/templates/apps/app.lua.mako +19 -0
- bmcgo/codegen/lua/templates/apps/class.lua.mako +35 -0
- bmcgo/codegen/lua/templates/apps/client.lua.mako +429 -0
- bmcgo/codegen/lua/templates/apps/controller.lua.mako +276 -0
- bmcgo/codegen/lua/templates/apps/datas.lua.mako +8 -0
- bmcgo/codegen/lua/templates/apps/db.lua.mako +89 -0
- bmcgo/codegen/lua/templates/apps/entry.lua.mako +128 -0
- bmcgo/codegen/lua/templates/apps/feature.lua.mako +37 -0
- bmcgo/codegen/lua/templates/apps/generate_route.mako +25 -0
- bmcgo/codegen/lua/templates/apps/impl_feature.lua.mako +72 -0
- bmcgo/codegen/lua/templates/apps/ipmi.lua.mako +97 -0
- bmcgo/codegen/lua/templates/apps/ipmi_cmd.lua.mako +18 -0
- bmcgo/codegen/lua/templates/apps/ipmi_message.lua.mako +36 -0
- bmcgo/codegen/lua/templates/apps/local_db.lua.mako +263 -0
- bmcgo/codegen/lua/templates/apps/main.lua.mako +25 -0
- bmcgo/codegen/lua/templates/apps/mc.lua.mako +77 -0
- bmcgo/codegen/lua/templates/apps/mdb.lua.mako +45 -0
- bmcgo/codegen/lua/templates/apps/mdb_interface.lua.mako +73 -0
- bmcgo/codegen/lua/templates/apps/message.lua.mako +38 -0
- bmcgo/codegen/lua/templates/apps/model.lua.mako +239 -0
- bmcgo/codegen/lua/templates/apps/orm_classes.lua.mako +16 -0
- bmcgo/codegen/lua/templates/apps/plugin.lua.mako +8 -0
- bmcgo/codegen/lua/templates/apps/redfish.proto.mako +47 -0
- bmcgo/codegen/lua/templates/apps/service.lua.mako +440 -0
- bmcgo/codegen/lua/templates/apps/signal_listen.lua.mako +19 -0
- bmcgo/codegen/lua/templates/apps/utils/default_intf.lua.mako +41 -0
- bmcgo/codegen/lua/templates/apps/utils/enum.mako +10 -0
- bmcgo/codegen/lua/templates/apps/utils/imports.mako +13 -0
- bmcgo/codegen/lua/templates/apps/utils/mdb_intf.lua.mako +25 -0
- bmcgo/codegen/lua/templates/apps/utils/mdb_obj.lua.mako +23 -0
- bmcgo/codegen/lua/templates/apps/utils/message.mako +160 -0
- bmcgo/codegen/lua/templates/apps/utils/request.lua.mako +59 -0
- bmcgo/codegen/lua/templates/apps/utils/validate.mako +83 -0
- bmcgo/codegen/lua/templates/errors.lua.mako +36 -0
- bmcgo/codegen/lua/templates/messages.lua.mako +32 -0
- bmcgo/codegen/lua/templates/new_app/.clang-format.mako +170 -0
- bmcgo/codegen/lua/templates/new_app/.gitignore.mako +26 -0
- bmcgo/codegen/lua/templates/new_app/CHANGELOG.md.mako +0 -0
- bmcgo/codegen/lua/templates/new_app/CMakeLists.txt.mako +29 -0
- bmcgo/codegen/lua/templates/new_app/Makefile.mako +25 -0
- bmcgo/codegen/lua/templates/new_app/README.md.mako +0 -0
- bmcgo/codegen/lua/templates/new_app/conanfile.py.mako +7 -0
- bmcgo/codegen/lua/templates/new_app/config.cfg.mako +6 -0
- bmcgo/codegen/lua/templates/new_app/mds/model.json.mako +3 -0
- bmcgo/codegen/lua/templates/new_app/mds/service.json.mako +21 -0
- bmcgo/codegen/lua/templates/new_app/permissions.ini.mako +16 -0
- bmcgo/codegen/lua/templates/new_app/src/lualib/${project_name}_app.lua.mako +16 -0
- bmcgo/codegen/lua/templates/new_app/src/service/main.lua.mako +25 -0
- bmcgo/codegen/lua/templates/new_app/test/integration/test_${project_name}.conf.mako +9 -0
- bmcgo/codegen/lua/templates/new_app/test/integration/test_${project_name}.lua.mako +47 -0
- bmcgo/codegen/lua/templates/new_app/test/unit/test.lua.mako +23 -0
- bmcgo/codegen/lua/templates/new_app/user_conf/rootfs/etc/systemd/system/${project_name}.service.mako +18 -0
- bmcgo/codegen/lua/templates/new_app/user_conf/rootfs/etc/systemd/system/multi-user.target.wants/${project_name}.service.link +1 -0
- bmcgo/component/__init__.py +10 -0
- bmcgo/component/analysis/analysis.py +183 -0
- bmcgo/component/analysis/build_deps.py +165 -0
- bmcgo/component/analysis/data_deps.py +333 -0
- bmcgo/component/analysis/dep-rules.json +912 -0
- bmcgo/component/analysis/dep_node.py +110 -0
- bmcgo/component/analysis/intf_deps.py +163 -0
- bmcgo/component/analysis/intf_validation.py +254 -0
- bmcgo/component/analysis/rule.py +211 -0
- bmcgo/component/analysis/smc_dfx_whitelist.json +11 -0
- bmcgo/component/analysis/sr_validation.py +391 -0
- bmcgo/component/build.py +222 -0
- bmcgo/component/component_dt_version_parse.py +348 -0
- bmcgo/component/component_helper.py +114 -0
- bmcgo/component/coverage/__init__.py +11 -0
- bmcgo/component/coverage/c_incremental_cov_report.template +53 -0
- bmcgo/component/coverage/incremental_cov.py +464 -0
- bmcgo/component/deploy.py +110 -0
- bmcgo/component/gen.py +169 -0
- bmcgo/component/package_info.py +236 -0
- bmcgo/component/template/conanbase.py.mako +278 -0
- bmcgo/component/template/conanfile.deploy.py.mako +40 -0
- bmcgo/component/test.py +947 -0
- bmcgo/errors.py +119 -0
- bmcgo/frame.py +217 -0
- bmcgo/functional/__init__.py +10 -0
- bmcgo/functional/analysis.py +96 -0
- bmcgo/functional/bmc_studio_action.py +98 -0
- bmcgo/functional/check.py +185 -0
- bmcgo/functional/conan_index_build.py +251 -0
- bmcgo/functional/config.py +332 -0
- bmcgo/functional/csr_build.py +724 -0
- bmcgo/functional/deploy.py +263 -0
- bmcgo/functional/diff.py +235 -0
- bmcgo/functional/fetch.py +235 -0
- bmcgo/functional/full_component.py +391 -0
- bmcgo/functional/maintain.py +381 -0
- bmcgo/functional/new.py +166 -0
- bmcgo/functional/schema_valid.py +111 -0
- bmcgo/functional/simple_sign.py +104 -0
- bmcgo/functional/upgrade.py +78 -0
- bmcgo/ipmigen/__init__.py +13 -0
- bmcgo/ipmigen/ctype_defination.py +82 -0
- bmcgo/ipmigen/ipmigen.py +309 -0
- bmcgo/ipmigen/template/cmd.c.mako +366 -0
- bmcgo/ipmigen/template/ipmi.c.mako +25 -0
- bmcgo/ipmigen/template/ipmi.h.mako +51 -0
- bmcgo/logger.py +176 -0
- bmcgo/misc.py +117 -0
- bmcgo/target/app.yml +17 -0
- bmcgo/target/install_sdk.yml +15 -0
- bmcgo/target/personal.yml +53 -0
- bmcgo/target/publish.yml +45 -0
- bmcgo/tasks/__init__.py +11 -0
- bmcgo/tasks/download_buildtools_hm.py +124 -0
- bmcgo/tasks/misc.py +15 -0
- bmcgo/tasks/task.py +354 -0
- bmcgo/tasks/task_build_conan.py +714 -0
- bmcgo/tasks/task_build_rootfs_img.py +595 -0
- bmcgo/tasks/task_buildgppbin.py +88 -0
- bmcgo/tasks/task_buildhpm_ext4.py +82 -0
- bmcgo/tasks/task_create_interface_config.py +122 -0
- bmcgo/tasks/task_download_buildtools.py +99 -0
- bmcgo/tasks/task_download_dependency.py +72 -0
- bmcgo/tasks/task_hpm_envir_prepare.py +112 -0
- bmcgo/tasks/task_packet_to_supporte.py +87 -0
- bmcgo/tasks/task_prepare.py +105 -0
- bmcgo/tasks/task_sign_and_pack_hpm.py +42 -0
- bmcgo/utils/__init__.py +10 -0
- bmcgo/utils/buffer.py +128 -0
- bmcgo/utils/combine_json_schemas.py +170 -0
- bmcgo/utils/component_post.py +54 -0
- bmcgo/utils/component_version_check.py +86 -0
- bmcgo/utils/config.py +1067 -0
- bmcgo/utils/fetch_component_code.py +232 -0
- bmcgo/utils/install_manager.py +61 -0
- bmcgo/utils/installations/__init__.py +10 -0
- bmcgo/utils/installations/base_installer.py +70 -0
- bmcgo/utils/installations/install_consts.py +30 -0
- bmcgo/utils/installations/install_plans/bingo.yml +11 -0
- bmcgo/utils/installations/install_workflow.py +50 -0
- bmcgo/utils/installations/installers/apt_installer.py +177 -0
- bmcgo/utils/installations/installers/pip_installer.py +46 -0
- bmcgo/utils/installations/version_util.py +100 -0
- bmcgo/utils/mapping_config_patch.py +443 -0
- bmcgo/utils/perf_analysis.py +114 -0
- bmcgo/utils/tools.py +704 -0
- bmcgo/worker.py +417 -0
- openubmc_bingo-0.5.240.dist-info/METADATA +30 -0
- openubmc_bingo-0.5.240.dist-info/RECORD +242 -0
- openubmc_bingo-0.5.240.dist-info/WHEEL +5 -0
- openubmc_bingo-0.5.240.dist-info/entry_points.txt +2 -0
- 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
|