openubmc-bingo 0.5.243__py3-none-any.whl → 0.5.254__py3-none-any.whl

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

Potentially problematic release.


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

Files changed (67) hide show
  1. bmcgo/__init__.py +1 -1
  2. bmcgo/bmcgo_config.py +81 -1
  3. bmcgo/codegen/lua/Makefile +13 -0
  4. bmcgo/codegen/lua/codegen.py +6 -3
  5. bmcgo/codegen/lua/script/dto/options.py +1 -0
  6. bmcgo/codegen/lua/script/{render_utils/factory.py → factory.py} +1 -1
  7. bmcgo/codegen/lua/script/gen_entry.py +6 -3
  8. bmcgo/codegen/lua/script/gen_intf_rpc_json.py +12 -0
  9. bmcgo/codegen/lua/script/gen_schema.py +2 -0
  10. bmcgo/codegen/lua/script/merge_model.py +10 -3
  11. bmcgo/codegen/lua/script/render_utils/__init__.py +5 -4
  12. bmcgo/codegen/lua/script/render_utils/client_lua.py +2 -2
  13. bmcgo/codegen/lua/script/render_utils/controller_lua.py +2 -2
  14. bmcgo/codegen/lua/script/render_utils/db_lua.py +2 -2
  15. bmcgo/codegen/lua/script/render_utils/error_lua.py +2 -2
  16. bmcgo/codegen/lua/script/render_utils/ipmi_lua.py +2 -2
  17. bmcgo/codegen/lua/script/render_utils/ipmi_message_lua.py +2 -2
  18. bmcgo/codegen/lua/script/render_utils/mdb_lua.py +2 -2
  19. bmcgo/codegen/lua/script/render_utils/message_lua.py +2 -2
  20. bmcgo/codegen/lua/script/render_utils/messages_lua.py +2 -2
  21. bmcgo/codegen/lua/script/render_utils/model_lua.py +2 -2
  22. bmcgo/codegen/lua/script/render_utils/old_model_lua.py +2 -2
  23. bmcgo/codegen/lua/script/render_utils/plugin_lua.py +2 -2
  24. bmcgo/codegen/lua/script/render_utils/redfish_proto.py +2 -2
  25. bmcgo/codegen/lua/script/render_utils/request_lua.py +2 -2
  26. bmcgo/codegen/lua/script/render_utils/service_lua.py +3 -2
  27. bmcgo/codegen/lua/script/template.py +5 -1
  28. bmcgo/codegen/lua/script/utils.py +9 -2
  29. bmcgo/codegen/lua/templates/Makefile +8 -0
  30. bmcgo/codegen/lua/templates/apps/Makefile +27 -1
  31. bmcgo/codegen/lua/templates/apps/controller.lua.mako +20 -4
  32. bmcgo/codegen/lua/v1/script/gen_schema.py +328 -0
  33. bmcgo/codegen/lua/v1/script/render_utils/model_lua.py +458 -0
  34. bmcgo/codegen/lua/v1/templates/apps/model.lua.mako +62 -0
  35. bmcgo/codegen/lua/v1/templates/apps/service.lua.mako +193 -0
  36. bmcgo/component/build.py +26 -43
  37. bmcgo/component/component_helper.py +54 -0
  38. bmcgo/component/coverage/incremental_cov.py +25 -33
  39. bmcgo/frame.py +9 -6
  40. bmcgo/functional/conan_index_build.py +16 -41
  41. bmcgo/functional/config.py +7 -0
  42. bmcgo/functional/csr_build.py +313 -88
  43. bmcgo/functional/diff.py +3 -3
  44. bmcgo/functional/json_check.py +109 -0
  45. bmcgo/functional/upgrade.py +31 -1
  46. bmcgo/misc.py +32 -2
  47. bmcgo/target/install_sdk.yml +6 -0
  48. bmcgo/tasks/task.py +69 -43
  49. bmcgo/tasks/task_build_conan.py +6 -2
  50. bmcgo/tasks/task_build_wbd_up.py +4 -4
  51. bmcgo/utils/basic_enums.py +45 -0
  52. bmcgo/utils/config.py +20 -8
  53. bmcgo/utils/install_manager.py +75 -20
  54. bmcgo/utils/installations/base_installer.py +114 -7
  55. bmcgo/utils/installations/install_consts.py +3 -1
  56. bmcgo/utils/installations/install_plans/bingo.yml +2 -4
  57. bmcgo/utils/installations/install_workflow.py +6 -2
  58. bmcgo/utils/installations/installers/apt_installer.py +58 -136
  59. bmcgo/utils/installations/installers/pip_installer.py +52 -18
  60. bmcgo/utils/installations/version_util.py +1 -1
  61. bmcgo/utils/json_validator.py +241 -0
  62. {openubmc_bingo-0.5.243.dist-info → openubmc_bingo-0.5.254.dist-info}/METADATA +2 -1
  63. {openubmc_bingo-0.5.243.dist-info → openubmc_bingo-0.5.254.dist-info}/RECORD +67 -60
  64. /bmcgo/codegen/lua/script/{render_utils/base.py → base.py} +0 -0
  65. {openubmc_bingo-0.5.243.dist-info → openubmc_bingo-0.5.254.dist-info}/WHEEL +0 -0
  66. {openubmc_bingo-0.5.243.dist-info → openubmc_bingo-0.5.254.dist-info}/entry_points.txt +0 -0
  67. {openubmc_bingo-0.5.243.dist-info → openubmc_bingo-0.5.254.dist-info}/top_level.txt +0 -0
bmcgo/functional/diff.py CHANGED
@@ -48,7 +48,7 @@ class BmcgoCommand:
48
48
  self.bconfig = bconfig
49
49
  if len(args) != 1 or len(args[0]) != 2:
50
50
  log.info("\n".join(command_info.help_info))
51
- raise errors.bingoException("参数格式错误, 请查看上述提示")
51
+ raise errors.BmcGoException("参数格式错误, 请查看上述提示")
52
52
  self.version_before = args[0][0]
53
53
  self.version_after = args[0][1]
54
54
 
@@ -227,9 +227,9 @@ class BmcgoCommand:
227
227
 
228
228
  def run(self):
229
229
  if "@" in self.version_before and "@" in self.version_after:
230
- raise errors.bingoException(f"不支持两个组件版本对比")
230
+ raise errors.BmcGoException(f"不支持两个组件版本对比")
231
231
  elif "@" not in self.version_before and "@" not in self.version_after:
232
232
  self.parse_commit_merge()
233
233
  else:
234
- raise errors.bingoException("输入的版本号无法解析")
234
+ raise errors.BmcGoException("输入的版本号无法解析")
235
235
  return 0
@@ -0,0 +1,109 @@
1
+ #!/usr/bin/env python3
2
+ # encoding=utf-8
3
+ # 描述:bingo 配置默认参数功能
4
+ # Copyright (c) 2025 Huawei Technologies Co., Ltd.
5
+ # openUBMC is licensed under Mulan PSL v2.
6
+ # You can use this software according to the terms and conditions of the Mulan PSL v2.
7
+ # You may obtain a copy of Mulan PSL v2 at:
8
+ # http://license.coscl.org.cn/MulanPSL2
9
+ # THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
10
+ # EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
11
+ # MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
12
+ # See the Mulan PSL v2 for more details.
13
+ import os
14
+ import re
15
+ import argparse
16
+ from pathlib import Path
17
+
18
+ from bmcgo import misc
19
+ from bmcgo.utils.tools import Tools
20
+ from bmcgo.utils.json_validator import JsonTypeEnum, JSONValidator, get_cpu_count
21
+ from bmcgo.bmcgo_config import BmcgoConfig
22
+
23
+
24
+ tools = Tools("JSONChecker")
25
+ logger = tools.log
26
+
27
+
28
+ command_info: misc.CommandInfo = misc.CommandInfo(
29
+ group=misc.GRP_MISC,
30
+ name="json_check",
31
+ description=["json 文件检查"],
32
+ hidden=False
33
+ )
34
+
35
+
36
+ def if_available(bconfig: BmcgoConfig):
37
+ return True
38
+
39
+
40
+ CMD = "bingo"
41
+
42
+
43
+ def get_desc(cmd):
44
+
45
+ return f"""
46
+ json 文件合法性检查工具:
47
+
48
+ 1. 检查当前路径下所有 sr 文件:
49
+ >> {cmd} json_test -e sr
50
+
51
+ 2. 检查其他路径下所有 sr, json, jn 文件:
52
+ >> {cmd} json_test -p /path/to/test/ -e .sr,json,jn
53
+
54
+ 3. 用其他工具检查,比如 pyjson5, json5 (需要提前通过 pip 安装):
55
+ >> {cmd} json_test -e sr -j pyjson5
56
+ """
57
+
58
+ DEFAULT_JSON_TYPE = JsonTypeEnum.JSON
59
+
60
+
61
+ class BmcgoCommand:
62
+ def __init__(self, bconfig: BmcgoConfig, *args):
63
+ self.bconfig = bconfig
64
+ jc = self.bconfig.bmcgo_config_list.get(misc.ENV_CONST, {}).get(misc.JSON_CHECKER, DEFAULT_JSON_TYPE)
65
+
66
+ parser = argparse.ArgumentParser(
67
+ prog=f"{CMD}参数配置",
68
+ description=get_desc(CMD),
69
+ add_help=True,
70
+ formatter_class=argparse.RawTextHelpFormatter
71
+ )
72
+ parser.add_argument(
73
+ "-p",
74
+ "--path",
75
+ type=Path,
76
+ default=Path(".").resolve(),
77
+ help="文件路径:检查单个文件合法性;文件夹路径:递归遍历所有指定拓展名文件合法性"
78
+ )
79
+ parser.add_argument(
80
+ "-e",
81
+ "--extensions",
82
+ type=lambda s: [ext.strip().lstrip('.').lower() for ext in re.split(r'\s*[,,]\s*', s) if ext],
83
+ required=True,
84
+ help="需要检查的文件后缀,通过','分隔,比如 -e sr,json"
85
+ )
86
+ parser.add_argument(
87
+ "-j",
88
+ "--json-type",
89
+ choices=list(JsonTypeEnum),
90
+ default=jc,
91
+ help=f"选择检查工具,可以通过 {CMD} config {misc.ENV_CONST}.{misc.JSON_CHECKER}=json/json5/pyjson5 指定默认值,当前为:{jc}\n"
92
+ "选择其他工具请先确认是否已经安装"
93
+ )
94
+ parser.add_argument(
95
+ "-n",
96
+ "--worker-num",
97
+ type=int,
98
+ default=get_cpu_count() * 2,
99
+ help=f"指定并行处理器数目,默认为{get_cpu_count() * 2}"
100
+ )
101
+
102
+ self.args, self.kwargs = parser.parse_known_args(*args)
103
+ self.logger = tools.log
104
+ self._json_checker = JSONValidator()
105
+
106
+ def run(self):
107
+ self._json_checker.validate_files(
108
+ self.args.path, self.args.extensions, self.args.json_type, self.args.worker_num)
109
+ return 0
@@ -60,16 +60,46 @@ class BmcgoCommand:
60
60
  default=install_consts.INSTALL_DEFAULT,
61
61
  help="列出所有配置"
62
62
  )
63
+ parser.add_argument(
64
+ "-f",
65
+ "--force",
66
+ action=misc.STORE_TRUE,
67
+ help="跳过确认,直接安装"
68
+ )
69
+ parser.add_argument(
70
+ "-l",
71
+ "--list",
72
+ action=misc.STORE_TRUE,
73
+ help="列出可安装版本"
74
+ )
63
75
 
64
76
  args, _ = parser.parse_known_args()
77
+
65
78
  self.version = args.version
79
+ self.force = args.force
80
+ self.list = args.list
81
+
66
82
  self.installer = InstallManager()
67
83
  self.plugin_path = Path(bconfig.bmcgo_config_list.get(misc.CUSTOM_PLUGINS, misc.DEFAULT_PLUGINS_PATH))
68
84
 
69
85
  def run(self):
70
- self.installer.install(*self._parse_version(), self.plugin_path)
86
+ app, opt, ver = self._parse_version()
87
+ self.installer.init(app, opt, ver, self.plugin_path)
88
+
89
+ if self.list:
90
+ self._list_all_versions()
91
+ return 0
92
+
93
+ self.installer.pre_install()
94
+ self.installer.install(self.force)
95
+ self.installer.post_install()
96
+
97
+ log.info(f"安装{self.version}已完成!")
71
98
  return 0
72
99
 
100
+ def _list_all_versions(self):
101
+ self.installer.show_versions()
102
+
73
103
  def _parse_version(self):
74
104
  match = re.search(self.VERSION_PATTERN, self.version)
75
105
  if match:
bmcgo/misc.py CHANGED
@@ -17,7 +17,7 @@ from bmcgo.logger import Logger
17
17
 
18
18
  log = Logger("work_prepare")
19
19
 
20
- CACHE_DIR = "/tmp/bmcgo"
20
+ CACHE_DIR = f"{os.path.expanduser('~')}/.bmcgo_log"
21
21
  CONAN_REPO = "openubmc_dev"
22
22
  CONAN_USER = 'openUBMC'
23
23
 
@@ -41,6 +41,7 @@ GRP_STUDIO = "Studio commands"
41
41
  DESCRIPTION = "description"
42
42
  PATTERN = "pattern"
43
43
  ENV_CONST = "env"
44
+ JSON_CHECKER = "json_checker"
44
45
  HTTP_PROXY_CONST = "http_proxy"
45
46
  HTTPS_PROXY_CONST = "https_proxy"
46
47
  FTP_PROXY_CONST = "ftp_proxy"
@@ -48,7 +49,7 @@ NO_PROXY_CONST = "no_proxy"
48
49
  TIMESTAMP_SIGN_SERVER = "timestamp_sign_server"
49
50
  JARSIGNER_HTTP_PROXY = "jarsigner_http_proxy"
50
51
  CUSTOM_PLUGINS = "plugins_path"
51
- DEFAULT_PLUGINS_PATH = "/usr/share/bmcgo/plugins/"
52
+ DEFAULT_PLUGINS_PATH = os.path.join(os.environ["HOME"], ".bmcgo", "plugins")
52
53
 
53
54
  DEPLOY_HOST_CONST = "deploy-host"
54
55
  PORT_CONST = "port"
@@ -73,6 +74,35 @@ HELP = "help"
73
74
  ROOTCA_DER = "rootca.der"
74
75
  CMS_CRL = "cms.crl"
75
76
 
77
+ # hpm签名CA根证书配置
78
+ HPM_SIGN_ROOTCA_DER = "rootca_der"
79
+
80
+ # hpm服务器签名配置
81
+ HPM_SERVER_SIGN = "hpm_server_sign"
82
+ HPM_SERVER_SIGN_CERT_ID = "cert_id"
83
+ HPM_SERVER_SIGN_URL = "url"
84
+ HPM_SERVER_SIGN_SSL_VERYFY = "ssl_verify"
85
+
86
+ # hpm自签名配置
87
+ HPM_SELF_SIGN = "hpm_self_sign"
88
+ HPM_SELF_SIGN_ROOTCA_CRL = "rootca_crl"
89
+ HPM_SELF_SIGN_SIGNER_PEM = "signer_pem"
90
+ HPM_SELF_SIGN_TS_PEM = "ts_signer_pem"
91
+ HPM_SELF_SIGN_TS_CNF = "ts_signer_cnf"
92
+
93
+ # eeprom服务器签名配置
94
+ E2P_SERVER_SIGN = "eeprom_server_sign"
95
+ E2P_SERVER_SIGN_URL = "url"
96
+
97
+ # eeprom自签名配置
98
+ E2P_SELF_SIGN = "eeprom_self_sign"
99
+ E2P_SELF_SIGN_PEM = "priv_pem"
100
+
101
+ # hpm加密配置
102
+ HPM_ENCRYPT = "hpm_encrypt"
103
+ HPM_ENCRYPT_ENABLE = "enable"
104
+ HPM_ENCRYPT_TOOL = "crypto_tool"
105
+
76
106
 
77
107
  class StageEnum(Enum):
78
108
  STAGE_DEV = "dev"
@@ -11,5 +11,11 @@ subworks:
11
11
  - work.prepare_env
12
12
  - name: task_download_dependency
13
13
  klass: bmcgo.tasks.task_download_dependency
14
+ wait:
15
+ - work.prepare_env
16
+ - name: work.task_prepare_tools
17
+ klass: works.packet.work_prepare_tools.TaskClass
18
+ # 当类不存在时,不执行
19
+ ignore_not_exist: true
14
20
  wait:
15
21
  - work.prepare_env
bmcgo/tasks/task.py CHANGED
@@ -257,50 +257,12 @@ class Task(Process):
257
257
  return self.tools.pipe_command(commands, out_file, **kwargs)
258
258
 
259
259
  def signature(self, unsigned_file, cms_output, crl_output, ca_output):
260
- sign_server = self.get_manufacture_config("base/signature/simple_signer_server")
261
- if not sign_server:
262
- """自签名方法"""
263
- unsigned_file = os.path.realpath(unsigned_file)
264
- cms_output = os.path.realpath(cms_output)
265
- tmp_dir = tempfile.TemporaryDirectory()
266
- cwd = os.getcwd()
267
- self.chdir(tmp_dir.name)
268
- rootca_der = self.config.rootca_der
269
- rootca_crl = self.config.rootca_crl
270
- signer_pem = self.config.signer_pem
271
- ts_signer_pem = self.config.ts_signer_pem
272
- ts_signer_cnf = self.config.ts_signer_cnf
273
- self.run_command(f"openssl x509 -in {rootca_der} -inform der -outform pem -out rootca.pem")
274
- self.run_command(f"openssl crl -in {rootca_crl} -inform der -outform pem -out cms.crl.pem")
275
- cmd = f"hpm_signer -s {signer_pem} -t {ts_signer_pem} -T {ts_signer_cnf} -i {unsigned_file} -o {cms_output}"
276
- self.run_command(cmd)
277
- self.run_command(f"hpm_verify -r rootca.pem -C cms.crl.pem -c {unsigned_file} -s {cms_output}")
278
- self.chdir(cwd)
279
- self.tools.copy(rootca_crl, crl_output)
280
- self.tools.copy(rootca_der, ca_output)
260
+ manifest_sign_server = self.get_manufacture_config("base/signature/simple_signer_server")
261
+ hpm_server_sign = self.config.bconfig.hpm_server_sign
262
+ if manifest_sign_server or hpm_server_sign:
263
+ self._server_signature(unsigned_file, cms_output, crl_output, ca_output)
281
264
  else:
282
- cert_id = sign_server.get("cert_id")
283
- url = sign_server.get("url")
284
- ssl_verify = sign_server.get("ssl_verify")
285
- rootca_der = sign_server.get("rootca_der")
286
- if not os.path.isfile(rootca_der):
287
- raise FileNotFoundError(f"签名根证书{rootca_der}不存在")
288
- unsigned_file = os.path.realpath(unsigned_file)
289
- cms_output = os.path.realpath(cms_output)
290
- crl_output = os.path.realpath(crl_output)
291
- ca_output = os.path.realpath(ca_output)
292
- cwd = os.getcwd()
293
- tmpdir = tempfile.TemporaryDirectory()
294
- self.chdir(tmpdir.name)
295
- args = ["-i", unsigned_file, "-s", cert_id, "-u", url, "-v", ssl_verify]
296
- cmd = SimpleSign(self.config.bconfig, args)
297
- cmd.run()
298
- # 签名工具会输出rootca.crl和signed.cms
299
- self.tools.copy("signed.cms", cms_output)
300
- self.tools.copy("rootca.crl", crl_output)
301
- # 签名根证书在manifest.yml中配置
302
- self.tools.copy(rootca_der, ca_output)
303
- os.chdir(cwd)
265
+ self._local_signature(unsigned_file, cms_output, crl_output, ca_output)
304
266
 
305
267
  def error(self, msg, *args, **kwargs):
306
268
  uptrace = kwargs.get("uptrace", None)
@@ -381,3 +343,67 @@ class Task(Process):
381
343
  self.info(f"执行脚本 {comp}/include/customization.py 开始")
382
344
  post = ComponentPost(self.config, os.path.join(conan_install, comp), profile)
383
345
  post.post_work(os.getcwd(), action)
346
+
347
+ def _local_signature(self, unsigned_file, cms_output, crl_output, ca_output):
348
+ """自签名方法"""
349
+ self_sign_config = self.config.bconfig.hpm_self_sign
350
+ unsigned_file = os.path.realpath(unsigned_file)
351
+ cms_output = os.path.realpath(cms_output)
352
+ tmp_dir = tempfile.TemporaryDirectory()
353
+ cwd = os.getcwd()
354
+ self.chdir(tmp_dir.name)
355
+ certificates = self.get_manufacture_config("base/signature/certificates")
356
+ if certificates:
357
+ rootca_der = self.config.rootca_der
358
+ rootca_crl = self.config.rootca_crl
359
+ signer_pem = self.config.signer_pem
360
+ ts_signer_pem = self.config.ts_signer_pem
361
+ ts_signer_cnf = self.config.ts_signer_cnf
362
+ else:
363
+ rootca_der = self_sign_config.rootca_der
364
+ rootca_crl = self_sign_config.rootca_crl
365
+ signer_pem = self_sign_config.signer_pem
366
+ ts_signer_pem = self_sign_config.ts_signer_pem
367
+ ts_signer_cnf = self_sign_config.ts_signer_cnf
368
+ self.run_command(f"openssl x509 -in {rootca_der} -inform der -outform pem -out rootca.pem")
369
+ self.run_command(f"openssl crl -in {rootca_crl} -inform der -outform pem -out cms.crl.pem")
370
+ cmd = f"hpm_signer -s {signer_pem} -t {ts_signer_pem} -T {ts_signer_cnf} -i {unsigned_file} -o {cms_output}"
371
+ self.run_command(cmd)
372
+ self.run_command(f"hpm_verify -r rootca.pem -C cms.crl.pem -c {unsigned_file} -s {cms_output}")
373
+ self.log.info(f"使用 hpm_signer 自签名 {unsigned_file} 成功")
374
+ self.chdir(cwd)
375
+ self.tools.copy(rootca_crl, crl_output)
376
+ self.tools.copy(rootca_der, ca_output)
377
+
378
+ def _server_signature(self, unsigned_file, cms_output, crl_output, ca_output):
379
+ manifest_sign_server = self.get_manufacture_config("base/signature/simple_signer_server")
380
+ hpm_server_sign = self.config.bconfig.hpm_server_sign
381
+ if manifest_sign_server:
382
+ rootca_der = manifest_sign_server.get("rootca_der")
383
+ url = manifest_sign_server.get("url")
384
+ cert_id = manifest_sign_server.get("cert_id")
385
+ ssl_verify = manifest_sign_server.get("ssl_verify")
386
+ else:
387
+ rootca_der = hpm_server_sign.rootca_der
388
+ url = hpm_server_sign.url
389
+ cert_id = hpm_server_sign.cert_id
390
+ ssl_verify = hpm_server_sign.ssl_verify
391
+
392
+ if not os.path.isfile(rootca_der):
393
+ raise FileNotFoundError(f"签名根证书{rootca_der}不存在")
394
+ unsigned_file = os.path.realpath(unsigned_file)
395
+ cms_output = os.path.realpath(cms_output)
396
+ crl_output = os.path.realpath(crl_output)
397
+ ca_output = os.path.realpath(ca_output)
398
+ cwd = os.getcwd()
399
+ tmpdir = tempfile.TemporaryDirectory()
400
+ self.chdir(tmpdir.name)
401
+ args = ["-i", unsigned_file, "-s", cert_id, "-u", url, "-v", ssl_verify]
402
+ cmd = SimpleSign(self.config.bconfig, args)
403
+ cmd.run()
404
+ # 签名工具会输出rootca.crl和signed.cms
405
+ self.tools.copy("signed.cms", cms_output)
406
+ self.tools.copy("rootca.crl", crl_output)
407
+ # 签名根证书在manifest.yml中配置
408
+ self.tools.copy(rootca_der, ca_output)
409
+ os.chdir(cwd)
@@ -540,15 +540,19 @@ class TaskClass(Task):
540
540
  self.run_command(f"rm -rf {self.top_rootfs_dir}")
541
541
  self.run_command(f"cp -rf {top_rootfs} {self.top_rootfs_dir}")
542
542
 
543
+ version_path = self.top_rootfs_dir
543
544
  # 复制单板目录下的权限配置和rootfs文件
544
545
  rootfs_dir = os.path.join(self.config.board_path, "rootfs")
545
546
  if os.path.isdir(rootfs_dir):
546
547
  self.run_command(f"rm -rf {self.openubmc_ins_dir}")
547
548
  self.run_command(f"cp -rf {rootfs_dir} {self.openubmc_ins_dir}")
548
- self.config.version_conf(f"{self.openubmc_ins_dir}/etc/version.json")
549
- self.config.show_version_conf(f"{self.openubmc_ins_dir}/etc/version.json")
550
549
  else:
551
550
  os.makedirs(self.openubmc_ins_dir)
551
+
552
+ if os.path.isfile(f"{self.openubmc_ins_dir}/etc/version.json"):
553
+ version_path = self.openubmc_ins_dir
554
+ self.config.version_conf(f"{version_path}/etc/version.json")
555
+ self.config.show_version_conf(f"{version_path}/etc/version.json")
552
556
  per_file = os.path.join(self.config.board_path, "permissions.ini")
553
557
  if os.path.isfile(per_file):
554
558
  shutil.copy(per_file, self.openubmc_ins_dir)
@@ -22,12 +22,12 @@ class TaskClass(Task):
22
22
 
23
23
  def get_wbd_file_config(self):
24
24
  wbd_up_file_config = None
25
- if self.config.tosupporte_code:
26
- wbd_config_path = f"tosupporte/{self.config.tosupporte_code}/wbd_up_files"
27
- wbd_up_file_config = self.get_manufacture_config(wbd_config_path)
28
- elif self.config.manufacture_code:
25
+ if self.config.manufacture_code:
29
26
  wbd_config_path = f"manufacture/{self.config.manufacture_code}/wbd_up_files"
30
27
  wbd_up_file_config = self.get_manufacture_config(wbd_config_path)
28
+ elif self.config.tosupporte_code:
29
+ wbd_config_path = f"tosupporte/{self.config.tosupporte_code}/wbd_up_files"
30
+ wbd_up_file_config = self.get_manufacture_config(wbd_config_path)
31
31
  else:
32
32
  pass
33
33
 
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/python
2
+ # -*- coding: utf-8 -*-
3
+ # Copyright (c) 2025 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
+ from enum import Enum, EnumMeta, auto
13
+
14
+
15
+ class StringEnumMeta(EnumMeta):
16
+ def __contains__(cls, value):
17
+ return value in cls._value2member_map_
18
+
19
+ def __iter__(cls):
20
+ return (mem.value for mem in super().__iter__())
21
+
22
+ def __repr__(cls):
23
+ return repr(list(cls))
24
+
25
+ def __str__(cls):
26
+ return str(list(cls))
27
+
28
+
29
+ class BaseStringEnum(str, Enum, metaclass=StringEnumMeta):
30
+ def __str__(self):
31
+ return self.value
32
+
33
+ def __repr__(self):
34
+ return f"'{self.value}'"
35
+
36
+ @staticmethod
37
+ def _generate_next_value_(name, start, count, last_values):
38
+ return name.lower()
39
+
40
+ @classmethod
41
+ def _missing_(cls, value):
42
+ for mem in cls:
43
+ if mem.value.lower() == value:
44
+ return mem
45
+ return None
bmcgo/utils/config.py CHANGED
@@ -142,10 +142,15 @@ class Config:
142
142
 
143
143
  @property
144
144
  def self_sign(self):
145
- certificates = self.get_manufacture_config("base/signature/certificates")
146
- if not certificates:
147
- certificates = self.get_manufacture_config("base/signature/simple_signer_server")
148
- return certificates is not None
145
+ self_sign_config = self.get_manufacture_config("base/signature/simple_signer_server")
146
+ if not self_sign_config:
147
+ self_sign_config = self.get_manufacture_config("base/signature/certificates")
148
+ if not self_sign_config:
149
+ self_sign_config = self.bconfig.hpm_server_sign
150
+ if not self_sign_config:
151
+ self_sign_config = self.bconfig.hpm_self_sign
152
+
153
+ return self_sign_config is not None
149
154
 
150
155
  @property
151
156
  def rootca_der(self):
@@ -1012,8 +1017,12 @@ class Config:
1012
1017
  def parse_args(self, args=None):
1013
1018
  parser = self.argparser(self.code_path)
1014
1019
  args, _ = parser.parse_known_args(args)
1020
+ if args.zip_code and args.supporte_code != "default":
1021
+ raise errors.ConfigException("manufacture 编码和 tosupporte 编码不能同时存在")
1022
+
1015
1023
  self.set_manufacture_code(args.zip_code)
1016
- self.set_tosupporte_code(args.supporte_code)
1024
+ if not args.zip_code:
1025
+ self.set_tosupporte_code(args.supporte_code)
1017
1026
  self.set_from_source(args.from_source)
1018
1027
  self.set_build_type(args.build_type)
1019
1028
  self.set_stage(args.stage)
@@ -1035,14 +1044,17 @@ class Config:
1035
1044
  self.get_archive()
1036
1045
  self.init_conan_profile(args.profile)
1037
1046
 
1038
- if self.manufacture_code is not None and self.tosupporte_code != "default":
1039
- raise errors.ConfigException("manufacture 编码和 tosupport E 编码不能同时存在")
1040
-
1041
1047
  # 构建阶段检查
1042
1048
  bt = ["dt", "debug", "release"]
1043
1049
  if args.build_type not in bt:
1044
1050
  raise errors.ConfigException("构建类型 build_type 错误, 可用选项为: [debug, release, dt], 请检查参数")
1045
1051
 
1052
+ hpm_encrypt = self.bconfig.hpm_encrypt
1053
+ if hpm_encrypt and hpm_encrypt.need_encrypt:
1054
+ if not shutil.which("crypto_tool"):
1055
+ raise errors.BmcGoException(f"开启了hpm加密配置, 在环境中未找到 'crypto_tool', 请确认环境配置是否正确.")
1056
+ os.environ["HPM_ENCRYPT"] = "true"
1057
+
1046
1058
  def _load_manifest_with_template(self, filename, template):
1047
1059
  try:
1048
1060
  real_sha256 = Config._calc_manifest_data_sha256(filename, template)
@@ -12,19 +12,23 @@
12
12
  # See the Mulan PSL v2 for more details.
13
13
 
14
14
  from pathlib import Path
15
- from bmcgo.utils.tools import Logger
15
+ from typing import Dict, List
16
+ from bmcgo import misc
17
+ from bmcgo.utils.tools import Tools
16
18
  from bmcgo.utils.installations import install_consts
17
19
  from bmcgo.utils.installations.install_workflow import InstallWorkflow
18
20
  from bmcgo.utils.installations.base_installer import BaseInstaller
19
21
 
20
- logger = Logger(name="upgrade", log_file="/usr/share/bmcgo/install.log")
21
- InstallWorkflow.logger = logger
22
- BaseInstaller.logger = logger
22
+
23
+ tools = Tools("install")
24
+ logger = tools.log
23
25
 
24
26
 
25
27
  class InstallManager:
26
28
  def __init__(self):
27
29
  self._custom_path = None
30
+ self._workflows = []
31
+ self._installers: Dict[str, List[BaseInstaller]] = {}
28
32
 
29
33
  @property
30
34
  def custom_installer_path(self):
@@ -33,29 +37,80 @@ class InstallManager:
33
37
  @property
34
38
  def custom_install_plan_path(self):
35
39
  return self._custom_path / install_consts.PLUGIN_INSTALL_PLAN_PATH
36
-
37
- def install(self, app_name, operator, version, custom_path):
40
+
41
+ def init(self, app_name, operator, version, custom_path):
38
42
  self._set_custom_path(custom_path)
39
- BaseInstaller.discover_installers()
40
- InstallWorkflow.discover_workflows()
41
43
 
42
- workflows = []
43
44
  if app_name == install_consts.INSTALL_ALL:
44
- workflows = list(InstallWorkflow.get_all_plans())
45
+ self._workflows = list(InstallWorkflow.get_all_plans())
45
46
  else:
46
- workflows = [app_name]
47
+ self._workflows = [app_name]
48
+
49
+ for wname in self._workflows:
50
+ workflow = InstallWorkflow.parse(wname)
51
+ plans = workflow.get(install_consts.PLAN_STEPS, [])
52
+ for plan in plans:
53
+ inst_type = plan.get(install_consts.PLAN_INSTALL_TYPE)
54
+ if not inst_type:
55
+ raise ValueError(f"未配置 {wname}/{install_consts.PLAN_STEPS}/{install_consts.PLAN_INSTALL_TYPE}")
56
+ inst = BaseInstaller.get_installer(inst_type)
57
+ inst.init(plan, operator, version)
58
+ self._installers.setdefault(wname, []).append(inst)
47
59
 
48
- for wname in workflows:
49
- logger.info(f"安装{wname}...")
60
+ def show_versions(self):
61
+ for wname in self._workflows:
62
+ if wname not in self._installers:
63
+ raise RuntimeError(f"初始化 {wname} 出现问题,请重试!")
64
+
65
+ for inst in self._installers[wname]:
66
+ logger.info(f"获取 {inst.package_name} {inst.type_name} 版本信息...")
67
+ inst.show_versions()
68
+
69
+ def pre_install(self):
70
+ for wname in self._workflows:
71
+ logger.info(f"安装 {wname} 前检查...")
50
72
  plans = InstallWorkflow.parse(wname)
51
- for plan in plans.get(install_consts.PLAN_STEPS, []):
52
- inst_type = plan.get(install_consts.PLAN_INSTALL_TYPE)
53
- BaseInstaller.get_installer(inst_type).install(plan, operator, version)
73
+ verisons = {}
74
+ if wname not in self._installers:
75
+ raise RuntimeError(f"初始化 {wname} 出现问题,请重试!")
76
+ for inst in self._installers[wname]:
77
+ inst.pre_install()
78
+ verisons[inst.type_name] = inst.target_version
79
+
80
+ require_version_homogeneous = plans.get(install_consts.PLAN_VERSION_HOMOGENEOUS, False)
81
+ if require_version_homogeneous and len(set(verisons.values())) > 1:
82
+ for t, v in verisons.items():
83
+ logger.error(f"{t}: {v}")
84
+ raise ValueError("版本不一致,终止安装!")
85
+
86
+ def install(self, force):
87
+ logger.info("开始安装...")
88
+ for wname in self._workflows:
89
+ logger.info(f"安装{wname}...")
90
+ try:
91
+ if wname not in self._installers:
92
+ raise RuntimeError(f"初始化 {wname} 出现问题,请重试!")
93
+ for inst in self._installers[wname]:
94
+ inst.install(force)
95
+ except Exception as e:
96
+ logger.info(f"安装失败,回退{wname}...")
97
+ if wname not in self._installers:
98
+ raise RuntimeError(f"初始化 {wname} 出现问题,请重试!") from e
99
+ for inst in self._installers[wname]:
100
+ inst.rollback()
101
+ raise RuntimeError("安装失败") from e
102
+
103
+ def post_install(self):
104
+ for wname in self._workflows:
105
+ logger.info(f"清理安装{wname}的中间文件...")
106
+ if wname not in self._installers:
107
+ raise RuntimeError(f"初始化 {wname} 出现问题,请重试!")
108
+ for inst in self._installers[wname]:
109
+ inst.post_install()
54
110
 
55
111
  def _set_custom_path(self, custom_path: str):
56
112
  self._custom_path = Path(custom_path).resolve()
57
- if not self._custom_path.exists() or not self._custom_path.is_dir():
58
- logger.warning(f"无效的地址: {self._custom_path}")
59
- return
60
113
  BaseInstaller.add_installer_dir(self.custom_installer_path)
61
- InstallWorkflow.add_plan_dir(self.custom_install_plan_path)
114
+ InstallWorkflow.add_plan_dir(self.custom_install_plan_path)
115
+ BaseInstaller.discover_installers()
116
+ InstallWorkflow.discover_workflows()