openubmc-bingo 0.6.45__py3-none-any.whl → 0.6.99__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.
Files changed (96) hide show
  1. bmcgo/__init__.py +1 -1
  2. bmcgo/bmcgo.py +9 -3
  3. bmcgo/bmcgo_config.py +16 -0
  4. bmcgo/cli/cli.py +72 -21
  5. bmcgo/codegen/__init__.py +1 -1
  6. bmcgo/codegen/lua/codegen.py +2 -2
  7. bmcgo/codegen/lua/script/check_intfs.py +1 -0
  8. bmcgo/codegen/lua/script/dto/options.py +1 -0
  9. bmcgo/codegen/lua/script/gen_db_json.py +4 -3
  10. bmcgo/codegen/lua/script/gen_rpc_msg_json.py +78 -11
  11. bmcgo/codegen/lua/script/model_consistency_check.py +1 -1
  12. bmcgo/codegen/lua/script/render_utils/db_lua.py +5 -6
  13. bmcgo/codegen/lua/script/render_utils/model_lua.py +5 -1
  14. bmcgo/codegen/lua/script/template.py +5 -0
  15. bmcgo/codegen/lua/script/utils.py +50 -8
  16. bmcgo/codegen/lua/templates/apps/Makefile +2 -2
  17. bmcgo/codegen/lua/templates/apps/client.lua.mako +1 -1
  18. bmcgo/codegen/lua/templates/apps/model.lua.mako +4 -3
  19. bmcgo/codegen/lua/templates/apps/service.lua.mako +1 -1
  20. bmcgo/codegen/lua/templates/apps/utils/mdb_intf.lua.mako +4 -0
  21. bmcgo/codegen/lua/templates/new_app_v2/CMakeLists.txt.mako +26 -0
  22. bmcgo/codegen/lua/templates/new_app_v2/conanfile.py.mako +9 -0
  23. bmcgo/codegen/lua/v1/script/render_utils/db_lua.py +5 -6
  24. bmcgo/codegen/lua/v1/script/render_utils/model_lua.py +13 -1
  25. bmcgo/codegen/lua/v1/templates/apps/client.lua.mako +1 -1
  26. bmcgo/codegen/lua/v1/templates/apps/local_db.lua.mako +0 -4
  27. bmcgo/codegen/lua/v1/templates/apps/message.lua.mako +3 -0
  28. bmcgo/codegen/lua/v1/templates/apps/model.lua.mako +3 -0
  29. bmcgo/codegen/lua/v1/templates/apps/utils/mdb_intf.lua.mako +6 -4
  30. bmcgo/component/analysis/analysis.py +9 -4
  31. bmcgo/component/analysis/dep-rules.json +20 -8
  32. bmcgo/component/analysis/dep_node.py +2 -0
  33. bmcgo/component/analysis/intf_validation.py +8 -7
  34. bmcgo/component/analysis/sr_validation.py +5 -4
  35. bmcgo/component/busctl_log_parse/busctl_log_parser.py +809 -0
  36. bmcgo/component/busctl_log_parse/mock_data_save.py +170 -0
  37. bmcgo/component/busctl_log_parse/test_data_save.py +49 -0
  38. bmcgo/component/component_helper.py +29 -0
  39. bmcgo/component/coverage/incremental_cov.py +5 -0
  40. bmcgo/component/fixture/__init__.py +29 -0
  41. bmcgo/component/fixture/auto_case_generator.py +490 -0
  42. bmcgo/component/fixture/busctl_type_converter.py +1081 -0
  43. bmcgo/component/fixture/common_config.py +15 -0
  44. bmcgo/component/fixture/dbus_gateway.py +669 -0
  45. bmcgo/component/fixture/dbus_library.py +250 -0
  46. bmcgo/component/fixture/dbus_mock_utils.py +514 -0
  47. bmcgo/component/fixture/dbus_response_handler.py +138 -0
  48. bmcgo/component/fixture/dbus_signature.py +110 -0
  49. bmcgo/component/template_v2/conanbase.py.mako +1 -5
  50. bmcgo/component/test.py +69 -10
  51. bmcgo/error_analyzer/__init__.py +0 -0
  52. bmcgo/error_analyzer/case_matcher.py +114 -0
  53. bmcgo/error_analyzer/log_parser.py +128 -0
  54. bmcgo/error_analyzer/unified_error_analyzer.py +359 -0
  55. bmcgo/error_cases/cases.yml +59 -0
  56. bmcgo/error_cases/cases_template_valid.json +71 -0
  57. bmcgo/error_cases/conanfile.py +58 -0
  58. bmcgo/frame.py +0 -4
  59. bmcgo/functional/analysis.py +18 -12
  60. bmcgo/functional/bmc_studio_action.py +21 -10
  61. bmcgo/functional/check.py +86 -42
  62. bmcgo/functional/conan_index_build.py +1 -1
  63. bmcgo/functional/config.py +22 -18
  64. bmcgo/functional/csr_build.py +63 -34
  65. bmcgo/functional/deploy.py +4 -3
  66. bmcgo/functional/diff.py +51 -34
  67. bmcgo/functional/full_component.py +16 -5
  68. bmcgo/functional/hpm_signer.py +484 -0
  69. bmcgo/functional/new.py +8 -2
  70. bmcgo/functional/schema_valid.py +111 -15
  71. bmcgo/functional/upgrade.py +6 -6
  72. bmcgo/misc.py +1 -0
  73. bmcgo/tasks/task_build_conan.py +27 -6
  74. bmcgo/tasks/task_build_rootfs_img.py +120 -83
  75. bmcgo/tasks/task_buildgppbin.py +30 -13
  76. bmcgo/tasks/task_buildhpm_ext4.py +5 -3
  77. bmcgo/tasks/task_download_buildtools.py +20 -11
  78. bmcgo/tasks/task_download_dependency.py +29 -20
  79. bmcgo/tasks/task_hpm_envir_prepare.py +32 -53
  80. bmcgo/tasks/task_packet_to_supporte.py +12 -4
  81. bmcgo/tasks/task_prepare.py +1 -1
  82. bmcgo/tasks/task_sign_and_pack_hpm.py +15 -7
  83. bmcgo/utils/component_version_check.py +4 -4
  84. bmcgo/utils/config.py +3 -0
  85. bmcgo/utils/fetch_component_code.py +148 -17
  86. bmcgo/utils/install_manager.py +2 -2
  87. bmcgo/utils/installations/base_installer.py +10 -27
  88. bmcgo/utils/installations/install_plans/studio.yml +3 -0
  89. bmcgo/utils/mapping_config_patch.py +5 -4
  90. bmcgo/utils/tools.py +49 -7
  91. {openubmc_bingo-0.6.45.dist-info → openubmc_bingo-0.6.99.dist-info}/METADATA +1 -1
  92. {openubmc_bingo-0.6.45.dist-info → openubmc_bingo-0.6.99.dist-info}/RECORD +95 -74
  93. bmcgo/tasks/download_buildtools_hm.py +0 -124
  94. {openubmc_bingo-0.6.45.dist-info → openubmc_bingo-0.6.99.dist-info}/WHEEL +0 -0
  95. {openubmc_bingo-0.6.45.dist-info → openubmc_bingo-0.6.99.dist-info}/entry_points.txt +0 -0
  96. {openubmc_bingo-0.6.45.dist-info → openubmc_bingo-0.6.99.dist-info}/top_level.txt +0 -0
@@ -13,6 +13,7 @@
13
13
  import os
14
14
  import json
15
15
  import argparse
16
+ import re
16
17
 
17
18
  import yaml
18
19
  import jsonschema
@@ -21,14 +22,34 @@ from jsonschema import exceptions as jc
21
22
  from bmcgo.logger import Logger
22
23
  from bmcgo.bmcgo_config import BmcgoConfig
23
24
  from bmcgo import misc
25
+ from bmcgo.errors import BmcGoException
24
26
 
25
27
  log = Logger()
26
28
  command_info: misc.CommandInfo = misc.CommandInfo(
27
29
  group=misc.GRP_MISC,
28
- name="validate_yml",
29
- description=["对指定目录下所有yaml文件或指定yaml文件进行 schema 规范检查"],
30
+ name="schema_validate",
31
+ description=["对指定目录下所有yaml/json文件或指定yaml/json文件进行 schema 规范检查"],
30
32
  hidden=True
31
33
  )
34
+ JSON_TYPE = "json"
35
+ YML_TYPE = "yml"
36
+ SCHEMA_FILES_DIR_PATH = "/usr/share/bingo/schema"
37
+
38
+
39
+ def load_json_safely(check_file):
40
+ try:
41
+ with open(check_file, "r") as fp:
42
+ check_data = json.load(fp)
43
+ return check_data
44
+ except json.JSONDecodeError as e:
45
+ log.info(f"Failed to parse JSON file {check_file} : {e}")
46
+ return None
47
+ except FileNotFoundError:
48
+ log.info(f"File not found: {check_file}")
49
+ return None
50
+ except Exception as e:
51
+ log.info(f"Unexpected error reading {check_file} : {e}")
52
+ return None
32
53
 
33
54
 
34
55
  def if_available(_: BmcgoConfig):
@@ -43,34 +64,95 @@ class BmcgoCommand:
43
64
  bconfig (BmcgoConfig): bmcgo 配置
44
65
  """
45
66
  self.bconfig = bconfig
46
- parser = argparse.ArgumentParser(prog=f"{misc.tool_name()} validate_yml", description="Validate yaml files",
67
+ parser = argparse.ArgumentParser(prog=f"{misc.tool_name()} schema_valid", description="Validate yaml files",
47
68
  add_help=True, formatter_class=argparse.RawTextHelpFormatter)
48
69
  parser.add_argument("-t", "--target", help="目标文件夹或单个yaml文件,默认当前目录", default=".")
70
+ parser.add_argument("-csr", "--csr", help="仅校验.sr文件", action=misc.STORE_TRUE, default=False)
49
71
 
50
72
  parsed_args = parser.parse_args(*args)
51
73
  self.target = os.path.realpath(parsed_args.target)
74
+ self.csr_pattern = parsed_args.csr
75
+
76
+ @staticmethod
77
+ def get_schema_in_json(check_file: str):
78
+ check_data = load_json_safely(check_file)
79
+ if check_data:
80
+ schema_file = check_data.get("$schema", "")
81
+ if schema_file:
82
+ return schema_file
83
+
84
+ cwd = os.getcwd()
85
+ os.chdir(os.path.dirname(check_file))
86
+ bconfig = BmcgoConfig()
87
+ os.chdir(cwd)
88
+ if bconfig.component and (os.path.dirname(check_file) == os.path.join(bconfig.component.folder, "mds")
89
+ or os.path.join(bconfig.component.folder, "mds", "debug")):
90
+ check_file_name, _ = os.path.basename(check_file).rsplit(".", 1)
91
+ schema_file = f"{SCHEMA_FILES_DIR_PATH}/mds.{check_file_name}.schema.v1.json"
92
+ if os.path.isfile(schema_file):
93
+ return schema_file
94
+ if bconfig.component and "json/intf/mdb" in check_file:
95
+ schema_file = f"{SCHEMA_FILES_DIR_PATH}/interface.schema.json"
96
+ if os.path.isfile(schema_file):
97
+ return schema_file
98
+ if bconfig.component and "json/intf/mdb" in check_file:
99
+ schema_file = f"{SCHEMA_FILES_DIR_PATH}/path.schema.json"
100
+ if os.path.isfile(schema_file):
101
+ return schema_file
102
+ if bconfig.component and check_file.endswith(".sr"):
103
+ schema_file = f"{SCHEMA_FILES_DIR_PATH}/csr.schema.json"
104
+ if os.path.isfile(schema_file):
105
+ return schema_file
106
+ return None
107
+
108
+ @staticmethod
109
+ def get_decleared_schema_file(check_file: str, file_type=YML_TYPE):
110
+ if file_type == JSON_TYPE:
111
+ return BmcgoCommand.get_schema_in_json(check_file)
112
+ return misc.get_decleared_schema_file(check_file)
52
113
 
53
114
  @staticmethod
54
- def schema_valid(check_file: str) -> bool:
115
+ def schema_valid(check_file: str, file_type=YML_TYPE) -> bool:
55
116
  """ 有效性校验
56
117
 
57
118
  Args:
58
119
  check_file (str): 要校验的文件名称
59
120
  """
60
- schema_file = misc.get_decleared_schema_file(check_file)
61
- if schema_file == "":
121
+ schema_file = BmcgoCommand.get_decleared_schema_file(check_file, file_type)
122
+ if not schema_file:
62
123
  log.warning(f"文件 {check_file} 没有配置 schema 检查")
63
124
  return True
125
+
126
+ http_regex = r'https?://.*'
127
+ if re.match(http_regex, schema_file):
128
+ log.warning(f"文件 {check_file} 配置的 {schema_file} 为外部schema, 跳过检查")
129
+ return True
130
+
131
+ schema_file_path = os.path.join(os.path.dirname(check_file), schema_file)
132
+ if not os.path.isfile(schema_file_path):
133
+ raise BmcGoException(f"schema校验文件 {schema_file_path} 不存在")
134
+
135
+ log.debug("开始校验文件:%s", check_file)
64
136
  with open(schema_file, "rb") as fp:
65
137
  schema = json.load(fp)
66
138
  with open(check_file, "r") as fp:
67
- check_data = yaml.safe_load(fp)
68
- log.info("开始校验文件: %s", check_file)
139
+ if file_type == JSON_TYPE:
140
+ try:
141
+ check_data = json.load(fp)
142
+ except Exception as e:
143
+ log.info(f"解析JSON文件失败:{check_file}, 错误:{e}")
144
+ return False
145
+ else:
146
+ check_data = yaml.safe_load(fp)
147
+
69
148
  try:
70
149
  jsonschema.validate(check_data, schema)
71
- log.success("校验成功: %s", check_file)
150
+ log.debug("校验成功:%s", check_file)
72
151
  return True
73
152
  except (jc.ValidationError, jc.SchemaError) as e:
153
+ if os.path.basename(check_file) != 'service.json':
154
+ log.warning(f" >>>>>> {check_file} 校验失败 <<<<<<\n{e}")
155
+ return True
74
156
  log.error(f" >>>>>> {check_file} 校验失败 <<<<<<\n{e}")
75
157
  return False
76
158
 
@@ -86,26 +168,40 @@ class BmcgoCommand:
86
168
  check_result = []
87
169
 
88
170
  if os.path.isfile(self.target):
89
- check_result.append(self.schema_valid(self.target))
171
+ if str(self.target).endswith(".sr"):
172
+ check_result.append(self.schema_valid(self.target, "json"))
173
+ else:
174
+ check_result.append(self.schema_valid(self.target))
90
175
  return 0
91
-
92
176
  check_result = self._validate_yml_files()
93
177
 
94
178
  if check_result and False in check_result:
95
179
  log.error("请仔细阅读报错日志, 日志中会提示哪些是必要属性, 或哪个属性配置错误")
96
180
  raise AttributeError(f"所有 .yml/.yaml 文件检查失败, 请仔细检查报错并解决问题项")
97
181
  if not check_result:
98
- log.warning("未找到yml文件")
182
+ if self.csr_pattern:
183
+ log.warning("未找到yml文件")
184
+ else:
185
+ log.warning("未找到yml文件")
99
186
  return 0
100
187
 
101
188
  def _validate_yml_files(self):
102
189
  check_result = []
103
190
  for root, _, files in os.walk(self.target):
104
191
  for filename in files:
105
- if not self._is_yml_file(filename):
106
- continue
107
192
  schema_file = os.path.join(root, filename)
108
- check_result.append(self.schema_valid(schema_file))
193
+ if "test" in schema_file.split(os.sep):
194
+ continue
195
+ file_type = None
196
+ if not self._is_yml_file(filename) and not self.csr_pattern:
197
+ file_type = YML_TYPE
198
+ elif filename.endswith(".json") and not self.csr_pattern:
199
+ file_type = JSON_TYPE
200
+ elif filename.endswith(".sr") and self.csr_pattern:
201
+ file_type = JSON_TYPE
202
+ else:
203
+ continue
204
+ check_result.append(self.schema_valid(schema_file, file_type))
109
205
  return check_result
110
206
 
111
207
 
@@ -43,8 +43,7 @@ bingo 升级工具
43
43
 
44
44
  class BmcgoCommand:
45
45
  VERSION_PATTERN = re.compile(
46
- r"^([a-zA-Z0-9_-]+)\s*([<>]=?|[!~]?=)?\s*([a-zA-Z0-9._+-]*|"
47
- rf"{install_consts.INSTALL_LATEST})$"
46
+ r"^([a-zA-Z0-9._-]+)((?:>=|<=|>|<|=)\s*[\s\S]+)"
48
47
  )
49
48
 
50
49
  def __init__(self, bconfig: BmcgoConfig, *args):
@@ -73,7 +72,7 @@ class BmcgoCommand:
73
72
  help="列出可安装版本"
74
73
  )
75
74
 
76
- args, _ = parser.parse_known_args()
75
+ args, _ = parser.parse_known_args(*args)
77
76
 
78
77
  self.version = args.version
79
78
  self.force = args.force
@@ -83,8 +82,9 @@ class BmcgoCommand:
83
82
  self.plugin_path = Path(bconfig.bmcgo_config_list.get(misc.CUSTOM_PLUGINS, misc.DEFAULT_PLUGINS_PATH))
84
83
 
85
84
  def run(self):
86
- app, opt, ver = self._parse_version()
87
- self.installer.init(app, opt, ver, self.plugin_path)
85
+ app, version_range = self._parse_version()
86
+ version_range = version_range.replace(",", " ")
87
+ self.installer.init(app, version_range, self.plugin_path)
88
88
 
89
89
  if self.list:
90
90
  self._list_all_versions()
@@ -105,4 +105,4 @@ class BmcgoCommand:
105
105
  if match:
106
106
  return match.groups()
107
107
  self.version = install_consts.INSTALL_DEFAULT
108
- return self._parse_version()
108
+ return install_consts.INSTALL_ALL, install_consts.INSTALL_LATEST
bmcgo/misc.py CHANGED
@@ -41,6 +41,7 @@ DESCRIPTION = "description"
41
41
  PATTERN = "pattern"
42
42
  ENV_CONST = "env"
43
43
  JSON_CHECKER = "json_checker"
44
+ HPM_SIGNER = "hpm_signer"
44
45
  HTTP_PROXY_CONST = "http_proxy"
45
46
  HTTPS_PROXY_CONST = "https_proxy"
46
47
  FTP_PROXY_CONST = "ftp_proxy"
@@ -148,6 +148,15 @@ class CopyComponent(Process):
148
148
  command_key=self.comp)
149
149
 
150
150
  def _copy_files(self):
151
+ mdb_path = os.path.join(self.package_folder, "opt/bmc/apps/mdb_interface/")
152
+ if os.path.isdir(mdb_path):
153
+ cmd = f"cp -dfr {mdb_path} {self.config.mdb_output}"
154
+ self.work.run_command(cmd)
155
+ mds_path = os.path.join(self.package_folder, "usr/share/doc/openubmc")
156
+ if os.path.isdir(mds_path):
157
+ cmd = f"cp -dfr {mds_path}/. {self.config.mdb_output}"
158
+ self.work.run_command(cmd)
159
+ # for dirs, file, _ in os.walk(mds_path)
151
160
  # 由于复制时有很多同名路径,cp命令有概率失败,10次复制尝试
152
161
  cmd = "sudo cp -dfr {}/. {}".format(self.package_folder, self.config.rootfs_path)
153
162
  for _ in range(0, 10):
@@ -251,8 +260,8 @@ class ConanLockParse:
251
260
  for com, entry_degree in entry_degree_temp_dict.items():
252
261
  if entry_degree != 0:
253
262
  continue
254
- # openubmc作为一个最终组件,不推送(远端没有,直接弹出)
255
- if com.startswith("openubmc/"):
263
+ # 最终组件,不推送(远端没有,直接弹出)
264
+ if com.startswith(f"{misc.community_name()}/"):
256
265
  self._degree.pop(com)
257
266
  break
258
267
  cmd_tmp = cmd.replace("com_name", f"{com}")
@@ -459,7 +468,7 @@ class TaskClass(Task):
459
468
  self.component_check = ComponentVersionCheck(
460
469
  manifest_yml="manifest.yml",
461
470
  ibmc_lock=self.lockfile,
462
- community_name="openubmc",
471
+ community_name=misc.community_name(),
463
472
  openubmcsdk=openubmcsdk
464
473
  )
465
474
  for dep in deps:
@@ -481,6 +490,9 @@ class TaskClass(Task):
481
490
  self.board_option = self.board_option + " -o */*:{}={}".format(key, val)
482
491
  else:
483
492
  self.board_option = self.board_option + " -o {}/*:{}={}".format(name, key, val)
493
+ options = dep.get("tool_options", {})
494
+ for key, val in options.items():
495
+ self.board_option = self.board_option + " -o:b {}/*:{}={}".format(name, key, val)
484
496
  # 当使能Luajit又未向skynet传递enable_luajit配置项时需要添加使能参数
485
497
  if not skynet_with_enable_luajit and self.config.enable_luajit:
486
498
  self.board_option += f" -o */*:enable_luajit={self.config.enable_luajit}"
@@ -521,7 +533,7 @@ class TaskClass(Task):
521
533
  self.component_check = ComponentVersionCheck(
522
534
  manifest_yml="manifest.yml",
523
535
  ibmc_lock=self.lockfile,
524
- community_name="openubmc",
536
+ community_name=misc.community_name(),
525
537
  openubmcsdk=openubmcsdk
526
538
  )
527
539
  for dep in deps:
@@ -547,6 +559,9 @@ class TaskClass(Task):
547
559
  self.warning(f"根据manifest.yml配置,当前产品的enable_luajit配置为{val},忽略命令行指定的-jit参数")
548
560
  self.config.set_enable_luajit(val)
549
561
  skynet_with_enable_luajit = True
562
+ options = dep.get("tool_options", {})
563
+ for key, val in options.items():
564
+ self.board_option = self.board_option + " -o:b {}/*:{}={}".format(name, key, val)
550
565
  # 当使能Luajit又未向skynet传递enable_luajit配置项时需要添加使能参数
551
566
  if not skynet_with_enable_luajit and self.config.enable_luajit:
552
567
  self.board_option += f" -o skynet:enable_luajit={self.config.enable_luajit}"
@@ -582,7 +597,7 @@ class TaskClass(Task):
582
597
  with os.fdopen(os.open(self.package_info, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, stat.S_IWUSR | stat.S_IRUSR |
583
598
  stat.S_IWGRP | stat.S_IRGRP | stat.S_IWOTH | stat.S_IROTH), 'w') as fp:
584
599
  for package in require_list:
585
- if "openubmc/" not in package:
600
+ if f"{misc.community_name()}/" not in package:
586
601
  fp.write(f"{package.split('#')[0]}\n")
587
602
  else:
588
603
  package_info_list.remove(package)
@@ -813,6 +828,9 @@ class TaskClass(Task):
813
828
  os.makedirs(openubmc_dir, exist_ok=True)
814
829
  shutil.copytree(conanfile_dir, openubmc_dir, dirs_exist_ok=True)
815
830
  self.chdir(openubmc_dir)
831
+ # 替换默认的根组件名为实际的community name
832
+ tools.run_command(f"sed -i 's/openubmc/{misc.community_name()}/g' conanfile.py")
833
+
816
834
  # 复制manifest.yml文件
817
835
  if misc.conan_v2():
818
836
  self.merge_manifest_v2()
@@ -1051,6 +1069,9 @@ class TaskClass(Task):
1051
1069
 
1052
1070
  def package(self):
1053
1071
  self.chdir(self.conan_install)
1072
+ if os.path.isdir(self.config.mdb_output):
1073
+ shutil.rmtree(self.config.mdb_output)
1074
+ os.makedirs(self.config.mdb_output, 0o755)
1054
1075
  if misc.conan_v2():
1055
1076
  self.package_v2()
1056
1077
  return
@@ -1061,7 +1082,7 @@ class TaskClass(Task):
1061
1082
  for dirname in os.listdir("."):
1062
1083
  if not os.path.isdir(dirname):
1063
1084
  continue
1064
- if dirname != "rootfs" and dirname != "openubmc":
1085
+ if dirname != "rootfs" and dirname != misc.community_name():
1065
1086
  comps.append(dirname)
1066
1087
 
1067
1088
  self.copy_components(comps, profile)
@@ -21,6 +21,7 @@ import stat
21
21
  import time
22
22
  import subprocess
23
23
  import tempfile
24
+ import re
24
25
  from multiprocessing import Process
25
26
 
26
27
  from git import Repo
@@ -32,19 +33,6 @@ from bmcgo.utils.mapping_config_patch import MappingConfigPatch
32
33
  from bmcgo import errors, misc
33
34
 
34
35
 
35
- class MakeZeroImageProcess(Process):
36
- def __init__(self, work, bs_count, img_path):
37
- super().__init__()
38
- self.work = work
39
- self.bs_count = bs_count
40
- self.img_path = img_path
41
-
42
- def run(self):
43
- self.work.work_name = os.path.basename(self.img_path)
44
- cmd = f"dd if=/dev/zero of={self.img_path} bs=4096 count={self.bs_count}"
45
- self.work.run_command(cmd)
46
-
47
-
48
36
  class TaskClass(Task):
49
37
  def __init__(self, config: Config, work_name=""):
50
38
  super(TaskClass, self).__init__(config, work_name)
@@ -57,6 +45,38 @@ class TaskClass(Task):
57
45
  self.rootfs_img_path = f"{self.config.work_out}/rootfs_BMC.img"
58
46
  self.datafs_img_path = f"{self.config.hpm_build_dir}/datafs_{self.config.board_name}.img"
59
47
 
48
+ @staticmethod
49
+ def make_strip_cmd(file_list, relative_path, build_type=None):
50
+ base = ["sudo find {} -type f ".format(relative_path)]
51
+ base.append("grep -v \"/share/\"")
52
+ base.append("grep -v \".json$\"")
53
+ base.append("grep -v \"\.lua$\"")
54
+ base.append("grep -v \".sh$\"")
55
+ base.append("grep -v \".png$\"")
56
+ base.append("grep -v \".jpg$\"")
57
+ base.append("grep -v \".jpeg$\"")
58
+ base.append("grep -v \".html$\"")
59
+ base.append("grep -v \".js$\"")
60
+ base.append("grep -v \".css$\"")
61
+ base.append("grep -v \".svg$\"")
62
+ base.append("grep -v \".sr$\"")
63
+ base.append("grep -v \".conf$\"")
64
+ base.append("grep -v \".service$\"")
65
+ base.append("grep -v \".cfg$\"")
66
+ base.append("grep -v \".gif$\"")
67
+ base.append("grep -v \".ttf$\"")
68
+ base.append("grep -v \".target$\"")
69
+ if build_type == "debug":
70
+ # so库一般带有版本号,此处不能注明具体的版本号,否则可能导致版本变更时不能正确strip
71
+ not_striped_list = ["rootfs/opt/bmc"]
72
+ for file in not_striped_list:
73
+ base.append("grep -v \"{}\"".format(file))
74
+ base.append("sudo xargs -P 0 -I {{}} file {{}}".format(file_list))
75
+ base.append("grep 'not stripped'")
76
+ base.append("awk -F: '{{print $1}}'")
77
+ base.append("grep -v '.ko$'")
78
+ return base
79
+
60
80
  def set_evn(self):
61
81
  self.buildimg_dir = self.config.buildimg_dir
62
82
  self.tools.check_path(self.buildimg_dir)
@@ -202,13 +222,37 @@ class TaskClass(Task):
202
222
  # 差异化处理完schema文件之后已完成schema整合,不在需要产品schema目录(强制删除时即使不存在也不会出错)
203
223
  self.run_command(f"rm -rf {product_schema_path}", sudo=True)
204
224
 
225
+ # 将默认接口配置复制到节点目录中
226
+ def copy_interface_config(self, config_path, custom_path):
227
+ for config_dir in os.listdir(config_path):
228
+ # redfish的schema文件仍放在原路径,不需要进行复制
229
+ if not re.match(r'^[a-fA-F0-9]{2}_[a-fA-F0-9]{2}$', config_dir) and \
230
+ config_dir != "static_resource" and config_dir != "config_patch":
231
+ source_path = os.path.join(config_path, config_dir)
232
+ copy_cmd = f"cp -r {source_path} {custom_path}/"
233
+ self.tools.run_command(copy_cmd, sudo=True)
234
+
235
+ # 支持产品层级多节点共包,每个节点有独立的定制化接口配置
236
+ def custom_mapping_config_patch(self, config_path):
237
+ for custom_item in os.listdir(config_path):
238
+ # 节点目录命名为xx_xx格式,以十六进制表示
239
+ if re.match(r'^[a-fA-F0-9]{2}_[a-fA-F0-9]{2}$', custom_item):
240
+ custom_path = os.path.join(config_path, custom_item)
241
+ self.copy_interface_config(config_path, custom_path)
242
+ patch_work = MappingConfigPatch(self.config, config_path=custom_path)
243
+ patch_work.run()
244
+
205
245
  # 支持映射配置文件根据产品差异进行打补丁
206
246
  def mapping_config_patch(self):
207
247
  self.info("开始根据配置映射打补丁")
208
248
  for item in ["redfish", "web_backend", misc.CLI, "snmp"]:
209
249
  config_path = os.path.join(self.rtos_rootfs, "opt/bmc/apps", item, "interface_config")
210
- if not os.path.isdir(config_path):
250
+ ret = self.tools.run_command(f"test -d {config_path}", ignore_error=True, sudo=True)
251
+ if ret.returncode != 0:
211
252
  continue
253
+
254
+ self.custom_mapping_config_patch(config_path)
255
+ # 各节点的配置打完补丁后再进行默认配置的打补丁操作
212
256
  patch_work = MappingConfigPatch(self.config, config_path=config_path)
213
257
  patch_work.run()
214
258
 
@@ -334,38 +378,19 @@ class TaskClass(Task):
334
378
  self.run_command(f"chmod {sr_dir_permission} {sr_dir}", sudo=True, command_echo=False)
335
379
  self.run_command(f"chmod 440 {csr_version_file_path}", sudo=True, command_echo=False)
336
380
 
337
- def make_strip_cmd(self, file_list):
381
+ def strip(self):
382
+ # strip非ko文件
383
+ file_list = os.path.join(self.buildimg_dir, "no_striped.filelist")
338
384
  work_path = os.getcwd()
339
385
  relative_path = os.path.relpath(work_path, self.rtos_rootfs)
340
- base = ["sudo find {} -type f ".format(relative_path)]
341
- base.append("grep -v \"/share/\"")
342
- base.append("grep -v \".json$\"")
343
- base.append("grep -v \"\.lua$\"")
344
- base.append("grep -v \".sh$\"")
345
- base.append("grep -v \".png$\"")
346
- base.append("grep -v \".jpg$\"")
347
- base.append("grep -v \".jpeg$\"")
348
- base.append("grep -v \".html$\"")
349
- base.append("grep -v \".js$\"")
350
- base.append("grep -v \".css$\"")
351
- base.append("grep -v \".svg$\"")
352
- base.append("grep -v \".sr$\"")
353
- base.append("grep -v \".conf$\"")
354
- base.append("grep -v \".service$\"")
355
- base.append("grep -v \".cfg$\"")
356
- base.append("grep -v \".gif$\"")
357
- base.append("grep -v \".ttf$\"")
358
- base.append("grep -v \".target$\"")
359
- if self.config.build_type == "debug":
360
- # so库一般带有版本号,此处不能注明具体的版本号,否则可能导致版本变更时不能正确strip
361
- not_striped_list = ["rootfs/opt/bmc"]
362
- for file in not_striped_list:
363
- base.append("grep -v \"{}\"".format(file))
364
- base.append("sudo xargs -P 0 -I {{}} file {{}}".format(file_list))
365
- base.append("grep 'not stripped'")
366
- base.append("awk -F: '{{print $1}}'")
367
- base.append("grep -v '.ko$'")
368
- return base
386
+ base = self.make_strip_cmd(file_list, relative_path, self.config.build_type)
387
+ strip = os.path.join(self.config.cross_compile_install_path, "bin", self.config.strip)
388
+ self.pipe_command(base, file_list)
389
+ if os.path.isfile(file_list) and not self.config.enable_arm_gcov:
390
+ cmd = ["cat {}".format(file_list), "sudo xargs -P 0 -I {{}} {} -R .comment {{}}".format(strip)]
391
+ self.pipe_command(cmd)
392
+ cmd = ["cat {}".format(file_list), "sudo xargs -P 0 -I {{}} {} {{}}".format(strip)]
393
+ self.pipe_command(cmd)
369
394
 
370
395
  def build_common_fs(self):
371
396
  """
@@ -374,43 +399,22 @@ class TaskClass(Task):
374
399
  self.chdir(self.buildimg_dir)
375
400
  self.info("开始构建 rootfs ...")
376
401
 
377
- rtos_tar = os.path.join(self.config.sdk_path, "rtos.tar.gz")
378
- sdk_tar = os.path.join(self.config.sdk_path, "hi1711sdk.tar.gz")
379
- # 解压SDK
380
- self.run_command(f"rm -rf {self.rtos_rootfs}", sudo=True)
381
- self.run_command(f"tar --xattrs --xattrs-include=* -xf {rtos_tar}", sudo=True)
382
- self.run_command(f"sudo chown -R 0:0 {self.rtos_rootfs}", sudo=True)
383
- self.info("拷贝RTOS提供的mke2fs.conf配置文件覆盖本地环境中的/etc/mke2fs.conf文件, 确保mkfs.ext4使用该配置文件")
384
- self.run_command(f"cp -f {self.rtos_rootfs}/etc/mke2fs.conf /etc/mke2fs.conf", sudo=True)
385
- self.run_command(f"rm -rf {self.rtos_rootfs}/etc/ssh", sudo=True)
386
- self.run_command(f"rm -rf {self.rtos_rootfs}/usr/share/doc/openubmc", sudo=True)
402
+ self.make_rtos_rootfs()
387
403
 
388
404
  # 记录代码分支和提交节点
389
405
  self.create_bmc_release()
390
406
 
391
- # 解压SDK并复制到指定位置
392
- sdk_path = os.path.join(self.buildimg_dir, "sdk")
393
- self.run_command(f"rm -rf {sdk_path}", sudo=True)
394
- self.run_command(f"mkdir -p {sdk_path}", sudo=True)
395
- self.run_command("tar -xf {} -C {}".format(sdk_tar, sdk_path), sudo=True)
396
- ko_path = f"{self.rtos_rootfs}/lib/modules/"
397
- self.run_command("cp -dfr {}/. {}".format(sdk_path, ko_path), sudo=True)
407
+ self.copy_ko_modules()
398
408
 
399
409
  self.chdir(self.config.work_out)
400
410
  self.copy_rtos_modules()
411
+ self.copy_upgrade_dat_file()
401
412
 
402
413
  for cus in self.customization:
403
414
  cus.rootfs_cust(self.rtos_rootfs)
404
- # strip非ko文件
405
- file_list = os.path.join(self.buildimg_dir, "no_striped.filelist")
406
- base = self.make_strip_cmd(file_list)
407
- strip = os.path.join(self.config.cross_compile_install_path, "bin", self.config.strip)
408
- self.pipe_command(base, file_list)
409
- if os.path.isfile(file_list) and not self.config.enable_arm_gcov:
410
- cmd = ["cat {}".format(file_list), "sudo xargs -P 0 -I {{}} {} -R .comment {{}}".format(strip)]
411
- self.pipe_command(cmd)
412
- cmd = ["cat {}".format(file_list), "sudo xargs -P 0 -I {{}} {} {{}}".format(strip)]
413
- self.pipe_command(cmd)
415
+
416
+ self.strip()
417
+
414
418
  # 删除.a文件
415
419
  cmd = ["sudo find {} -type f -name *.a".format(self.rtos_rootfs), "sudo xargs -P 0 -i{{}} rm {{}}"]
416
420
  self.pipe_command(cmd)
@@ -422,6 +426,18 @@ class TaskClass(Task):
422
426
  self.prepare_preloader_for_luacov()
423
427
  self.prepare_coverage_config()
424
428
 
429
+ def make_rtos_rootfs(self):
430
+ self.info("开始构建 rootfs ...")
431
+ rtos_tar = os.path.join(self.config.sdk_path, "rtos.tar.gz")
432
+ # 解压SDK
433
+ self.run_command(f"rm -rf {self.rtos_rootfs}", sudo=True)
434
+ self.run_command(f"tar --xattrs --xattrs-include=* -xf {rtos_tar}", sudo=True)
435
+ self.run_command(f"sudo chown -R 0:0 {self.rtos_rootfs}", sudo=True)
436
+ self.info("拷贝RTOS提供的mke2fs.conf配置文件覆盖本地环境中的/etc/mke2fs.conf文件, 确保mkfs.ext4使用该配置文件")
437
+ self.run_command(f"cp -f {self.rtos_rootfs}/etc/mke2fs.conf /etc/mke2fs.conf", sudo=True)
438
+ self.run_command(f"rm -rf {self.rtos_rootfs}/etc/ssh", sudo=True)
439
+ self.run_command(f"rm -rf {self.rtos_rootfs}/usr/share/doc/openubmc", sudo=True)
440
+
425
441
  def create_bmc_release(self):
426
442
  bmc_release_path = f"{self.rtos_rootfs}/etc/bmc-release"
427
443
  temp_bmc_release_file = tempfile.NamedTemporaryFile()
@@ -448,6 +464,16 @@ class TaskClass(Task):
448
464
  self.run_command(f"cp {temp_bmc_release_file.name} {bmc_release_path}", sudo=True, command_echo=False)
449
465
  self.run_command(f"chmod 644 {bmc_release_path}", sudo=True)
450
466
 
467
+ def copy_ko_modules(self):
468
+ # 解压SDK并复制到指定位置
469
+ sdk_tar = os.path.join(self.config.sdk_path, "hi1711sdk.tar.gz")
470
+ sdk_path = os.path.join(self.buildimg_dir, "sdk")
471
+ self.run_command(f"rm -rf {sdk_path}", sudo=True)
472
+ self.run_command(f"mkdir -p {sdk_path}", sudo=True)
473
+ self.run_command("tar -xf {} -C {}".format(sdk_tar, sdk_path), sudo=True)
474
+ ko_path = f"{self.rtos_rootfs}/lib/modules/"
475
+ self.run_command("cp -dfr {}/. {}".format(sdk_path, ko_path), sudo=True)
476
+
451
477
  def copy_rtos_modules(self):
452
478
  self.run_command("cp -af {}/. {}".format(self.config.rootfs_path, self.rtos_rootfs), sudo=True)
453
479
  cp_cmd = "cp -df {} {}"
@@ -455,14 +481,17 @@ class TaskClass(Task):
455
481
  f"{self.rtos_rootfs}/lib64/libgcc_s.so.1"), sudo=True)
456
482
  self.run_command(cp_cmd.format("/opt/hcc_arm64le/aarch64-target-linux-gnu/lib64/libstdc++.so.6",
457
483
  f"{self.rtos_rootfs}/lib64/libstdc++.so.6"), sudo=True)
484
+ self.run_command("chmod 755 {}".format(f"{self.rtos_rootfs}/lib64/libgcc_s.so.1"), sudo=True)
485
+ self.run_command("chmod 755 {}".format(f"{self.rtos_rootfs}/lib64/libstdc++.so.6"), sudo=True)
486
+
487
+ def copy_upgrade_dat_file(self):
488
+ cp_cmd = "cp -df {} {}"
458
489
  self.run_command("mkdir -p {}".format(f"{self.rtos_rootfs}/opt/pme/upgrade"), sudo=True)
459
490
  self.run_command(cp_cmd.format(f"{self.config.code_path}/manufacture/misc/pme_profile_en.dat",
460
491
  f"{self.rtos_rootfs}/opt/pme/upgrade/pme_profile_en"), sudo=True)
461
492
  self.run_command(cp_cmd.format(f"{self.config.code_path}/manufacture/misc/datatocheck_upgrade.dat",
462
493
  f"{self.rtos_rootfs}/opt/pme/upgrade/datatocheck_upgrade.dat"),
463
494
  sudo=True)
464
- self.run_command("chmod 755 {}".format(f"{self.rtos_rootfs}/lib64/libgcc_s.so.1"), sudo=True)
465
- self.run_command("chmod 755 {}".format(f"{self.rtos_rootfs}/lib64/libstdc++.so.6"), sudo=True)
466
495
  self.run_command("chmod 400 {}".format(f"{self.rtos_rootfs}/opt/pme/upgrade/pme_profile_en"), sudo=True)
467
496
  self.run_command("chmod 400 {}".format(f"{self.rtos_rootfs}/opt/pme/upgrade/datatocheck_upgrade.dat"),
468
497
  sudo=True)
@@ -496,6 +525,20 @@ class TaskClass(Task):
496
525
  self.run_command(f"chown 0:0 {tar_path}", sudo=True)
497
526
  return
498
527
 
528
+ def rootfs_customization(self):
529
+ if self.config.build_type == 'debug':
530
+ for cus in self.customization:
531
+ cus.rootfs_debug_cust(self.mnt_datafs)
532
+ elif self.config.build_type == 'release':
533
+ for cus in self.customization:
534
+ cus.rootfs_release_cust(self.mnt_datafs)
535
+
536
+ for cus in self.customization:
537
+ cus.rootfs_common(self.mnt_datafs)
538
+
539
+ def make_img(self):
540
+ self.tools.make_img(self.rootfs_img_path, self.mnt_datafs, "376")
541
+
499
542
  def make_rootfs_img(self):
500
543
  self.make_datafs_img()
501
544
 
@@ -519,18 +562,11 @@ class TaskClass(Task):
519
562
 
520
563
  self.component_swbom()
521
564
  self.run_command(f"sudo cp -a {self.rtos_rootfs}/. {self.mnt_datafs}/")
522
- if self.config.build_type == 'debug':
523
- for cus in self.customization:
524
- cus.rootfs_debug_cust(self.mnt_datafs)
525
- elif self.config.build_type == 'release':
526
- for cus in self.customization:
527
- cus.rootfs_release_cust(self.mnt_datafs)
528
-
529
- for cus in self.customization:
530
- cus.rootfs_common(self.mnt_datafs)
565
+ self.rootfs_customization()
531
566
  self.chdir(self.config.work_out)
532
- self.tools.make_img(self.rootfs_img_path, self.mnt_datafs, "376")
567
+ self.make_img()
533
568
 
569
+ def post_make_rootfs_img(self):
534
570
  self.run_command(f"zerofree -v {self.rootfs_img_path}")
535
571
  self.run_command(f"get_img_parma_area.sh {self.rootfs_img_path}")
536
572
 
@@ -568,3 +604,4 @@ class TaskClass(Task):
568
604
  self.set_evn()
569
605
  self.build_common_fs()
570
606
  self.make_rootfs_img()
607
+ self.post_make_rootfs_img()