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
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
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
|
+
from enum import Enum
|
|
14
|
+
|
|
15
|
+
from bmcgo.component.analysis.dep_node import DepNode
|
|
16
|
+
from bmcgo.logger import Logger
|
|
17
|
+
|
|
18
|
+
global log
|
|
19
|
+
log = Logger()
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class SubSys():
|
|
23
|
+
def __init__(self, level: int):
|
|
24
|
+
self.level = level
|
|
25
|
+
self.apps: list[str] = []
|
|
26
|
+
self.libraries: list[str] = []
|
|
27
|
+
self.tools: list[str] = []
|
|
28
|
+
self.configurations: list[str] = []
|
|
29
|
+
self.commands: list[str] = []
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class DepExcept():
|
|
33
|
+
def __init__(self, obj):
|
|
34
|
+
self.tag = obj.get("tag")
|
|
35
|
+
self.operator = obj.get("op")
|
|
36
|
+
self.value = obj.get("value", [])
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class DepWhen():
|
|
40
|
+
def __init__(self, obj):
|
|
41
|
+
self.tag = obj.get("tag")
|
|
42
|
+
self.operator = obj.get("op")
|
|
43
|
+
self.value = obj.get("value", [])
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class DepRuleType(Enum):
|
|
47
|
+
SUBSYSTEM_DEP = 1
|
|
48
|
+
INTERFACE_DEP = 2
|
|
49
|
+
BUILD_DEP = 3
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class Rule():
|
|
53
|
+
def __init__(self, rule_type: DepRuleType, obj):
|
|
54
|
+
self.rule_type = rule_type
|
|
55
|
+
self.from_key = obj.get("from")
|
|
56
|
+
self.to_key = obj.get("to")
|
|
57
|
+
self.description = obj.get("description")
|
|
58
|
+
self.message = obj.get("message")
|
|
59
|
+
if not self.from_key or not self.to_key:
|
|
60
|
+
log.error("无法从 json 对象中获取 'from' 或 'to'")
|
|
61
|
+
self.whe = None
|
|
62
|
+
self.excpt = None
|
|
63
|
+
excpt = obj.get("except")
|
|
64
|
+
if excpt:
|
|
65
|
+
self.excpt = DepExcept(excpt)
|
|
66
|
+
whe = obj.get("when")
|
|
67
|
+
if whe:
|
|
68
|
+
self.whe = DepWhen(whe)
|
|
69
|
+
|
|
70
|
+
# 检查src和tgt是否适用当前的规则
|
|
71
|
+
def match_rule(self, src: DepNode, tgt: DepNode):
|
|
72
|
+
from_matched = self.from_key == "*" or self.from_key in src.package_type
|
|
73
|
+
to_matched = self.to_key == "*" or self.to_key in tgt.package_type
|
|
74
|
+
return from_matched and to_matched
|
|
75
|
+
|
|
76
|
+
# 检查from_key和to_key是否适用当前的规则
|
|
77
|
+
def match_rule(self, from_key: str, to_key: str):
|
|
78
|
+
from_matched = self.from_key == "*" or self.from_key == from_key
|
|
79
|
+
to_matched = self.to_key == "*" or self.to_key == to_key
|
|
80
|
+
return from_matched and to_matched
|
|
81
|
+
|
|
82
|
+
def build_dep_check(self, src: DepNode, tgt: DepNode):
|
|
83
|
+
if self.rule_type != DepRuleType.BUILD_DEP:
|
|
84
|
+
return False
|
|
85
|
+
return not self.whe
|
|
86
|
+
|
|
87
|
+
def subsystem_dep_check(self, src: DepNode, tgt: DepNode, intf: str):
|
|
88
|
+
if self.rule_type != DepRuleType.SUBSYSTEM_DEP:
|
|
89
|
+
return False
|
|
90
|
+
if self.from_key != src.subsys_name or self.to_key != tgt.subsys_name:
|
|
91
|
+
return False
|
|
92
|
+
if not self.excpt:
|
|
93
|
+
return True
|
|
94
|
+
# Currently the input rule only defines one single exception
|
|
95
|
+
return self.excpt.tag == "Interface" and self.excpt.operator == "oneOf" and intf not in self.excpt.value
|
|
96
|
+
|
|
97
|
+
def intf_dep_check(self, src: DepNode, tgt: DepNode, intf: str):
|
|
98
|
+
if self.rule_type != DepRuleType.INTERFACE_DEP:
|
|
99
|
+
return False
|
|
100
|
+
if self.from_key != src.package_name or self.to_key != tgt.package_name:
|
|
101
|
+
return False
|
|
102
|
+
if not self.excpt:
|
|
103
|
+
return True
|
|
104
|
+
return self.excpt.tag == "Interface" and self.excpt.operator == "oneOf" and intf not in self.excpt.value
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
class Rules():
|
|
108
|
+
def __init__(self, obj, allow: bool):
|
|
109
|
+
self.description = obj.get("description", "")
|
|
110
|
+
self.subsystem_deps: list[Rule] = []
|
|
111
|
+
self.interface_deps: list[Rule] = []
|
|
112
|
+
self.build_rules: list[Rule] = []
|
|
113
|
+
self.allow = allow
|
|
114
|
+
|
|
115
|
+
for rule in obj.get("SubsystemDeps", []):
|
|
116
|
+
self.subsystem_deps.append(Rule(DepRuleType.SUBSYSTEM_DEP, rule))
|
|
117
|
+
|
|
118
|
+
for sub in obj.get("IntfDeps", []):
|
|
119
|
+
for rules in sub.values():
|
|
120
|
+
for rule in rules:
|
|
121
|
+
self.interface_deps.append(Rule(DepRuleType.INTERFACE_DEP, rule))
|
|
122
|
+
|
|
123
|
+
for rule in obj.get("BuildDeps", []):
|
|
124
|
+
self.build_rules.append(Rule(DepRuleType.BUILD_DEP, rule))
|
|
125
|
+
|
|
126
|
+
# Check if the interface dependency between two packages is allowed based on the rules
|
|
127
|
+
def intf_dep_check(self, src: DepNode, tgt: DepNode, intf: str):
|
|
128
|
+
# Whitelist rules
|
|
129
|
+
if self.allow:
|
|
130
|
+
return self._intf_dep_check_whitelist(src, tgt, intf)
|
|
131
|
+
|
|
132
|
+
# Blacklist rules
|
|
133
|
+
return self._intf_dep_check_blacklist(src, tgt, intf)
|
|
134
|
+
|
|
135
|
+
def build_dep_check(self, src: DepNode, tgt: DepNode):
|
|
136
|
+
# Whitelist rules
|
|
137
|
+
if self.allow:
|
|
138
|
+
return self._build_dep_check_whitelist(src, tgt)
|
|
139
|
+
|
|
140
|
+
# Blacklist rules
|
|
141
|
+
return self._build_dep_check_blacklist(src, tgt)
|
|
142
|
+
|
|
143
|
+
def _intf_dep_check_whitelist(self, src: DepNode, tgt: DepNode, intf: str):
|
|
144
|
+
if src.package_name in ['event', 'sensor']:
|
|
145
|
+
return True
|
|
146
|
+
# Check the subsystem rules first and then interface rules
|
|
147
|
+
subsys_allowed = False
|
|
148
|
+
for rule in self.subsystem_deps:
|
|
149
|
+
if rule.subsystem_dep_check(src, tgt, intf):
|
|
150
|
+
subsys_allowed = True
|
|
151
|
+
break
|
|
152
|
+
|
|
153
|
+
if src.subsys_name != tgt.subsys_name or not subsys_allowed:
|
|
154
|
+
return subsys_allowed
|
|
155
|
+
|
|
156
|
+
intf_allowed = False
|
|
157
|
+
for rule in self.interface_deps:
|
|
158
|
+
if rule.intf_dep_check(src, tgt, intf):
|
|
159
|
+
intf_allowed = True
|
|
160
|
+
break
|
|
161
|
+
return intf_allowed
|
|
162
|
+
|
|
163
|
+
def _intf_dep_check_blacklist(self, src: DepNode, tgt: DepNode, intf: str):
|
|
164
|
+
subsys_unallowed = False
|
|
165
|
+
for rule in self.subsystem_deps:
|
|
166
|
+
if rule.subsystem_dep_check(src, tgt, intf):
|
|
167
|
+
subsys_unallowed = True
|
|
168
|
+
break
|
|
169
|
+
if src.subsys_name != tgt.subsys_name or subsys_unallowed:
|
|
170
|
+
return not subsys_unallowed
|
|
171
|
+
|
|
172
|
+
intf_unallowed = False
|
|
173
|
+
for rule in self.interface_deps:
|
|
174
|
+
if rule.intf_dep_check(src, tgt, intf):
|
|
175
|
+
intf_unallowed = True
|
|
176
|
+
break
|
|
177
|
+
return not intf_unallowed
|
|
178
|
+
|
|
179
|
+
def _build_dep_check_whitelist(self, src: DepNode, tgt: DepNode):
|
|
180
|
+
for rule in self.build_rules:
|
|
181
|
+
# 跳过不适用的规则
|
|
182
|
+
if not rule.match_rule(src, tgt):
|
|
183
|
+
continue
|
|
184
|
+
result = rule.build_dep_check(src, tgt)
|
|
185
|
+
# 白名单有一个匹配就满足
|
|
186
|
+
if result:
|
|
187
|
+
return True
|
|
188
|
+
# 白名单都不匹配时不满足
|
|
189
|
+
return False
|
|
190
|
+
|
|
191
|
+
def _match_rule(self, src: DepNode, tgt: DepNode, from_key: str, to_key: str):
|
|
192
|
+
for rule in self.build_rules:
|
|
193
|
+
if not rule.match_rule(from_key, to_key):
|
|
194
|
+
continue
|
|
195
|
+
if rule.build_dep_check(src, tgt):
|
|
196
|
+
return True
|
|
197
|
+
|
|
198
|
+
return False
|
|
199
|
+
|
|
200
|
+
def _build_dep_check_blacklist(self, src: DepNode, tgt: DepNode):
|
|
201
|
+
# 未配置黑名单时默认满足
|
|
202
|
+
if not bool(self.build_rules):
|
|
203
|
+
return True
|
|
204
|
+
|
|
205
|
+
# 源组件和目标组件只要有一组类型不在黑名单内就满足
|
|
206
|
+
for from_key in src.package_type:
|
|
207
|
+
for to_key in tgt.package_type:
|
|
208
|
+
if not self._match_rule(src, tgt, from_key, to_key):
|
|
209
|
+
return True
|
|
210
|
+
|
|
211
|
+
return False
|
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
#!/usr/bin/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
|
+
import json
|
|
14
|
+
import os
|
|
15
|
+
import stat
|
|
16
|
+
import re
|
|
17
|
+
from collections import defaultdict
|
|
18
|
+
from pathlib import Path
|
|
19
|
+
from typing import Dict, List
|
|
20
|
+
from colorama import Fore, Style
|
|
21
|
+
from bmcgo.logger import Logger
|
|
22
|
+
|
|
23
|
+
global log
|
|
24
|
+
log = Logger()
|
|
25
|
+
|
|
26
|
+
SOFT_SR_SUFFIX = "_soft.sr"
|
|
27
|
+
SOFTWARE_SUFFIX = "software"
|
|
28
|
+
CHIP_KEY = "Chip"
|
|
29
|
+
LEVEL_ERROR = "error"
|
|
30
|
+
LEVEL_WARNING = "warning"
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class DirectedGraph:
|
|
34
|
+
VISITING = 1
|
|
35
|
+
VISITED = 2
|
|
36
|
+
|
|
37
|
+
def __init__(self):
|
|
38
|
+
self.edges = defaultdict(set)
|
|
39
|
+
self.flags = dict()
|
|
40
|
+
|
|
41
|
+
def add_edge(self, node_from: str, node_to: str):
|
|
42
|
+
self.edges[node_from].add(node_to)
|
|
43
|
+
|
|
44
|
+
def has_edge(self, node_from: str, node_to: str):
|
|
45
|
+
return node_to in self.edges[node_from]
|
|
46
|
+
|
|
47
|
+
def remove_edge(self, node_from: str, node_to: str):
|
|
48
|
+
self.edges[node_from].discard(node_to)
|
|
49
|
+
|
|
50
|
+
def check_loop(self):
|
|
51
|
+
for node in self.edges:
|
|
52
|
+
if node in self.flags:
|
|
53
|
+
continue
|
|
54
|
+
route = [node]
|
|
55
|
+
if self.depth_first_search(node, route):
|
|
56
|
+
return route
|
|
57
|
+
return []
|
|
58
|
+
|
|
59
|
+
def depth_first_search(self, node: str, route: List[str]):
|
|
60
|
+
if node not in self.edges:
|
|
61
|
+
self.flags[node] = self.VISITED
|
|
62
|
+
return False
|
|
63
|
+
self.flags[node] = self.VISITING
|
|
64
|
+
for child in self.edges[node]:
|
|
65
|
+
route.append(child)
|
|
66
|
+
if child not in self.flags:
|
|
67
|
+
if self.depth_first_search(child, route):
|
|
68
|
+
return True
|
|
69
|
+
elif self.flags[child] == self.VISITING:
|
|
70
|
+
return True
|
|
71
|
+
route.pop()
|
|
72
|
+
self.flags[node] = self.VISITED
|
|
73
|
+
return False
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
class SrParser:
|
|
77
|
+
def __init__(self, sr_dir: str):
|
|
78
|
+
self.issues_report = defaultdict(set)
|
|
79
|
+
self.sr_dir = sr_dir
|
|
80
|
+
|
|
81
|
+
@staticmethod
|
|
82
|
+
def get_obj_name(prop_val: str):
|
|
83
|
+
obj_prop = prop_val.split('/', 1)[1]
|
|
84
|
+
obj_name = obj_prop.split('.', 1)[0]
|
|
85
|
+
if SrParser.is_sync(prop_val) and obj_name.startswith('::'):
|
|
86
|
+
return obj_name[2:]
|
|
87
|
+
return obj_name
|
|
88
|
+
|
|
89
|
+
@staticmethod
|
|
90
|
+
def get_class_name(obj_name: str):
|
|
91
|
+
return obj_name.split('_', 1)[0]
|
|
92
|
+
|
|
93
|
+
@staticmethod
|
|
94
|
+
def is_ref(prop_val: str):
|
|
95
|
+
return prop_val.startswith("#/")
|
|
96
|
+
|
|
97
|
+
@staticmethod
|
|
98
|
+
def is_sync(prop_val: str):
|
|
99
|
+
return prop_val.startswith("<=/")
|
|
100
|
+
|
|
101
|
+
@staticmethod
|
|
102
|
+
def get_prop_name(prop_val: str):
|
|
103
|
+
if '.' not in prop_val:
|
|
104
|
+
return ""
|
|
105
|
+
ret = prop_val.split('.', 2)[1]
|
|
106
|
+
if "|>" in ret:
|
|
107
|
+
ret = ret.split("|>", 1)[0].strip()
|
|
108
|
+
return ret
|
|
109
|
+
|
|
110
|
+
@staticmethod
|
|
111
|
+
def get_logger(level: str):
|
|
112
|
+
if level == 'error':
|
|
113
|
+
return log.error
|
|
114
|
+
if level == 'warning':
|
|
115
|
+
return log.warning
|
|
116
|
+
return log.info
|
|
117
|
+
|
|
118
|
+
@staticmethod
|
|
119
|
+
def get_log_color(level: str):
|
|
120
|
+
if level == 'error':
|
|
121
|
+
return Fore.RED
|
|
122
|
+
if level == 'warning':
|
|
123
|
+
return Fore.YELLOW
|
|
124
|
+
return Fore.WHITE
|
|
125
|
+
|
|
126
|
+
@staticmethod
|
|
127
|
+
def log_issue(sr_path: str, level: str, msg: str):
|
|
128
|
+
logger = SrParser.get_logger(level)
|
|
129
|
+
if 'CLOUD_BUILD_RECORD_ID' in os.environ:
|
|
130
|
+
logger("%s: %s: %s", sr_path, level, msg)
|
|
131
|
+
else:
|
|
132
|
+
color = SrParser.get_log_color(level)
|
|
133
|
+
logger("%s: %s: %s%s%s", sr_path, level, color, msg, Style.RESET_ALL)
|
|
134
|
+
|
|
135
|
+
def log_issues(self, issues_log_path=None):
|
|
136
|
+
file_count = 0
|
|
137
|
+
problems_total = 0
|
|
138
|
+
issues_count = defaultdict(int)
|
|
139
|
+
issues_content = ''
|
|
140
|
+
for sr_path, issues in self.issues_report.items():
|
|
141
|
+
if not issues:
|
|
142
|
+
continue
|
|
143
|
+
file_count += 1
|
|
144
|
+
for level, msg in issues:
|
|
145
|
+
problems_total += (level == LEVEL_ERROR or level == LEVEL_WARNING)
|
|
146
|
+
issues_count[level] += 1
|
|
147
|
+
issues_content += f'{sr_path}: {level}: {msg}\n'
|
|
148
|
+
if issues_log_path is None or level == LEVEL_ERROR:
|
|
149
|
+
self.log_issue(sr_path, level, msg)
|
|
150
|
+
if issues_log_path is not None:
|
|
151
|
+
msg = f"Finished data dependency analysis: found {problems_total} issues in {file_count} files"
|
|
152
|
+
if issues_count[LEVEL_ERROR]:
|
|
153
|
+
msg += f', errors: {issues_count[LEVEL_ERROR]}'
|
|
154
|
+
if issues_count[LEVEL_WARNING]:
|
|
155
|
+
msg += f', warnings: {issues_count[LEVEL_WARNING]}'
|
|
156
|
+
issues_content += msg
|
|
157
|
+
with os.fdopen(os.open(issues_log_path, os.O_WRONLY | os.O_CREAT | os.O_TRUNC,
|
|
158
|
+
stat.S_IWUSR | stat.S_IRUSR), 'w') as fp:
|
|
159
|
+
fp.write(issues_content)
|
|
160
|
+
return file_count, problems_total, issues_count
|
|
161
|
+
|
|
162
|
+
def walk_sr_dir(self):
|
|
163
|
+
for root, _, files in os.walk(self.sr_dir):
|
|
164
|
+
for file in files:
|
|
165
|
+
if not file.endswith(".sr"):
|
|
166
|
+
continue
|
|
167
|
+
self.load_sr(os.path.join(root, file))
|
|
168
|
+
|
|
169
|
+
def load_sr(self, sr_path: str):
|
|
170
|
+
relpath = os.path.relpath(sr_path, self.sr_dir)
|
|
171
|
+
with open(sr_path, 'r') as file_descriptor:
|
|
172
|
+
try:
|
|
173
|
+
sr_content = json.load(file_descriptor)
|
|
174
|
+
except json.decoder.JSONDecodeError as error:
|
|
175
|
+
self.issues_report[relpath].add(("error", f"格式错误: {error.msg}"))
|
|
176
|
+
except Exception as error:
|
|
177
|
+
self.issues_report[relpath].add(("error", f"解析失败: {error}"))
|
|
178
|
+
else:
|
|
179
|
+
self.parse_sr(relpath, sr_content)
|
|
180
|
+
|
|
181
|
+
def parse_sr(self, relpath: str, sr_content: Dict):
|
|
182
|
+
# 由子类实现
|
|
183
|
+
pass
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
class SrValidate(SrParser):
|
|
187
|
+
def __init__(self, sr_dir: str):
|
|
188
|
+
super().__init__(sr_dir)
|
|
189
|
+
self.sr_objs: Dict[str, Dict[str, Dict]] = dict()
|
|
190
|
+
self.objects_used = defaultdict(set)
|
|
191
|
+
self.soft_sr_objects = defaultdict(dict)
|
|
192
|
+
self.soft_sr_files = dict()
|
|
193
|
+
self.is_sr_repo = False
|
|
194
|
+
self.is_product_sr_repo = False
|
|
195
|
+
self.check_repo_type()
|
|
196
|
+
self.smc_dfx_whitelist: Dict[str, List[Dict[str, int]]] = defaultdict(list)
|
|
197
|
+
self.load_smc_dfx_whitelist()
|
|
198
|
+
|
|
199
|
+
@staticmethod
|
|
200
|
+
def merge_sr_objects(hardware_sr_objects: Dict[str, Dict], software_sr_objects: Dict[str, Dict]):
|
|
201
|
+
for obj_name, obj_data in software_sr_objects.items():
|
|
202
|
+
if obj_name not in hardware_sr_objects:
|
|
203
|
+
hardware_sr_objects[obj_name] = obj_data
|
|
204
|
+
continue
|
|
205
|
+
for prop_name, prop_data in obj_data.items():
|
|
206
|
+
if prop_name in hardware_sr_objects[obj_name]:
|
|
207
|
+
continue
|
|
208
|
+
hardware_sr_objects[obj_name][prop_name] = prop_data
|
|
209
|
+
|
|
210
|
+
@staticmethod
|
|
211
|
+
def get_uid(sr_objects: Dict[str, Dict]):
|
|
212
|
+
tianchi_uid = ""
|
|
213
|
+
for obj_name, obj_data in sr_objects.items():
|
|
214
|
+
class_name = SrParser.get_class_name(obj_name)
|
|
215
|
+
uid = obj_data.get("UID")
|
|
216
|
+
if class_name == 'SRUpgrade' and uid:
|
|
217
|
+
# 优先返回SRUpgrade对象下配置的UID
|
|
218
|
+
return uid
|
|
219
|
+
tianchi_data = obj_data.get("bmc.dev.Board.TianChi")
|
|
220
|
+
if isinstance(tianchi_data, dict) and not tianchi_uid:
|
|
221
|
+
inner_uid = tianchi_data.get("UID")
|
|
222
|
+
if inner_uid:
|
|
223
|
+
tianchi_uid = inner_uid
|
|
224
|
+
elif uid:
|
|
225
|
+
tianchi_uid = uid
|
|
226
|
+
# 找不到SRUpgrade对象下配置的UID后,再返回按设备树方案查找的UID
|
|
227
|
+
return tianchi_uid
|
|
228
|
+
|
|
229
|
+
@staticmethod
|
|
230
|
+
def get_chip_ref(obj_data: Dict):
|
|
231
|
+
value = obj_data.get(CHIP_KEY)
|
|
232
|
+
if not isinstance(value, str) or not SrParser.is_ref(value):
|
|
233
|
+
return ""
|
|
234
|
+
return value[2:]
|
|
235
|
+
|
|
236
|
+
def check_repo_type(self):
|
|
237
|
+
service_path = os.path.join(self.sr_dir, 'mds/service.json')
|
|
238
|
+
try:
|
|
239
|
+
with open(service_path, 'r') as file_descriptor:
|
|
240
|
+
content = json.load(file_descriptor)
|
|
241
|
+
project_name = content.get('name')
|
|
242
|
+
if project_name in ['vpd', 'TaiShanServer2.9.0_CSR', 'TS900-K2_5.0.0_CSR']:
|
|
243
|
+
self.is_sr_repo = True
|
|
244
|
+
self.is_product_sr_repo = (project_name != 'vpd')
|
|
245
|
+
except Exception as e:
|
|
246
|
+
log.error('mds/service.json 文件解析失败: %s', e)
|
|
247
|
+
|
|
248
|
+
def load_smc_dfx_whitelist(self):
|
|
249
|
+
whitelist_file = Path(__file__).parent.joinpath("smc_dfx_whitelist.json")
|
|
250
|
+
if not os.path.exists(whitelist_file):
|
|
251
|
+
return
|
|
252
|
+
try:
|
|
253
|
+
with open(whitelist_file, 'r') as file_descriptor:
|
|
254
|
+
content = json.load(file_descriptor)
|
|
255
|
+
for item in content:
|
|
256
|
+
self.smc_dfx_whitelist[item.get("UID")] = item.get("Scanners")
|
|
257
|
+
except Exception as e:
|
|
258
|
+
log.error('smc_dfx_whitelist.json 文件解析失败: %s', e)
|
|
259
|
+
|
|
260
|
+
def run(self):
|
|
261
|
+
if not self.is_sr_repo:
|
|
262
|
+
return True
|
|
263
|
+
self.find_soft_sr_files()
|
|
264
|
+
self.walk_sr_dir()
|
|
265
|
+
file_count, problems_total, issues_count = self.log_issues()
|
|
266
|
+
msg = f"Finished SR analysis: found {problems_total} issues in {file_count} files"
|
|
267
|
+
if issues_count["error"]:
|
|
268
|
+
msg += f', errors: {issues_count["error"]}'
|
|
269
|
+
if issues_count["warning"]:
|
|
270
|
+
msg += f', warnings: {issues_count["warning"]}'
|
|
271
|
+
log.info(msg)
|
|
272
|
+
if problems_total == 0:
|
|
273
|
+
log.info("sr 校验通过")
|
|
274
|
+
else:
|
|
275
|
+
log.error("sr 校验失败")
|
|
276
|
+
return problems_total == 0
|
|
277
|
+
|
|
278
|
+
def find_soft_sr_files(self):
|
|
279
|
+
for root, _, files in os.walk(self.sr_dir):
|
|
280
|
+
for file in files:
|
|
281
|
+
if not file.endswith(SOFT_SR_SUFFIX):
|
|
282
|
+
continue
|
|
283
|
+
hard_sr_name = f"{file[:-len(SOFT_SR_SUFFIX)]}.sr"
|
|
284
|
+
soft_sr_path = os.path.join(root, file)
|
|
285
|
+
hard_sr_path = os.path.join(root, hard_sr_name)
|
|
286
|
+
if not os.path.exists(hard_sr_path) and root.endswith(SOFTWARE_SUFFIX):
|
|
287
|
+
hard_sr_path = os.path.join(root[:-len(SOFTWARE_SUFFIX)], "src", hard_sr_name)
|
|
288
|
+
self.soft_sr_files[hard_sr_path] = soft_sr_path
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
def get_soft_sr_objects(self, relpath):
|
|
292
|
+
sr_path = os.path.join(self.sr_dir, relpath)
|
|
293
|
+
if sr_path not in self.soft_sr_files:
|
|
294
|
+
return {}
|
|
295
|
+
|
|
296
|
+
soft_sr_path = self.soft_sr_files[sr_path]
|
|
297
|
+
if not os.path.exists(soft_sr_path):
|
|
298
|
+
return {}
|
|
299
|
+
try:
|
|
300
|
+
with open(soft_sr_path, 'r') as file_descriptor:
|
|
301
|
+
content = json.load(file_descriptor)
|
|
302
|
+
return content.get("Objects", {})
|
|
303
|
+
except Exception as e:
|
|
304
|
+
log.error('sr 文件 %s 解析失败: %s', soft_sr_path, e)
|
|
305
|
+
return {}
|
|
306
|
+
|
|
307
|
+
def parse_sr(self, relpath: str, sr_content: Dict):
|
|
308
|
+
if relpath.endswith(SOFT_SR_SUFFIX):
|
|
309
|
+
return
|
|
310
|
+
objs = sr_content.get("Objects", {})
|
|
311
|
+
self.merge_sr_objects(objs, self.get_soft_sr_objects(relpath))
|
|
312
|
+
self.sr_objs[relpath] = objs
|
|
313
|
+
self.check_smc_dfx_info(relpath)
|
|
314
|
+
if self.is_product_sr_repo:
|
|
315
|
+
return
|
|
316
|
+
|
|
317
|
+
for obj_name, obj_data in objs.items():
|
|
318
|
+
for key, value in obj_data.items():
|
|
319
|
+
if isinstance(value, str):
|
|
320
|
+
self.parse_prop_val(obj_name, key, value, relpath)
|
|
321
|
+
|
|
322
|
+
if "ManagementTopology" in sr_content:
|
|
323
|
+
self.check_topology(sr_content["ManagementTopology"], relpath)
|
|
324
|
+
|
|
325
|
+
def parse_prop_val(self, obj_name: str, prop_key: str, prop_val: str, relpath: str):
|
|
326
|
+
for global_sign, target_obj in re.findall(re.compile("(?:<=|#)\/(:*)(\w+)"), prop_val):
|
|
327
|
+
self.objects_used[relpath].add(target_obj)
|
|
328
|
+
if not global_sign and target_obj not in self.sr_objs[relpath]:
|
|
329
|
+
self.issues_report[relpath].add(("error",
|
|
330
|
+
f"'{obj_name}.{prop_key}'同步或引用的对象'{target_obj}'没有在Objects中定义"))
|
|
331
|
+
if not self.is_ref(prop_val) and not self.is_sync(prop_val):
|
|
332
|
+
return
|
|
333
|
+
|
|
334
|
+
for val in prop_val.split(';'):
|
|
335
|
+
val = val.strip()
|
|
336
|
+
if not (val.startswith('#/') or val.startswith("<=/")):
|
|
337
|
+
self.issues_report[relpath].add(("error", f"对象'{obj_name}'的属性'{prop_key}'值不规范:{val}"))
|
|
338
|
+
|
|
339
|
+
def check_topology(self, management_topology: dict, relpath: str):
|
|
340
|
+
chips = set()
|
|
341
|
+
for node_data in management_topology.values():
|
|
342
|
+
for key, objects in node_data.items():
|
|
343
|
+
for obj in objects:
|
|
344
|
+
self.objects_used[relpath].add(obj)
|
|
345
|
+
self.validate_topology_object(key, obj, chips, relpath)
|
|
346
|
+
|
|
347
|
+
def validate_topology_object(self, key: str, obj: str, chips: set, relpath: str):
|
|
348
|
+
if key not in ["Connectors", "Chips"]:
|
|
349
|
+
return
|
|
350
|
+
if obj not in self.sr_objs[relpath]:
|
|
351
|
+
self.issues_report[relpath].add(("error", f"器件'{obj}'没有在Objects中列出"))
|
|
352
|
+
if key == "Chips":
|
|
353
|
+
if obj in chips:
|
|
354
|
+
self.issues_report[relpath].add(("error", f"器件'{obj}'有多条上行总线"))
|
|
355
|
+
chips.add(obj)
|
|
356
|
+
|
|
357
|
+
def match_smc_dfx_whitelist(self, file_objs: Dict[str, Dict], uid: str, chip: str, scanner_data: Dict):
|
|
358
|
+
if chip not in file_objs or uid not in self.smc_dfx_whitelist:
|
|
359
|
+
return False
|
|
360
|
+
chip_data = file_objs.get(chip)
|
|
361
|
+
smc_address = chip_data.get("Address")
|
|
362
|
+
scanner_offset = scanner_data.get("Offset")
|
|
363
|
+
if not smc_address or not scanner_offset:
|
|
364
|
+
return False
|
|
365
|
+
for item in self.smc_dfx_whitelist.get(uid):
|
|
366
|
+
if item.get("SmcAddress") == smc_address and item.get("ScannerOffset") == scanner_offset:
|
|
367
|
+
return True
|
|
368
|
+
return False
|
|
369
|
+
|
|
370
|
+
def check_smc_dfx_info(self, relpath: str):
|
|
371
|
+
smc_dfx_info_objs = {}
|
|
372
|
+
for obj_name, obj_data in self.sr_objs[relpath].items():
|
|
373
|
+
chip = self.get_chip_ref(obj_data)
|
|
374
|
+
if chip and self.get_class_name(obj_name) == "SmcDfxInfo":
|
|
375
|
+
smc_dfx_info_objs[chip] = (obj_name, obj_data)
|
|
376
|
+
if not smc_dfx_info_objs:
|
|
377
|
+
return
|
|
378
|
+
|
|
379
|
+
uid = self.get_uid(self.sr_objs[relpath])
|
|
380
|
+
for obj_name, obj_data in self.sr_objs[relpath].items():
|
|
381
|
+
chip = self.get_chip_ref(obj_data)
|
|
382
|
+
condition = self.get_class_name(obj_name) == "Scanner" and obj_name != "Scanner_PowerGood" \
|
|
383
|
+
and chip and chip in smc_dfx_info_objs
|
|
384
|
+
condition = condition and not self.match_smc_dfx_whitelist(self.sr_objs[relpath], uid, chip, obj_data)
|
|
385
|
+
if not condition:
|
|
386
|
+
continue
|
|
387
|
+
smc_dfx_info_obj_name, smc_dfx_info_obj_data = smc_dfx_info_objs.get(chip)
|
|
388
|
+
if obj_name not in smc_dfx_info_obj_data.get("Mapping", {}):
|
|
389
|
+
error_msg = f"对象'{obj_name}'没有在对象'{smc_dfx_info_obj_name}'的Mapping中配置"\
|
|
390
|
+
"(特殊配套原因不能配置的场景,输出子系统DE讨论纪要后增加到白名单bmcgo/component/analysis/smc_dfx_whitelist.json)"
|
|
391
|
+
self.issues_report[relpath].add(("error", error_msg))
|