openubmc-bingo 0.5.277__py3-none-any.whl → 0.6.2__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 (53) hide show
  1. bmcgo/__init__.py +1 -1
  2. bmcgo/bmcgo_config.py +22 -10
  3. bmcgo/cli/cli.py +95 -39
  4. bmcgo/cli/config.conan2.yaml +9 -0
  5. bmcgo/codegen/lua/codegen.py +2 -2
  6. bmcgo/codegen/lua/script/gen_intf_rpc_json.py +15 -14
  7. bmcgo/component/analysis/analysis.py +8 -8
  8. bmcgo/component/analysis/intf_validation.py +23 -12
  9. bmcgo/component/build.py +76 -14
  10. bmcgo/component/component_dt_version_parse.py +3 -2
  11. bmcgo/component/component_helper.py +43 -15
  12. bmcgo/component/coverage/incremental_cov.py +2 -2
  13. bmcgo/component/deploy.py +68 -14
  14. bmcgo/component/gen.py +1 -1
  15. bmcgo/component/package_info.py +128 -38
  16. bmcgo/component/template/conanbase.py.mako +1 -0
  17. bmcgo/component/template_v2/conanbase.py.mako +383 -0
  18. bmcgo/component/template_v2/conanfile.deploy.py.mako +26 -0
  19. bmcgo/component/test.py +53 -20
  20. bmcgo/frame.py +7 -3
  21. bmcgo/functional/analysis.py +3 -2
  22. bmcgo/functional/check.py +10 -6
  23. bmcgo/functional/conan_index_build.py +96 -20
  24. bmcgo/functional/csr_build.py +1 -1
  25. bmcgo/functional/diff.py +1 -1
  26. bmcgo/functional/fetch.py +1 -1
  27. bmcgo/functional/full_component.py +32 -24
  28. bmcgo/functional/git_history.py +220 -0
  29. bmcgo/functional/maintain.py +55 -12
  30. bmcgo/functional/new.py +1 -1
  31. bmcgo/functional/schema_valid.py +2 -2
  32. bmcgo/logger.py +2 -3
  33. bmcgo/misc.py +130 -9
  34. bmcgo/tasks/conan/__init__.py +10 -0
  35. bmcgo/tasks/conan/conanfile.py +45 -0
  36. bmcgo/tasks/task.py +27 -4
  37. bmcgo/tasks/task_build_conan.py +425 -53
  38. bmcgo/tasks/task_buildgppbin.py +8 -2
  39. bmcgo/tasks/task_download_buildtools.py +76 -0
  40. bmcgo/tasks/task_download_dependency.py +1 -0
  41. bmcgo/tasks/task_hpm_envir_prepare.py +1 -1
  42. bmcgo/utils/build_conans.py +231 -0
  43. bmcgo/utils/component_post.py +6 -4
  44. bmcgo/utils/component_version_check.py +75 -16
  45. bmcgo/utils/config.py +76 -40
  46. bmcgo/utils/fetch_component_code.py +44 -25
  47. bmcgo/utils/tools.py +239 -117
  48. bmcgo/worker.py +2 -2
  49. {openubmc_bingo-0.5.277.dist-info → openubmc_bingo-0.6.2.dist-info}/METADATA +4 -2
  50. {openubmc_bingo-0.5.277.dist-info → openubmc_bingo-0.6.2.dist-info}/RECORD +53 -46
  51. {openubmc_bingo-0.5.277.dist-info → openubmc_bingo-0.6.2.dist-info}/WHEEL +0 -0
  52. {openubmc_bingo-0.5.277.dist-info → openubmc_bingo-0.6.2.dist-info}/entry_points.txt +0 -0
  53. {openubmc_bingo-0.5.277.dist-info → openubmc_bingo-0.6.2.dist-info}/top_level.txt +0 -0
bmcgo/utils/tools.py CHANGED
@@ -26,22 +26,38 @@ import functools
26
26
  import inspect
27
27
  import configparser
28
28
  from typing import Callable
29
- from tempfile import TemporaryFile
29
+ from tempfile import TemporaryFile, TemporaryDirectory
30
30
  from string import Template
31
31
  from subprocess import Popen, PIPE
32
32
  from collections import OrderedDict
33
33
 
34
34
  import jsonschema
35
+ import requests
36
+ from tqdm import tqdm
35
37
  import yaml
36
- from conans.model.profile import Profile
37
- from conans.client.profile_loader import read_profile
38
38
 
39
+ from bmcgo import misc
39
40
  from bmcgo.logger import Logger
40
41
  from bmcgo.errors import BmcGoException, EnvironmentException
41
- from bmcgo import misc
42
42
  from bmcgo import errors
43
43
  from bmcgo.logger import Logger
44
44
 
45
+ if misc.conan_v2():
46
+ from conan.internal.api.profile.profile_loader import ProfileLoader
47
+ else:
48
+ from conans.client.profile_loader import read_profile
49
+
50
+
51
+ def env_set(key, value, append=False):
52
+ if not append:
53
+ os.environ[key] = value
54
+ return
55
+ old_value = os.environ.get(key, "")
56
+ new_value = ":" + value
57
+ if new_value in old_value:
58
+ return
59
+ os.environ[key] = old_value + new_value
60
+
45
61
 
46
62
  class Tools():
47
63
  """
@@ -68,7 +84,10 @@ class Tools():
68
84
 
69
85
  @property
70
86
  def conan_home(self):
71
- return os.path.expanduser("~/.conan")
87
+ if misc.conan_v2():
88
+ return os.path.expanduser("~/.conan2")
89
+ else:
90
+ return os.path.expanduser("~/.conan")
72
91
 
73
92
  @property
74
93
  def conan_profiles_dir(self):
@@ -93,10 +112,11 @@ class Tools():
93
112
  cmd_args = command
94
113
  elif isinstance(command, str):
95
114
  cmd_args = shlex.split(command)
96
- cmd = shutil.which(cmd_args[0])
97
- if cmd is None:
98
- raise EnvironmentException(f"{cmd_args[0]}不存在, 请检查命令或环境配置")
99
- cmd_args[0] = cmd
115
+ if cmd_args[0] != "source":
116
+ cmd = shutil.which(cmd_args[0])
117
+ if cmd is None:
118
+ raise EnvironmentException(f"{cmd_args[0]}不存在, 请检查命令或环境配置")
119
+ cmd_args[0] = cmd
100
120
  else:
101
121
  raise BmcGoException(f"不支持的命令参数格式: {command}, 请检查命令格式")
102
122
  sudo_cmd = shutil.which("sudo")
@@ -187,17 +207,24 @@ class Tools():
187
207
  return profile_help_text
188
208
 
189
209
  @staticmethod
190
- def get_conan_profile(profile: str, build_type: str, enable_luajit=False):
210
+ def get_conan_profile(profile: str, build_type: str, enable_luajit=False, test=False):
191
211
  """
192
212
  根据参数与配置获取conan构建使用的profile文件名。
193
213
  """
194
214
  if profile:
195
215
  return str(profile)
196
216
 
197
- if build_type == "dt":
217
+ if misc.conan_v1() and build_type == "dt":
198
218
  return "profile.dt.ini"
199
-
200
- return "profile.luajit.ini"
219
+ if misc.conan_v2 and test:
220
+ return "profile.dt.ini"
221
+ if misc.community_name() == "openubmc":
222
+ return "profile.luajit.ini"
223
+ if not enable_luajit:
224
+ return "profile.ini"
225
+ if misc.conan_v1():
226
+ return "profile.luajit.ini"
227
+ return "profile.ini"
201
228
 
202
229
  @staticmethod
203
230
  def check_product_dependencies(top, base):
@@ -213,7 +240,6 @@ class Tools():
213
240
  @staticmethod
214
241
  def check_base_dependencies(base_manifest, com_package, dependency_type):
215
242
  name = com_package.get(misc.CONAN)
216
- action = com_package.get("action", "")
217
243
  pkg_info = name.split("/")
218
244
  pkg_name = pkg_info[0]
219
245
  has_version = len(pkg_info) > 1
@@ -222,7 +248,7 @@ class Tools():
222
248
  sub_pkg_name = sub_name.split("/")[0]
223
249
  # 上下层具有相同组件名的组件
224
250
  if pkg_name == sub_pkg_name:
225
- if has_version or action:
251
+ if has_version:
226
252
  raise errors.BmcGoException(
227
253
  "配置错误: 不允许删除平台组件或定制平台组件版本号{}".format(name)
228
254
  )
@@ -277,74 +303,26 @@ class Tools():
277
303
  if stage == misc.StageEnum.STAGE_DEV.value:
278
304
  # 开发者测试模式
279
305
  stage = misc.StageEnum.STAGE_RC.value
280
- # else: rc和stable模式
281
- channel = f"@{Tools().conan_user}/{stage}"
282
306
 
283
307
  if len(version_split) == 2:
308
+ # rc和stable模式
309
+ channel = f"@{misc.conan_user()}/{stage}"
284
310
  package[misc.CONAN] += channel
285
311
 
286
- @staticmethod
287
- def install_platform(platform_package, stage, remote):
288
- Tools().fix_platform(platform_package, stage)
289
- rtos_version = platform_package.get("options", {}).get(
290
- "rtos_version", "rtos_v2"
291
- )
292
- append_cmd = f"-r {remote}" if remote else ""
293
- Tools().run_command(
294
- f"conan install {platform_package[misc.CONAN]} {append_cmd} -o rtos_version={rtos_version}"
295
- )
296
- version_split = re.split(r"[/, @]", platform_package[misc.CONAN])
297
- package_conan_dir = os.path.join(
298
- os.path.expanduser("~"), ".conan/data/", *version_split
299
- )
300
- cmd = f"conan info {platform_package[misc.CONAN]} {append_cmd} -o rtos_version={rtos_version} -j"
301
- cmd_info = Tools().run_command(
302
- cmd,
303
- capture_output=True,
304
- )
305
- info = json.loads(cmd_info.stdout)
306
- for i in info:
307
- package_conan_dir = os.path.join(
308
- package_conan_dir, "package", i["id"], rtos_version
309
- )
310
- return package_conan_dir
311
-
312
- @staticmethod
313
- def get_manifest_dependencies(manifest_build_dir, file_path, stage, remote):
314
- with open(file_path, "r") as f_:
315
- base_manifest = yaml.safe_load(f_)
316
- top_dependencies = base_manifest[misc.CONAN_DEPDENCIES_KEY]
317
- platform_package = base_manifest.get("platform", {})
318
- if platform_package:
319
- package_conan_dir = Tools.install_platform(platform_package, stage, remote)
320
- top_dependencies.append(platform_package)
321
- platform_src = os.path.join(package_conan_dir, "manifest.yml")
322
- with open(platform_src, "r") as f_:
323
- platform_manifest = yaml.safe_load(f_)
324
- Tools.check_product_dependencies(base_manifest, platform_manifest)
325
- top_dependencies = Tools.merge_dependencies(
326
- top_dependencies, platform_manifest[misc.CONAN_DEPDENCIES_KEY]
327
- )
328
- inc_filename = base_manifest.get("include")
329
- if not inc_filename:
330
- return top_dependencies
331
- file_path = inc_filename.replace(
332
- "${product}", os.path.join(manifest_build_dir, "product")
333
- )
334
- base_dependencies = Tools.get_manifest_dependencies(manifest_build_dir, file_path, stage, remote)
335
- dep = Tools.merge_dependencies(top_dependencies, base_dependencies)
336
- return dep
337
-
338
312
  @staticmethod
339
313
  def create_common_parser(description):
340
314
  parser = argparse.ArgumentParser(description=description)
341
315
  parser.add_argument("-cp", "--conan_package", help="软件包名, 示例: kmc/24.0.0.B020", default="")
342
316
  parser.add_argument("-uci", "--upload_package", help="是否上传软件包", action=misc.STORE_TRUE)
343
- parser.add_argument("-o", "--options", help="组件特性配置, 示例: -o skynet:enable_luajit=True",
344
- action='append')
317
+ if misc.conan_v2():
318
+ parser.add_argument("-o", "--options", help="组件特性配置, 示例: -o skynet/*:enable_luajit=True", action="append",)
319
+ parser.add_argument("-bt", "--build_type", help="构建类型,可选:debug(调试包), release(正式包)",
320
+ default="debug")
321
+ else:
322
+ parser.add_argument("-o", "--options", help="组件特性配置, 示例: -o skynet:enable_luajit=True", action='append')
323
+ parser.add_argument("-bt", "--build_type", help="构建类型,可选:debug(调试包), release(正式包), dt(开发者测试包)",
324
+ default="debug")
345
325
  parser.add_argument("-r", "--remote", help="指定conan远端")
346
- parser.add_argument("-bt", "--build_type", help="构建类型,可选:debug(调试包), release(正式包), dt(开发者测试包)",
347
- default="debug")
348
326
  parser.add_argument("--stage", help="包类型,可选值为: dev(调试包), rc(预发布包), stable(发布包)\n默认:dev",
349
327
  default="dev")
350
328
  parser.add_argument("-jit", "--enable_luajit", help="Enable luajit", action=misc.STORE_TRUE)
@@ -359,7 +337,7 @@ class Tools():
359
337
  return parser
360
338
 
361
339
  @staticmethod
362
- def get_module_symver_option(module_symver_path: str):
340
+ def get_171x_module_symver_option(module_symver_path: str):
363
341
  sha256 = Tools.sha256sum(module_symver_path)
364
342
  return ("module_symver", sha256)
365
343
 
@@ -373,6 +351,70 @@ class Tools():
373
351
  else:
374
352
  os.makedirs(conan_bin)
375
353
 
354
+ @staticmethod
355
+ def download_file(url, file_path):
356
+ response = requests.get(url, stream=True)
357
+ response.raise_for_status()
358
+ total_size = int(response.headers.get("content-length", 0))
359
+
360
+ with open(file_path, 'wb') as f, tqdm(
361
+ total=total_size,
362
+ unit='B',
363
+ unit_scale=True,
364
+ desc=file_path,
365
+ miniters=1
366
+ ) as pbar:
367
+ for chunk in response.iter_content(chunk_size=8192):
368
+ f.write(chunk)
369
+ pbar.update(len(chunk))
370
+
371
+ @staticmethod
372
+ def get_hi171x_module_symver_option(path: str):
373
+ sha256 = Tools.sha256sum(path)
374
+ return ("module_symvers", sha256)
375
+
376
+ @staticmethod
377
+ def install_platform_v1(platform_package, stage, remote):
378
+ Tools().fix_platform(platform_package, stage)
379
+ rtos_version = platform_package.get("options", {}).get(
380
+ "rtos_version", "rtos_v2"
381
+ )
382
+ append_cmd = f"-r {remote}" if remote else ""
383
+ Tools().run_command(
384
+ f"conan install {platform_package[misc.CONAN]} {append_cmd} -o rtos_version={rtos_version} --build=missing"
385
+ )
386
+ version_split = re.split(r"[/, @]", platform_package[misc.CONAN])
387
+ package_conan_dir = os.path.join(
388
+ os.path.expanduser("~"), ".conan/data/", *version_split
389
+ )
390
+ cmd = f"conan info {platform_package[misc.CONAN]} {append_cmd} -o rtos_version={rtos_version} -j"
391
+ cmd_info = Tools().run_command(
392
+ cmd,
393
+ capture_output=True,
394
+ )
395
+ info = json.loads(cmd_info.stdout)
396
+ for i in info:
397
+ package_conan_dir = os.path.join(
398
+ package_conan_dir, "package", i["id"], rtos_version
399
+ )
400
+ return package_conan_dir
401
+
402
+ @staticmethod
403
+ def get_package_folder_from_graph_file(graph_file, package):
404
+ """
405
+ 安装conan包到指定outdir目录
406
+ """
407
+ with open(graph_file, "r") as file_handler:
408
+ package_info = json.load(file_handler)
409
+ pkg_name = package.split("/")[0] + "/"
410
+ nodes: dict[str, dict] = package_info.get("graph", {}).get("nodes", {})
411
+ for _, node in nodes.items():
412
+ ref = node.get("ref")
413
+ if not ref or not ref.startswith(pkg_name):
414
+ continue
415
+ return node.get("package_folder")
416
+ return None
417
+
376
418
  @functools.cached_property
377
419
  def is_ubuntu(self):
378
420
  """
@@ -387,17 +429,54 @@ class Tools():
387
429
  return True
388
430
  return False
389
431
 
390
- @functools.cached_property
391
- def conan_user(self):
392
- if os.access(misc.GLOBAL_CFG_FILE, os.R_OK):
393
- try:
394
- conf = configparser.ConfigParser()
395
- conf.read(misc.GLOBAL_CFG_FILE)
396
- return conf.get(misc.CONAN, "user")
397
- except (configparser.NoSectionError, configparser.NoOptionError):
398
- pass
432
+ def install_platform_v2(self, platform_package, remote, update_conan_cache=False):
433
+ name = platform_package.get(misc.CONAN)
434
+ if misc.conan_v2():
435
+ name = name.lower()
436
+ option_key = name.split("/")[0] + "/*"
437
+ rtos_version = platform_package.get("options", {}).get(
438
+ "rtos_version", "rtos_v2"
439
+ )
440
+ enable_haf = platform_package.get("options", {}).get("enable_haf", False)
441
+ append_cmd = f"-o {option_key}:rtos_version={rtos_version}"
442
+ append_cmd += f" -r {remote}" if remote else ""
443
+ append_cmd += f" -o {option_key}:enable_haf=True" if enable_haf else ""
444
+ if update_conan_cache:
445
+ append_cmd += " -u"
446
+ append_cmd += " --build=missing"
447
+ package_folder = self.get_conan_package_folder(name, append_cmd)
448
+ return os.path.join(package_folder, rtos_version)
449
+
450
+ def install_platform(self, platform_package, stage, remote, update_conan_cache=False):
451
+ if misc.conan_v1():
452
+ return self.install_platform_v1(platform_package, stage, remote)
453
+ else:
454
+ return self.install_platform_v2(platform_package, remote, update_conan_cache)
399
455
 
400
- return misc.ConanUserEnum.CONAN_USER_RELEASE.value
456
+ def get_manifest_dependencies(self, manifest_build_dir, file_path, stage, remote, update_conan_cache=False):
457
+ with open(file_path, "r") as f_:
458
+ base_manifest = yaml.safe_load(f_)
459
+ top_dependencies = base_manifest[misc.CONAN_DEPDENCIES_KEY]
460
+ platform_package = base_manifest.get("platform", {})
461
+ if platform_package:
462
+ package_conan_dir = self.install_platform(platform_package, stage, remote, update_conan_cache)
463
+ top_dependencies.append(platform_package)
464
+ platform_src = os.path.join(package_conan_dir, "manifest.yml")
465
+ with open(platform_src, "r") as f_:
466
+ platform_manifest = yaml.safe_load(f_)
467
+ Tools.check_product_dependencies(base_manifest, platform_manifest)
468
+ top_dependencies = Tools.merge_dependencies(
469
+ top_dependencies, platform_manifest[misc.CONAN_DEPDENCIES_KEY]
470
+ )
471
+ inc_filename = base_manifest.get("include")
472
+ if not inc_filename:
473
+ return top_dependencies
474
+ file_path = inc_filename.replace(
475
+ "${product}", os.path.join(manifest_build_dir, "product")
476
+ )
477
+ base_dependencies = self.get_manifest_dependencies(manifest_build_dir, file_path, stage, remote)
478
+ dep = Tools.merge_dependencies(top_dependencies, base_dependencies)
479
+ return dep
401
480
 
402
481
  def get_conan_remote_list(self, remote):
403
482
  conan_remote_list = []
@@ -410,13 +489,16 @@ class Tools():
410
489
 
411
490
  def download_conan_recipes(self, conan_version, conan_remote_list):
412
491
  download_flag = False
492
+ args = "--only-recipe" if misc.conan_v2() else "--recipe"
413
493
  for remote in conan_remote_list:
414
- try:
415
- self.run_command(f"conan download {conan_version} -r {remote} -re", show_error_log=False)
416
- download_flag = True
417
- break
418
- except Exception as e:
419
- self.log.info(f"Recipe not fount in {remote}: {conan_version}")
494
+ # 重试3次
495
+ for _ in range(1, 3):
496
+ try:
497
+ self.run_command(f"conan download {conan_version} -r {remote} {args}", show_error_log=False)
498
+ download_flag = True
499
+ break
500
+ except Exception as e:
501
+ self.log.info(f"Recipe not fount in {remote}: {conan_version}")
420
502
  if not download_flag:
421
503
  raise BmcGoException(f"Download {conan_version} failed")
422
504
 
@@ -532,13 +614,10 @@ class Tools():
532
614
  os.remove(f"{src_file}_bak")
533
615
 
534
616
  def make_img(self, img_path, mnt_datafs, size):
535
- try:
536
- self.run_command(f"/sbin/mkfs.ext4 -d {mnt_datafs} -r 1 -N 0 -m 5 -L \"rootfs\" -I 256 -O \
537
- ^64bit,^metadata_csum {img_path} \"{size}M\"", ignore_error=True, sudo=True)
538
- user_group = f"{os.getuid()}:{os.getgid()}"
539
- self.run_command(f"chown {user_group} {img_path}", sudo=True)
540
- except Exception:
541
- self.log.error(f"{img_path} 镜像制作失败")
617
+ self.run_command(f"/sbin/mkfs.ext4 -d {mnt_datafs} -r 1 -N 0 -m 5 -L \"rootfs\" -I 256 -O \
618
+ ^64bit,^metadata_csum {img_path} \"{size}M\"", sudo=True)
619
+ user_group = f"{os.getuid()}:{os.getgid()}"
620
+ self.run_command(f"chown {user_group} {img_path}", sudo=True)
542
621
 
543
622
  def get_studio_path(self):
544
623
  ret = self.run_command("whereis bmc_studio", sudo=True, ignore_error=True,
@@ -561,20 +640,28 @@ class Tools():
561
640
  command_key = kwargs.get("command_key", None)
562
641
  command_echo = kwargs.get("command_echo", True)
563
642
  show_log = kwargs.get("show_log", False)
643
+ show_error_log = kwargs.get("show_error_log", True)
564
644
  uptrace = kwargs.get("uptrace", 0) + 1
565
645
  error_log = kwargs.get("error_log")
566
646
  warn_log = kwargs.get("warn_log")
647
+ log_name = kwargs.get("log_name")
567
648
  timeout = kwargs.get("timeout", 1200)
568
649
  capture_output = kwargs.get("capture_output", False)
569
650
  if command_key:
570
651
  key = command_key + ":"
571
652
  else:
572
653
  key = ""
573
- if command_echo and not self.log.is_debug:
574
- self.log.info(f">> {key}{command}", uptrace=uptrace)
654
+ if isinstance(command, list):
655
+ cmd_str = " ".join(command)
656
+ else:
657
+ cmd_str = command
658
+ if command_echo or self.log.is_debug:
659
+ self.log.info(f">> {key}{cmd_str}", uptrace=uptrace)
575
660
  command = self.format_command(command, sudo)
576
661
  ret = None
577
- log_fd = os.fdopen(os.open(self.log_name, os.O_RDWR | os.O_CREAT | os.O_APPEND,
662
+ if not log_name:
663
+ log_name = self.log_name
664
+ log_fd = os.fdopen(os.open(log_name, os.O_RDWR | os.O_CREAT | os.O_APPEND,
578
665
  stat.S_IWUSR | stat.S_IRUSR), 'a+')
579
666
  try:
580
667
  check = False if ignore_error else True
@@ -593,8 +680,8 @@ class Tools():
593
680
  self.log.error(error_log, uptrace=uptrace)
594
681
  elif warn_log:
595
682
  self.log.warning(warn_log, uptrace=uptrace)
596
- else:
597
- self.log.error(f"执行命令 {key}{command} 错误, 日志: {self.log_name}", uptrace=uptrace)
683
+ elif show_error_log:
684
+ self.log.error(f"执行命令 {key}{cmd_str} 错误, 日志: {log_name}", uptrace=uptrace)
598
685
  log_fd.flush()
599
686
  log_fd.close()
600
687
  raise e
@@ -613,10 +700,11 @@ class Tools():
613
700
  stdin = None
614
701
  command_echo = kwargs.get("command_echo", True)
615
702
  uptrace = kwargs.get("uptrace", 0) + 1
616
- ignore_error = kwargs.get('ignore_error', False)
617
- capture_output = kwargs.get('capture_output', False)
618
- if command_echo and not self.log.is_debug:
619
- self.log.info(f">> " + ' | '.join(commands), uptrace=uptrace)
703
+ ignore_error = kwargs.get("ignore_error", False)
704
+ capture_output = kwargs.get("capture_output", False)
705
+ append_output = kwargs.get("append", False)
706
+ if command_echo or self.log.is_debug:
707
+ self.log.info(f">> " + " | ".join(commands), uptrace=uptrace)
620
708
  for command in commands:
621
709
  stdout = TemporaryFile(flag)
622
710
  cmd = self.format_command(command, False)
@@ -633,8 +721,14 @@ class Tools():
633
721
  if stdin:
634
722
  context = stdin.read()
635
723
  if out_file:
636
- with os.fdopen(os.open(out_file, os.O_WRONLY | os.O_CREAT,
637
- stat.S_IWUSR | stat.S_IRUSR), flag) as fp:
724
+ flags = os.O_WRONLY | os.O_CREAT | os.O_TRUNC
725
+ if append_output:
726
+ flags = os.O_WRONLY | os.O_CREAT | os.O_APPEND
727
+ mode = stat.S_IWUSR | stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH
728
+ with os.fdopen(
729
+ os.open(out_file, flags, mode),
730
+ flag,
731
+ ) as fp:
638
732
  fp.write(context)
639
733
  stdin.close()
640
734
  if capture_output:
@@ -658,16 +752,44 @@ class Tools():
658
752
  cmd = [f"find {self.conan_data} -maxdepth 4 -mindepth 4 -type f -name *.count*", "xargs rm -f"]
659
753
  _, _ = self.pipe_command(cmd, out_file=None)
660
754
 
661
- def get_profile_config(self, profile_name) -> (Profile, OrderedDict):
662
- """根据profile文件名获取~/.conan/profiles对应文件的配置内容"""
663
- if not profile_name:
664
- return None, None
665
- profile_file = os.path.join(self.conan_profiles_dir, profile_name)
666
- if not os.path.isfile(profile_file):
667
- raise BmcGoException(f"{profile_file} 文件不存在")
755
+ def get_profile_config(self, profile_name):
756
+ if misc.conan_v2():
757
+ return ProfileLoader(".temp").load_profile(
758
+ profile_name, self.conan_profiles_dir
759
+ ), {}
760
+ else:
761
+ """根据profile文件名获取~/.conan/profiles对应文件的配置内容"""
762
+ if not profile_name:
763
+ return None, None
764
+ profile_file = os.path.join(self.conan_profiles_dir, profile_name)
765
+ if not os.path.isfile(profile_file):
766
+ raise BmcGoException(f"{profile_file} 文件不存在")
767
+
768
+ profile, profile_vars = read_profile(profile_name, os.getcwd(), self.conan_profiles_dir)
769
+ return profile, profile_vars
668
770
 
669
- profile, profile_vars = read_profile(profile_name, os.getcwd(), self.conan_profiles_dir)
670
- return profile, profile_vars
771
+ def get_conan_package_folder(self, package, install_args):
772
+ """
773
+ 安装conan包到指定outdir目录
774
+ """
775
+ tmpdir = TemporaryDirectory()
776
+ graph_file = os.path.join(tmpdir.name, "package.json")
777
+ cmd = f"conan install --requires='{package}' {install_args}"
778
+ cmd += f" -f json --out-file={graph_file}"
779
+ self.run_command(cmd, ignore_error=False)
780
+ return self.get_package_folder_from_graph_file(graph_file, package)
781
+
782
+ def install_conan_package_to(self, package, install_args, outdir):
783
+ """
784
+ 安装conan包到指定outdir目录
785
+ """
786
+ package_folder = self.get_conan_package_folder(package, install_args)
787
+ if not package_folder:
788
+ raise errors.BmcGoException(f"未找到{package}包的打包目录,可能包不存在或构建失败")
789
+ for file in os.listdir(package_folder):
790
+ source = os.path.join(package_folder, file)
791
+ cmd = ["/usr/bin/cp", "-arf", source, outdir]
792
+ self.run_command(cmd, ignore_error=False)
671
793
 
672
794
  def _save_tempfile_safety(self, temp_fd, target_file, show_log=False):
673
795
  lock_fd = open(self.lock_file, "r")
bmcgo/worker.py CHANGED
@@ -120,7 +120,7 @@ class WorkStatusClient():
120
120
  @staticmethod
121
121
  def __comm(msg, ignore_error):
122
122
  fd = socket(AF_INET, SOCK_STREAM)
123
- fd.settimeout(2)
123
+ fd.settimeout(10)
124
124
  while True:
125
125
  try:
126
126
  fd.connect(("", WORK_SERVER_PORT))
@@ -202,7 +202,7 @@ class WorkerScheduler(Process):
202
202
  if self.klass == "":
203
203
  return None
204
204
  # bmcgo的任务类名固定为TaskClass
205
- if self.klass.startswith("bmcgo"):
205
+ if self.klass.startswith("bingo") or self.klass.startswith("bmcgo"):
206
206
  work_path = self.klass
207
207
  class_name = "TaskClass"
208
208
  else:
@@ -1,13 +1,13 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: openubmc-bingo
3
- Version: 0.5.277
3
+ Version: 0.6.2
4
4
  Summary: Tools provided by openubmc
5
5
  Home-page: https://openubmc.cn
6
6
  Classifier: Programming Language :: Python :: 3
7
7
  Classifier: License :: OSI Approved :: Mulan Permissive Software License v2 (MulanPSL-2.0)
8
8
  Classifier: Operating System :: OS Independent
9
9
  Description-Content-Type: text/markdown
10
- Requires-Dist: conan <=1.62.0
10
+ Requires-Dist: conan
11
11
  Requires-Dist: cryptography <=42.0.7
12
12
  Requires-Dist: dbus-python
13
13
  Requires-Dist: ecdsa
@@ -19,6 +19,7 @@ Requires-Dist: jsonschema
19
19
  Requires-Dist: launchpadlib
20
20
  Requires-Dist: mako
21
21
  Requires-Dist: meson
22
+ Requires-Dist: node-semver ==0.6.1
22
23
  Requires-Dist: paramiko <4.0.0
23
24
  Requires-Dist: protobuf ==3.19.1
24
25
  Requires-Dist: psutil
@@ -27,6 +28,7 @@ Requires-Dist: pyinstaller
27
28
  Requires-Dist: pyopenssl <=24.1.0,>=23.2.0
28
29
  Requires-Dist: pysftp
29
30
  Requires-Dist: pyyaml-include
31
+ Requires-Dist: tqdm ==4.67.1
30
32
  Requires-Dist: typeguard ==2.13.3
31
33
 
32
34
  build and code generate tools